Sign in to follow this  
FredrikHolmstr

Synchronizing server and client time

Recommended Posts

FredrikHolmstr    262
I know this has been debated a lot on the forums here, and I have searched and probably read 25+ threads - I've done my research, I have a couple of pretty simple questions that I would like answered if possible.

[b]Question 1: [/b]The standard way of synchronizing time between client is something like this:
[list=1][*]Client sends timestamp to server[*]Server responds with clients timestamp + its own timestamp[*]Client does something like this when it gets the server response: [i]localTime = servertime + ((currentTime - timestampSentToServer) / 2)[/i][*]This gives the client a timer that is somewhat approximate to the server, step 3 can be repeated one or many times to create a more accurate time stamp[/list]
Is my reasoning correct here?
[b]
[/b]
[b]Question 2: [/b]You have two options, either you stick to your guns with the initial clock sync (as describe in question 1) for the entire game or you update it at set intervals (every packet, every 20 seconds, whatever) and adjust accordingly. Is there a preferred approach here (stick to your guns, or update as you go along), what are the benefits of one or the other? And if you update the timer as you go along how do you deal with times where the client might end up way of (either in the past or the future)?
[b]
[/b]
[b]Question 3: [/b]I think this is my most important question (as I think I got 1 and 2 groked in my head): The two previous questions talked about syncing using time but the concept of [i]time[/i] isn't really important is it? What you're really looking for is how many ticks behind the client is, isn't it? Both the server and the client runs on the same tick speed, 15ms (66.66Hz), they both hold a tick counter that keeps track of the current tick they're on, wouldn't this scheme be possible:

[list=1][*]The client connects[*]Server sends its current tick count to the client[*]Client adopts the servers tick count, incrementing it for each tick that passes[/list]
Now when the client sends a command to the server, it attaches it's tick count to that message so the server knows when in time (according to the client) this command was generated, so things like lag compensation, etc. can be employed? I suppose my question is pretty simple: Is there a reason the time/clock is used instead of just what really matters to the game: [b]amount of ticks passed.[/b]
[b]
[/b]
Thanks again for all the help this forum has given me!

Share this post


Link to post
Share on other sites
ApochPiQ    23003
Especially when dealing with PCs, it is not possible to guarantee that one machine will elapse time at the same fixed rate as another. Even on a single machine you won't get perfect n-Hz cycles, there will be variances between frames/ticks. The purpose of using a time value instead of a tick count is to help absorb these variances.

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='ApochPiQ' timestamp='1314265316' post='4853573']
Especially when dealing with PCs, it is not possible to guarantee that one machine will elapse time at the same fixed rate as another. Even on a single machine you won't get perfect n-Hz cycles, there will be variances between frames/ticks. The purpose of using a time value instead of a tick count is to help absorb these variances.
[/quote]

Of course, it's so obvious! Thanks man :)

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
So, the "best solution" in my eyes seems to be this:

[list=1][*]On every world state (every 45ms, 22.22Hz) that is sent from the server, the current servers game time is attached[*]The client sets it's local gametime clock like this: [i][b]gametime = server game time + (avarage roundtrip/2)[/b][/i][*]Every tick the client doesn't get an update from the server (every 15ms, 66.66Hz) it increments its local gametime with 15ms (the tick time)[*]The server also keeps track of the last gametime that was sent to each client[*]When the client issues a command such as "FORWARD" it attaches it's local, estimade gametime: [i][b]lastReceivedServerTime + (avarageRoundtrip/2) + (currentTime - timeSinceLastServerUpdate) [/b][/i][*]When the server receives a command from a client it verifies that the attached gametime falls within a valid range, say +/- (100 + avarageRoundTrip/2) ms of current time, if it falls outside the command is discarded, if not it gets snapped to the nearest tick-size and put in the queue of commands to be processed.[/list]
Is this scheme plausible? Good? bad?

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
Ok, I think I got something works reasonably well in code now, one last itching question:

How do you deal with the fact that sometimes your client will jump ahead of the server? Occasionally, maybe once every 10 updates or something, the client time will be further into the future then the server time I received. How do I deal with this? Do I adjust the multiplier of the RTT, say that I take 0.3 instead of 0.5 of the RTT and add, etc.? Do I skew the whole time back/forward with some small multiplier like 0.000001? The most logical to me would be to take less of the RTT then half, since that's what's giving me the wrong offset (probably server->client is faster then client->server). For example doing RTT/2 - (abs(negativeDiff)/2).

