Delta-time and framerate independence

Favourite 301 favourites
Tutorial written by AshleyOriginally published on 10th, October 2011 - 10 revisions

Framerate independent games are games that run at the same speed, no matter the framerate. For example, a game might run at 30 FPS (Frames Per Second) on a slow computer, and 60 FPS on a fast one. A framerate independent game progresses at the same speed on both computers (objects appear to move at the same speed). On the other hand, a framerate dependent game progresses at half the speed on the slow computer, in a sort of slow-motion effect. Making framerate independent games is important to make sure your game is enjoyable and playable for everyone, no matter what kind of computer they have. Games which slow down when the framerate dips can severely affect gameplay, making players get frustrated and quit!

This tutorial describes how you can make your game framerate independent. The same technique also enables time scaling, which allows for deliberate slow-motion effects and easy pausing.

The dt system expression

The key to framerate independence is the dt system expression. dt stands for delta-time. Delta means a change in a quantity, so delta-time means the change in time. It is the time, in seconds, since the last tick.

For example, at 100 fps dt will be 0.01 (one hundredth of a second), and at 10 fps dt will be 0.1 (one tenth of a second). In practice, dt varies tick-by-tick, so it is unlikely to be exactly the same value for long periods of time.

Notice that if you add dt to a variable every tick, it adds 1 every second, because the time between all the ticks over a period of 1 second must add up to 1! Here's an example showing just that. (Adding dt to an object's instance variable is also a handy way to have a timer in an object.)

How to use dt

Typically, framerate dependent motion is done with an event like this:

Framerate dependent motion
Every tick (once per frame), the object moves one pixel to the right. Notice that at 30 FPS this means 30 pixels per second, and at 60 FPS this means 60 pixels per second. Those are different speeds, depending on the framerate.

Remember from the example above that dt always adds up to 1 every second. So if we change the event to the following:

Framerate independent motion
...the object will move to the right at 60 pixels per second at any framerate. Since dt adds up to 1 every second, 60 * dt adds to up to 60 every second. This means at both 30 FPS and 60 FPS our object moves to the right 60 pixels every second - the same speed, regardless of framerate.

Use dt everywhere

Any time you move an object at a steady speed, you need to use dt in that way to achieve framerate independence. For example, Sprite's Move forward action takes a number of pixels to move the object forward. If you constantly move the object forwards, you could move it forward 60 * dt pixels to move it at 60 pixels per second at its current angle.

Behaviors already use dt

All of Construct 2's behaviors use dt in their internal movement calculations. That means anything moved by behaviors like Platform and 8 Direction don't need any special treatment - they do this already!

Note that Physics is an exception. By default it does not use dt, and therefore is framerate dependent. This is because dt usually has small random variations. These variations can make the same setup in a physics game give different results even if exactly the same thing is done twice. This is often annoying for physics games, so by default it is framerate dependent. However, you can enable use of dt by using the Set Stepping Mode physics action on start of layout, and choose Framerate independent. Note in this mode it still clamps the maximum timestep for physics to 1/30 (about 33ms), because using a very large timestep can cause instability in physics simulations.

Timescaling

A really cool feature in Construct 2 is timescaling. This allows you to change the rate time passes at in the game, also known as the time scale. You can set the time scale with the system Set Time Scale action. A time scale of 1 means normal speed. 0.5 means half as fast, and 2.0 means twice as fast. If you set your game's time scale to 0.1, it's going ten times slower but still smoothly - a nice slow-motion effect!

Timescaling works by changing the value returned by dt. This means behaviors are affected, and any movement using dt. If you don't use dt in your movement calculations (like the first event above) the motion is not affected by the time scale! So to use time scaling, you simply have to use dt properly in all movement.

Pausing

You can set the time scale to 0. This stops all motion. It's an easy way to pause the game. Set it back to 1 and the game will resume.

You might notice you can still do things like shoot using the game controls. You can get around that by putting your main game events in a group, and activating/deactivating that group as you pause and unpause.

