271
\$\begingroup\$

Should a game loop be based on fixed or variable time steps? Is one always superior, or does the right choice vary by game?

Variable time step

Physics updates are passed a "time elapsed since last update" argument and are hence framerate-dependent. This may mean doing calculations as position += distancePerSecond * timeElapsed.

Pros: smooth, easier to to code
Cons: non-deterministic, unpredictable at very small or large steps

deWiTTERS example:

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

Fixed time step

Updates might not even accept a "time elapsed", as they assume each update is for a fixed time period. Calculations may be done as position += distancePerUpdate. The example includes an interpolation during render.

Pros: predictable, deterministic (easier to network sync?), clearer calculation code
Cons: not synced to monitor v-sync (causes jittery graphics unless you interpolate), limited max frame rate (unless you interpolate), hard to work within frameworks that assume variable time steps (like Pyglet or Flixel)

deWiTTERS example:

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 );
}

Some resources

\$\endgroup\$
7
  • 8
    \$\begingroup\$ Use variable timesteps for your game and fixed steps for physics \$\endgroup\$ Commented May 6, 2011 at 5:11
  • 9
    \$\begingroup\$ I wouldn't say that variable time step is easier to code exactly because with fixed time step you "don't have to confuse all calculations with timeElapsed variable everywhere". Not that it's that hard, but I wouldn't add "easier to code" as a pro. \$\endgroup\$
    – pek
    Commented Sep 26, 2011 at 3:05
  • \$\begingroup\$ True, I think I was referring to how you wouldn't need to interpolate variable time steps. \$\endgroup\$ Commented Sep 26, 2011 at 4:22
  • \$\begingroup\$ @pek I agree with you. Variable time step has a simpler coded game loop but you have more to code in your entities that deal with that variability in order to "pace it". Fixed time step has a more complicated to code game loop (because you have to accuratelly compensate for time approximation variances, and recalculate what extra delay to add or how many updates to skip to keep it fixed) but has simpler coding for the entities that will always have to deal with the same time interval. On the whole none of the approaces is clearly simpler than the other. \$\endgroup\$ Commented Sep 28, 2012 at 10:44
  • \$\begingroup\$ You can check these visuall from this tool: s3.amazonaws.com/picobots/assets/unity/jerky-motion/… although it doesn't give you an idea about how would they look when frame rate is varying \$\endgroup\$
    – Buddy
    Commented Aug 15, 2015 at 15:32

11 Answers 11

143
\$\begingroup\$

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.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ I've played The Floor is Jelly before and after upgrading my machine and it was silly: it wasn't the same thing because the physics were indeed invoked from the game-loop (and so tied to the frame-rate) and not from a timer. My old machine was very bad so it constantly switched between slow-motion and too-fast motion and it had great impact on the gameplay. Now it's just at a very fast motion. Anyways that game is a fine example of how problematic this issue can get to be (still a cute game though). \$\endgroup\$ Commented Aug 11, 2014 at 18:32
  • \$\begingroup\$ what is the difference between TimeStep and DeltaTime? \$\endgroup\$
    – user124631
    Commented Nov 8, 2020 at 23:10
  • \$\begingroup\$ "In general it is better to target a physics update rate of twice your target FPS" why? This doesn't make intuitive sense given how physics can be expensive to calculate \$\endgroup\$ Commented Nov 25, 2023 at 21:32
63
\$\begingroup\$

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:

https://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.

\$\endgroup\$
6
  • \$\begingroup\$ 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. \$\endgroup\$
    – Kaj
    Commented Aug 14, 2010 at 4:13
  • 6
    \$\begingroup\$ 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. \$\endgroup\$
    – drxzcl
    Commented Aug 17, 2010 at 11:15
  • \$\begingroup\$ Option 3 - sounds like Joel Martinez's description of XNA approach. \$\endgroup\$
    – topright
    Commented Oct 14, 2010 at 13:42
  • 1
    \$\begingroup\$ This is a really good answer. All three options have their place and it's important to understand when they are appropriate. \$\endgroup\$ Commented Sep 4, 2014 at 15:18
  • 1
    \$\begingroup\$ @drxzcl 14 years late but this is not exactly correct. Verlet integration in its raw form is sensitive in this way yes, but it is trivial to add a term to Verlet to compensate for the last frame having a different delta time. Note this is not an issue at all either with Velocity Verlet. This shouldn't be a reason for choosing one option over the other really. \$\endgroup\$
    – Lemon Drop
    Commented Jul 27 at 16:32
25
\$\begingroup\$

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.

\$\endgroup\$
6
  • \$\begingroup\$ This is the most common way of doing a game loop. However, it's not great for battery life when working with mobile devices. \$\endgroup\$
    – knight666
    Commented Jul 26, 2010 at 15:07
  • 1
    \$\begingroup\$ @knight666; are you suggesting that using a longer timestep, the reduced amount of iterations will save batterylife? \$\endgroup\$
    – falstro
    Commented Jul 26, 2010 at 15:09
  • \$\begingroup\$ 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). \$\endgroup\$ Commented Jul 26, 2010 at 15:11
  • 1
    \$\begingroup\$ @Dennis: as i understand it, the Update function is called with a fixed delta... \$\endgroup\$
    – RCIX
    Commented Jul 27, 2010 at 2:45
  • 4
    \$\begingroup\$ @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! \$\endgroup\$ Commented Jul 27, 2010 at 5:21
12
\$\begingroup\$

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 prove itself future proof.

\$\endgroup\$
8
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ 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. \$\endgroup\$
    – Ipsquiggle
    Commented Sep 8, 2010 at 17:44
  • \$\begingroup\$ Without fixed hardware like an arcade machine, having arcade games slow the simulation when the hardware can't keep up makes playing on a slower machine cheating. \$\endgroup\$
    – user744
    Commented Sep 9, 2010 at 9:11
  • \$\begingroup\$ Joe that only matters if we care about "cheating". Most modern games aren't really about competition between players, just making a fun experience. \$\endgroup\$
    – Iain
    Commented Sep 9, 2010 at 9:36
  • 1
    \$\begingroup\$ Iain, we are talking specifically about arcade-style games here, which are traditionally high-score-list / leaderboard driven. I play a ton of shmups, and I know if I found someone was posting scores with artificial slowdown to leaderboards I'd want their scores wiped. \$\endgroup\$
    – user744
    Commented Sep 10, 2010 at 6:17
  • \$\begingroup\$ Not trying to diminish your answer, but I would interpret this as fixed step where rendering is not tied to directly to physics update rate, except that catching up on physics takes priority over rendering. It definitely has good qualities. \$\endgroup\$
    – AaronLS
    Commented Apr 14, 2017 at 23:22
6
\$\begingroup\$

This solution doesn't apply to everything, but there is another level of variable timestep -- variable timestep for each object in the world.

This seems complicated, and it can be, but think of it as modeling your game as a discrete event simulation. Each player movement can be represented as an event which starts when the motion starts, and ends when the motion ends. If there is any interaction that requires the event be split (a collision for instance) the event is canceled and another event pushed onto the event queue (which is probably a priority queue sorted by event end time).

Rendering is totally detached from the event queue. The display engine interpolates points between event start/end times as necessary, and can be as accurate or as sloppy in this estimate as need be.

To see a complex implementation of this model, see the space simulator EXOFLIGHT. It uses a different execution model from most flight simulators -- an event-based model, rather than the traditional fixed time-slice model. The basic main loop of this type of simulation looks like this, in pseudo-code:

while (game_is_running)
{
   world.draw_to_screen(); 
   world.get_player_input(); 
   world.consume_events_until(current_time + time_step); 
   current_time += time_step; 
}

The main reason for using one in a space simulator is the necessity of providing arbitrary time-acceleration without loss of accuracy. Some missions in EXOFLIGHT may take game-years to complete, and even a 32x acceleration option would be insufficient. You'd need over 1,000,000x acceleration for a usable sim, which is difficult to do in a time-slice model. With the event-based model, we get arbitrary time rates, from 1 s = 7 ms to 1 s = 1 yr.

Changing the time rate does not change the behavior of the sim, which is a critical feature. If there is not enough CPU power available to run the simulator at the desired rate, events will stack up and we might limit UI refreshing until the event queue is cleared. Similarly, we can fast-forward the sim as much as we want and be sure we're neither wasting CPU nor sacrificing accuracy.