What would I do with commands that are issued when in "future" time on the client? Should I snap them to the correct time, send them with the future timestamp?

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
Ok this is becoming a lot, but figured I might as well ask while it's in my head: Why are we "required" to add the RTT/2 time to the server time we get back from the server on the client? Can't we just keep the server time we get from the server and increase it as we go along, just syncing it once in the beginning? Considering all the updates we will get from the server also will be RTT/2 behind? Even if our RTT changes considerably, say we start with a 100ms RTT, but even if we swing down to 15ms RTT or up to 500ms RTT, the time will still be in "sync" (as in it will be behind with as much as it's always been, even though updates will take longer to send/receive) ? Maybe I'm confusing myself.

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
Becoming a monologue here, but I hope someone has the time to look at my questions, my main problem now is dealing with negative numbers, which seem to be happen quite a lot for me, here's a print out of the log I create when I update the clients gametime with [b][i]server gametime+(rtt/2) [/i][/b]and how much the previous time was wrong with (negative time: we're [b]ahead[/b], positive: we're [b]behind[/b])


[code]
diff: 0.007507324
diff: 0.007507324
diff: -0.01499939
diff: -0.007507324
diff: 0.02252197
diff: -0.007507324
diff: 0.007507324
diff: -0.02250671
diff: 0.007522583
diff: 0.02249146
diff: -0.02999878
diff: 0.02250671
diff: -0.01498413
diff: 0.007492065
diff: -0.02249146
diff: 0.02249146
diff: -0.007492065
diff: 0.01501465
diff: -0.007507324[/code]

As you can see negative times are very common for me, however I have been getting pretty good offsets about 5-25ms diff only. Is this the way it's suppoed to be, with a long of negative "in the future" values, or am I doing something wrong?

Share this post


Link to post
Share on other sites
ApochPiQ    23003
Your distribution looks to be about 50%, so I'd say it's pretty much to be expected. Any form of round-trip compensation is going to introduce some inaccuracy, but seeing that inaccuracy evenly mixed between too-fast and too-slow is more or less what you want.

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='ApochPiQ' timestamp='1314290856' post='4853719']
Your distribution looks to be about 50%, so I'd say it's pretty much to be expected. Any form of round-trip compensation is going to introduce some inaccuracy, but seeing that inaccuracy evenly mixed between too-fast and too-slow is more or less what you want.
[/quote]

Thanks! So last one: What do I actually DO (code/algorithm wise) when I think I'm in the future? Do I snap to 0.0 offset, or do I keep going like nothing happened - since I know I'm never actually IN the future?

Share this post


Link to post
Share on other sites
Shift53    123
[quote name='ApochPiQ' timestamp='1314265316' post='4853573']
Especially when dealing with PCs, it is not possible to guarantee that one machine will elapse time at the same fixed rate as another. Even on a single machine you won't get perfect n-Hz cycles, there will be variances between frames/ticks. The purpose of using a time value instead of a tick count is to help absorb these variances.
[/quote]

I was wondering something... Assuming we are talking about time variance, not hardware saturation, how does the time variance matter exactly? Can't you simply do a (TickCount * Frequency) formula to determine the time of a given frame and ignore the variance that gets reset every frames? It's not as if the variance would stack up and make the game drift.

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='Shift53' timestamp='1314292258' post='4853731']
[quote name='ApochPiQ' timestamp='1314265316' post='4853573']
Especially when dealing with PCs, it is not possible to guarantee that one machine will elapse time at the same fixed rate as another. Even on a single machine you won't get perfect n-Hz cycles, there will be variances between frames/ticks. The purpose of using a time value instead of a tick count is to help absorb these variances.
[/quote]

I was wondering something... Assuming we are talking about time variance, not hardware saturation, how does the time variance matter exactly? Can't you simply do a (TickCount * Frequency) formula to determine the time of a given frame and ignore the variance that gets reset every frames? It's not as if the variance would stack up and make the game drift.
[/quote]

I was thinking the exact same thing in this instance, since the _only_ reason we sync time is to make sure we don't perform X+1 before we perform X+2, and the variance gets cancelled out every frame anyway. But maybe there are more things at play here :)

Share this post


