godot-2d-animation
Expert patterns for 2D animation in Godot using AnimatedSprite2D and skeletal cutout rigs. Use when implementing sprite frame animations, procedural animation (squash/stretch), cutout bone hierarchies, or frame-perfect timing systems. Trigger keywords: AnimatedSprite2D, SpriteFrames, animation_finis
By thedivergentai · 537 installs
npx skills add thedivergentai/gd-agentic-skills --skill godot-2d-animation
Source repository · Upstream listing
NEVER Do
NEVER use AnimatedTexture — This class is deprecated, highly inefficient in modern renderers, and may be removed in future Godot versions. Use AnimatedSprite2D or AnimationPlayer instead.
NEVER allow Tweens to fight over the same property — If multiple Tweens animate the same property, the last one created forcibly takes priority. Always assign your Tween to a variable and call kill() on the previous instance before creating a new one.
NEVER process kinematic movement outside the physics tick — If your AnimationPlayer moves a CharacterBody2D, ensure the AnimationPlayer's callback mode is set to Physics. Animating physics bodies during the Idle (render) frame breaks fixed timestep physics interpolation and causes stutter.
NEVER use animation finished for looping animations — The signal only fires on non looping animations. Use animation looped instead for loop detection.
NEVER call play() and expect instant state changes — AnimatedSprite2D applies play() on the next process frame. Call advance(0) immediately after play() if you need synchronous property updates (e.g., when changing animation + flip h simultaneously).
NEVER set frame directly when preserving animation progress — Setting frame resets frame progress to 0.0. Use set frame and progress(frame, progress) to maintain smooth transitions when swapping animations mid frame.
NEVER forget to cache @onready var anim sprite — The node lookup getter is surprisingly slow in hot paths like physics process() . Always use @onready .
NEVER mix AnimationPlayer tracks with code driven AnimatedSprite2D — Choose one animation authority per sprite. Mixing causes flickering and state conflicts.
NEVER use paper thin skeletons for deformation — 2D meshes require balanced vertex density. If your mesh deforms poorly, increase the vertex count near joints in the Mesh2D editor.
Available Scripts
MANDATORY : Read the script for the pattern you are implementing. Inline recipes that duplicated these scripts were removed — the script is the source of truth.
Do NOT Load (by scenario)
Scenario Load Do NOT Load
Single character / player one frame sync fix.gd , animation state sync.gd , optional animation tree step.gd / tween lifecycle manager.gd multimesh swarm anim.gd , gpu mesh optimizer.gd (unless fill rate profiling demands it)
Frame events / hitboxes / SFX sync animation sync.gd (+ AnimationPlayer method tracks) Swarm/MultiMesh scripts
Squash/stretch game feel MANDATORY procedural squash stretch.gd Inline landing condition snippets in this skill
Cutout / IK limbs skeleton 2d rig helper.gd MultiMesh swarm scripts
Shader flash / dissolve on anim shader hook.gd —
Thousands of bats/fish/props multimesh swarm anim.gd (+ docs fish tutorial) Per entity AnimatedSprite2D / Tween managers
Script index
[one frame sync fix.gd](scripts/one frame sync fix.gd) — Golden sync path : play() + advance(0) with flip h / property changes.
[animation state sync.gd](scripts/animation state sync.gd) — State driven animation + transition queue.
[animation sync.gd](scripts/animation sync.gd) — Method tracks, signal orchestration, blend space hooks.
[animation tree step.gd](scripts/animation tree step.gd) — AnimationNodeStateMachinePlayback.travel() .
[procedural squash stretch.gd](scripts/procedural squash stretch.gd) — Sole source for physics driven squash/stretch (do not re implement landing checks here).
[tween lifecycle manager.gd](scripts/tween lifecycle manager.gd) — Kill/reuse Tweens; property fight prevention.
[skeleton 2d rig helper.gd](scripts/skeleton 2d rig helper.gd) — FABRIK/CCDIK stacks, rest poses.
[shader hook.gd](scripts/shader hook.gd) — AnimationPlayer → ShaderMaterial uniforms.
[gpu mesh optimizer.gd](scripts/gpu mesh optimizer.gd) — Sprite → tight 2D mesh for fill rate.
[multimesh swarm anim.gd](scripts/multimesh swarm anim.gd) — GPU swarm motion only.
[animation data extractor.gd](scripts/animation data extractor.gd) — Value/method tracks decouple hitbox/spawn metadata from SpriteFrames visuals.
[procedural walker 2d.gd](scripts/procedural walker 2d.gd) — TwoBoneIK foot planting via raycast targets (pairs with skeleton 2d rig helper.gd ).
[sprite sheet memory manager.gd](scripts/sprite sheet memory manager.gd) — Threaded high res frame inject + unload for VRAM spikes.
Expert Decision Tree: Choosing the Right Animation Tool
Scenario Recommended Node Expert Insight
Isolated, pure frame by frame spritesheets AnimatedSprite2D Cannot animate non visual properties or method tracks — escalate to AnimationPlayer when you need those.
Cutout animations, non visual sync, audio/particles AnimationPlayer Owns transforms, mesh deformation, method/value tracks.
Complex state machines, blending, locomotion AnimationTree Logic graph over an AnimationPlayer; use travel() via animation tree step.gd .
Procedural, dynamic, fire and forget UI/fx Tween Runtime targets; always go through tween lifecycle manager.gd .
Swarms of thousands of entities MultiMeshInstance2D + Shader Load multimesh swarm anim.gd only; skip character sync scripts.
Golden Path: One Frame Sync ( play + advance(0) )
When changing animation and sprite properties in the same frame, play() alone applies next process tick — one frame glitch.
MANDATORY : Read [one frame sync fix.gd](scripts/one frame sync fix.gd). Minimal contract:
Related: animation looped (loops) vs animation finished (one shots); use set frame and progress when swapping skins mid clip (see AnimatedSprite2D class docs).
Procedural Squash & Stretch
Do NOT paste landing snippets into agents. A prior body used an impossible condition ( not is on floor() and is on floor() ).
MANDATORY sole source : [procedural squash stretch.gd](scripts/procedural squash stretch.gd) — impact squash, velocity stretch, lerp recovery. Pair with godot characterbody 2d / godot 2d physics for floor/velocity authority.
Quick routing (scripts own the recipes)
Tween interrupt / flash loops → tween lifecycle manager.gd (never race two Tweens on one property).
AnimationTree travel → animation tree step.gd ( start then travel ).
IK foot plant → skeleton 2d rig helper.gd + SkeletonModification2DTwoBoneIK docs.
Fill rate / swarms → gpu mesh optimizer.gd / multimesh swarm anim.gd per Do NOT Load table.
Pixel filter / shared SpriteFrames → Official Documentation (2D sprite animation, SpriteFrames); keep resources shared via preload.
Expert insights (WHY — keep in body)
Hybrid cutout + cel — Animate bones for body motion; keyframe frame / texture on child sprites for hand/face swaps. WHY: transform only motion is cheap; cel swaps stay art directable without re rigging.
GPU fill rate — Large transparent sprites waste fill rate. WHY: tight MeshInstance2D polygons skip transparent texels; pair with [gpu mesh optimizer.gd](scripts/gpu mesh optimizer.gd).
Tween property fights — WHY: the last Tween on a property wins silently. Always kill() the prior instance ([tween lifecycle manager.gd](scripts/tween lifecycle manager.gd)).
AnimationTree travel — WHY: StateMachine uses internal A between states; call start() before travel() ([animation tree step.gd](scripts/animation tree step.gd)).
Deep recipes (on demand)
Topic Reference / script
Signals / frame events / skin swap [signals and frame events.md](references/signals and frame events.md)
Cutout rigs / procedural IK feet [cutout and skeletal.md](references/cutout and skeletal.md)
GPU mesh / swarms / memory streaming [expert techniques.md](references/expert techniques.md)
Frame metadata / spawn offsets [animation data extractor.gd](scripts/animation data extractor.gd)
Async SpriteFrames VRAM [sprite sheet memory manager.gd](scripts/sprite sheet memory manager.gd)
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API;
load Related Skills when routing work to a peer domain — do not preload the whole lattice.
Official Documentation
[2D sprite animation](https://docs.godotengine.org/en/stable/tutorials/2d/2d sprite animation.html) — Canonical AnimatedSprite2D + SpriteFrames workflow for frame based sheets and signal timing.
[Introduction to the animation features](https://docs.godotengine.org/en/stable/tutorials/animation/introduction.html) — When to graduate from spritesheets to AnimationPlayer for tracks, methods, and non visual properties.
[Cutout animation](https://docs.godotengine.org/en/stable/tutorials/animation/cutout animation.html) — Paper doll hierarchies and hybrid cutout/cel setups before full skeletal IK.
[2D skeletons](https://docs.godotengine.org/en/stable/tutorials/animation/2d skeletons.html) — Skeleton2D / Bone2D rigging, rest poses, and deformation expectations for cutout meshes.
[Using AnimationTree](https://docs.godotengine.org/en/stable/tutorials/animation/animation tree.html) — Blend spaces and state machine graphs that drive an underlying AnimationPlayer.
[Animation track types](https://docs.godotengine.org/en/stable/tutorials/animation/animation track types.html) — Method/value/property tracks for frame perfect SFX, hitboxes, and shader uniform hooks.
[AnimatedSprite2D](https://docs.godotengine.org/en/stable/classes/class animatedsprite2d.html) — play() , advance() , set frame and progress() , and animation looped vs animation finished contracts.
[SpriteFrames](https://docs.godotengine.org/en/stable/classes/class spriteframes.html) — Shared frame resources, loop flags, and per animation timing used by AnimatedSprite2D.
[Tween](https://docs.godotengine.org/en/stable/classes/class tween.html) — Runtime squash/stretch and interruptible one shot motion without baking AnimationPlayer clips.
[Animating thousands of fish](https://docs.godotengine.org/en/stable/tutorials/performance/vertex animation/animating thousands of fish.html) — GPU vertex / MultiMesh patterns for swarm motion that must leave the node tree.
[SkeletonModification2DTwoBoneIK](https://docs.godotengine.org/en/stable/classes/class skeletonmodification2dtwoboneik.html) — Lightweight two bone IK for procedural foot/hand planting on Skeleton2D stacks.
Related Skills
Prerequisites
[godot animation player](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot animation player/SKILL.md) — AnimationPlayer ownership, callback modes, and track authoring that this skill’s hybrid/cutout patterns assume.
[godot characterbody 2d](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot characterbody 2d/SKILL.md) — Physics tick movement so animated CharacterBody2D motion stays on the fixed timestep.
[godot signal architecture](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot signal architecture/SKILL.md) — Safe wiring for animation finished / animation looped / frame changed without lifecycle leaks.
Complements
[godot animation tree mastery](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot animation tree mastery/SKILL.md) — Deepen blend trees, OneShot layers, and travel() pathfinding beyond the 2D locomotion basics here.
[godot tweening](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot tweening/SKILL.md) — Broader Tween composition when squash/stretch or UI pops outgrow inline create tween() snippets.
[godot shaders basics](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot shaders basics/SKILL.md) — CanvasItem shader uniforms driven by AnimationPlayer tracks or MultiMesh swarm materials.
[godot 2d physics](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/