Game loop updating – and physics.
Monday, December 1st, 2008I’ve been on an epic quest to figure out how to best structure my game loop. The game loop is the one place where all your game’s logic should be updated. It’s the control center.
I’ve used delta time before, and that works fine in many cases. It’s where you measure the time since last game tick (aka frame) and tell all your objects how much time has passed so they can scale their responses accordingly. This is simple, and it works for very simple physics models. The trouble starts when you’re using a complex physics simulation to control objects.
I’m using Box2d, and for a physics sim, you want every update to use the same delta time. Fluctuations can cause the simulation to get all wigged out and blow up. Lucky for me, on the game I’m working on (not announced yet), I’m mostly only using Box2d for collision detection. There are no stacks of boxes or whatever, so there’s not a lot of simulating happening, and that makes it more tolerant to variable tick durations. Still not ideal, because it can cause weird collision glitches, like tunneling.
My view camera, though, tends to be very sensitive to update time fluctuations, and if the player moves more one frame than in the last, he jitters. It’s very annoying, and makes the whole game look jerky and twitchy, even at respectable framerates.
So my quest has been to find a game loop that can smooth all this out.
One thing I did was enforce a constant framerate. This allows the rendering to happen at a steady rate (like 30 fps) by sleeping for a few milliseconds if it’s rendering faster than your desired framerate. You basically measure if the last frame took more or less time than what you want, add (sleep your timer) or subtract (don’t sleep) that time from the current frame, and that evens them out.
So I had the physics decoupled from the rendering, but even with the steady framerate, the physics was updating at varying speeds to keep a steady 60 updates per second. So, for each frame (at 30 fps) the physics would typically update twice. But sometimes the interval since the last update would be more than that, so it would update 3 times, or maybe only once. Again, this causes jittery movement and makes the game feel really terrible.
So I’ve decided to just frame lock the physics and rendering. That means when there’s a frame rendered, there’s a corresponding physics update. As long as you have the CPU to stay at or above the minimum frames per second, the game will look nice and smooth.
This is great. Mostly. The problem happens when the computer can’t keep up with your desired framerate. Since things are on a fixed time step, the whole game slows down. Slow motion is only fun if you mean for it to happen! But I haven’t found a better solution, and I’m on a tight deadline. This’ll have to do for now.
Some linky goodness:
http://www.8bitrocket.com/newsdisplay.aspx?newspage=10248
http://gafferongames.wordpress.com/game-physics/fix-your-timestep/
I stumbled across this totally accidentally today while searching to find out if it’s possible to subclass Rectangle (I don’t think it is, but I never found a definitive answer):