Tuesday, February 4, 2020

turn based - Start timer in two clients the same time


I want to create a client/server turned-based game where each player will have 5 seconds in order to play. If extends this time will be other player's turn to play. In order to do this, I have created a timer in both clients. I have created a method to the server that will send a message to both clients to start their timers. When clients will receive the message they will start counting. The problem is that due to the network lag I cannot be sure that both clients started counting in the same time. Is there a way in order to ensure this?


P.S.: When I say "the same time" I mean the same second. I'm not referring in millisec or microsec.



Thanks in advance!



Answer



Note that your current solution will likely start both timers within 1 second of eachother, probably even within a few hundred milliseconds. Getting this more accurate is a difficult problem to solve with certainty, but you can get it "close enough" for games, although it's still not easy. I would also note that timing mechanisms on two different machines may not always match, so either read up on that, or experiment with your method. I had problems where one machine's Timer object would run faster than the exact same code on a slower machine.


To sync the start-time of timers on two different machines, I would go about this in a few steps:



  1. Use a time sync protocol like NTP to get the clocks in sync

  2. The server would send out a message to indicate a future time that would indicate when to start the game. This must be far enough in the future to allow for lag hiccups.

  3. When the future date is hit, both clients start





How NTP works (roughly):


One of your machines will act as the authoritative clock (likely your server). By clock, I simply mean some method to measure the passing of time, it does not have to be your wall clock. In games, "time" is often measured from the start of the game.


The problem: If your server sends the current time to the clients, they will receive this information after some period of time (~RTT / 2) and the server's time will have moved forward already. It's impossible to know what the Round Trip Time (RTT) will be for any given packet. So how can the client's time ever match the servers exactly?


The solution: It can't match exactly, but you can get it close by measuring how long it takes for packets to get between the server and client and use that to adjust the time sent from the server. So, the server will send the current time, then after some unknown delay the client will have what used to be the server's time. The client then sends an acknowledgement to the server, and when the server gets this, it calculates the RTT based on the amount of time that has passed since the first packet, then sends the RTT back to the client where it can be used to adjust the time.


eg:


//Server Time is T0
Server sends out T0

-- Packet travels with a delay of 100ms


//Server Time is T100
Client receives T0 from the server
Client sends an acknowledgement to the server (ACK for short)
Client sets time to T0, even though it is wrong

-- Packet travels with a delay of 100ms

//Server Time is T200, Client time = T100
Server receives ACK and calculates RTT as 200ms (Current Time - Start Time)
Server sends RTT of 200ms to client


//Server Time is T300, Client time = T400
Client receives message from server about RTT being 200ms
Client adjusts clock to T300 (Client Time - (RTT / 2))

// Server Time is T400, Client time = T400
And there was much rejoicing

The RTT is usually calculated multiple times and an average is used.





So, once the clocks are in sync (roughly), the server can send out a command to start the game at some future time. Both clients should receive this message with ample time to spare, then start their timers at the same real-world time.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...