1
\$\begingroup\$

I watched a recent YouTube video about deltaTime and at around 3:50 the author talks about how it is calculated. He goes on to claim that it is NOT

The time elapsed between the frame currently being processed and the one preceding it

but rather is

The time elapsed between the last frame and the frame preceding it

And this confused me. The video's explanation of the reasoning also didn't help but just raised more questions. So now I'm here. :)

Let's set up a timeline. Since I'm too lazy to draw, I'll use numbered bullet points:

  1. Frame 1 starts
  2. Update() is called. It checks the inputs and updates the game state.
  3. Render() is called. It renders the game state into a frame.
  4. DisplayFrame() is called. It swaps out the previous frame for the new one. Depending on vertical sync/double-buffering/triple-buffering settings, this might also add some delay until the new frame is actually displayed. Or not.
  5. Frame 2 starts.
  6. Update() is called. It checks the inputs and updates the game state.
  7. Render() is called. It renders the game state into a frame.
  8. DisplayFrame()...
  9. Frame 3 starts
  10. Update()...
  11. Render()...
  12. DisplayFrame()...
  13. Rinse and repeat.

Now (ignoring the very first frame ever) I'd expect that the deltaTime passed into Update() at step 10 would be the difference between timestamps taken at points 5 and 9. However that would fit the description of "Time elapsed between the frame currently being processed and the one preceding it". The "time elapsed between the last frame and the frame preceding it" would be the difference between points 1 and 5 which to me doesn't make sense.

Alternatively, we could say that the "time of the current frame" is actually when it's displayed, so right after DisplayFrame(). In this kind of sense, yes, the difference between points 5 and 9 could be considered "the time between the last frame and the previous one".

However that interpretation comes with another scary implication - it means that Update() should actually try to predict the future. I always thought that Update() tries to calculate what the game state looks like NOW. When a frame starts, Update() has the previous game state and knows that since then deltaTime time has passed. So now it has to calculate how the game state has evolved, but the end result is the game state how it should look like NOW, not deltaTime in the future.

Calculating the future however means that you need to do all kinds of compensations when the frame rate varies, which gets pretty hairy fast. But the video does not speak of this, so I don't think that's what it meant either.

Of course, my interpretation (calculating the NOW, not the future) also has drawbacks - it means that what the user sees on the screen is always in the past.

So how is it really? Between what points is deltaTime being actually calculated and how should Update() interpret that information?

Note: this question isn't engine-specific, but I realize that the answers might differ in various game engines (or maybe not). If there is a difference, please specify which engine does what.

\$\endgroup\$
5
  • \$\begingroup\$ Between what points is deltaTime being actually calculated and how should Update() interpret that information? No matter the exact moment its calculated, it'll always be the time between the last frame and the frame before that. \$\endgroup\$
    – tkausl
    Commented Jul 10, 2023 at 4:38
  • \$\begingroup\$ I'd expect that the deltaTime passed into Update() at step 10 would be the difference between timestamps taken at points 5 and 9. It might be. However that would fit the description of "Time elapsed between the frame currently being processed and the one preceding it". It actually wouldn't. The frame currently processed is complete at step 12. You're not at step 12 yet and you don't know when step 12 will be in the future. You only know that the previous frame completed X milliseconds after the frame before that. \$\endgroup\$
    – tkausl
    Commented Jul 10, 2023 at 4:38
  • \$\begingroup\$ @tkausl - OK. But does that mean that my Upadate() function should try and predict when step 12 will be and calculate what the world will be like then? As opposed to calculating what the game world is like right now, at at the start of step 10? What if it completes waaay to early? Should it postpone DisplayFrame() until the right time? \$\endgroup\$
    – Vilx-
    Commented Jul 10, 2023 at 8:11
  • \$\begingroup\$ Furthermore, should I also try to adjust for whatever misestimate happened in the previous update? \$\endgroup\$
    – Vilx-
    Commented Jul 10, 2023 at 8:19
  • \$\begingroup\$ @tkausl Wait, I think an adjustment of terminology might help clarify things! I propose: a "frame" is the picture shown on screen. A "tick" is a single iteration of the game loop, consisting of Update, Render and DisplayFrame. During the tick N, the frame N-1 will be displayed. Only at the very end of tick N will frame N get displayed. Ok, so now the question becomes - should Update calculate the game state at the start of its tick, or at the (predicted) end of it? \$\endgroup\$
    – Vilx-
    Commented Jul 10, 2023 at 8:45

0

You must log in to answer this question.

Browse other questions tagged .