up vote 23 down vote favorite
11
Share on Facebook

What is better for games when developing game loops, fixed time steps or variable time steps? What type of games are better with one or the other?

Variable time steps:

With variable time step, I mean physics updates will take in some sort of "time elapsed since last update" argument and hence dependent on framerate. This may mean doing calculations as position = position + distancePerSecond*timeElapsed.

  • pro: smooth
  • pro: easier to to code
  • con: hard to record/replay actions as time steps vary
  • con: weird physics errors that are hard to predict with very small or large time steps

eg (from dewitters):

while( game_is_running ) {
    prev_frame_tick = curr_frame_tick;
    curr_frame_tick = GetTickCount();
    update( curr_frame_tick - prev_frame_tick );
    render();
}

Fixed time steps:

With fixed time steps, the update method may not even accept a "time elapsed" as it assumes that each update is for a fixed time period. Calculations may be done as position = position + distancePerUpdate. The example includes an interpolation during render.

  • pro: physics are very predictable
  • pro: easier to record actions per time step as they are fixed
  • pro: possibly easier to sync up with other players over network?
  • pro: don't have to confuse all calculations with timeElapsed variable everywhere
  • con: it will never sync up vertical refresh so you either have jittery graphics or you have to always interpolate.
  • con: maximum frame rate is limited unless you interpolate
  • con: hard to work within frameworks that assume variable time steps (like pyglet or flixel)

eg (from dewitters):

while( game_is_running ) {
    while( GetTickCount() > next_game_tick) {
        update();
        next_game_tick += SKIP_TICKS;
    }
    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick ) / float( SKIP_TICKS );
    render( interpolation );
}

Notes:

link|flag

6 Answers

up vote 17 down vote

There are two issues related to the question.

  • Should physics step rate be tied to frame rate?
  • Should physics be stepped with constant deltas?

In Glen fielder's Fix your time step he says to "Free the Physics". That means your physics update rate should not be tied to your frame rate.

For example, if the display framerate is 50fps and the simulation is designed to run at 100fps then we need to take two physics steps every display update to keep the physics in sync.

In Erin Catto's recommendations for Box2D he advocates this as well.

So don't tie the time step to your frame rate (unless you really, really have to).

Should Physics step rate be tied to your frame rate? No.


Erin's thoughts on fixed step vs variable stepping:

Box2D uses a computational algorithm called an integrator. Integrators simulate the physics equations at discrete points of time. ... We also don't like the time step to change much. A variable time step produces variable results, which makes it difficult to debug.

Glen's thoughts on fixed vs variable stepping:

Fix your timestep or explode

... If you have a series of really stiff spring constraints for shock absorbers in a car simulation then tiny changes in dt can actually make the simulation explode. ...

Should physics be stepped with constant deltas? Yes.


The way to step the physics with constant deltas and not tie your physics update rate to the frame rate still is to use a time accumulator. In my game I take it a step further. I apply a smoothing function to incoming time. That way large FPS spikes don't cause the physics to jump too far, instead they're simulated more quickly for a frame or two.

You mention that with a fixed rate, the physics wouldn't sync up with the display. This is true if the target physics rate is near the target frame rate. It's worse the frame rate is larger than the physics rate. In general it is better to target a physics update rate of twice your target FPS, if you can afford it.

If you can't afford a large physics update rate, consider interpolating the graphics' positions between frames to make the drawn graphics appear to move more smoothly than the physics actually moves.

link|flag
up vote 6 down vote

I think there are really 3 options, but you're listing them as only 2:

Option 1

Do nothing. Attempt to update and render at a certain interval, e.g. 60 times per second. If it falls behind, let it and don't worry. The games will slow down into jerky slow motion if the CPU can't keep up with your game. This option won't work at all for real-time multi-user games, but is fine for single player games and has been used successfully in many games.

Option 2

Use the delta time between each update to vary the movement of objects. Great in theory, especially if nothing in your game accelerates or decelerates, but just moves at a constant speed. In practice, many developers implement this badly, and it can lead to inconsistent collision detection and physics. It seems some developers think this method is easier than it is. If you want to use this option you need to step your game up considerably and bring out some big-gun maths and algorithms, for example using a Verlet physics integrator (rather than the standard Euler that most people use) and using rays for collision detection rather than simple Pythagoras distance checks. I asked a question about this on Stack Overflow a while back and got some great answers:

http://stackoverflow.com/questions/153507/calculate-the-position-of-an-accelerating-body-after-a-certain-time

Option 3

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 way, easy to implement game logic like Euler integrators and simple collision detection still work. You also have the option of interpolating graphical animations based on delta time, but this is only for visual effects, and nothing that affects your core game logic. You can potentially get in trouble if your updates are very intensive - if the updates fall behind, you will need more and more of them to keep up, potential making your game even less responsive.

Personally, I like Option 1 when I can get away with it and Option 3 when I need to sync to real time. I respect that Option 2 can be a good option when you know what you're doing, but I know my limitations well enough to stay well away from it.

link|flag
regarding option 2: I am not sure a raycast can ever be faster than pythagoras distance checks, except if you are very brute force in your application of pythagoras, but a raycast will also be very expensive if you don't add a broadphase. – Kaj Aug 14 at 4:13
1  
If you use Verlet with unequal time steps you are throwing out the baby with the bathwater. The reason Verlet is as stable as it is, is because errors cancel out in subsequent time steps. If the time steps are not equal, this does not happen and you are back in exploding physics land. – Ranieri Aug 17 at 11:15
up vote 3 down vote

I really like the way the XNA Framework implements fixed time step. If a given draw call takes a bit too long, it will call update repeatedly until it "catches up". Shawn Hargreaves describes it here:
http://blogs.msdn.com/b/shawnhar/archive/2007/11/23/game-timing-in-xna-game-studio-2-0.aspx

