Sign in to follow this  
jbrennan

Where networking code (client/server) belongs in a 2D tile-based game engine

Recommended Posts

I'm writing a simple iOS game to teach myself game programming. It's a simple 2D tile-based platformer, and the camera is fixed. Input comes from the accelerometer in the device. I've got all that moving and now I'm starting to add some multiplayer to it (2-4 players). But I'm having a little trouble fitting that in.

Multiplayer goes through Apple's GameCenter service, and I've got that all set up and working. I am at the point now where:
1. All devices can connect to each other
2. I can send packets to all players (or just specific ones)
3. I can elect a device to act as the "Host" or "Server", where all the logic should go.

But now I'm a bit stuck at just how the architecture of this game should work. Below I'll show a basic pseudo-code outline of how my game works currently:

[code]
// Main game loop
void gameLoop () {
// Called around 60 times/sec
// Calculates a delta… assume that's done
makeGameControllerUpdateCurrentSceneWithDelta(delta);
render();
}



// Where the game controller updates the current Scene (aka level)
void makeGameControllerUpdateCurrentSceneWithDelta(delta) {
// input has already been received from the device's accelerometer at this point.
// Assume the scene is not in a paused state and thus should be updated…

// Update every Entity (player) in the scene
updateAllEntitiesWithDelta(delta);

// Do collision detection
updateCollisionDetectionForAllEntitiesWithDelta(delta);

// Check to see if a player has won
updateMatchStateWithDelta(delta);

// Update UI
updateUIWithDelta(delta);
}
[/code]


So my basic question is, where does my networking code go? Also, how should my networking really work? That is, my understanding is:
1. All players should send data to the host device on every frame (or less, maybe say 20 times per second?).
2. The host device computes the real logic of the game (collision? win conditions? updating entity positions? What?)
3. The host sends the new "truth" to all players in the game
4. All players then update immediately? (OR Should this "from the server" value be stored for the next time they render? I guess those are both the same thing)

Making the clients wait lock-step for the server's truth to come back seems like it would really interrupt the flow of the game (if on a cellular network, for example, it could get bad). So I'm guessing client-side they should do some kind of prediction, but how? Just use the local input unless what comes back from the server tells them otherwise? But won't the "Server truth" be stale by then?


Thanks so much for any help you can offer!

Share this post


Link to post
Share on other sites
I am also in the state of learning, so i'll do what i can to answer you questions.

1. This depends on alot of things. For example an FPS might need to send user input directly as recived, while an mmp might need to queue up some data before sending it. You could also prioritize you packets; input gets sent every frame, but chat messesages every 20ms.

2. The host, or server if you will, runs the entire game simulation. This is done to keep control over your clients, because lets say someone tickles their clieng to send false data, aka cheat, then it does not matter because you got his real position ln the server.

3. Yes, correct. All clients should trust you server and not their own simulations.

4. Updating the clients position right away might not be the best thing to do, but again this depends on your game. If possible, you should only update an entities position when its too far off, say 10-50 pixels. If you ever played WoW you might have noticed that sometimes players jump to a new position. This is when the client notices that the player is way off, and decides to use the correct position from the server.

The basic idea is that all clients and the server runs their own simulatkons, but when needed the clients update theirs with correct values from the server.

Hope i could help you in someway! :)

Share this post


Link to post
Share on other sites
[quote name='Zomgbie' timestamp='1298443673' post='4777862']
I am also in the state of learning, so i'll do what i can to answer you questions.

1. This depends on alot of things. For example an FPS might need to send user input directly as recived, while an mmp might need to queue up some data before sending it. You could also prioritize you packets; input gets sent every frame, but chat messesages every 20ms.

2. The host, or server if you will, runs the entire game simulation. This is done to keep control over your clients, because lets say someone tickles their clieng to send false data, aka cheat, then it does not matter because you got his real position ln the server.

3. Yes, correct. All clients should trust you server and not their own simulations.

4. Updating the clients position right away might not be the best thing to do, but again this depends on your game. If possible, you should only update an entities position when its too far off, say 10-50 pixels. If you ever played WoW you might have noticed that sometimes players jump to a new position. This is when the client notices that the player is way off, and decides to use the correct position from the server.

The basic idea is that all clients and the server runs their own simulatkons, but when needed the clients update theirs with correct values from the server.

Hope i could help you in someway! :)
[/quote]
As I stated in my question, it's a 2D platformer game, not FPS or MMO (although I'm sure some of the concepts are similar). But I'm glad my basic thoughts seem to be correct.



So that helps re-affirm what I was thinking but I'm still unsure of where the code belongs, how often to send, how to handle prediction+correction.

Share this post


Link to post
Share on other sites
Every frame is too much. You should send them periodically, maybe once every 50ms or 100 ms, depending on round trip time. You should be using some form of simulation on the client side to hide latency.

Share this post


Link to post
Share on other sites
[quote name='smr' timestamp='1298500167' post='4778163']
Every frame is too much. You should send them periodically, maybe once every 50ms or 100 ms, depending on round trip time. You should be using some form of simulation on the client side to hide latency.
[/quote]

OK, that makes sense too. So all clients send to the server, server creates its "truth simulation" of where everyone should be, any collisions that happened, etc. And then the server sends this new info to all the clients.

At this point though, all the clients will already be, say, 5 frames ahead. So what are they to do? If the server said my client should be at x,y but in that time I've moved to x+5, y then should my player jump back? Maybe the network will be fast enough that this won't really happen visibly to the user, I really don't know (first time doing any real-time networking of this sort). Thoughts?

Share this post


Link to post
Share on other sites
in my 2D engine i made it this way:
after user presses the button to walk a packet is sent to the server and then to other clients (instantly) that the user walks right,
all users see that guy walking right and every 130px he re-sends the walking right packet, else other users would see him stopping after 150 px (walking 130px == ~600ms so its not that fast at all )

its just amazing, tested with 20 open clients on my dekstop computer and 10 clients on my laptop, my eyes cannot see any difference in moving position !

ofc u can make it per 50px or 200px :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this