Original Post
So, I've implemented a generic server (generic as in the server core is not tied to the game itself, it can be re-used) for a game I'm developing. It has a simulation loop running which is timed using the multimedia timers from winmm.dll (though I am using C#, so I'm P/Invoking). They give me a very good accuracy, at about +/- 1ms. But, even at this accuracy there will be times when time drifts backward or forward due to this, and depending on the tick rate of the server this may (or may not) drift a whole tick back or forth.
Now I've figured out two ways to deal with this, the first one is to, even though I have a fixed tick rate of say 20Hz, calculate the delta between each tick and by doing so let the game automatically compensate for the sway of the timer. Sometimes the delta will be 1 ms behind at ~49ms, sometimes it will be a head at ~51 ms and sometimes right at the spot at ~50ms. This seems like the best approach as the simulation will be at the correct time constantly. Pseudo code this would look something like a normal frame-based game loop:
[source lang="python"]while true:
waitForTick()
now = currentTime()
delta = now - prev
prev = now
update(delta)[/source]
This is the current version I'm using. The reasons I like it because it smooths out the discrepancies in the clock over a longer period, giving no sudden jumps. But there's also a possible to get to a situation where you have run one tick less then you should have, but that ticks "time" has been spread out over all the previous ticks - so I don't know how much this matters.
The second solution I've come up with is to fix the delta time between ticks at the set tick interval, so 50ms (assuming a tick rate of 20Hz), and then detect when I have drifted far enough to perform one extra tick to catch up again. Basically running the server as a fixed time step physics simulation, pseudo code it would look like this:
[source lang="python"]while true:
waitForTick()
while currentTick < expectedTicks:
update(0.05)[/source]
This feels more robust in theory to me, but the fact that you can slip almost a full tick behind before you catch up worries me, as it feels like it would cause a sudden jump in the world when I do my "extra" tick to catch up.
Now I've figured out two ways to deal with this, the first one is to, even though I have a fixed tick rate of say 20Hz, calculate the delta between each tick and by doing so let the game automatically compensate for the sway of the timer. Sometimes the delta will be 1 ms behind at ~49ms, sometimes it will be a head at ~51 ms and sometimes right at the spot at ~50ms. This seems like the best approach as the simulation will be at the correct time constantly. Pseudo code this would look something like a normal frame-based game loop:
[source lang="python"]while true:
waitForTick()
now = currentTime()
delta = now - prev
prev = now
update(delta)[/source]
This is the current version I'm using. The reasons I like it because it smooths out the discrepancies in the clock over a longer period, giving no sudden jumps. But there's also a possible to get to a situation where you have run one tick less then you should have, but that ticks "time" has been spread out over all the previous ticks - so I don't know how much this matters.
The second solution I've come up with is to fix the delta time between ticks at the set tick interval, so 50ms (assuming a tick rate of 20Hz), and then detect when I have drifted far enough to perform one extra tick to catch up again. Basically running the server as a fixed time step physics simulation, pseudo code it would look like this:
[source lang="python"]while true:
waitForTick()
while currentTick < expectedTicks:
update(0.05)[/source]
This feels more robust in theory to me, but the fact that you can slip almost a full tick behind before you catch up worries me, as it feels like it would cause a sudden jump in the world when I do my "extra" tick to catch up.