Game Programming · June 28, 2026
Fixed Timestep and Delta Time in Shmups: Determinism and Smooth Motion
How a shmup ticks is one of the least visible but most consequential design decisions in the codebase. The frame-update strategy determines whether bullet patterns behave identically on every run, whether replays are trustworthy, and whether the game feels the same on a 60 Hz monitor and a 144 Hz one. Delta time scaling and fixed timestep are both valid answers, but they answer different questions.
Published June 28, 2026
When a game runs its update loop, it has to decide how much simulated time has passed since the last frame. The two dominant strategies — delta time scaling and fixed timestep accumulation — produce fundamentally different guarantees about simulation behaviour. In a shmup, where bullet positions are calculated potentially hundreds of times per second and collisions must be pixel-precise, the choice matters more than it might in a slower-paced genre.
Delta time scaling: the simple path
Delta time scaling works by measuring the real elapsed time between frames and multiplying every velocity and position update by that value. If the previous frame took 16.67 ms (the target at 60 fps), objects move by their velocity times 0.01667. If the frame took 33 ms because of a spike, they move twice as far in one step. The simulation stays wall-clock-accurate regardless of frame rate.
The appeal is obvious: the implementation is simple, and the game runs at whatever frame rate the hardware delivers without needing special handling. The problem is that floating-point arithmetic is not associative. Multiplying a velocity by 0.01667 twice does not produce the same result as multiplying by 0.03334 once. Over many frames, and especially under variable load, bullet positions can drift. Two identical play sessions at different frame rates will produce slightly different bullet positions by the tenth second, and meaningfully different ones by the end of a long boss fight.
For many games this is fine. For a shmup that needs deterministic replays, where the entire run must be reconstructable from an initial seed plus the recorded input stream, delta time scaling is a liability. Every replay plays back slightly differently depending on frame timing, making replay files unreliable long-term.
Fixed timestep: determinism through consistency
Fixed timestep runs the simulation at a constant rate regardless of how fast the renderer is running. The canonical implementation uses an accumulator: each real frame, the elapsed time is added to the accumulator, and the simulation is stepped forward in fixed increments (commonly 1/60th of a second) until the accumulator is depleted. Rendering happens once per real frame, potentially interpolating between the last two simulation states for visual smoothness.
Because the simulation always advances by exactly the same timestep, floating-point operations produce identical results every run. A replay file recorded on a 60 Hz machine plays back identically on a 144 Hz machine, on a laptop running at 40 fps, or in a headless test runner. This is the property that makes score verification and competitive leaderboards meaningful.
The spiral of death and capping the accumulator
Fixed timestep has one critical failure mode: if the simulation is slow and real frames take longer than the fixed step, the accumulator grows faster than it drains. The simulation runs more and more steps per frame trying to catch up, which makes each frame even slower, which makes the accumulator grow even faster. This is the spiral of death.
The fix is to cap the accumulator at a maximum value — typically three to five fixed steps — before running the update loop. If the cap is hit, the simulation falls behind real time and the game slows down rather than running infinite catch-up steps. For a shmup this is the correct tradeoff: a brief slowdown during an intense boss explosion is survivable; an infinite update loop is not.
Interpolation and visual smoothness
Rendering at a fixed 60 Hz simulation rate on a 144 Hz display produces visible judder if each render frame simply shows the last simulation state. The interpolation alpha value from the accumulator solves this: the renderer blends between the previous simulation state and the current one by the fractional amount the accumulator represents. At 144 fps with a 60 Hz simulation, each render frame interpolates about 40% of the way to the next simulation state, producing visually smooth motion even though the underlying physics is stepping at 60 Hz.
Implementing interpolation requires storing two copies of position for every moving entity: the state at the end of the last simulation step and the state at the end of the step before that. For a shmup with hundreds of active bullets this doubles the memory for position data, but positions are small (two floats each) and the total overhead is negligible on any modern hardware.
Which to choose
If replays, determinism, and online leaderboard integrity matter, fixed timestep is the right foundation and the complexity cost of the accumulator pattern is worth paying. If the game is a single-player experience with no replay system and frame rates are consistent on target hardware, delta time scaling is simpler to implement correctly and has no meaningful downside. Most shmup engines capable of recording replays use fixed timestep; most quick prototypes and jam games use delta time because the implementation is three lines instead of fifteen.
Whichever you choose, make the decision early. Migrating from delta time to fixed timestep after bullet pattern scripting is complete means auditing every velocity, acceleration, and timer in the codebase. The physics of a shmup are deeply coupled to its update model, and retrofitting that assumption is far more work than building on the correct foundation from the start.