Link to post
Share on other sites
hplus0603    11347
[quote name='fholm' timestamp='1314292478' post='4853733']
I was thinking the exact same thing in this instance, since the _only_ reason we sync time is to make sure we don't perform X+1 before we perform X+2, and the variance gets cancelled out every frame anyway. But maybe there are more things at play here :)
[/quote]

I think you should use your time estimation algorithm for each packet you send and receive. Then you should update your approximation of client/server clock offset using a leaky integrator -- when you have a new estimate of the offset N, calculate the actual offset O you will be using from old estimate oO as O = oO * 0.95 + N * 0.05. (You may want to adjust those factors -- 0.99 and 0.01 may actually works just as well and be more stable!)

You will be unlikely to be "ahead" of the server, because you will have an actual server timestep number in the packet you received.

Also, I prefer to ONLY use time step numbers in the protocol, rather than times. Time doesn't matter as much as time steps evolved per unit of time, and unit of time is what you measure using the local PC clock. (Note that offset and rate between PC clock and time steps may still be measured in fractional steps, even though only whole steps make it on the wire).


Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='hplus0603']
O = oO * 0.95 + N * 0.05.

[/quote]

So the algorithm should be like this: [i]gameTime = (oldGameTime * 0.95) + ((serverTimeStamp + (rtt/2)) * 0.05);[/i]
I suppose my question is if N in your algorithm should include the rtt/2 or just the timestamp from server?


[quote name='hplus0603']
Also, I prefer to ONLY use time step numbers in the protocol, rather than times. Time doesn't matter as much as time steps evolved per unit of time, and unit of time is what you measure using the local PC clock. (Note that offset and rate between PC clock and time steps may still be measured in fractional steps, even though only whole steps make it on the wire).
[/quote]

By timestep numbers do you mean "timestep X", "timestep X+1", "timestep X+2", so basically the tick/step-count? In my mind this last paragraph of yours conflicts with what your first two + the formula said, but I assume I'm missing something. When you send a command to the server do you do [i][b]gameTime/stepTime [/b]or do you just send your[b] gameTime?[/b][/i]

Again, thanks for all your help and your help in my other threads, very appreciated!


Share this post


Link to post
Share on other sites
FredrikHolmstr    262
I got a very nice implementation using the method/algorithm that [b]hsplus0603 [/b]described, using a leaky integrator with 0.99/0.01 which provides (as was clearly stated) very stable results and a smooth curve estimation without any jerkyness, etc. I have one last question, when my new estimate is a tiny bit behind (always behind the server) the previous estimate, how do I handle this? Do I just ignore it and go on trucking and let the server figure out the order of things? For example early on, I can have jumps like this:

[code]old: 5.665365
new: 5.654861[/code]

You can clearly see how the new estimate is 11ms before the old one, does this matter? or can I just continue on as I was? What I'm asking is: [i][b]Do I need to do anything special when my new estimate is "before" (in time) my old one?[/b][/i][b][i]
[/i][/b]
Here's the implementation for reference:

[code] public static void SetClientTime(float serverTime, float rtt) {
if(gameTime == 0.0f) {
gameTime = (serverTime + (rtt*0.5f));

} else {
gameTime = (gameTime * 0.99f) + ((serverTime + (rtt*0.5f)) * 0.01f);
}
}[/code]

The reason I'm asking is because, in my mind this would be confusing:

[list=1][*]I have "FORWARD" pressed down and I send this to the server with the current timestep (estimateGameTime/timeStepSize), call it X[*]At the start of the next simulation step I have received an updated gametime and now my estimated gametime is 11ms behind what I assumed it to be in in the previous simulation step[*]I send a new "FORWARD" command (since I have it pressed down till) to the server, but now when i send the current timestep (estimatedGameTime/timeStepSize) the timestep ends up at X-1[*]Server receives the command with timestep X and applies that[*]Server receives the command with timestep X-1 but notices the timestep is behind what was applied just before it[/list]
How would this be sorted out?

Share this post


Link to post
Share on other sites
smasherprog    568
I wouldn't have the client send a timestamp to the server. The client should be attempting to maintain synchronization with the server, not both ways (otherwise cheating can occur). The server should process the requests as they come in, so that the server isn't trying to go back and change an estimate of a players position (this is where cheating can occur). This also means that if a single player is laggy, then everyone else wont notice the problem- --only the laggy player will. Also, on the first pressing of the forward key, the client should send the request to move forward. If you continue to press the forward key down and do nothing else, there should be no new requests sent to the server. In other words, think of the client as continuing its last action until a change occurs. This will dramatically decrease the complexity of your program and the amount of data being sent back and forth. The server then sends its normal updates with a timestamp and some sort of position, speed, and direction information.

Hope that helps

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='smasherprog' timestamp='1314365979' post='4854046']
I wouldn't have the client send a timestamp to the server. The client should be attempting to maintain synchronization with the server, not both ways (otherwise cheating can occur). The server should process the requests as they come in, so that the server isn't trying to go back and change an estimate of a players position (this is where cheating can occur). This also means that if a single player is laggy, then everyone else wont notice the problem- --only the laggy player will. Also, on the first pressing of the forward key, the client should send the request to move forward. If you continue to press the forward key down and do nothing else, there should be no new requests sent to the server. In other words, think of the client as continuing its last action until a change occurs. This will dramatically decrease the complexity of your program and the amount of data being sent back and forth. The server then sends its normal updates with a timestamp and some sort of position, speed, and direction information.

Hope that helps
[/quote]


Ok, but if there is no need to send the time to the server, what is the need to sync the clock to the server? What is it actually used for? I imagined that I would need the clock time for when the client presses "FIRE" and then attach the timestamp to it so the server knows "when" in time the client fired, but I realized this is as simple as doing "receivedTime - (RTT*0.5)" on the server to get a decent approximate.

So what is this the synced time on the client actually *used* for?

Share this post


Link to post
Share on other sites
smasherprog    568
The server sends timestamps to the client, and the client attempts to sync with the servers time.
Here is how it should go ( there might be a better way)

Player A sends to server a request to fire a gun (no timestamp)
Server receives the request and does its necessary checks to ensure the request is valid. If everything is valid, the server then sends out player A shot a gun and attaches a timestamp to with it.
all players receive the gun fire event with the timestamp the server sent (which was when the server actually received the command, not when the player sent the request)

This actually will lead to a less jerky simulation because instead of having to play an event that occurred possibly 500 ms ago (which would be possible for laggy players), the event plays for an even that occured yourroundtrip/2.

In other words, you dont want the entire server at the mercy of laggy players (where events are received at a delay of 200 ms in the case of a laggy connection ). The server should continue blindly and if a request(command as you put it) is received, the server should treat it as happening then. Think of how your simulation would run if the server was running commands based on a laggy player. Imagine getting a few laggy players together and having them run around each other trying to fight, or collide. All the information would be running 200 ms in the past. The server would be freaking out trying to decide what to send out because the information is all interlaced and it would receive commands in the past which could be very bad and lead to very jerky simulations.

Basically, the server would have to hold all information being sent out to sync with the laggiest player otherwise, there would be many correction events that can occur with a player telling the server when he or she moved, or shot a gun. Player A (who has a bad ping) might tell the server that he moved forward 500 ms ago, but player B (who has a good ping) told the server that he shot at player A 30 ms ago. So the server receives player B's packet with the info and the server decides that player A should be dead. But then 470 ms later, the server receives a packet from player A saying that he was moving for the past 500 ms, which means that player B never actually hit player A.

The synced time on the client is used when the server sends the clients events that have occurred. The client will always be running in the past just behind the server by a time of roundtrip/2 ms. Our job as programmers is to try and guess the events that occur between the updates that we receive. If we guess wrong, we have to correct it. In most cases a wrong guess is a position change, in which case you can slowly adjust a players position over time instead of jerking the player into the correct position.

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='smasherprog' timestamp='1314369643' post='4854066']
The server sends timestamps to the client, and the client attempts to sync with the servers time.
Here is how it should go ( there might be a better way)

Player A sends to server a request to fire a gun (no timestamp)
Server receives the request and does its necessary checks to ensure the request is valid. If everything is valid, the server then sends out player A shot a gun and attaches a timestamp to with it.
all players receive the gun fire event with the timestamp the server sent (which was when the server actually received the command, not when the player sent the request)

This actually will lead to a less jerky simulation because instead of having to play an event that occurred possibly 500 ms ago (which would be possible for laggy players), the event plays for an even that occured yourroundtrip/2.

In other words, you dont want the entire server at the mercy of laggy players (where events are received at a delay of 200 ms in the case of a laggy connection ). The server should continue blindly and if a request(command as you put it) is received, the server should treat it as happening then. Think of how your simulation would run if the server was running commands based on a laggy player. Imagine getting a few laggy players together and having them run around each other trying to fight, or collide. All the information would be running 200 ms in the past. The server would be freaking out trying to decide what to send out because the information is all interlaced and it would receive commands in the past which could be very bad and lead to very jerky simulations.
[/quote]

Thank you so much, exactly what I needed! much love to you for this explanation! This is what made it "click" for me :)


Share this post


Link to post
Share on other sites
smasherprog    568
Cool. I actually continued to add more to the post above. I have this bad habit of thinking of things after I make a post then adding to the post. I think I did that like 3 times for this one :P

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='smasherprog' timestamp='1314370289' post='4854076']
Cool. I actually continued to add more to the post above. I have this bad habit of thinking of things after I make a post then adding to the post. I think I did that like 3 times for this one :P
[/quote]

I do the same thing, ha :) Just read the rest of it, I have one follow up question though:

So I get that the client time (that is somewhat in sync in with the server) is used when we receive events from the server, but [b]how [/b]is it used? To sort the events in the right order? Or is it just used to make better predictions (possibly correct our earlier predictions) ?

Share this post


Link to post
Share on other sites
smasherprog    568
[quote name='fholm' timestamp='1314370403' post='4854078']
[quote name='smasherprog' timestamp='1314370289' post='4854076']
Cool. I actually continued to add more to the post above. I have this bad habit of thinking of things after I make a post then adding to the post. I think I did that like 3 times for this one :P
[/quote]

I do the same thing, ha :) Just read the rest of it, I have one follow up question though:

So I get that the client time (that is somewhat in sync in with the server) is used when we receive events from the server, but [b]how [/b]is it used? To sort the events in the right order? Or is it just used to make better predictions (possibly correct our earlier predictions) ?
[/quote]

Well, yes to both questions. You need to be able to adjust things based on when they occured. For example, you are running in a world and receive a small lag spike for one second where you lose all information sent to you. Once you start receiving all the missed information, you will get things like, player A shot a gun 1020 ms ago and player B started running 1040 ms ago. So now the question becomes, what do you do with this information? The standard way is to play those events, but at a fast speed to catch up to where they should be now. So, all the animations, players speed -- everything runs at for example 3x speed. So, it will take about 300 ms to get events up to where they should be. Its like fast forward on VCRs ( you might not remember them, but I am old enough to!). So, you can use the timestamp to say, " wow, we are 1 second behind the server. I better play this animation really fast to catch up, otherwise I never will." If you are 50ms behind the server, your guess will be very close to exact ( should be very small, like .1 or .2 units max error) on where players are located so you can make small adjustments to a players position over time to correct their positions without speeding anything up.

But the client is synced so that the client can know what to do about information that is received late. You are always going to receive events that have already occurred. The syncing will help you know what type of measures you need to do in order to keep the client running correctly whether it is small adjustments (not noticeable because it is moving a player .1 units over 300 ms) or if the client is lagging badly, running everything at a faster than normal speed to catch up.

Share this post


Link to post
Share on other sites
hplus0603    11347
[quote name='smasherprog' timestamp='1314365979' post='4854046']
I wouldn't have the client send a timestamp to the server.[/quote]


The reason you send the client timestamp or clock to the server is so that you can measure round trip time, and so that you can adjust offset as appropriate. Also, for certain networking schemes, the timestamp for each event generated on the client is crucial for lag compensation.


O in my formula is the "offset" between client and server time, not the time itself. Thus, I'm assuming a client clock, which (indirectly) determines client timesteps.


timestep = (int)(clock() * StepsPerSecond - Offset)

Client sends "based on my timestep X, the following events happen" (which may be for more than one time step)

Server sends back "I received your timestep X data at my timestep Y" plus whatever other data is pending for the client.

When client gets this data, it measures its own timestep Z. This gives it enough information to figure out which way to adjust the offset. Calculate the "instantaneous" offset as N in the formula above, and adjust the "actual" offset O using the leaky integrator formula.


When starting up, you may want the leaky integrator to be more like 0.9/0.1, and as time goes on, move to 0.99/0.01. This allows you to quickly determine a good match, and then make it more stable once it's established. Or perhaps it's too complex to be worth it. Regarding the adjustments being such that time runs "backwards," I would treat that as a momentary lag on the client, where "nothing happens." If you get a good guess for the offset before you start simulating (from the first client/server handshake, say), and adjust it smoothly, it really shouldn't be a problem.

Share this post


