Fix the fixed-timestep loop in a game engine
Your task
Your engine's main loop adds each frame's time to an accumulator and runs physics in fixed steps until the accumulator is drained. On a slow laptop, physics took longer than a step, each frame queued more work than it could run, and the game froze: a death spiral. The fix clamps long frames, caps the steps per frame and drops any backlog the cap leaves behind.
An assistant wrote simulate_fixed_steps(frame_times_ms, fixed_dt_ms, max_frame_ms, max_steps_per_frame). It is in the editor. It has a bug. Find it and fix it.
Input and output:
frame_times_ms: each frame's measured time in milliseconds, in order.fixed_dt_ms: the length of one physics step.max_frame_ms: the most time one frame may add (0 or more).max_steps_per_frame: the most steps one frame may run.- Return the number of physics steps each frame runs.
Rules the tests check:
- If
fixed_dt_msis 0 or less, return[]. - The accumulator starts at 0. For each frame:
- A negative frame time counts as 0, and a frame time above
max_frame_mscounts asmax_frame_ms. Add it to the accumulator. - While the accumulator is at least
fixed_dt_msand fewer thanmax_steps_per_framesteps have run this frame, run a step: subtractfixed_dt_ms. - Then keep only the accumulator's remainder after dividing by
fixed_dt_ms. Whole steps the cap left over are dropped, never carried into the next frame. - Record the number of steps run.
- A negative frame time counts as 0, and a frame time above
Examples
simulate_fixed_steps(frame_times_ms: list[int], fixed_dt_ms: int, max_frame_ms: int, max_steps_per_frame: int) -> list[int]Example 1
Input
simulate_fixed_steps([16, 16, 16], 16, 250, 5)Output
[1, 1, 1]Example 2
Input
simulate_fixed_steps([1000], 16, 250, 5)Output
[5]