About todays Q&A - Day 018

One of the viewers asked about having a constant physics time, and then just display snapshots from this for each frame. IMO this is the right way to do it.

Because if you are not able to display enough video to make it seems responsive then, do you really have a game worth shipping?

Of course, I wouldn't know. I never written a game. But I would like it if you could clarify your thinking on this.

I think also this is the right way to do threading. That the mainthread just displays as many frames (or other data) as it can from the physics, which may run by itself on a different thread.

I tried this once, long time a go. And I seem to remember it worked very well. And that other ways or doing it worked poorly. And so, I plan of doing this in future code.

Therefore, I would like also other people to give more input on this. Why or why not?
My main objection to this technique is that it pretends that simulating the game is valuable even if the user cannot see the results, which seems somewhat nonsensical to me. The user can only react to the things that they actually see happening, so showing them "in-between" frames that are not even the base frames being used to apply the next control input seems, if anything, a step backwards.

That said, I have never done a game loop this way, so maybe there is some benefit to it that I would realize if I actually implemented it. But I am very skeptical of it.

- Casey
For those who would like to know more about this technique, I recommend this article.

From my limited experience, I would say the main advantage is increased accuracy in the physics simulation. If the physics timestep is coupled to the (fixed) frame rate, it's 33 ms in a 30 FPS game. That's a really long time, especially in complicated collision situations with fast moving objects. A car in a racing game moving at 100kph (that's about 60mph for the imperialists) moves almost a whole meter (3ft) in that timespan. So instead of crashing into the roadside barrier, it could get stuck, with no good collision resolution available (other than shooting it out in a random direction).

Of course, there are other solutions to that, but using a small physics timestep decoupled from the graphics framerate seems to be the most straight-forward one.

By the way, if anyone wants to see what a bad coupling of FPS and physics timestep look like, I can recommend TotalBiscuit's video about Need for Speed: Rivals.
I like Casey's attitude of simplifying things by asserting on fixed behavior. Many Amiga games were very smooth when they were designed with that constant frame budget of 50 Hz (PAL) and so never skipped a frame. But it remains an open question whether supporting only 120/60/30 Hz (and temporary transitions between modes) is enough? Interesting to see what Casey has in mind here. With clever design everything can be multiples of a base rate (so having constant physics step quite easy) and frame budget can perhaps be ensured by having strict budgets to all resources (spawning particles etc), allowing for "progressive jpeg" style degradation, always hitting the target frame budget.

The opposite way is more complex, preparing for variable frame rate by admitting/regretting one cannot control the resource usage (complex physics interactions in 3D-engine, for example), where that decoupling of physics and render loops becomes relevant. But then one has effectively two snapshots of the world at render time and a proportional blend factor between them (because the physics time step is constant and separate), a sort of like subpixel rendering situation. I guess that kind of game loops are found in many browser games, for example, where gc and stuff may interrupt at any point, and so skipping cannot be avoided. That gaffer link above had nice explanation, and for an operational example see for example https://github.com/vladikoff/cube.../blob/master/lib/game.js#L97-L150 (actual game with nice tracker/mod-like music at https://cubeslam.com).

EDIT: It may be notable that 8 years later the author of that gaffer article commented: "A much easier solution [than interpolation] is to just always lock to 60HZ or so, if you can get away with that, it’s the best and simplest option." :)

Edited by Petri on