Controlling spritesheet animation speed programmatically (DEF-1590)


Once an animation is defined from a group of images in the Outline of an Atlas, I can set its FPS to a value I like, however I couldn’t find a documented way to programmatically control sprite sheet animation speed.

I’m thinking about two work-arounds: defining animations with suffixes like run_10fps, run_11fps, run_12fps, etc for different FPS and switching between these animations programmatically - which will most likely cause animation cycle synchronisation issues; alternatively - I can try and create my own sprite sheet animation system on top of Defold and switch the sprites programmatically (one-frame animation per each frame of the cycle).

Am I missing anything?


It’s correct that there is no way to programmatically control the sprite sheet animation speed. All I can think of is doing exactly what you are doing I’m afraid.

I’ve created a ticket for it (DEF-1590). Let’s see if one of the engine guys can provide some feedback.


Thank you @britzl. At least there’s a workaround I can use right now!


I’ve needed the same functionality and based on second workaround I’ve prepared simple animation function which does the job using Atlas-based manual animation
First you need to prepare your atlas a bit differently - don’t aggregate your animation frames in animations. Just place the frames in your atlas.
Then use this function:

-- animation [table] - animation description table with following members:
--     * object [string] - url of the sprite which will be animated
--     * time [float] - current time of animation. Elapsed value since start of animaton in seconds. pass 0.0 to start from begining of animation.
--     * duration [float] - animation duration in second. Must be greater than 0.0
--     * time_scale [float] - scalar of animation speed. 1.0 - default speed, 2.0 - double speed, 0.5 - half speed, etc.
--     * frames [table] - a table with animation frames, which are strings of names of your animation frames, e.g. {"frame1", "frame2", "frame3"}
--     * finish_callback - callback function which will be fired when animation finished. May be nil. Will be fired only in case of non-looped animations.
-- dt [float] - time since last frame in seconds.
function update_animation(animation, dt)
    if animation.loop == false and animation.time == animation.duration then
    animation.time = animation.time + dt * animation.time_scale
    if animation.time > animation.duration then
        if animation.loop then
            while animation.time > animation.duration do
                animation.time = animation.time - animation.duration
            animation.time = animation.duration
    local frames_count = table.getn(animation.frames)
    local current_frame = math.min(math.floor((animation.time / animation.duration) * frames_count) + 1, frames_count), "play_animation", {id = hash(animation.frames[current_frame])})
    if animation.time == animation.duration and not animation.loop and animation.finish_callback ~= nil then

You can put the function into a module or use it directly.
The usage is quite simple:

function init(self)
    self.idle_animation =
            object = "#sprite",
            time = 0,
            duration = 0.4,
            time_scale = 1.0,
            loop = true,
            frames = 
                    "frame_0", "frame_1", "frame_2", "frame_3", "frame_4"
            finish_callback = nil

function update(self, dt)
    update_animation(self.idle_animation, dt)

I hope that helps!


Nice! Thanks for sharing!


This workaround is good, but it’s planned to be added in the engine?

So strange to use workaround for this.



Yes, it’s in our backlog but it hasn’t been assigned to a future release though.


I am using this workaround, too.
Would be nice to replace it by engine method.


Hello @britzl ,

I don’t know its a dump question but, I wonder if your backlog covers spine animation speed. I couldn’t find a away to control it.

Best Regards,


Yes, this is covered by a ticket in our backlog. I don’t have access to it right now though so I can’t see it’s priority.


Is there any news?


Yes, the changes related to speed, playback offsets, etc. is being designed right now. :slight_smile: Sorry for the poor follow-up in this thread.


Is there any updates on this issue, or is the workaround the way to go at the moment?


Yes, I’m afraid so.