Stop changing your sprite sheet to fix animation speed
FrameSpriteDEV Community
3 views
An eight-frame animation does not have a fixed duration. At 8 fps it lasts one second; at 12 fps it lasts two-thirds of a second; at 16 fps it lasts half a second. Before drawing or generating more frames, check whether the problem is missing poses or the time each pose stays on screen.
We maintain FrameSprite, a browser workspace for game assets. This is a timing and export note, not a claim that a particular frame count makes AI animation reliable. The equations work with hand-drawn sprites too.
Three numbers that are easy to mix up
Source FPS describes how a recording was sampled. Frame count is the number of entries you put in an animation. Playback FPS controls how fast those entries advance in the game. A 24 fps source video can provide eight selected poses that you play at 12 fps. You do not need to preserve every source frame.
For equal holds, forward playback and a speed multiplier of 1:
duration_seconds = frame_count / playback_fps
frame_hold_ms = 1000 / playback_fps
fps_for_target = frame_count * 1000 / target_duration_ms
Same eight frames
Hold per frame
Full loop
8 fps
125 ms
1.000 s
12 fps
83.333… ms
0.667 s
16 fps
62.5 ms
0.500 s
You changed the cadence without changing one pixel of the sprite sheet.
A test you can reproduce
Use the public eight-frame sample. Keep the same frames, order, canvas and pivot for all three trials. Change only playback FPS between 8, 12 and 16.
Check the animation alone at its intended game size.
Run it beside actual movement or attack timing.
If cadence improves but a foot or weapon still jumps, inspect the missing phase instead of raising FPS again.
If every frame jumps by a small amount, inspect canvas and pivot alignment.
If the pause happens only at the seam, look for an accidental duplicate endpoint.
The sample makes the arithmetic test repeatable. It is not evidence that eight frames is the right budget for every character or action.
Do not accumulate rounded timestamps
At 24 fps, one hold is 41.666… milliseconds. Storing 41.67 ms and repeatedly adding it introduces rounding drift. Calculate each boundary from its index instead:
function timingRows(frameCount, fps) {
if (!Number.isInteger(frameCount) || frameCount < 1 || frameCount > 1000) {
throw new RangeError("Frame count must be an integer from 1 to 1000");
}
if (!Number.isFinite(fps) || fps < 0.01 || fps > 240) {
throw new RangeError("FPS must be between 0.01 and 240");
}
return Array.from({ length: frameCount }, (_, index) => ({
index,
startMs: index * 1000 / fps,
endMs: (index + 1) * 1000 / fps,
}));
}
For 60 frames at 24 fps, the last entry is index 59. It starts at approximately 2458.333 ms and ends at 2500 ms. Round when displaying or serializing, not before calculating the next boundary.
Transfer the schedule, not an assumption
In Godot, SpriteFrames.set_animation_speed() sets animation FPS. Individual frames also have relative durations: a duration of 2 holds twice as long as 1. The simple equation above assumes all those durations are 1 and playback speed has not been changed. See the official SpriteFrames reference.
In Phaser, animation frameRate controls frame advancement; it is separate from the game's rendering frame rate. Check overrides such as extra frame duration, delays and playback speed. See the official Animation reference. Both references were checked on 2026-09-05.
Variable holds, ping-pong traversal, transition blending and runtime stalls need additional reasoning. A spreadsheet of equal frame holds cannot diagnose them.
A small handoff that prevents rework
We added shareable settings and a per-frame timing CSV to the free FrameSprite timing calculator. The CSV contains index, start, end and hold in milliseconds. It is a planning file, not an engine importer. Calculations run locally, no image upload or account is needed, and paid AI generation is a separate feature.
Send the timing settings alongside the sheet when handing work to another developer. “Eight frames at 12 fps, equal holds, no duplicate endpoint” is a more useful contract than “make it smooth.”
Hello, I’m simply asking because I’m aspiring to become a web developer, and I’m curious about how viable the field is nowadays. I don’t think you can really blame people for asking this either, because front-end development has been heavily trivialised by AI(not my opinion), or at least that’s what
Project Name: Podcode Repo/Website Link: https://podcode.io Description: Quick background, since this matters for the rest. I run a small private AI stack for my own work. Coding agents like Claude Code and Codex are part of my daily flow. They are great when they work. The thing that drove me nuts
ChatGPT.com reached about 1.09 billion monthly US visits in July 2026, a 48.38% year-over-year increase, according to Semrush Traffic Analytics data. In the same comparison, Bing.com traffic fell about 50.43%. The contrast does not show AI replacing conventional search overnight. Google and YouTube