Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have 2 to 3 clients, that can exchange messages through Apple Game Center.

The only synchronization I need is: start the game at the same moment.

I guess this involves clock synchronization. How to accomplish this?

share|improve this question
3  
The short answer is 'you can't'. The inevitable (and inconsistent) delay in communications between devices means that even if one device says 'I believe it is now 12:00:00.00' then it could easily be anywhere from 12:00:00.10 to 12:00:05 by the time that message is received elsewhere. In a server-based model you can't do much better than just having your server send the 'Start game' message to the clients at the same time. –  Steven Stadnicki Jul 11 '12 at 18:27
    
Good that I do not need perfection. How to do it better than nothing? Maybe: each player sends "START" message, and starts as soon it receives START message from all other players –  GameCoder Jul 11 '12 at 18:41
add comment

2 Answers 2

Steven's comment is right: this is theoretically impossible to do.

Luckily, in practice you can come close, which is how things like NTP work.

For example, better than just sending a message out to 3 clients saying "start now", you can exchange a couple of ping messages beforehand to measure the time it takes to get a message to the client, and when you send the start message, instead of "start now" say "start in X milliseconds" and adjust X for the different times taken for a message to arrive.

eg.:

  • You send a message to Client 1 and get a response back 20ms later. You guess that it takes roughly 10ms to get a message to client 1.
  • You do the same for Client 2 and get a response 28ms later - so the transmission time there is likely to be about 14ms.
  • So you send out a message to Client 1 saying "start the game in 50ms" and send one to Client 2 saying "start the game in 46ms". Client 2 will get the message about 4ms later, but will wait 4ms less before starting the game.

This can't guarantee synchronisation because the time taken to send a message across the internet varies, and because it can be different in each direction. The first you can reduce the effects of by performing the measurement several times and taking a median reading. The second is trickier and may be theoretically impossible to solve (though I can't remember the proof right now). The good news is that you probably don't need that much accuracy.

share|improve this answer
    
I will probably need to limit my apps activity during the synchronization – right now I give some CPU time to network subsystem at each drawing frame. If framerate is 30 FPS, then I will answer the ping in 1/30 = 33 ms anyway. I could also add the 33 ms, or the difference between "TCP stack receive time" and my current MilisecondTicks().. –  GameCoder Jul 11 '12 at 19:18
1  
If you're hoping to keep the systems precisely synchronised frame-by-frame during play, I think that's a losing game and you should give up now. Clocks and latency will drift and information will always take time to travel. Whatever you're trying to do, you probably don't need this level of synchronisation. –  Kylotan Jul 11 '12 at 20:21
    
I think we are missing the point. It is not perfection that bothers me, it's user experience. This can be good or better, and I would like the better. That's it. –  GameCoder Jul 12 '12 at 9:36
1  
A good user experience does not require precise synchronisation. That's why most games don't attempt it. –  Kylotan Jul 12 '12 at 11:28
    
I still believe in gradation. –  GameCoder Jul 12 '12 at 12:42
show 4 more comments

As mentioned, this is impossible, so I'd try another approach:

If you don't have a dedicated server, elect one participating client to become the host (this can be transferred if the need arises to).

The host will now perform all important game logic, like hit detection, AI controls, inventory handling, etc. as well as time tracking (i.e. dictating game time).

The other clients will just try to stay in sync to the host, trying to estimate or approximate the expected value. If lag increases or there's packet loss, things might get choppy, but it's trivial to catch up, essentially just waiting for the next update.

Most games (especially FPS) hide this fact by doing their own local calculation for the player's own movement, shots being fired, etc. to avoid the game feeling laggy. Everything is still corrected based on server data. This can lead to some confusion, e.g. you see yourself shooting the enemy, but the same moment you drop dead (without the enemy taking a hit), but it's still a far better approach than full synchronization.


If you still insist on keeping everything in sync, you'd probably want to create some kind of step or frame counter, so all client only process one logic step, then syncing their data, etc. Keep in mind that this can be both bandwidth intensive as well as laggy, so I wouldn't recommend doing that unless you've got lots of data otherwise and your gameplay is turn based (e.g. Artillery/Worms style games).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.