# How to synchronize clocks in multiplayer game?

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?

• 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
• @StevenStadnicki Network delays do not make this impossible. The general problem is called "clock synchronization" and it's well studied. (However, if you only control the endpoints, then it's not possible to account for asymmetry of delays.) – Praxeolitic Sep 18 '17 at 14:22
• I may be misunderstanding your problem, but can you not just make the message you send to clients indicate a start time slightly in the future? If the time is now and you send a message to start at exactly now + halfSecond then as long as they all receive the message within half a second, and as long as their system clocks are correctly synchronised, they will all start at the same time. – Mark Jan 30 '18 at 13:12

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.

• 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
• 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
• 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
• It's theoretically impossible if each player controls their own bat, because it takes a non-zero amount of time for that information to reach the other computer, during which the 2 sides have different information. Instead you find ways to cope with the differences. Your problem isn't really any different from any other fast-paced online game and there are several other questions on how to handle networking for them on this site. One is here: gamedev.stackexchange.com/questions/22444/… – Kylotan Dec 21 '12 at 18:09

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).

I recommend synchronizing system timers on all clients and the server by means of NTP [Stratum 2] protocol, then the server sends a command to start the game at specified time, say, when all the timers reach 0:05:00. This approach should give you 3-4 ms accurate synchronization, I believe.