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?
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.:
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.
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.
now
and you send a message to start at exactlynow + 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\$