I've recently encountered a problem in my game and i'm not sure how to fix it. As you know, most physics engines use equation solvers that assume a constant time step in order for the simulation to be stable and consistent. Most beginners incorrectly tie their rendering framerate to their physics framerate:
float curTime = getTime();
while (!quit)
{
float newTime = getTime();
float elapsed = curTime - newTime;
curTime = newTime;
do_physics(elapsed);
do_render(elapsed);
}
... which leads to unstable behaviors. Of course, assuming a constant time step:
float curTime = getTime();
const float timeStep = 1.0f / 100.0f; // 100 Hz
while (!quit)
{
float newTime = getTime();
float elapsed = curTime - newTime;
curTime = newTime;
do_physics(timeStep);
do_render(elapsed);
}
... is even worse, since now, you're renderer-framerate dependent.
So far i've been using a better approach, that i think pretty much everybody use now, using an accumulator:
float curTime = getTime();
const float timeStep = 1.0f / 100.0f; // 100 Hz
float accTime = 0; // accumulated time step
while (!quit)
{
float newTime = getTime();
float elapsed = curTime - newTime;
curTime = newTime;
accTime += elapsed;
while (accTime > timeStep)
{
accTime -= timeStep;
do_physics(timeStep);
}
do_render(elapsed);
}
Unfortunately i'm getting fundamental problems with it, too.
The problem with it is that it behaves "well" as long as the performance is high. But as soon as the framerate goes down, OR if the time to execute this "do_physics" call is too high, it enters into an infinite loop: because at frame N-1 the value of "elapsed" was high, it increases the number of calls to "do_physics", which in turn will reduce the performance and increase the value of "elapsed" in the next frame. See a trend ?
Once the code is starting to fall into that never-ending spiral, your program is basically freezing. Of course, adding a limit to the number of time steps allowed per frame doesn't help to avoid falling into that spiral in the first place, and you get single-digits framerate while your rendering framerate has theorically returned to "normal" since long.
I'm looking for suggestions to fix this problem, and avoid the performance effect onto the time step..
Y.