1
\$\begingroup\$

I read Gaffer's Fix Your Timestep article many years ago, and have since had the impression that game code should have a fixed timestep, with only non-gameplay related tasks outside of that in the main loop.

However, I recently reread the article, along with several others, and realized the emphasis is on physics. Which makes sense, but now I'm wondering if it only applies to physics.

What about games which don't use a real physics simulation? People talk about 60fps games, doesn't that imply a fixed timestep? What about multiplayer where you have regular updates to and from the server?

The only alternative I know of is variable rate with time delta, but that sounds like it wouldn't be any better, and less exact. What method is typically used?

\$\endgroup\$
1
\$\begingroup\$

It definitely also applies to game logic.

Computers are imprecise, so weird things can happen if you just let the update loop go as fast as it can.

For example, the goal of a game is to produce as much points as possible. Player A has a slow computer and runs at 1 update per second. Player B has a faster computer at runs at 10 updates per second

Both players start the same game and create one factory. One factory produces one 'score' per second. For player A the computation is easy. The game updates one per second, and adds one item to the list every update

For player two its also easy. The game updates ten times per second, so adds 1/10th of a score to the list. So how much points will both players have after one second?

playerAscore = 1.0
playerBscore = 1.0000001

Eh... wait what!? Turns out that 32bit floating point numbers can't exactly represent 0.1. The nearest number it can represent is 0.100000001490116119384765625. Updating ten times actually adds a bit more of an error, because the intermediate steps are also not represented exactly. So the end result is 1.0000001.

Now what if we had a win condition. This sounds reasonable, right?

if(playerBscore > playerAScore) 
{
    print("player B wins!");
}

Seems unfair, right?

Ok, so we require someone to have a full point more to win. Fixed? Oh now the problem only occurs after 16 weeks. Nobody plays that long right? Except every factory that produces a point you add makes it worse.

So we're now using extremely costly exact numbers, like big decimal. It can't go wrong anymore now right? Let's do a quick check. What are the scores of the players after 1.5 seconds?

playerAscore = 1.0
playerBscore = 1.5

Whoa!! player B is winning by a margin of 50%... Why? Because player A hasn't updated yet. What would happen if we checked the win condition after 1.5 seconds? :).

Now this is only silly example. But imagine the myriad of problems you have to fix, when you allow variable update rates.

Please note, that you have these floating point imprecision problems all the times. But normally we don't really care. They are too small for us to notice (most of the time). But when you start comparing stuff, its when things go wrong.

Real world examples: see in this video how a high fps leads to more gravity in Quake 3 :) https://www.youtube.com/watch?v=MbznZbuWcpY

Other fun floating point precision bugs: you could drive slightly faster on lap 1, 3, 5,.. than on lap 2, 4, 6... in this race game: https://www.iracing.com/q-circles-the-crop-circles-of-iracing/

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.