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
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.
I think there are really 3 options, but you’re listing them as only 2:
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.
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:
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.
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:
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.