It's also a good way to test you have used dt correctly. If you have used it correctly, setting the time scale to 0 will stop everything in the game. If you have not used it correctly, some objects might continue to move, even though the game is supposed to be paused! In that case you can check how those objects are moved, and make sure you are using dt properly.

Other kinds of movement

It's important to realise that dt must be used for all kinds of motion. This includes rotation and acceleration.

Rotation

Similar to before, the following event rotates the piggy 1 degree every tick:

Framerate dependent rotation
This is 30 degrees per second at 30 FPS, and 60 degrees per second at 60 FPS - again, different speeds for different framerates. Using dt in the same way solves the problem again. This way the piggy rotates at 60 degrees per second regardless of the framerate:

Framerate independent rotation

Acceleration

Acceleration is also fairly straightforward. Usually this only applies when you are making a custom movement via events.

If you have a speed variable, your object will be moving at Object.Speed * dt pixels per tick. Your object's speed variable therefore contains a speed in pixels per second.

Suppose you want to accelerate the object by 100 pixels per second over one second. You simply need to add 100 * dt to the object's speed variable every tick, and it will accelerate in a framerate independent way. In other words, you use dt both to adjust the object's position, and to adjust the object's speed.

Lerp

If lerping from two fixed positions, simply ensure the factor (x in lerp(a, b, x)) increases using dt like any other moving value. A more complicated case is when lerping from the last result of lerp, e.g.

Set X to lerp(Self.X, TargetX, factor)

In this case the correct form is to use:

lerp(a, b, 1 - f ^ dt)

...where f is between 0 and 1, e.g. 0.5. Commonly lerp(a, b, f * dt) is used instead, but this is not perfectly accurate and has some other pitfalls. The maths involved is explained in more detail in the blog post Using lerp with delta-time.

Common mistakes

Never use dt in the Every X seconds condition! An event like Every 1 second will run every 1 second regardless of the framerate, thus is already framerate independent. The condition measures time, not frames. If you make an event like Every 60 * dt seconds, you have inadvertently made the condition framerate dependent - the opposite of what you want to achieve! Such a condition will run every 6 seconds at 10 FPS (when dt = 0.1), or every 0.6 seconds at 100 FPS (when dt = 0.01); if you just use Every 6 seconds, it already runs every 6 seconds regardless of the framerate.

Advanced considerations

Minimum framerate

At very low framerates, dt can become very large. For example, at 5 FPS, dt is 0.2. An object moving at 500 pixels per second is therefore moving 100 pixels per tick. This can cause it to "teleport" through walls or miss collisions with other objects.

Games are usually unplayable at such low framerates, but it is even worse if they become unstable like that. To help the game stay reliable even at very low framerates, Construct 2 does not let dt get larger than 1/30 (about 0.033). In other words, below 30 FPS, dt stays at 0.033. This does also mean below 30 FPS the game starts going in to a slow-motion effect (described earlier as one of the issues of framerate dependent games), however this is usually a better result than the "teleporting objects" problem.

If you want to set a different limit to 1/30, you can use the system action Set minimum framerate.

Random variation

As mentioned with physics, dt usually has small and random variations, usually due to imperfect timers in the computer. Like with physics, this can also cause slight random variations in your game. However, usually the effect is negligable and much less noticable than with physics. It's recommended that you always use dt in your games unless exact precision is required (which is rare).

Object time scales

You can set a time scale for an individual object, via the system Set object time scale action. This allows you to have, for example, a game running in slow-motion with a time scale of 0.3, but still have the player acting at full speed with a time scale of 1. This is achieved by setting the time scale to 0.3, then using Set object time scale to set the player's time scale. The system expression dt is only affected by the game time scale. Objects have their own dt expression (e.g. Player.dt) which you must use instead of the system dt for all motion relating to that object. This way, there are now two values of dt: one for the game, and one for the player. Since they return different values, different parts of the game can progress at different rates.

