9
\$\begingroup\$

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?

\$\endgroup\$
4
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jul 11, 2012 at 18:27
  • \$\begingroup\$ 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 \$\endgroup\$
    – GameCoder
    Commented Jul 11, 2012 at 18:41
  • 1
    \$\begingroup\$ @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.) \$\endgroup\$ Commented Sep 18, 2017 at 14:22
  • \$\begingroup\$ 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. \$\endgroup\$
    – Mark
    Commented Jan 30, 2018 at 13:12

3 Answers 3

16
\$\begingroup\$

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.

\$\endgroup\$
11
  • 2
    \$\begingroup\$ 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. \$\endgroup\$
    – Kylotan
    Commented Jul 11, 2012 at 20:21
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – GameCoder
    Commented Jul 12, 2012 at 9:36
  • 2
    \$\begingroup\$ A good user experience does not require precise synchronisation. That's why most games don't attempt it. \$\endgroup\$
    – Kylotan
    Commented Jul 12, 2012 at 11:28
  • 1
    \$\begingroup\$ 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/… \$\endgroup\$
    – Kylotan
    Commented Dec 21, 2012 at 18:09
  • 1
    \$\begingroup\$ @SOFe It doesn't really matter. Even if it were possible to measure the previous upload or download time precisely, it's no guarantee that the next message will have the same latency. Perfect synchronisation is impossible so it's best not to even try. All we're doing here is forming a reasonable estimate, which can be used to decide buffer sizes and the like. \$\endgroup\$
    – Kylotan
    Commented Mar 28, 2021 at 17:15
3
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .