Tutorial: Delta time in Corona

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0

Today’s guest tutorial comes to you courtesy of Christer Eckermann, the co-founder of Snuti, a small Norway-based indie game start-up. Snuti consists of two University graduates, Clare Falconer and Christer Eckermann, trying to make their independent game development dream come true.

Making games run smoothly with delta time

One method of animating, moving, and timing things in games is to programmatically change certain values on each frame update. However, if you update with a specific value every frame, for example, moving an object down one pixel every frame, then, with fluctuating frame rates, the speed of this action may seem inconsistent to the player. In that case, the player will experience both a choppy frame rate and a fluctuating game speed.

But if your game already runs smoothly, why should you worry about it? Well, even if it does run smoothly, there are constant small changes in the frame rate. To compensate for this, you can use delta time. This helps ensure that your game runs more stable on older devices.  More significantly, frame rate often drops noticeably when the device is displaying notifications or when your game is processing something heavy.

In my opinion, all games should use delta time, no matter the size and depth, if you want the game speed to appear consistent.

What is delta time?

The word delta means “change,” and thus delta time means “change in time.”

In games, delta time is a compensation value. In practical use, the delta time value is multiplied by values that are affected by time. When the frame rate is lower, affected values increase to compensate for the time gap, or decrease for fast frame rates. If your frame rate is consistently 60 frames per second, then the delta time value is 1.0, effectively enacting no change. If the frame rate drops to 30 fps, then the delta time increases to 2.0, making all values twice the size to compensate for the slower frame rate.

Where to use delta time

  • For a moving object which changes position, rotation, or scale.
  • Manual countdowns in the frame update, as you may want these countdowns to reflect time instead of how many frames have passed.
  • Most values which are changed over time.

The delta time function

The function below calculates the delta time value which you can use in your frame update function. Corona games can run at two different frames-per-second rates: 30 and 60. The function below is set up for 60 fps, but you can adjust it for a 30 fps game by changing (1000/60) to (1000/30).

If you print out the delta time value for each frame, it will look something like this:

The value will be very close to 1.0 when the game runs at 59-61 frames a second, but it will change more significantly if the frame rate fluctuates more severely.

Implementing delta time

Assuming you have the above function in your code, implementing delta time shouldn’t change your existing code much. However, be careful to only multiply it by changing values, not the entire value, as illustrated in the code below.

Testing delta time

To confirm that your setup is working properly and that your game has become “framerate independent,” just change the fps value in config.lua to 30 and 60, back and forth over several tests. Your game should appear to run at the exact same speed, except that the 30 fps tests will likely seem a bit “choppy.”

That’s it! Your game should now appear to run at the same speed no matter what the frame rate is. This technique can be used for all types of delta-related processes, so feel free to expand its functionality to suit your needs.

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0

Brent Sorrentino serves as a full-time Developer Evangelist for Corona Labs, assisting developers in the forums, maintaining documentation/guides, and creating samples which highlight core features of Corona SDK.

This entry has 20 replies

  1. Very interesting. I’m going to try to implement this tomorrow. Thanks for sharing!

  2. J. A. Whye says:

    Cool post! This is the kind of thing that can really help your game — and seeing it laid out like this is very helpful.


  3. Scott Shapio says:


    For most of my games I am implementing transition.to. How would i apply delta time in this situation?



    • Hi Scott,
      transition.to() is already “framerate independent” as you specify transition time in milliseconds already. So delta time would not be necessary in this case.

      • Scott Shapio says:


        Thanks for your response. Is there a reason I should be using rotation, scale and translate over transitions?


        • Default transitions in Corona are not very flexible, as far as I know it is not possible to pause a transition mid way, which might be necessary if the user pauses the game. Unless you use a module similar to this one:

          In general using manual rotation, scale and translate gives you better control of how things move in your game, in my experience.

          • Beloudest says:

            it is possible if you create your own transition class. I have achieved this. Works well. I think there is a class in the code section of the site.

  4. Just one quick thing that might be useful. In getDeltaTime(), instead of hard coding the base framerate you could use

    local dt = (temp-runtime) / (1000/display.fps)

    I believe that display.fps returns the ideal fps value (from config.lua), and not the currrent frame rate.
    Just saves you having to adjust it later in the code if you change your base rate to 30 for some reason.

    • That’s a very good idea, didn’t cross my mind. That would indeed be a more flexible solution.

      But it would cause problems if you decided to test if your game have become “framerate independant”, using the config.lua technique (changing the fps between 30 and 60 in the config.lua file). As that value in the delta time function should not be changed while testing, it would cause your game to run in slow motion or super speed while testing, defeating the purpose of the test.

    • Matt says:

      To save a little extra CPU time, you could also percale this at the start, to avoid calculating it every frame…

      fpsFraction = 1000/display.fps

  5. Tom says:

    Ups, display.fps shows ideal FPS not current ;/

  6. Chris says:

    That’s a really nice advice, I’ve used that in some games aswell.
    Also make sure to use that correctly with transitions – you could use it this way:
    transition.to(obj, {time=1000/dt,…}
    The only downside to this is that the transition won’t change it’s speed corresponding to your FPS. Best way would be to move everything manually.

  7. Hector says:


    The first i think is that would be practical not having to do for each frame 1000/fps and use a local variable with the result of this fixed calc. And because i want to use the delta time in diferente “classes” at the same time, i prefer to give its own enterframe event and use a get method only for recover the current/last delta value.

    Here my class that maybe can help someone.

    module ( …, package.seeall )

    function new ( _fps )

    local o = {}

    ———— ** ATRIBUTOS ** ————

    local delta = 0
    local lastTime = 0
    local divisor = 1000 / _fps — 60 or 30 fps

    ————- ** METODOS ** ————

    function o:getCurrent () return delta end

    ————— ** LOOP ** —————-

    local function eLoop ( event )
    local time = system.getTimer () — Tiempo actual en milisegundos
    delta = ( time – lastTime ) / divisor
    lastTime = time

    —————- ** INICIO ** ————–

    Runtime:addEventListener( “enterFrame”, eLoop )

    return o

  8. Beloudest says:

    long time coming this post. I always remember a piece of code called super timer when doing flash that took this even further. Nice tip for newcomers and key to smooth pixel movement without transitions.

  9. Craig says:

    Hmmm I have been testing this kind of method already. There is one problem I have with my programming style. Often I will do custom invserse log type animations and I’m wondering how to implement delta time. It seems easy to implement for speeds etc, but not so much ratios? e.g:
    local xTarget = 100
    object.x = 0

    function enterFrame()
    object.x = object.x + (xTarget – object.x)*0.5

    Every frame the object will move half again the distance between it and the xTarget. I know there is an elegant mathematical solution to time and log curves… but my brain just aint connecting the dots right now.

    • If you have a target to move to with a given time, then I often find that the transition.to() function works well, you need no delta time with that.

      But if the target position is constantly changing, I usually do this using velocity, it’s not based on ratio. But if I understand you correctly this might do what your looking for, I’ve written a blog post on it in the past, see the headline: “Example use: 2D Rubber Band Movement”: http://ecker00.tumblr.com/post/51964198092/

      But if your not looking for a rubber band effect, but rather a perfect ratio movement, maybe this will work. In the blog post above there is an “Influence” function described, which is essentially a ratio method, but to do a ratio movement you need to know your start position.

      function influence( val1, val2, inf )
      local aInf = 1 – inf
      return (val1*aInf) + (val2*inf)

      local object = display.newRect( 10, 10, 10, 10 )
      object.start = {x=10, y=10}
      object.target = {x=200, y=200}
      object.transition = 0.0
      object.speed = 0.01

      function enterFrame()
      local dt = getDeltaTime()
      object.x = influence( object.start.x, object.target.x, object.transition )
      object.y = influence( object.start.y, object.target.y, object.transition )
      object.transition = object.transition + (object.speed * dt)
      if object.transition > 1 then object.transition = 1 end

      Multiply the transition speed with the delta time, should do the trick.

  10. Jason Gay says:

    Thank you for the post! Wasn’t until final testing and noticing significant differences between Android and iOS devices additive object movement inside my main game loop. I think this will help keep everyone closer to the same precision and ensure a more consistent experience across platforms.

  11. Jamie says:

    When I do this my players movement becomes super choppy….
    Not sure if I am doing it wrong. I have the ‘getDeltaTime()’ function at the top, then I have the ‘movePlayer()’ just under….

    ———————————————————————— Delta Time
    local getDeltaTime = function()
    local temp = system.getTimer() –Get current game time in ms
    local dt = (temp-runtime) / (1000/60) –60fps or 30fps as base
    runtime = temp –Store game time
    return dt
    ———————————————————————— Move Player
    local movePlayer = function()
    local dt = getDeltaTime()
    player1.x = player1.x + (motion*dt)
    Am I doing it right?

    Thanks for this btw, I was looking for a tutorial on this 🙂

  12. viet dung says:

    self.tempTime = 0
    function scene:enterFrame( event )
    local time = event.time
    event.deltaTime = (time – self.tempTime)/1000
    self.tempTime = time

  13. Jorge Tapia says:

    This should help compensate the gaps on my parallax scrolling backgrounds I guess…