# Variable physics step, bad idea?

Currently, when I update the entities I calculate the time passed since the last update, and then pass that to their update function. They will in turn pass that duration to all their components.

    currentTime = clock.getTime()
timePassed = currentTime - lastUpdate


This means that the physics components also gets a variable time step, but it appears this is bad and can lead to inconsistent simulations. Here's some details on this:

The answers suggest that the physics simulation time step should be constant and higher than the rendering time step. But since I can't ensure how well the game will perform, this can be rather difficult to achieve.

Use Gaffer's "fix your time step" approach. Update the game in fixed steps as in option 1, but do so multiple times per frame rendered - based on how much time has elapsed - so that the game logic keeps up with real time, while remaining in discrete steps.

This seems like a good approach to me, but I don't really understand how I should be doing it. Instead of doing:

physics.step(timePassed)


I should be doing the following?

while timePassed > 0:
physics.step(1) # millisecond
timePassed -= 1

• This isn't much of a question. I don't know what you're after, really - the answer is "yes, basically". – Jari Komppa Sep 16 '11 at 20:08
• @Jari Is that last code sample the right way to deal with variable time steps? – Paul Manta Sep 16 '11 at 20:09
• It handles physics in fixed steps of time, so.. yes. There's a couple of caveats, of course, mainly what happens if timePassed grows a lot for some reason. – Jari Komppa Sep 16 '11 at 20:12
• yes, I believe so. The problem with a variable time-step is simply that the physics system could potentially calculate things just a little differently each time. If you take a variable time-step and make it "fixed" by doing exactly what you wrote, then the physics engine will calculate everything the same every time. You don't have to decrease the timePassed by "1", but decrease it by some constant value. – John McDonald Sep 16 '11 at 20:15
• Here's another article related to this, from my tutorial series: sol.gfxile.net/gp/ch09.html – Jari Komppa Sep 16 '11 at 20:15

The problem with the physic simulations lays on the integration step to solve equation of motion.

What you should do is simply to set an error in integration you can accept (ε) then look to your integration algorithm to see for what step size it gives you that error (ε(Δt)); let say that this error is Tmin.

Now if your elapsed time is less than Tmin a simple step may suffice; if is greater you have to split it in n substeps where each substep is less than Tmin (n = floor(elapsed / tmin); substep = elapsed / n).

Now everything is related to your ε: greather ε means more integration error but less iterations; little ε assures you both a better precision and more iterations.

Please keep in mind that integration errors sums up so your motion trajectory will diverge from the real one (more if the system is badly conditioned).

With physical simulations, you don't want to vary the time rate because what you most likely are using is a "Discrete" solver. What this means, is that it ignores the between state of objects between each "step". Sub-stepping and sweeping to check for tunneling also fall under the Discrete Solver umbrella.

Variable time-steps can only be faithfully used in simulations that use a "Continuous Solver", which involves extremely high-end mathematics and can't be used for real-time applications, games for instance.

For a Discrete Solver, think of time as flowing in chunks. It only advances when you call the "step" function. If you call step() 60 times a second, then time flows forward 60 chunks in one second of our time. If you call step() only 30 times per second, it advances only 30 chunks, and from our perspective it appears to be half as fast. But within the simulation, it does not see that.

If you vary the time between frames in the way you describe, what you are doing is actually causing the 'chunks' of time to become larger and smaller arbitrarily. It would be as though time in our reality got choppier then smoother, and it'd cause all sorts of problems for us.

As for how to set up the timestep, assuming you want the framerate to be 60...

int last_time = 0;
int recent_time = 0;
int times_executed = 0;
float time_step = 1000.0 / 60.0;
// ...

last_time = recent_time;
times_executed = 0;
recent_time = getTimeInMS();
while(recent_time + (times_executed * time_step) < last_time + time_step){
physics.step(time_step);
times_executed += 1;
}


I haven't tested the above but it may help you get started