Animation tools¶
Skeletal animation, controllers, IK, bone attachments and cinematic sequences.
15 tools in the animation category. Badges: read-only tools never change the project; mutating tools are undoable and attributed; open-world tools reach outside the engine and MCP clients ask before running them.
| Tool | Summary |
|---|---|
animation_list |
Skeleton and clips of a rigged model or animated character. |
animator_setup |
Create a state machine controller (*.animctl.json) for a character and assign it. |
animation_preview |
Render a character posed at a clip or state at given times (editor preview; the scene is not changed). |
animator_set |
Set an animator's parameters and triggers, or play a state/clip with a crossfade — live while the simulation runs (same as Wander set_param / trigger / play_animation), or as the editor preview while editing. |
bone_attach |
Make an entity follow a bone of an animated character: a sword in the right hand, a hat on the head, a lantern on the hip. |
bone_ik |
Make a character's hand or foot reach a point with two-bone IK (the elbow/knee and shoulder/hip bend; bone lengths are kept): a hand on a door handle, rail or lever, a foot planted on a step. |
sequence_create |
Create a cinematic sequence asset (*.sequence.json) and an entity whose sequencer plays it when the simulation starts. |
sequence_key |
Add or replace keys in a sequence, many at once. |
sequence_camera_shot |
Add a procedural camera move to a sequence — the quickest way to direct cinematics. |
sequence_get |
A sequence's tracks (type, entity, property, key count and time span) and length; with time, the evaluated property values and live camera at that moment. |
sequence_play |
Play or stop a sequence. |
sequence_scrub |
Look at a sequence at any time without playing: renders through the sequence's live camera (cuts and shots) with every keyed property and animation applied, then restores the scene. |
character_inspect |
Everything about a character's animation and look in one call: the humanoid bone map of its skeleton (slots like hips, leftHand, rightFoot with the bone names found, convention mixamo / suffixed / generic, missing slots), key bone positions in the world, clips with their root speed (m/s) and root turn (degrees per cycle), root motion / in-place / root yaw settings, retargeting (retargetFrom and how its clips map), foot and hand IK status of the last solve (contact, locked, ground offset, slope, pelvis drop, hand reach error), hair and fur attachment (follows the skin?, bound roots, colliders), and the material model of every mesh part (skin, eye, cloth, hair_card, pbr). |
character_ik |
Set up automatic foot IK, hand targets and turning for a humanoid character (adds or updates its characterIk component; undoable). |
animation_retarget |
Retarget clips from one humanoid rig to another in pose space and save them as a new library (.anim) on the target's skeleton: different bone names (mixamo / suffixed like thigh_l / generic, detected by name and topology), rest poses (T-pose vs A-pose), bone axes and proportions (the hips move by the source motion scaled by the leg-length ratio; bones keep their own lengths, so nothing stretches). |
animation_list¶
List animations read-only
Skeleton and clips of a rigged model or animated character. With entity: its animator's library (clips with duration and rootSpeed in m/s for locomotion clips), controller (parameters, states), current state, recent animation events and warnings. With model: a .anim library or an imported .glb/.gltf. With neither: every animation library in the project. bones=true lists bone names (for bone_attach, layer masks, look-at). Example: {"entity": "Hero"}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | Character with an animator (or a child of one) | ||
model |
string | Animation library (.anim) or rigged model (.glb/.gltf), project-relative | ||
bones |
boolean | Include the bone hierarchy (default: true for model, false for entity) |
animator_setup¶
Set up animator mutating
Create a state machine controller (*.animctl.json) for a character and assign it. preset=locomotion (default) finds idle/walk/run/jump clips by name and builds: parameter speed (m/s) driving a 1D blend Idle -> Walk -> Run whose thresholds are the clips' real root speeds (feet don't slide when you set speed to the actual velocity), and if there is a jump clip a jump trigger with Jump -> back to locomotion. preset=clips: one state per clip, no transitions (drive with play_animation). preset=directional: a polar 2D blend space for strafing characters: parameters moveX (right) and moveY (forward) in m/s drive idle, forward, back, left, right and diagonal clips placed at their measured root velocities (direction and speed blend separately: no slowdown or foot sliding between directions). Override clip choices with clips ({"idle": "Breathe", "run": "Sprint"}), or pass a full controller document (parameters, layers with states/blend/blend2d, transitions with "when" conditions like "speed > 0.1 and grounded", exit times, events, masks) — it is validated with did-you-mean errors. Then drive it from Wander: set_param(self, "speed", v), trigger(self, "jump"), play_animation(self, "Wave").
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | yes | The character | |
preset |
string | Generated controller (default locomotion) | locomotion clips directional |
|
clips |
object | Clip choice overrides: idle, walk, run, jump; directional: idle, forward, back, left, right, forward_left, forward_right, back_left, back_right | ||
controller |
object | A full controller document instead of a preset | ||
path |
string | Where to save the controller (default: next to the library, <name>.animctl.json) | ||
library |
string | Animation library (.anim) if the character has none yet | ||
root_motion |
boolean | Move the character by its clips' root motion (default: unchanged) |
animation_preview¶
Preview animation read-only
Render a character posed at a clip or state at given times (editor preview; the scene is not changed). Frames the character automatically (three_quarter / front / side / back) unless eye/target are given. times=[0, 0.25, 0.5, 0.75] returns a contact sheet of images — check walk cycles, attacks, hand poses, props attached to bones. While playing, captures the live pose instead. Example: {"entity": "Hero", "clip": "Run", "times": [0, 0.2, 0.4]}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | yes | The character (or any entity under its animator) | |
clip |
string | Clip or state to show (default: what the animator plays by default) | ||
time |
number | Seconds into the clip/state (default 0) | ||
times |
number[] | Several times -> one image each (max 8), e.g. a walk cycle contact sheet | ||
params |
object | Controller parameters for the preview, e.g. | ||
view |
string | Automatic framing (default three_quarter) | three_quarter front side back |
|
eye |
number[3] | Custom camera position (instead of automatic framing) | ||
target |
number[3] | Custom look-at point (with eye) | ||
width |
integer | Image width (default 512) | ||
height |
integer | Image height (default 512) | ||
save_path |
string | Also write the (first) PNG to this project-relative path |
animator_set¶
Drive animator mutating
Set an animator's parameters and triggers, or play a state/clip with a crossfade — live while the simulation runs (same as Wander set_param / trigger / play_animation), or as the editor preview while editing. Also sets look_at (head/spine IK toward an entity; "" clears), the editor preview mode/time. Returns the animator state. Example: {"entity": "Hero", "params": {"speed": 3}, "trigger": "jump"}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | yes | The character | |
params |
object | Parameter values, e.g. | ||
trigger |
any | Trigger name or list of names | ||
play |
string | State or clip to crossfade to (editing: shown as the preview) | ||
fade |
number | Crossfade seconds (default 0.2) | ||
loop |
boolean | Loop the played clip (default: the state's setting; clips play once and return) | ||
layer |
integer | Layer index for play (default 0) | ||
time |
number | Editor preview time in seconds | ||
preview |
string | Editor preview mode | rest pose play |
|
look_at |
string | Entity the head turns toward ("" = off) | ||
preview_time |
number | Editing: show the default state (or play) at this time without saving it (live scrubbing) |
||
clear_preview |
boolean | Remove a preview set by play / preview_time while editing |
bone_attach¶
Attach to bone mutating
Make an entity follow a bone of an animated character: a sword in the right hand, a hat on the head, a lantern on the hip. Validates the bone (did-you-mean; animation_list bones=true lists them), adds the attach component and (by default) parents the entity under the character. offset/rotation are in the bone's space. Example: {"entity": "Sword", "to": "Hero", "bone": "RightHand", "offset": [0, 0.08, 0.02]}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | yes | The prop to attach | |
to |
integer | string | yes | The character (entity with the animator) | |
bone |
string | yes | Bone name, e.g. RightHand, Head, mixamorig:Spine2 | |
offset |
number[3] | Position in bone space (m) | ||
rotation |
number[3] | Rotation in bone space (Euler degrees) | ||
follow_scale |
boolean | Inherit the bone's scale (default false) | ||
parent |
boolean | Parent the prop under the character (default true) |
bone_ik¶
Reach with IK mutating
Make a character's hand or foot reach a point with two-bone IK (the elbow/knee and shoulder/hip bend; bone lengths are kept): a hand on a door handle, rail or lever, a foot planted on a step. Either give entity (an existing object becomes the effector — the bone reaches it) or a position (a new effector entity is created under the character; default: where the bone is now). Move or keyframe the effector (sequence_key transform.position) to animate the reach; weight blends with the animation. pole = bend direction in the character's space ([0,0,-1] knees forward; elbows usually [0,0,1]). Example: {"character": "Hero", "bone": "RightHand", "entity": "Door Handle"}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
character |
integer | string | yes | The character (entity with the animator) | |
bone |
string | yes | End bone: LeftHand, RightHand, LeftFoot, RightFoot... | |
entity |
integer | string | Existing entity to reach (it gets the ik component) | ||
position |
number[3] | World position for a new effector entity | ||
name |
string | Name of the new effector (default "<bone> IK") | ||
weight |
number | 0..1 (default 1) | ||
pole |
number[3] | Bend direction in the character's space (default: keep the animated bend) | ||
match_rotation |
boolean | Also orient the bone like the effector (default false) |
sequence_create¶
Create sequence mutating
Create a cinematic sequence asset (*.sequence.json) and an entity whose sequencer plays it when the simulation starts. Then add content with sequence_key (keyed properties, camera cuts, events, animations) and sequence_camera_shot (orbit / dolly / crane / track / pan / static / path / flyover moves), check frames with sequence_scrub and play with sequence_play. tracks may hold a full track list (see docs/ANIMATION.md). Example: {"path": "cinematics/intro.sequence.json", "duration": 10}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
path |
string | yes | Project-relative path ending in .sequence.json | |
name |
string | Display name (default: file name) | ||
duration |
number | Length in seconds (0 = until the last key) | ||
tracks |
object[] | Initial tracks (optional) | ||
entity |
string | Entity to play it: an existing one gets the sequencer, a new name creates it (default: a new entity named after the sequence) | ||
play_on_start |
boolean | Start with the simulation (default true) | ||
loop |
boolean | Loop (default false) | ||
overwrite |
boolean | Replace an existing file |
sequence_key¶
Key sequence mutating
Add or replace keys in a sequence, many at once. keys: property keys {entity, property, t, value, ease} animating any component field ("transform.position", "transform.rotation", "light.intensity", "light.color", "camera.fov", "mesh.color", "mesh.emissive", "particles.rate", or "environment.sunElevation" without entity). ease: linear (default), step, smooth, ease_in, ease_out, auto (smooth spline through neighbours — best for camera paths) or [x1,y1,x2,y2] cubic-bezier. camera_cuts: [{t, camera}] which camera is live. events: [{t, event, target?}] Wander events. animations: [{entity, t, play, fade?, loop?, params?}] drive animators. A key at an existing time replaces it; replace=true clears touched tracks first. Example: {"sequence": "cinematics/intro.sequence.json", "keys": [{"entity": "Sun", "property": "light.intensity", "t": 0, "value": 0}, {"entity": "Sun", "property": "light.intensity", "t": 3, "value": 4, "ease": "smooth"}]}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
sequence |
any | yes | Sequence path (.sequence.json) or an entity with a sequencer | |
keys |
object[] | Property keys | ||
camera_cuts |
object[] | Camera cuts | ||
events |
object[] | Events | ||
animations |
object[] | Animation keys | ||
replace |
boolean | Clear every touched track before adding (default false: merge) | ||
remove |
object[] | Tracks to delete: {entity, property} or {type} | ||
duration |
number | Set the sequence length (seconds) |
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "sequence_key",
"arguments": {
"sequence": "cinematics/intro.sequence.json",
"keys": [
{
"entity": "Sun",
"property": "light.intensity",
"t": 0,
"value": 0
},
{
"entity": "Sun",
"property": "light.intensity",
"t": 3,
"value": 4,
"ease": "smooth"
}
]
}
}
}
sequence_camera_shot¶
Camera shot mutating
Add a procedural camera move to a sequence — the quickest way to direct cinematics. Shots are evaluated live each tick, so they follow moving targets. Kinds: orbit (around target; radius, height, from/to degrees), dolly (distance [far, near] along angle, or from/to points), crane (height [low, high]), track (side-on, slides from/to meters while following the target), pan (fixed position, look from/to: entities, points or yaw degrees), static (position looking at target), path (Catmull-Rom through points, looking at target or along the path), flyover (straight aerial pass over the target from the angle side: distance = half the pass length, height). fov: number or [from, to] (zoom), roll in degrees, ease (default smooth). cut=true (default) also switches to this camera at start. Missing cameras are created. Example: {"sequence": "Intro", "camera": "Cam A", "shot": "orbit", "target": "Hero", "start": 0, "duration": 5, "radius": 5, "height": 1.8, "from": -30, "to": 60}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
sequence |
any | yes | Sequence path or entity with a sequencer | |
camera |
string | Camera entity (created if missing; default "Shot Camera") | ||
shot |
string | yes | Kind of move | orbit dolly crane track pan static path flyover |
start |
number | Start time in seconds (default: after the camera's previous shot) | ||
duration |
number | yes | Seconds | |
target |
any | Entity name or [x,y,z] the camera frames | ||
offset |
number[3] | Added to the target point (e.g. [0, 1.6, 0] for eye height) | ||
radius |
number | orbit radius (m) | ||
height |
any | Camera height above the target: number or [from, to] | ||
distance |
any | Distance from the target: number or [from, to] | ||
angle |
number | Direction from the target (yaw degrees, 0 = +Z) | ||
from |
any | Start: angle (orbit/pan), lateral meters (track), point (dolly/pan) | ||
to |
any | End: like from | ||
position |
number[3] | Camera position (pan, static) | ||
points |
array[] | Path points (path) | ||
pitch |
number | Pan pitch (degrees) | ||
fov |
any | Field of view: number or [from, to] (zoom) | ||
roll |
number | Dutch angle (degrees) | ||
ease |
any | linear, smooth (default), ease_in, ease_out or [x1,y1,x2,y2] | ||
cut |
boolean | Switch to this camera at start (default true) |
sequence_get¶
Inspect sequence read-only
A sequence's tracks (type, entity, property, key count and time span) and length; with time, the evaluated property values and live camera at that moment.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
sequence |
any | yes | Sequence path or entity with a sequencer | |
time |
number | Evaluate at this time (seconds) |
sequence_play¶
Play sequence mutating
Play or stop a sequence. Sequences run in the simulation: while editing this starts the simulation (like sim_control play) and plays the sequence from from; while playing it restarts / seeks or stops it. Sequencers with playOnStart start by themselves when the simulation starts. Watch with viewport_capture view="scene" after sim_control step.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
sequence |
any | yes | Entity with a sequencer, or a sequence path played by one | |
action |
string | Default play | play stop |
|
from |
number | Start time in seconds (default 0) |
sequence_scrub¶
Scrub sequence mutating
Look at a sequence at any time without playing: renders through the sequence's live camera (cuts and shots) with every keyed property and animation applied, then restores the scene. times=[...] returns up to 8 images (a storyboard). Render a whole shot to disk with fps + from/to + save_dir (PNG frames, e.g. for a video). persist=true instead leaves the editor showing that time (sequencer preview). Only while editing. Example: {"sequence": "Intro", "times": [0, 2.5, 5]}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
sequence |
any | yes | Entity with a sequencer, or a sequence path played by one | |
time |
number | Seconds | ||
times |
number[] | Several times (max 8 images) | ||
fps |
number | Render frames at this rate between from and to into save_dir | ||
from |
number | Render range start (default 0) | ||
to |
number | Render range end (default: the sequence length) | ||
save_dir |
string | Project-relative folder for rendered frames (frame_0000.png ...) | ||
camera |
string | Look through the sequence's camera (default) or the editor camera | sequence editor |
|
width |
integer | Image width (default 768) | ||
height |
integer | Image height (default 432) | ||
persist |
boolean | Keep showing this time in the editor (sets sequencer preview/time) | ||
include_image |
boolean | Return the images (default true; false = just render / save) | ||
transient |
boolean | Only show time in the editor viewport (no capture, not saved) until clear |
||
clear |
boolean | End a transient scrub |
character_inspect¶
Inspect character read-only
Everything about a character's animation and look in one call: the humanoid bone map of its skeleton (slots like hips, leftHand, rightFoot with the bone names found, convention mixamo / suffixed / generic, missing slots), key bone positions in the world, clips with their root speed (m/s) and root turn (degrees per cycle), root motion / in-place / root yaw settings, retargeting (retargetFrom and how its clips map), foot and hand IK status of the last solve (contact, locked, ground offset, slope, pelvis drop, hand reach error), hair and fur attachment (follows the skin?, bound roots, colliders), and the material model of every mesh part (skin, eye, cloth, hair_card, pbr). Start here before retargeting, adding IK or grooming a character. Example: {"entity": "Hero"}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | yes | The character (or any of its parts) | |
clips |
boolean | Include the clip list (default true) |
character_ik¶
Character foot and hand IK mutating
Set up automatic foot IK, hand targets and turning for a humanoid character (adds or updates its characterIk component; undoable). Feet plant on stairs, slopes and rocks under them (ground probes every tick), the pelvis drops so the lower foot reaches, feet pitch / roll onto the slope (max_slope) and lock in place while in contact (contact: auto = low and slow, velocity, events = foot_l_down / foot_l_up / foot_r_down / foot_r_up animation events, always, never), re-planting with a short step once the animation pulls a foot lock_distance away. Hands reach entities: a grip point on a staff held in the other hand (no lag), a ledge, a rail; animate the weights for grabs. turn_to turns a standing character in place (yaw degrees, or an entity / point to face). Returns the solve status. Example: {"entity": "Monk", "feet": true, "left_hand": "Staff Grip"}.
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
entity |
integer | string | yes | The character | |
feet |
boolean | Automatic foot planting (default true when the component is created) | ||
feet_weight |
number | 0..1 blend of the foot IK | ||
step_height |
number | Meters a foot may reach up or down (stairs: 0.3-0.5) | ||
foot_height |
number | Ankle height above the sole in meters (-1 = from the rest pose) | ||
pelvis |
boolean | Lower the hips for the lower foot | ||
align_feet |
boolean | Tilt the feet onto the slope | ||
max_slope |
number | Steepest slope the feet align to (degrees) | ||
contact |
string | When a foot locks in place | auto velocity events always never |
|
lock_speed |
number | m/s below which a foot counts as planted | ||
lock_distance |
number | m a locked foot may lag before re-planting | ||
smoothing |
number | 1/s: how fast pelvis and feet follow the ground | ||
left_hand |
any | Entity the left hand reaches ("" clears) | ||
left_hand_weight |
number | 0..1 | ||
right_hand |
any | Entity the right hand reaches ("" clears) | ||
right_hand_weight |
number | 0..1 | ||
hand_rotation |
boolean | Also orient the hands like their targets | ||
turn_speed |
number | Turn-in-place rate (degrees per second) | ||
turn_to |
any | Turn in place: world yaw in degrees (0 = -Z), or an entity / [x, y, z] point to face | ||
remove |
boolean | Remove the characterIk component |
animation_retarget¶
Retarget animations read-only
Retarget clips from one humanoid rig to another in pose space and save them as a new library (.anim) on the target's skeleton: different bone names (mixamo / suffixed like thigh_l / generic, detected by name and topology), rest poses (T-pose vs A-pose), bone axes and proportions (the hips move by the source motion scaled by the leg-length ratio; bones keep their own lengths, so nothing stretches). source / target are a library (.anim or a rigged .glb) or a character entity. preview=true only reports the bone maps and alignment. Use the result with "
| Argument | Type | Required | Description | Values |
|---|---|---|---|---|
source |
any | yes | Library path (.anim / .glb) or character entity with the clips | |
target |
any | yes | Library path or character entity to retarget onto | |
clips |
string[] | Clips to retarget (default: all) | ||
output |
string | Output .anim path (default: next to the target library, <target>_<source>.anim) | ||
fps |
number | Resampling rate of the output clips (default 30) | ||
translation |
boolean | Move the hips / root with the source (default true; false keeps them at rest) | ||
source_map |
object | Slot overrides for the source, e.g. | ||
target_map |
object | Slot overrides for the target | ||
preview |
boolean | Only report the bone maps and alignment (no file) |