Skip to content

Animation list — what you can animate

This is the scannable index of every animation state the rig can show, and how an artist hands the engine a clip for each. It answers one question: “what states exist, and what do I author for each?” For the mechanics of authoring a clip (the constructor block, joint masking, overlay stacking, properties), see Animations — this page is the catalogue, that page is the how-to.

Every animable state can be filled one of three ways. The whole catalogue below is just “which of these three applies, and is it done yet.”

  • (A) GLOBAL replace — the base biped motion, one FULL_BODY clip for every entity (player + NPC). This is how base locomotion works: bind a LivingMotion (WALK, IDLE, …) to one clip and everyone uses it. Replaces that motion’s whole body.

  • (B) Per-item FULL_BODY replace — an item binds a motion to its own whole-body clip via animations.living_motions with mode: "FULL_BODY". When that item is worn, its clip replaces the base motion entirely. No shipped item does this today, and for restraints the recommendation is to avoid it: “bound” = plain base motion + an arm OVERLAY (so the legs keep the real walk cycle), rather than a monolithic per-item bound clip.

  • (C) Per-item OVERLAY — an item composes only the joints it declares on top of whatever base motion is playing; the base shows through everywhere else (arms posed, legs still walk). This is mode: "OVERLAY" + a joints[] list. All four shipped authored clips are overlays (armbinder = the 8-joint arm chain, classic_collar = [Head]). The deeper mechanics — joint masking, overlay stacking, the base-layer dependency — are on the FULL_BODY vs OVERLAY section of the Animations page.

The shared base biped motions, used by everyone. One FULL_BODY clip per motion.

The whole group is not shipped: on a clean/release build every id resolves to the empty animation (no pose), so there is no base locomotion at all until these are authored. This is the highest-leverage place to start — every entity, bound or not, uses these.

State (canonical id)When it playsHow to provideStatus
base.locomotion.idle
tiedup:context_stand_idle
Standing still & not bound (IDLE) — also the universal fallback every unbound motion slides to(A) GLOBAL FULL_BODY⚠️ Placeholder (identity)
base.locomotion.walk
tiedup:walk
Moving on ground (WALK) — bound or not; a bound mover plays this base + an arm overlay(A) GLOBAL FULL_BODY❌ Not shipped — author it
base.locomotion.run
tiedup:run
Sprinting on ground & not bound (RUN)(A) GLOBAL FULL_BODY❌ Not shipped
base.locomotion.jump
tiedup:jump
On jump (JUMP)(A) GLOBAL FULL_BODY❌ Not shipped
base.locomotion.fall
tiedup:fall
Airborne, deltaY < 0 (FALL) — bound or not(A) GLOBAL FULL_BODY❌ Not shipped
base.locomotion.sneak
tiedup:sneak
Moving + sneaking (SNEAK) — bound or not; players only(A) GLOBAL FULL_BODY❌ Not shipped
base.locomotion.swim
tiedup:swim
In water (SWIM — same clip for bound & unbound; no SWIM_BOUND)(A) GLOBAL FULL_BODY❌ Not shipped
base.locomotion.struggle
STRUGGLE
Actively struggling — the writhe while the struggle minigame is on. A base motion, not a *_BOUND clip.(A) GLOBAL FULL_BODY base + (C) per-item arm OVERLAY (armbinder supplies the arm wiggle)⚠️ Only an arm OVERLAY exists (no full-body base)
base.locomotion.sit
tiedup:sit
NPC sitting (SIT) — NPC-only; players use pose_furniture_seat(A) GLOBAL FULL_BODY❌ Not shipped
base.locomotion.sleep
tiedup:sleep
Plain SLEEP — bound players route to pose_sleep_bound instead(A) GLOBAL FULL_BODY❌ Not shipped + inert
base.locomotion.kneel
tiedup:kneel
Vanilla EF KNEEL — never selected (bound kneel uses pose_kneel_bound)(A) GLOBAL FULL_BODY❌ Not shipped + dead
base.locomotion.landing_recovery
tiedup:landing
LANDING_RECOVERY — stock-bound, never selected(A) GLOBAL FULL_BODY❌ Not shipped + dead
base.locomotion.float
tiedup:float
FLOAT — stock-bound, never selected(A) GLOBAL FULL_BODY❌ Not shipped + dead

The moving gaits (walk / run / sneak / swim) bind as speed-synced gaits — their playback tracks the player’s actual movement speed so the feet don’t slide. “FULL_BODY” here means whole-body, not a fixed cadence. See Animating restraints, rule 9.

Held poses the rig selects for steady states. All FULL_BODY, GLOBAL/shared.

State (canonical id)When it playsHow to provideStatus
base.bound.pose_kneel_boundNPC kneeling pose while bound (POSE_KNEEL_BOUND) — NPC-only(A) GLOBAL/shared FULL_BODY❌ Not shipped — author it
base.bound.pose_dogDog-pose: arms bound with poseType=DOG (POSE_DOG, player + NPC)(A) GLOBAL/shared FULL_BODY❌ Not shipped — author it
base.bound.pose_sleep_boundAsleep while bound (POSE_SLEEP_BOUND)(A) GLOBAL/shared FULL_BODY❌ Not shipped — author it
base.bound.pose_furniture_seatRiding a furniture seat (POSE_FURNITURE_SEAT, player + NPC)(A) GLOBAL/shared FULL_BODY, or per-seat via the seat JSON’s sit_animation field❌ Missing (falls back to idle)
base.bound.pose_unconsciousIntended steady-state post-capture (POSE_UNCONSCIOUS)(A) GLOBAL/shared FULL_BODY if wired❌ No selection route — needs wiring first

The only states with real authored clips today. All are (C) per-item OVERLAYs. All four are self-labelled TEST poses — placeholders for a final Blender export, not final art.

State (canonical id)When it playsHow to provideStatus
item.armbinder.idle
tiedup:armbinder_idle
IDLE while armbinder equipped(C) OVERLAY — ARMS (8 arm-chain joints: Shoulder/Arm/Elbow/Hand L+R)⚠️ Authored (TEST, static)
item.armbinder.walk
tiedup:armbinder_walk
WALK while armbinder equipped — composes over the plain WALK base whether bound or not(C) OVERLAY — ARMS (8 arm-chain)⚠️ Authored (TEST, static)
item.armbinder.struggle
tiedup:armbinder_struggle
STRUGGLE while armbinder equipped(C) OVERLAY — ARMS (8 arm-chain)⚠️ Authored (TEST, the only animated clip)
item.classic_collar.idle
tiedup:classic_collar_idle
IDLE while classic_collar equipped(C) OVERLAY — NECK ([Head], slight tilt)⚠️ Authored (TEST)

Discrete one-shots fired by a gameplay event and broadcast by id to every viewer and the affected entity. Not a LivingMotion binding — these are ONESHOTs. They are referenced by synced_actions/*.json + action_events.json but ship no asset.

Several events share one clip, so you author it once: reaction.restrain.{initiator,target} covers all four capture flows (capture_grab / enslave / recapture / punish), and reaction.flinch covers both hurt and lockpick.

Reaction clip (canonical id)Bound to which event(s)RolesHow to provideStatus
reaction.struggle
tiedup:reaction.struggle
STRUGGLE — fired on both the struggle-start edge and the shock-collar interrupt edgeselfONESHOT (broadcast by id)❌ Referenced, no asset — author it
reaction.flinch
tiedup:reaction.flinch
HURT and LOCKPICK_FAIL — one shared flinch clipselfONESHOT❌ Referenced, no asset — author it
reaction.restrain.initiator
tiedup:reaction.restrain.initiator
Shared initiator clip for all four capture flows: CAPTURE_GRAB / ENSLAVE / RECAPTURE / PUNISHinitiatorONESHOT (coop role)❌ Referenced, no asset — author it
reaction.restrain.target
tiedup:reaction.restrain.target
Shared target clip for the same four flowstargetONESHOT (coop role)❌ Referenced, no asset — author it
reaction.leash_yank
tiedup:leash_yank
LEASH_YANK — its own distinct reactionselfONESHOT❌ Placeholder — author it

The takedown has two waypointed roles, each combining a synced clip with anchored position waypoints (POSITION+CLIP). Respect the waypoint timing in takedown.json when authoring the clips.

State (canonical id)When it playsHow to provideStatus
coop.takedown.initiator
tiedup:takedown_initiator
Takedown action, initiator rolePOSITION+CLIP (2 waypoints)❌ Referenced, no asset — author it
coop.takedown.target
tiedup:takedown_target
Takedown action, target rolePOSITION+CLIP (3 waypoints, eased pull-in, yaw 180)❌ Referenced, no asset — author it

Fired on on_equip / on_unequip of an item. Full-biped ONESHOTs.

State (canonical id)When it playsHow to provideStatus
item.armbinder.equip
tiedup:armbinder_equip_oneshot
on_equip of armbinder — the only equip one-shot any item declaresONESHOT (full biped)⚠️ Placeholder + renders on wrong layer
item.<item>.unequip
e.g. item.armbinder.unequip
on_unequip eventONESHOT (full biped)❌ Missing — no item declares it
item.<bind>.equip
straitjacket, shibari, …
on_equip for restraints other than armbinderONESHOT (full biped)❌ Missing — product decision

Gait / movement-style — a sparse OVERLAY collection (DEFERRED) ❌ Planned

Section titled “Gait / movement-style — a sparse OVERLAY collection (DEFERRED) ”

The WADDLE / SHUFFLE / HOP / CRAWL movement styles already affect gameplay (speed modifiers, jump suppression, crawl hitbox) and the active style is synced to every client — but the gait → animation route is deferred. So a waddling/shuffling/hopping bound player currently renders on the plain WALK base + the item’s arm overlay: the gait is felt (slower, no jump) but not yet seen. Authoring gait clips does nothing until the route lands.

Proposed gait clipWhat it isHow to provideWiring
base.gait.waddleSide-to-side swaying walk (WADDLE style, severity 1) — overrides only the moving gait(A) GLOBAL sparse collection, or (C) LEGS OVERLAY over WALKNeeds Java — the deferred style→gait route (reads the already-synced MovementStyle)
base.gait.shuffleTiny dragging foot-shuffle (SHUFFLE style; ankle-cuff / chained-feet)(A) GLOBAL / (C) LEGS OVERLAYNeeds Java — style→gait route; also implies a new ankle-restraint item (no item uses the LEGS region today)
base.gait.hopSmall forward bunny-hops (HOP style, auto-hop replaces jump)(A) GLOBAL / (C) LEGS OVERLAYNeeds Java — style→gait route, ideally timed to the auto-hop cooldown
base.gait.crawl_moveMoving-on-all-fours crawl (CRAWL style, dogbinder) — distinct from the static POSE_DOG(A) GLOBAL, or (B) per-item FULL_BODY on dogbinderNeeds Java — a moving-crawl branch (the dog pose currently has no moving variant)

New bondage states (need enum value + selection route + clip)

Section titled “New bondage states (need enum value + selection route + clip)”
Proposed stateWhat it isHow to provideWiring
base.bound.pose_hogtieProne hogtie idle: face-down, wrists+ankles drawn together, conscious (distinct from sleep_bound / unconscious)(A) GLOBAL, or (B) per-item FULL_BODY on a hogtie itemNeeds Java — a new hogtie pose + a selection route
base.bound.pose_hogtie_struggleFloor-bound wriggle/thrash while hogtied (on-ground analogue of the standing STRUGGLE)(A) GLOBALNeeds Java — depends on the hogtie route + a struggling-while-prone branch
base.bound.pose_suspension_idleHanging/suspended idle: arms up or body off the ground, slow sway, feet dangling(A) GLOBAL pose, likely + (C) per-item OVERLAY for the cuff arm angleNeeds Java — a new suspension pose + a “anchored to a suspension point” detection route
base.bound.pose_suspension_struggleSwinging/twisting struggle while suspended (pendulum sway, legs kick)(A) GLOBALNeeds Java — same suspension route
base.bound.pose_kneel_submissionPlayer submission kneel (head bowed) — the catalogue’s pose_kneel_bound is NPC-only(A) GLOBAL (can reuse the NPC pose)Needs Java — a player selection route for kneel (none returns a kneel for players today)
coop.carry.initiator / coop.carry.targetOver-the-shoulder / fireman’s carry — net-new coop role pair (mirrors coop.takedown)coop POSITION+CLIP (two synced roles)Needs Java — a new carry coop action + a sustained ride/attach state (heavier than the instantaneous takedown)

Pure-clip (artist can deliver alone, no engine work)

Section titled “Pure-clip (artist can deliver alone, no engine work)”
Proposed stateWhat it isHow to provideWiring
base.bound.bound_idle_fidgetSubtle passive bound idle — weight-shifts, tugging at restraints; replaces dead-still idle so a tied player looks restrained at rest. Not active struggle(C) per-item IDLE OVERLAY (armbinder already binds IDLE this way) — or (A) global, which would need a minor route tweakPure-clip as a per-item overlay; minor Java only if you want it global-conditional
item.<head_item>.head_down_submissionDeeper bowed-head submission OVERLAY ([Head], optionally Chest), reusable across collars/leashes — distinct from the slight classic_collar.idle tilt(C) per-item OVERLAY (NECK)Pure-clip — same OVERLAY path classic_collar uses; only needs a trigger if it should be conditional rather than always-on

Reactions / recovery (need a new event or route)

Section titled “Reactions / recovery (need a new event or route)”
Proposed stateWhat it isHow to provideWiring
reaction.jump_blockedShort stumble/lurch when a jump-disabled style (SHUFFLE/HOP/CRAWL) eats the jump inputreaction ONESHOT (broadcast by id)Needs Java — fire a synced reaction when a jump is suppressed
base.bound.landing_recovery_boundBound landing recovery — knees-buckle on hitting ground while restrained (complements the airborne FALL)(A) GLOBALNeeds Java — a bound-and-just-landed selection branch (LANDING_RECOVERY is never selected today)
reaction.fall_to_kneesForced drop-to-knees for capture/enslave/punish climaxes — transitions into the kneel/submission posereaction ONESHOTNeeds Java — new event; must land in the kneel pose, so depends on the kneel route

These names are never selected by the rig — a clip you author for them will never play. Don’t author them.

  • Declared but never selected: KNEEL (bound kneel uses POSE_KNEEL_BOUND on NPCs), SLEEP (asleep players route to POSE_SLEEP_BOUND), LANDING_RECOVERY, FLOAT, POSE_UNCONSCIOUS (see the Poses table above — not selectable yet). (RUN and SIT are not here — both are selected; they are simply not-shipped, like walk/jump.)
  • Sentinels (not animations): ALL, INACTION, NONE — internal, never author.
  • DEATH (the LivingMotion) is not a selectable motion. The death pose plays via a separate engine path, not as a selected LivingMotion. (Distinct from the death synced-action reaction above, whose clip you do author.)