Link to post
Share on other sites
smasherprog    568
I guess if TCP is used, the roundtriptime can be gathered from the tcpclass.

If UDP is used, then roundtriptime must be calculated, so cant the server and the client calculate the round trip time without the need for timestamps at all?

For example, client send the server packet ID 5 and the client notes its local time. Then, the server acknowledges receipt of the data and sends to the client that the packet was received. Then, the client receives the acknowledgement that the server received ID5. When the client receives this packet, it notes the the received time.
So the round trip time becomes the

roundtriptime = (time when client received acknowledgment of packet ID5) - (time when the client sent out packet ID 5) ;


Also, since the server can calculate the roundtriptime, wouldn't it know by inference what time the client has? For example, if the server knows the roundtriptime is 50 ms, the one way trip should be 25 ms. So, if the server time is 100000 ms, then the clients time would be 25 ms behind the server, correct?

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='hplus0603']
O in my formula is the "offset" between client and server time, not the time itself. Thus, I'm assuming a client clock, which (indirectly) determines client timesteps.
timestep = (int)(clock() * StepsPerSecond - Offset)
Client sends "based on my timestep X, the following events happen" (which may be for more than one time step)
Server sends back "I received your timestep X data at my timestep Y" plus whatever other data is pending for the client.
When client gets this data, it measures its own timestep Z. This gives it enough information to figure out which way to adjust the offset. Calculate the "instantaneous" offset as N in the formula above, and adjust the "actual" offset O using the leaky integrator formula.
[/quote]
Going to try to break this down into a flow:

[list=1][*]Server starts, incrementing its time step[*]Client starts, incrementing its time step, running a different timestep counter then the server, but which will be converted from/to server time using the offset[*]Client sends to the server its current timestep [b][i](x)[/i][/b] with a request[*]Server receives requests, responds with its current timestep [b][i](y)[/i][/b] and also returns the timestep the client sent [b][i](x)[/i][/b][*]Client receives the server response and measures its current timestep [i][b](z)[/b][/i] the client then calculates its current offset using this forumula: [b][i]offsetNew = y - (z - ((z-x) / 2)[/i][/b][*]The client then calculates the real offset using the leaky integrator, something like: [b]offset = (offsetOld * 0.95) + (offsetNew * 0.05)[/b][/list]

Share this post


Link to post
Share on other sites
FredrikHolmstr    262
[quote name='smasherprog' timestamp='1314371372' post='4854089']
[quote name='fholm' timestamp='1314370403' post='4854078']
[quote name='smasherprog' timestamp='1314370289' post='4854076']
Cool. I actually continued to add more to the post above. I have this bad habit of thinking of things after I make a post then adding to the post. I think I did that like 3 times for this one :P
[/quote]

I do the same thing, ha :) Just read the rest of it, I have one follow up question though:

So I get that the client time (that is somewhat in sync in with the server) is used when we receive events from the server, but [b]how [/b]is it used? To sort the events in the right order? Or is it just used to make better predictions (possibly correct our earlier predictions) ?
[/quote]

Well, yes to both questions. You need to be able to adjust things based on when they occured. For example, you are running in a world and receive a small lag spike for one second where you lose all information sent to you. Once you start receiving all the missed information, you will get things like, player A shot a gun 1020 ms ago and player B started running 1040 ms ago. So now the question becomes, what do you do with this information? The standard way is to play those events, but at a fast speed to catch up to where they should be now. So, all the animations, players speed -- everything runs at for example 3x speed. So, it will take about 300 ms to get events up to where they should be. Its like fast forward on VCRs ( you might not remember them, but I am old enough to!). So, you can use the timestamp to say, " wow, we are 1 second behind the server. I better play this animation really fast to catch up, otherwise I never will." If you are 50ms behind the server, your guess will be very close to exact ( should be very small, like .1 or .2 units max error) on where players are located so you can make small adjustments to a players position over time to correct their positions without speeding anything up.

But the client is synced so that the client can know what to do about information that is received late. You are always going to receive events that have already occurred. The syncing will help you know what type of measures you need to do in order to keep the client running correctly whether it is small adjustments (not noticeable because it is moving a player .1 units over 300 ms) or if the client is lagging badly, running everything at a faster than normal speed to catch up.
[/quote]

Thanks, now you gave me the whole roundtrip! How to sync, what parts to sync (client to server, not the other way around) and what to use the sync for on the synced part (client). Perfect!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this