In this example, to return the player back to game time, use the system Restore object time scale action.

Conclusion

It's important to design your game from the start using dt. This improves the gameplay, ensuring the pace never slows down in particularly intense parts of the game. As an extra bonus, you can also use the time scaling feature, easily pause the game, and even control object's individual time scales.

Don't forget behaviors already use dt (except with Physics where you must turn it on yourself). If you use behaviors to control all motion in your game, you don't have to worry about dt at all! However, most games have some event-controlled motion, and it's important to remember how to make it framerate independent.

Unlock your full gamedev potential

Upgrade to the Personal Edition of Construct 2, it has way more features and won't holding back from making money and using your full creativity like the free edition does. It's a one off payment and all Construct 2 editor updates are free for life!

View deals

Plus, it's got a lot of additional features that will help you save time and make more impressive games!

Congratulations on finishing this tutorial!

Did you learn a lot from it? Share it now with your friends!

Share and Copy this Tutorial

You are free to copy, distribute, transmit and adapt this work with correct attribution. Click for more info.

Comments

14
VampyricalCurse 8,335 rep

Very helpful and nifty. :)

Monday, October 10, 2011 at 4:24:25 AM
23
gaboduarte 13.8k rep

Great article!
I admit I was a bit slopppy using deltatime in CClassic, but since the C2 games can behave differently with each browser, it is VERY necessary! I used it on my game and it was very helpful!

Monday, October 10, 2011 at 2:45:17 PM
7
ludodesign 30.6k rep

Hard... I don't undestand everthing, I will try put this in my test games and try harder get the idea.

Tuesday, October 11, 2011 at 1:12:23 PM
3
renegade1991 3,350 rep

Great tutorial, just what i needed

Thursday, November 03, 2011 at 6:39:00 PM
6
AngeloFernandes 4,503 rep

I had to read it three times to fully understand the difference in applying * dt or not. It came in handy.

Thursday, November 10, 2011 at 4:27:28 PM
4
roidayan 4,077 rep

thanks for the tutorial

Thursday, January 19, 2012 at 9:30:47 AM
4
Kazan 4,996 rep

Works fine and all. But how do you stop the motion?

Monday, January 23, 2012 at 1:12:24 PM
3
Ashley 196.0k rep

@Kazan, did you see the bit about pausing?

Monday, January 23, 2012 at 3:16:06 PM
2
carl 2,703 rep

I don't undestand i need more help with the Physics side of fps as i have sprites that are just controlled with physics and no direct movement controls and when i try on the local testing on my phone and tablet the fps is diabolical thanks for the little bit of help on this tutorial but i need more.

Monday, February 27, 2012 at 6:34:38 PM
2
Ashley 196.0k rep

@carl best post to the forum for help! However, have you tried "Set Stepping Mode" to "Framerate independent" in Physics like the tutorial mentions?

Monday, February 27, 2012 at 7:10:54 PM
3
solidgames 2,307 rep

Very clear explanation. I added plus/minus timescale to my sandbox just to play around with timescale. Very useful even for debugging. This would also be a very simple way to do a number of in-game time based effects. Seems this is also a must-have basic technique for high quality games.

Friday, March 09, 2012 at 4:50:23 PM
1
blackvikinggames 4,934 rep

Much needed info!

Saturday, April 07, 2012 at 7:38:26 PM
1
Schoening 8,453 rep

This is VERY useful ! Especially once we move to some multiplayer games :D Slow pc vs Fast pc haha

Sunday, April 08, 2012 at 9:18:38 PM
1
leonhard 7,988 rep

the mouse moves differently on the browser chrome.because

Tuesday, April 24, 2012 at 3:39:22 PM
2
AndyWatson 6,682 rep

Very useful tutorial, now I can stop my game going into hyperspeed mode on powerful PCs.

Tuesday, May 15, 2012 at 1:04:29 PM

Leave a comment

Everyone is welcome to leave their thoughts! Register a new account or login.