You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cap main loop elapsed time instead of resetting it (#3178)
This change adjusts the way the main loop handles the game logic updates
falling significantly behind real time. There are three main ways this
can occur: a single, very slow operation (like loading a level);
consistently slow game logic updates; and consistently slow rendering.
By limiting the maximum number of logic steps per frame to 4, the main
loop couples rendering and game updates together, making it practical to
treat them being slow in the same way.
Previously, when the `elapsed_time` difference between real-ish time
and game time grew too large (> 8 steps), it would be reset to zero.
This works OK for transient slow operations, but when the game logic
or rendering runs just a bit slower than real time, the `elapsed_time`
difference would slowly grow until hitting the threshold, be reset to
zero, and then repeat, leading to a sort of sawtooth pattern. The number
of game steps run in each loop iteration is roughly proportional to
`elapsed_time` (with an upper limit), so the number of game steps per
drawn frame would also have a sawtooth pattern (like 1,2,3,3,4,4,1...),
perceivable as periodically shaky motion of the rendered scene.
By capping the `elapsed_time` to a fixed value, instead of resetting
it, this change eliminates the sawtooth pattern, making the game run
more evenly. (It also now runs faster, when logic or render is slow,
because the main loop can consistently use 3 or 4 steps per frame.)
The cost is that, on normal transient lag spikes (startup, level load,
sector switch) there may be multiple steps for the frame instead of
zero; however, such lag spikes are rare, concealed by loading screens
or safe regions, and do not occur during critical moments of game play.
0 commit comments