So summing up: We can model one vehicle in a long, leisurely orbit (using Runge-Kutta integration) and another vehicle simultaneously bouncing along the ground -- both vehicles will be simulated at the appropriate accuracy since we do not have a global timestep.

Cons: Complexity, and lack of any off-the-shelf physics engines which support this model :)

\$\endgroup\$
5
\$\begingroup\$

Fixed time step is useful when taking into account floating point accuracy and to make updates consistent.

It's a simple piece of code so it would be useful to try it out and see if it works for your game.

now = currentTime
frameTime = now - lastTimeStamp // time since last render()
while (frameTime > updateTime)
    update(timestep)
    frameTime -= updateTime     // update enough times to catch up
                                // possibly leaving a small remainder
                                // of time for the next frame

lastTimeStamp = now - frameTime // set last timestamp to now but
                                // subtract the remaining frame time
                                // to make sure the game will still
                                // catch up on those remaining few millseconds
render()

The main issue with using a fixed time step is that players with a fast computer won't be able to make use of the speed. Rendering at 100fps when the game is updated only at 30fps is the same as just rendering at 30fps.

That being said, it may be possible to use more than one fixed time step. 60fps could be used to update trivial objects (such as UI or animated sprites) and 30fps to update non-trivial systems (such as physics and) and even slower timers to do behind the scenes management such as deleting unused objects, resources etc.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ If the game is carefully made, the render method can do interpolation to make 30fps updates actually not the same as rendering at 30fps. \$\endgroup\$
    – Ricket
    Commented May 5, 2011 at 13:33
3
\$\begingroup\$

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.

\$\endgroup\$
2
  • 5
    \$\begingroup\$ 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. \$\endgroup\$
    – falstro
    Commented Jul 26, 2010 at 14:15
  • \$\begingroup\$ 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. \$\endgroup\$
    – Kaj
    Commented Aug 14, 2010 at 5:36
0
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ If you're gonna steal answers at least credit the person! \$\endgroup\$
    – PrimRock
    Commented Sep 23, 2016 at 4:08
0
\$\begingroup\$

I have found that fixed timesteps synchronized to 60fps gives mirror smooth animation. This is especially important for VR applications. Anything else is physically nauseating.

Variable timesteps are unsuited for VR. Have a look at some Unity VR examples which use variable timesteps. It is unpleasant.

The rule is if your 3D game is smooth in VR mode, it will be excellent in non-VR mode.

Compare these two (Cardboard VR apps)

(Variable timesteps)

(Fixed timesteps)

Your game must be multithreaded in order to achieve consistent timestep/framerate. Physics, UI and rendering must be separated into dedicated threads. It is hideous PITA to sync them, but the results are that mirror smooth rendering that you want (esp. for VR).

Mobile games are esp. challenging because the embedded CPUs and GPUs have limited performance. Use GLSL (slang) sparingly to offload as much work from the CPU as possible. Be aware than passing parameters to the GPU consumes bus resources.

Always keep your framerate displayed during development. The real game is to keep it fixed at 60fps. This is the native sync rate for most screens and also for most eyeballs.

The framework you are using should be able to notify you of a sync request, or use a timer. Do not insert a sleep/wait delay to acheive this - even slight variations are noticeable.

\$\endgroup\$
0
\$\begingroup\$

Variable time steps are for procedures which should be run as often as possible: Render cycles, event handling, network stuff etc.

Fixed time steps are for when you need something to be predictable and stable. This includes, but is not limited to physics & collision detection.

In practical terms, physics and collision detection should be decoupled from everything else, on it's own time step. The reason for performing procedures like these on a small fixed time step, is to keep them accurate. Impulse magnitudes are highly dependent on time, and if the interval gets too big, the simulation becomes unstable, and crazy stuff happens like a bouncing ball phases through the ground, or bounces out of the game world, Neither of which is desirable.

Everything else can run on a variable time step (though professionally speaking, it's often a good Idea to allow locking rendering to a fixed time step). In order for a game engine to be responsive, things like network messages and user input should be handled as soon as possible, which means that the interval between polling should ideally be as short as possible. This generally means variable.

Everything else can be handled asynchronously, making timing a moot point.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .