For the complete documentation index, see llms.txt. This page is also available as Markdown.

Spine Animations

You can add animated interactable objects to your game using our existing library of 50k+ Spine rigs.

Spine is how animated characters and props work in All Out (chests, animals, props, VFX rigs, and the player).

To make Spine feel simpler, keep this mental model:

  • Spine rig (.spine): the “blueprint” (bones + animation names + skin names)

  • Spine_Animator: a component on an entity that renders/updates a Spine rig in the world

  • Spine_Instance: a standalone (non-component) instance — used for UI animations or manual lifetime control

  • Skins: “outfits/variants” that decide which images are visible

  • Animations: named timelines (e.g. "idle", "walk", "open")

When to use Spine_Animator vs Spine_Instance

  • Use Spine_Animator for anything that exists in the world (props, NPCs, interactables).

  • Use Spine_Instance directly when you want to draw a Spine in UI or you need manual lifetime control.

The engine updates a Spine_Animator automatically. A standalone instance must be updated and destroyed by your code.

Spine API reference (CSL)

// Component — attached to world entities
Spine_Animator :: class : Component {
    depth_offset: float;
    layer: s32;
    mask_in_shadow: bool;
    instance: Spine_Instance #read_only;

    // Visuals
    color_multiplier: v4;
    scale: v2;
    speed_multiplier: float;
    state_machine: State_Machine #read_only;

    set_skeleton :: method(asset: Spine_Asset) -> u64;
    get_skeleton :: method(id: u64 = 0) -> Spine_Asset;
    set_animation :: method(animation: string, loop: bool, track: s64, speed: float = 1);

    // Skins
    set_skin          :: method(skin: string);
    enable_skin       :: method(skin: string);
    disable_skin      :: method(skin: string);
    disable_all_skins :: method();
    refresh_skins     :: method();
    get_skins         :: method() -> []string;
    set_to_setup_pose :: method();

    // Bone local offsets (advanced)
    get_bone_local_position :: method(bone_name: string) -> v2;
    set_bone_local_position :: method(bone_name: string, position: v2);

    // Optional: drive animations via a state machine
    set_state_machine       :: method(machine: State_Machine, transfer_ownership: bool);
    set_color_replace_color :: method(color: Color_Replace_Color);
    set_material            :: method(material: Material, transfer_ownership: bool);
    get_tint                :: method() -> v4;
    set_tint                :: method(tint: v4);
    set_destroy_entity_when_done_current_animation :: method(enabled: bool);
}

Spine_Animator inherits Component.awaken(). When your script and animator start on the same entity, call awaken() before accessing the animator's instance.

Adding animated objects to your world

There are 3 ways to add animated objects to your scene, all of which will create a Spine_Animator component.

  • Drag any animated asset from the Asset Catalog into your scene

  • Create a new entity and add the Spine_Animator component

    • Set the Skeleton Data Asset field to a .spine file in your assets

  • Add a spine animator to your world using scripting (covered in the examples)

If your code and the Spine_Animator are on the same entity and start at the same time, call spine.awaken() before calling any animation methods.

Examples

Openable Chest

An interactable chest that plays an “open” animation and then stays open:

Animation and skin names must match the names in the rig.

Walking Chicken

A simple “idle vs walk” loop based on movement:

Driveable Car

If you want "driveable" behavior, the simplest approach is to drive the movement with your own gameplay logic, and drive the animation based on whether the car is moving.

If you're switching between only two looping animations, direct set_animation calls are usually simpler than building a state machine.

Skins (variants/outfits)

Some spines don't start with a default skin. If your entity is "invisible", you likely need to pick a skin.

Animation events

Use callbacks when a Spine timeline event should trigger gameplay or audio. For a Spine_Animator component, register callbacks on its instance.

The event callback runs in the shared predicted path. Call gameplay and SFX directly; do not guard it with Game.is_server() or is_local().

Standalone instances and UI.spine

The standalone API provides manual lifetime and animation updates:

Keep the instance in persistent player UI state. Create it once, update and draw it from ao_late_update, then destroy it from ao_end:

Do not create the instance inside ao_late_update; that would restart its animation every frame and leak the previous instance.

State machines (optional, for complex animation logic)

You can keep animation logic simple by calling set_animation directly. If you have many states (idle/run/attack/hit/death), a State_Machine helps you define transitions once and then just set variables/triggers.

The key idea: state names must match animation names in your Spine file.

What a state machine does

Think of a state machine as a tiny “animation controller”:

  • You define states (each state name should match a Spine animation name)

  • You define variables (bool, trigger, int, float)

  • You define transitions between states based on those variables

  • At runtime, you only update variables (the state machine chooses the animation)

Minimal example: idle/walk + attack trigger

If you pass transfer_ownership = true to set_state_machine, the animator will destroy the state machine for you. Otherwise, you must destroy it yourself.

Troubleshooting

Q: I dragged a spine asset into my scene and I don't see any object, it's just an empty entity

A: Make sure to click "Add Skin" and select a variant of the spine to apply! Some spines don't start with a default skin.

Q: My script crashes when I call animation methods on my Spine_Animator

A: If your script and the Spine_Animator start at the same time, call spine.awaken() before calling any animation methods.

Q: I changed skins but nothing happened

A: After any skin change (set_skin, enable_skin, disable_skin, disable_all_skins), you must call refresh_skins().

Custom Player Skins/Animations

If you want to add custom animations to your player, you can do so by merging the base All Out player spine rig together with a custom rig containing more animations. We can provide many of these; just Developer Support.

The Spine Rig Format

Spine rigs include:

  • A skeleton file (.spine) with the bones, skins, animations, and structure.

  • An atlas file (.atlas) that maps attachments to images.

  • Every image page named by the atlas. A one-page export usually has one .png.

Creating your own animations

Export Format

To use a custom Spine rig in All Out, export the standard Spine bundle into your res folder:

  • something.spine

  • something.atlas

  • Every image file named by something.atlas

If you're unsure about export settings, start from an existing All Out Spine asset from the Asset Catalog and mirror its structure or reach out to us!

Last updated