# How to sync game tick in peer to peer game?

I am making a 2-player iphone action game using a synchronization service (in this case Firebase). The service allows state syncing through the internet, but I have to execute all game logic on the phones.

I've read a bunch of game networking articles, and since I have no server, it seems like if I can get both phones to start the game at "exactly" the same time in realtime, I can adjust everything from there. (Planning on using a "tick" count on each phone, and sending the tick along with actions, then rewinding the simulation if necessary. The phones divide the game into halves to determine authority).

But how do you get remote clients to start a game tick at the same time?? It seems like this would be necessarily in lock step peer-to-peer, and something like it in FPS games.

The strategy I'm using now tries to have one client "guess" the other client's clock time, including ping time. If correct, they both start the game based on the guess (since for that message it was on).

• a: sends a.localTime
• b: receives message. Returns b.localTime, and dTime(a-b)
• a: receives message. Returns a.localTime, and dTime(b-a)
• b: receives message. If a.localTime + dTime(b-a) is very close to new b.localTime, send accept message.
• b: starts game at: new b.localTime + 1 second
• a: receives accept. Starts game at accepted a.localTime + dTime(b-a) + 1s

I made a little number counter thing to go with the tick, and they're just barely off. I can't see how this is possible though, since A "guessed" B's time, they should start at exactly the same time...

See anything wrong with my method? What's an easier way? I'm trying to avoid using a server if possible.

• exact synchronisation of clocks is impossible, so the question is how synchronised do you need? You'll need better sync if it's a twitch shooter vs a turn based strategy game. What kind of game are we talking about? – Martin May 28 '13 at 14:48
• It is an action game where wizards shoot spells at each other. Timing is fairly critical because you can block the other wizard's spells by countering it at the last second. – Sean Clark Hess May 28 '13 at 14:59
• I've heard it's impossible, but I don't see why I couldn't theoretically within 1ms with the algorithm above. – Sean Clark Hess May 28 '13 at 15:04
• Delay Jitter will prevent the clocks from reliably getting to within 1ms of each other. Basically... the amount of time it takes for a packet from A to B will vary. – John McDonald May 28 '13 at 15:19
• I suggest you take a look at this article. It's for client/server scheme but I think its worth considering gafferongames.com/networking-for-game-programmers/… – XiaoChuan Yu May 28 '13 at 16:00

I think your algorithm is pretty close to one I wrote in this answer to a similar question, but I'm concerned that this line in your algorithm isn't doing what you'd like:

b: receives message. If a.localTime + dTime(b-a) is very close to new b.localTime, send accept message.

You should be figuring out roughly how long the packets are taking to get from a to b, and adjust b's clock to equal a.localTime - (averageRTT / 2). RTT stands for Round Trip Time and is easily acquired by timing how long it takes the other side to reply.

The reason that clock sync methods can only get so accurate is because the time it takes packets to get from A to B will vary from packet to packet. A lot of the variance comes from each piece of hardware between point A and B. For an example:

• Router queues can add a variable delay
• If you're using TCP and packets get dropped, there will be an additional delay
• Wireless transmission systems are particularly lossy and can introduce delays
• etc.

Since you can't be sure how long it will take each packet to arrive, the best you can do is get a reasonable estimate of the round trip time (RTT). Since the RTT is used to sync the clocks, the best anyone can do is related to how accurate the RTT is.

• Hmm, I totally that averageRTT is useful for most algorithms, but imagine that instead I could magically start tick 0 on both phones at exactly the same time. Then it wouldn't matter that packet time varies, because I could include the tick with the packet, and rewind the simulation no matter when it arrives. Make sense? It seems like either you didn't quite understand what I was going for, or there's something fundamental I'm not understanding about networking :) – Sean Clark Hess May 28 '13 at 22:18
• You can start tick 0 on both phones at nearly the same real-time, and that's all anyone can do. In the linked answer, I explain how to sync clocks, and above I try to explain why it's the best that can be done. As you said, once the clocks are nearly the same, you should send the current tick with each action to other side. This article may be a bit confusing, but it describes how the source engine does networking (after clocks are synced). I'm happy to talk at length in chat – John McDonald May 29 '13 at 0:14