In 2.0, the Draw behavior has changed:

  • Call Update as many times as needed to catch up to the current time
  • Call Draw once
  • Wait until it is time for the next Update

The biggest pro in my opinion to this is one that you mentioned, that it makes all of your game code calculations so much simpler because you don't have to include that time variable all over the place.

note: xna supports variable timestep as well, it's just a setting.

link|flag
This is the most common way of doing a game loop. However, it's not great for battery life when working with mobile devices. – knight666 Jul 26 at 15:07
@knight666; are you suggesting that using a longer timestep, the reduced amount of iterations will save batterylife? – roe Jul 26 at 15:09
That's still a variable update -- the update delta changes based on how long the frame took to render rather than some fixed value (i.e, 1/30th of a second). – Dennis Munsie Jul 26 at 15:11
1  
@Dennis: as i understand it, the Update function is called with a fixed delta... – RCIX Jul 27 at 2:45
1  
@knight666 Uh - how do you figure that? If you have vsync on and are not stuttering - these methods should be identical! And if you have vsync off you're updating more often than you need to and probably wasting CPU (and therefore battery) by not letting it idle! – Andrew Russell Jul 27 at 5:21
show 1 more comment
up vote 2 down vote

There's another option - decouple Game update and physics update. Trying to tailor the physics engine to the game timestep leads to problem if you fix your timestep (the problem of spinning out of control because integration needs more timesteps which take more time which needs more timesteps), or make it variable and get wonky physics.

The solution that I see a lot is to have the physics run on a fixed timestep, in a different thread (on a different core). The game interpolates or extrapolates given the two most recent valid frames it can grab. Interpolation adds some lag, extrapolation adds some uncertainty, but your physics will be stable and not spin your timestep out of control.

This is not trivial to implement, but might proof future proof.

link|flag
up vote 1 down vote

On top of what you've already stated it may come down to the feel you want your game to have. Unless you can guarantee that you will always have a constant frame rate then you're likely to have slowdown somewhere and fixed and variable time steps will look very different. Fixed will have the effect of your game going in slow motion for a while, which can sometimes be the intended effect (look at an old school style shooter like Ikaruga where massive explosions cause slowdown after beating a boss). Variable timesteps will keep things moving at the correct speed in terms of time but you may see sudden changes in position etc. which can make it hard for the player to perform actions accurately.

I can't really see that a Fixed time step will make things easier over a network, they would all be slightly out of sync to begin with and slowdown on one machine but not another would push things more out of sync.

I've always leant towards the variable approach personally but those articles have some interesting things to think about. I've still found fixed steps quite common though, especially on consoles where people think of the framerate being a constant 60fps compared to the very high rates achievable on PC.

link|flag
3  
You should definitely read the Gaffer on games link in the original post. I don't think this is a bad answer per se, so I won't down vote it, but I don't agree with any of your arguments. – roe Jul 26 at 14:15
I don't think slowdown in a game as a result of fixed timestep can ever be intentional, because it's because of lack of control. Lack of control is by definition surrendering to chance and thus can't be intentional. It can happen to be what you had in mind, but that's as far as I'd like to go on that. As for fixed timestep in networking, there's a definite plus there, as keeping physics engines on two different machines in synch without the same timestep is pretty impossible. Since the only option to synch then would be to send all entity transforms, that would be way too bandwidth heavy. – Kaj Aug 14 at 5:36
up vote 1 down vote

Personally, I use a variation of variable time-step (which is sort of a hybrid of fixed and variable I think). I stress tested this timing system in several ways, and I find myself using it for many projects. Do I recommend it for everything? Probably not.

My game loops calculate the amount of frames to update by (let's call this F), and then perform F discrete logic updates. Every logic update assumes a constant unit of time (which is often 1/100th of a second in my games). Each update is performed in sequence until all F discrete logic updates are performed.

Why discrete updates in logic steps? Well, if you try and use continuous steps, and suddenly you have physics glitches because the calculated speeds and distances to travel are multiplied by a huge value of F.

A poor implementation of this would just do F = current time - last frame time updates. But if calculations get too far behind (sometimes due to circumstances beyond your control like another process stealing CPU time), you will quickly see awful skipping. Quickly, that stable FPS you tried to maintain becomes SPF.

In my game, I allow "smooth" (sort of) slowdown to restrict the amount of logic catchup that should be possible between two draws. I do this by clamping: F = min(F, MAX_FRAME_DELTA) which usually has MAX_FRAME_DELTA = 2/100 * s or 3/100 * s. So instead of skipping frames when too far behind game logic, discard any massive frame loss (which slows things down), recover a few frames, draw, and try again.

By doing this, I also make sure that the player controls keep in closer sync with what is actually shown on the screen.

Final product pseudocode is something like this (delta is F mentioned earlier):

// Assume timers have 1/100 s resolution
const MAX_FRAME_DELTA = 2
// Calculate frame gap.
var delta = current time - last frame time
// Clamp.
delta = min(delta, MAX_FRAME_RATE)
// Update in discrete steps
for(i = 0; i < delta; i++)
{
    update single step()
}
// Caught up again, draw.
render()

This sort of updating is not suitable for everything, but for arcade style games, I would much rather see the game slow down because there is a lot of stuff going on than miss frames and lose player control. I also prefer this to other variable-time step approaches which end up having irreproducible glitches caused by frame loss.

link|flag
Strongly agree with that last point; in pretty much all games, input should 'slow down' when the framerate drops. Even though this isn't possible in some games (i.e. multiplayer), it would still be better if it were possible. :P It simply feels better than having a long frame and then having the game world 'jump' to the 'correct' state. – Ipsquiggle 13 hours ago

Your Answer

get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.