rendering.set_animation_speed() skips frames

Bugs that are actually features.
User avatar
ownlyme
Filter Inserter
Filter Inserter
Posts: 401
Joined: Thu Dec 21, 2017 8:02 am
Contact:

rendering.set_animation_speed() skips frames

Post by ownlyme »

I needed an animated graphic with render layer that i can dynamically change the animation speed of ( https://mods.factorio.com/mod/windturbines )
so i stumbled over your new LuaRendering API and was really happy about it's seemingly endless possibilities.

But i soon ran into an issue when i changed the animation speeds of the turbine blades and shadow to simulate wind speeds.
For the orientation i replaced the animations by simply using rendering.set_animation() which didn't cause frame skips but i thought i should maybe mention it.

It would be really nice if the animation wouldn't skip frames when you changed it's speed.

I thought it was possible to calculate the frame offset, but it doesn't seem to be deterministic at all... (but i'm sure my formula is correct .. at least now) (it also glitches when i dont replace the animation)

Code: Select all

game.print("total ticks "..(game.tick-turbine.creation_tick))
local current_wind_speed = wind_speeds[turbine.base.surface.name]*WIND_SPEED_MULT
turbine.last_frame_count = turbine.last_frame_count+(game.tick-turbine.last_change)*turbine.last_speed
game.print("actual frames until now: "..turbine.last_frame_count)
game.print("changing speed to "..current_wind_speed)
local new_frame_number = (game.tick-turbine.creation_tick) * current_wind_speed
game.print("expected frame at new speed: "..new_frame_number)
local new_offset = (new_frame_number-turbine.last_frame_count)*-1
game.print("calculated offset: "..new_offset)

rendering.set_animation_speed(turbine.turbine,current_wind_speed )
rendering.set_animation_speed(turbine.shadow,current_wind_speed)
rendering.set_animation_offset(turbine.shadow,new_offset)
rendering.set_animation_offset(turbine.turbine,new_offset)

turbine.last_change = game.tick
turbine.last_speed = current_wind_speed 
https://www.dropbox.com/s/auc73v9ag8kj2 ... .zip?raw=1

Happy new year!
Attachments
debug.jpg
debug.jpg (217.06 KiB) Viewed 2461 times
mods.factorio.com/user/ownlyme
My requests: uiAbove||Grenade arc||Blueprint allies||Creeps forget command/ don't get removed||Player Modifiers||textbox::selection||Better Heat IF||Singleplayer RCON||tank bug w/ min_range >= projectile_creation_distance

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5221
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: rendering.set_animation_speed() skips frames

Post by Klonan »

The rendering animation speed is done in the same way as the most of the rest of the game, essentially like this

Code: Select all

local frame = ((game.tick * animation_speed) + animation offset) % #frames)
It doesn't store any state about what frame it was on, or progressing frames, that is bad for memory performance

User avatar
ownlyme
Filter Inserter
Filter Inserter
Posts: 401
Joined: Thu Dec 21, 2017 8:02 am
Contact:

Re: rendering.set_animation_speed() skips frames

Post by ownlyme »

if that formula is correct i should be able to calculate an offset, but it doesn't work (but i'll try something new based on your formula, give me 1 hour...)
if you're not able to calculate the offset, the set_animation_speed function is useless.
i'm pretty sure there's something you can do to fix this, without hurting memory performance, for example only when a mod utilizes this.
Normal entities that scale their animation speed by activity also work without skipping frames, so why not this too?
but i feel like you're again declaring something as not-a-bug too quickly
mods.factorio.com/user/ownlyme
My requests: uiAbove||Grenade arc||Blueprint allies||Creeps forget command/ don't get removed||Player Modifiers||textbox::selection||Better Heat IF||Singleplayer RCON||tank bug w/ min_range >= projectile_creation_distance

User avatar
TruePikachu
Filter Inserter
Filter Inserter
Posts: 978
Joined: Sat Apr 09, 2016 8:39 pm
Contact:

Re: rendering.set_animation_speed() skips frames

Post by TruePikachu »

Your math likely does have an error, since substituting it into the equation Klonan provided states that the animation would transition to the same frame only if `turbine.creation_tick * (turbine.last_speed - current_wind_speed) ≡ (turbine.last_change - game.tick) * turbine.last_speed (mod frame_count)`.

EDIT: I'd suspect that normal entities (read: C++ code) have built-in computation of the new offset via setter member function. It might be an API request to expose this automatic calculation, but the omission of it, strictly speaking, isn't a bug.

EDIT 2: The corrected formula should be along the lines of `offset' = (tick * (speed - speed') + offset) % #frames` (where offset' and speed' are the new values for offset and speed)
Last edited by TruePikachu on Thu Jan 02, 2020 6:13 am, edited 1 time in total.

User avatar
ownlyme
Filter Inserter
Filter Inserter
Posts: 401
Joined: Thu Dec 21, 2017 8:02 am
Contact:

Re: rendering.set_animation_speed() skips frames

Post by ownlyme »

i tried a new algorithm based on your formula but it still glitches

Code: Select all

local expected_frame = (((game.tick * turbine.last_speed) + turbine.last_offset) % 24)
game.print("currently at frame: "..expected_frame)
local current_wind_speed = wind_speeds[turbine.base.surface.name]*WIND_SPEED_MULT
local new_frame = (((game.tick * current_wind_speed)) % 24)
game.print("new speed: "..current_wind_speed)
game.print("new frame w/o offset: "..new_frame)

new_offset = (expected_frame - new_frame)%24
game.print("new offset: "..new_offset)
game.print(string.rep("-",game.tick%80))
rendering.set_animation_speed(turbine.turbine,current_wind_speed )
rendering.set_animation_speed(turbine.shadow,current_wind_speed)
rendering.set_animation_offset(turbine.shadow,new_offset)
rendering.set_animation_offset(turbine.turbine,new_offset)

turbine.last_offset = new_offset			
turbine.last_speed = current_wind_speed 
Attachments
debug2.jpg
debug2.jpg (90.12 KiB) Viewed 2404 times
mods.factorio.com/user/ownlyme
My requests: uiAbove||Grenade arc||Blueprint allies||Creeps forget command/ don't get removed||Player Modifiers||textbox::selection||Better Heat IF||Singleplayer RCON||tank bug w/ min_range >= projectile_creation_distance

User avatar
TruePikachu
Filter Inserter
Filter Inserter
Posts: 978
Joined: Sat Apr 09, 2016 8:39 pm
Contact:

Re: rendering.set_animation_speed() skips frames

Post by TruePikachu »

I have just verified the math in the new algorithm; assuming the formula provided by Klonan is correct, and the animation is exactly 24 frames long, there shouldn't be any frame skipping.

User avatar
ownlyme
Filter Inserter
Filter Inserter
Posts: 401
Joined: Thu Dec 21, 2017 8:02 am
Contact:

Re: rendering.set_animation_speed() skips frames

Post by ownlyme »

but there is... (a lot) .. if it only skipped 1 or 2 frames i'd know that i was on the right way but it often skips half of the animation
https://www.dropbox.com/s/079sm3hc4tpfm ... .zip?raw=1
mods.factorio.com/user/ownlyme
My requests: uiAbove||Grenade arc||Blueprint allies||Creeps forget command/ don't get removed||Player Modifiers||textbox::selection||Better Heat IF||Singleplayer RCON||tank bug w/ min_range >= projectile_creation_distance

User avatar
TruePikachu
Filter Inserter
Filter Inserter
Posts: 978
Joined: Sat Apr 09, 2016 8:39 pm
Contact:

Re: rendering.set_animation_speed() skips frames

Post by TruePikachu »

Set the animation speed in your prototypes to 1.0, or account for the effects that setting a not-1.0 speed in the prototypes has on the actual speeds. The actual animation speed is the speed set on the render object multiplied by the animation's speed in prototypes.

I just verified the equation provided by Klonan via disassembly of the relevant function, but came across that additional factor of the prototype speed.

User avatar
ownlyme
Filter Inserter
Filter Inserter
Posts: 401
Joined: Thu Dec 21, 2017 8:02 am
Contact:

Re: rendering.set_animation_speed() skips frames

Post by ownlyme »

OMG THANK YOU SO MUCH!!!!!
IT WORKS! :D :) ;) :shock: :lol: :P :mrgreen:
mods.factorio.com/user/ownlyme
My requests: uiAbove||Grenade arc||Blueprint allies||Creeps forget command/ don't get removed||Player Modifiers||textbox::selection||Better Heat IF||Singleplayer RCON||tank bug w/ min_range >= projectile_creation_distance

Post Reply

Return to “Not a bug”