Motion clips and rigs (.motion, .rig)
A .motion file is a keyframe animation: it moves, rotates and scales named
parts over time. A .rig file is a hierarchy of joints and attachments (for
example shoulder → hand → weapon) that a clip can animate. Studio's Model
Animation editor and Timeline create both.
The engine doesn't play these files by itself. Your BT code loads them and
applies the poses with the BT functions below. Register them
in the asset registry under files.
There are two kinds of clip, told apart by the clip's file format version:
- Rig clips (format 2.x, the current version) animate the nodes of a rig
(or of a scene; see Scenes as rigs). A clip without a
formatsection is a rig clip. - Model clips (format 1.x) animate the parts of a
procedural model. They start with
format:andversion: 1.0.0under it.
Clips saved by older versions of cTurtle say version: 1 (a model clip) or
version: 2 (a rig clip) instead. They still load.
.motion example
A model clip, animating a model part:
format:
version: 1.0.0
model: robot
duration: 1.0
loop: true
tracks:
- part: arm
property: rotation
interpolation: smooth
keys:
- time: 0.0
value: [0.0, 0.0, 0.0]
- time: 1.0
value: [0.0, 0.0, 1.570796]
A rig clip, animating a rig node:
binding: data/weapon-rig.rig
model: Weapon display
duration: 4
loop: true
tracks:
- part: hand
property: rotation
interpolation: bezier
curve: [0.25, 0.1, 0.25, 1.0]
keys:
- time: 0
value: [0, 0, 0]
- time: 4
value: [0, 0, 3.141593]
.motion fields
| Field | Type | Default | Description |
|---|---|---|---|
format | map | none | The file format version: leave it out for a rig clip, write version: 1.0.0 under it for a model clip. |
binding | string | — | Rig clips only, required. Project-relative path of the .rig (or scene) the clip animates. |
model | string | — | Required. Model clip: the procedural model's name. Rig clip: the rig's name. |
duration | number | — | Required. Clip length in seconds, more than 0 and at most 3600. |
loop | bool | — | Required. true repeats the clip; false holds the last pose. |
tracks | list | — | Required. 1 to 128 tracks. |
tracks[]
Each track animates one property of one part. A part can't have two tracks for the same property.
| Field | Type | Default | Description |
|---|---|---|---|
part | string | — | Required. Model clip: model part name. Rig clip: rig node id. |
property | string | — | Required. position, rotation or scale. |
interpolation | string | — | Required. How values move between keys: step (jump), linear, smooth (eases in and out) or bezier (uses curve). |
curve | [x1, y1, x2, y2] | [0.25, 0.1, 0.25, 1.0] | Easing curve for bezier, like CSS cubic-bezier. Each value 0–1. Applies to every segment of the track. |
keys | list | — | Required. 1 to 512 keyframes. |
keys[]
| Field | Type | Description |
|---|---|---|
time | number | Seconds from the start, between 0 and duration. Must increase from key to key. |
value | [x, y, z] | The part's position, rotation (radians) or scale at that time, relative to its parent. Scale must stay above 0. Values must be within ±1,000,000. |
Playback
- Properties without a track stay at the rest pose. Before the first key and after the last, the part holds that key's value.
- Model clip rotations blend each angle separately, so to spin a full turn you
write the full angle (for example
6.283185). - Rig clip rotations take the shortest path between keys.
.rig example
name: Weapon display
nodes:
- id: shoulder
name: Shoulder
kind: joint
position: [0, 1.4, 0]
- id: hand
kind: joint
parent: shoulder
position: [0.8, 0, 0]
- id: weapon
kind: attachment
parent: hand
model: gun
.rig fields
| Field | Type | Default | Description |
|---|---|---|---|
format | map | none | Optional file format version. |
name | string | — | Required. Rig name; rig clips refer to it in model. |
nodes | list | — | Required. 1 to 512 nodes. |
nodes[]
| Field | Type | Default | Description |
|---|---|---|---|
id | string | — | Required. Unique; can't contain / or :. Clip tracks name it in part. |
kind | string | — | Required. joint, attachment or entity. |
name | string | id | Display name. |
parent | string | none | Parent node's id. Children move with their parent. |
model | string | none | Procedural model drawn at this node, typically on an attachment. |
position | [x, y, z] | [0, 0, 0] | Rest position, relative to the parent. |
rotation | [x, y, z] | [0, 0, 0] | Rest rotation in radians, relative to the parent. |
scale | [x, y, z] | [1, 1, 1] | Rest scale. Each value above 0. |
Unknown fields are ignored, and Studio keeps them when editing.
Scenes as rigs
A rig clip's binding can name a scene file instead of a
.rig. The scene's entities with kind: entity become the nodes, using the
same id, parent, position, rotation, scale and model fields as
rig nodes. The rig name is the scene's top-level animation_name (default
Scene).
Runtime API
| Function | Purpose |
|---|---|
ctMotionLoad(path) / ctMotionParse(text) | Load a .motion file. |
ctMotionTime(clip, elapsed) | Turn elapsed seconds into clip time (wraps when looping, otherwise stops at the end). |
ctMotionPose(clip, part, time, rest) | Get one part's pose at a time. |
ctAnimationBindingLoad(path) / ctAnimationBindingParse(text) | Load a .rig or a scene used as a rig. |
ctAnimationBind(binding, clip) | Connect a rig clip to its rig. |
ctMotionRigCreate(restParts, clip) / ctMotionRigSample(rig, clip, time, weight) | Animate a whole hierarchy and get world poses. |
Your game decides when clips play and whether animation or physics moves an
object. Signatures are in cturtle/ui/btlib.
Errors
Loading stops at the first problem.
| Message | Cause |
|---|---|
.motion file uses format version X; this cTurtle reads format 1.x up to 1.0.0 and 2.x up to 2.0.0 | The clip was written for a newer cTurtle; see File format versions. |
.motion file: `version: N` is not a clip version | An old-style version other than 1 or 2. |
Animation requires a binding asset | Rig clip without binding. |
Animation needs a model and a duration in (0, 3600] seconds | Missing model, or bad duration. |
Animation needs 1 to 128 tracks | No tracks, or too many. |
Track needs a part and position, rotation or scale property | Missing part or bad property. |
Interpolation must be step, linear, smooth or bezier | Bad interpolation. |
Duplicate part/property animation track | Two tracks for the same part and property. |
Track needs 1 to 512 keyframes | No keys, or too many. |
Key times must increase strictly within the clip duration | Key times out of order or outside the clip. |
Animated scale must stay positive | A scale key is 0 or negative. |
Animation values must be finite and within +/-1000000 | Value too large. |
Expected [x, y, z] | A vector isn't a one-line list of three numbers. |
Curve coordinates must be finite and between 0 and 1 | Bad curve. |
.rig file: `version: 1` is no longer used | Delete the version line (an older file). |
.rig file uses format version X; this cTurtle reads format … | The rig was written for a newer cTurtle; see File format versions. |
Binding needs 1 to 512 nodes | No nodes, or too many. |
Node IDs must be nonempty and contain no slash or colon | Bad id. |
Node kind must be joint, entity or attachment | Bad kind. |
Duplicate part name: …, Missing parent part: …, Part hierarchy contains a cycle, Part hierarchy exceeds 128 levels | Problems in the node hierarchy. |
Animation part is missing: … | A track names a part or node that doesn't exist. |
Clip does not match its joint/scene binding | Clip model doesn't equal the rig's name, or a model clip was bound to a rig. |
Vectors (value, position, rotation, scale, curve) must be one-line
lists like [1, 2, 3].