What is delta time?

Published 2 years ago Updated 6 months ago


You may have heard the term “delta time” before. Unity represents this with the Time.deltaTime property. Unreal represents this with the DeltaSeconds parameter in the Tick event.

But if you've ever asked "what does delta time even mean?", this is the post for you.

TL;DR

In a nutshell: with regards to game engines, “delta time” means the amount of time that has elapsed since the previous frame. This is most commonly provided as a floating-point value representing the time in seconds (as in the case of Unity and Unreal), though it doesn't have to be. A notable exception to this is XNA/MonoGame which provides a GameTime struct to continuous functions like Update, and this struct actually offers you a TimeSpan, but I digress.

What does “delta” mean?

The term “delta” comes the fourth letter of the Greek alphabet Δ/δ, and we commonly use it in physics to represent how a value changes over time. When dealing with games and game engines, you may commonly see delta time written as dt or even Δt.

Why is it important?

Suppose we have a behaviour which moves an object forward 2 units per second. How would we go about this?

We'll use Unity for this example, but the same logic applies anywhere. Let's assume our game runs at 60fps. This means Update is called 60 times every second. So, if we wanted to move an object forward 2 units per second, we would simply move it forward at a rate of 2/60. After one frame (one Update call), it will move forward 0.03 units. After another frame, it'll move forward another 0.03 units. And it'll repeat this every frame, until finally one second has passed and we've moved forward a grand total of 2 units.

void Update()
{
    transform.position += transform.forward * (<mark>2f / 60f</mark>);
}

Great! This'll work. Except no, it really won't.

Computers are bad at timekeeping. Your game will pretty much never run at a solid and steady 60fps; you may hit 59, or 61. You may encounter a lag spike and drop to 50. And what about players whose computers are only capable of rendering at 30fps? Their Update will be called only half as often, which means after 1 second we'd only move forward 1 unit, not 2. Or consider players who can run at 120fps. Their Update will be called twice as much! They'd move forward 4 units per second.

Delta time to the rescue

To combat this issue, we need a way for our code to accommodate any possible framerate.

Right now, our calculation 2/60 assumes we are running at 60fps. So let's change our code so that we are calculating 2/frameRate - where frameRate will be some variable holding the current framerate.

void Update()
{
    transform.position += transform.forward * (<mark>2f / frameRate</mark>);
}

But now, you ask, how do we know what the framerate is?

Time.deltaTime is how. In Unity, this value tells us how many seconds have passed since the last frame - since the last time Update was called. The framerate can be retrieved by calculating the multiplicative inverse of this value (also known as the reciprocal.)

void Update()
{
    <mark>float frameRate = 1f / Time.deltaTime;</mark>
    transform.position += transform.forward * (2f / frameRate);
}

Now our code works and is almost perfect. We are accommodating any framerate, and whether you're running at 6fps, or 600fps, we'll move forward precisely 2 units each second.

We're not done just yet though. We can improve on this code; right now we're doing 2 divisions which is not exactly the most optimal thing to do - especially when the dividends are known in advance. We can reduce it to a single multiplication:

\[ \frac{2}{\frac{1}{\Delta t}} = 2 \Delta t \]
void Update()
{
    transform.position += transform.forward * (<mark>2f * Time.deltaTime</mark>);
}

Why does this work?

Let's step through and try to figure it out. Let's say your game is running at 1fps. Δt=1/f where f = the current framerate, so Time.deltaTime is 1, and the expression evaluates to 2*1, which is simply 2. 1 second has elapsed since the last frame, so we jump forward 2 units.

What about if we were running at 2fps? Δt=1/f which means Time.deltaTime will be ½, or 0.5. This gives us 2*0.5 = 1, and so after the first frame after a half-second our object moves forward 1 unit. The second frame after another half-second moves the object forward another 1 unit. After 2 frames, one full second has passed and the object has moved forward 2 units in total.

The math follows from there. We scale how much we're moving by however many seconds have passed - which ensures we move forward at the same speed regardless of framerate.