Another way to fix your timestep:
[/color]the famous article "fix your timestep":
http://gafferongames.com/game-physics/fix-your-timestep/
attempts to address the problem of your simulation not running at the same speed on all PC's:
1. first, variable timestep is used to get the same speed on all pc's - but variable timesteps which are large can make physics blow up, large et's can cause the spiral of death, and variable timesteps are non-deterministic.
2. semi-variable timestep is then used to eliminate physics blowing up due to large et, but sim bound games and large et's can still cause the spiral of death, and semi-variable timesteps are still non-deterministic.
3. a render bound or et capped semi-variable timestep is used to eliminate the spiral of death. but the semi-varible timesteps are still non-deterministic. Note that render bound only prevents spiral of death from long update times, not from long render times, which requires an et cap.
4. it is ASSUMED that the game needs to be deterministic - an assumption which is not necessarily valid for all games.
5. fixed timestep with variable render speed is used to make the sim deterministic, but this leads to temporal aliasing. although not implemented in the example, an et cap can be used to avoid the spiral of death.
6. fixed timestep with variable render speed, and interpolation from previous to current state when rendering is used to eliminate temporal aliasing. although not implemented in the example, an et cap can be used to avoid the spiral of death.
after all of this you get:
1. same sim speed on all pc's
2. no large dt's to blow up physics
3. no sprial of death from large et's
4. deterministic behavior
5. no temporal aliasing
6. renders as fast as possible, possibly even faster than refresh rate if et is small enough.
[color=#ff8c00]Here's an alternative:[/color]
[color=#0000ff]while !quitgame[/color]
[color=#0000ff]{[/color]
[color=#0000ff]render[/color]
[color=#0000ff]process_input[/color]
[color=#0000ff]update // with a fixed_dt[/color]
[color=#0000ff]while (elapsedtime[color=#0000ff]}[/color]
this is a basic game loop with a framerate limiter.
1. it runs at the same speed on all pc's
2. fixed_dt is always small, so physics won't blow up.
3. always one render and input per update, so no spiral of death.
4. fixed_dt is a constant value, so its deterministic.
5. render is based on the exact current state of the sim, so no temporal aliasing.
the only difference:
fixed timestep will render as fast as possible - perhaps even faster than the refresh rate. framerate limited will only render as fast as you specify via maxfps (where: maxfps=1/min_frametime). by selecting maxfps to be as close to refresh rate as possible, this difference can be minimized. if maxfps = refresh rate, the difference is eliminated entirely. in fact, when min_frametime = et_cap, the two loops behave identically.
additional benefits of framerate limited:
1. no need for a loop to update in dt sized chunks.
2. no need for an accumulator.
3. no need to track both previous and current states.
4. no need to interpolate for rendering.
5. no need for an et cap to avoid the spiral of death.
6. more accurate: render shows the actual current state, not the state as it was dt seconds ago (a side effect of interpolating from previous to current state, instead of predicting from current to next state).
7. by selecting a lower maxfps, the game can have longer et's without any noticeable slowdowns. this means means more milliseconds per frame to draw, process input, and simulate.
[color=#ff8c00]So, why does fix your timestep go to all that work to accomplish almost the same thing?[/color]
it seems to stem from two assumptions:
1. you want the sim to run at the same speed on all pcs all the time, irregardless of et, as opposed to simply not running too fast when et is not large.
2. the game needs to be deterministic.
because they try to make it run at the same speed all the time by using variable et, instead of simply trying to make it not run too fast, they create, then solve a series of problems, adding code complexity with each new solution:
1. variable timesteps are added to make the sim run at the same speed all the time, but long et's can make the physics blow up, and can lead to the spiral of death. also, variable timesteps are non-deterministic.
2. semi-variable et's are used to keep the physics from blowing up, and an et cap is mentioned as a way to avoid the spiral of death, but this still doesn't make the code deterministic.
3. fixed timestep with variable render speed (and et cap to avoid spiral of death - one would assume) are used to make the code deterministic, but leads to temporal aliasing.
4. finally, interpolation from previous to current state is used when rendering to eliminate temporal aliasing.
[color=#ff8c00]So, is fix your timestep worth it?[/color]
it depends:
1. fixed timestep will render as often as possible - perhaps even faster than the refresh rate. framerate limited never renders faster than the maxfps you specify, but you can specify the maxfps to be equal to the refresh rate (or even higher - but there's not point in rendering faster than the refresh rate). when et_cap = min_frametime, the two loops behave identically.
2. fixed timestep draws the scene as is was dt seconds before the current state, not as it actually is at the time of render. framerate limited always renders the exact current state.
Your solution will lead to jittering when computation takes ~ desired frame time. This may happen all the time due to scheduling conflicts in the OS. You opt to slow down the whole simulation if you can't keep up. This leads to your game character running at, say, 1/2 real time speed only to switch back to full speed and back - it jitters. E.g. take a frame rate of 10 FPS:
The 0.2 seconds are lost. Your simulation ran slower during the lagging frames and there's nothing you can do about it. So it doesn't run at same speed on all machines. Advanced game loops might catch up if simulation doesn't take too long.
If you start lagging heavily you have to drop frames, effectively slowing down the simulation. You're doing it implicitely by only simulating a single update step. Advanced game loop drop accumulated (and not yet accounted for) real time. There is no way around it. That's one of the reasons multiplayer lockstep simulations may halt - if one machine can't keep up all others have to wait for it.
The benefit of advanced game loops is that they cope with OS induced jitter that can be easily handled by performing 2 update iterations in a single render frame. The render delay is most of the time either irrelevant (say 60Hz game state updates) or can be masked (by animating wrt render rate instead of game logic rate).
To be frank, I don't see the advantages of your scheme as I understand it, except that my laptop might be killed by your busy wait loop :)