Agreed, and I’ve just experienced it (by pausing my local game simulation and letting it get behind intentionally). However, remember that my objective is make only the laggy player experience lag. So, for me, thats exactly what should happen, a player is so laggy that they get well behind simulation time and hence get a laggy response. However, what I hadn’t really thought about is how lag spikes get compounded in this system.
If the player gets one lag spike they get a bit behind time. If they get another they get further behind time. Hence that 10 seconds is getting closer and closer
What I hadn’t thought about was the compound nature. So, yes there is a problem.
Time for a coping strategy.
-
For another reason I’ve added a keep alive message. Every so often (lagBuffer / 2) the server sends out a keep alive command. The clients arn’t allowed to progress unless they’ve command in their local scheduled list to work towards. The keep alive keeps something in their lists. This prevents clients running off into the future (and hence screwing up the whole distributed simulation)
-
Here comes the science…
Or something. I haven’t implemented this yet (some point today) so I don’t know if it works. A client is sat there recieving its commands (one at miminum every lagBuffer / 2 (*)) and it knows what the lag buffer is. Lets say the buffer is set at 200ms. It knows that when it recieves a command it should be 200ms in the future of its current simulation time. So, now it knows how far infront/behind the simulation its running (well plus the transmission time from server to client).
So let says, its detected its got 100ms behind where it should be, i.e. its recieved a command thats scheduled 300ms in the future (instead of the 200 expected).
Each frame render my client goes to the game world and tells it to update by how much time has passed. Say 25ms has passed since last frame renderered. My game world currently moves forward in incremenets of 10ms, so normally I divide the amount of time passed by 10ms and work out the number of cycles to update through the data. The dividing by 10ms and working it out in terms on a set number of cycles is what allows me to keep the simulations synchronised.
So, normally this would mean I need to run 2 simulation turns and remember that I’ve got 5ms of time outstanding for next update. However, this time I know I’m an additional 100ms behind so naively I might run an extra 10 turns this update. This naive approach could of course mean that the rendering of the clients world would suddenly speed up, 10 additonal moves. I’m going to implement it this way initially, I spect I’ll need to temper this down a bit to smooth things out. I think the neat thing about this is going to be that if my player gets to far ahead in the simulation I can detect this, miss a few turns next update and the sim comes back in line. So hopefully I’ll be tending towards have a consistent lag at all times while coping with lag spikes.
Moreover, if I was add a player mid game - I could send them all the commands that have occured in the game (maybe cache them at the server or something). They’d get a command scheduled for a long time in the future. The above algorithm would detect this and on the next game update would progress their simulation all the way through to the point other players are at. Since its all deterministic, it should place them in the current game state.
Apologies for the long post, hope it makes enough sense to be able to be considered.
Kev
PS. On advice from Elias I’ve added checksums for the game world to ensure they’re staying consistent. It turns out “CHECKSUMS ARE YOUR FRIENDS” ! 
(*) note that this messages is very very small (6 bytes) so the impact isn’t going to be to scary)