Constraints
Constraints are spatial pins layered on top of segments. Three primitives
exist in v1: root_path, effector_target, and pose_keyframe. Since 1.3
a fourth, ground_height, describes the ground rather than the character;
it is optional (see ground_height).
All constraints carry a type discriminator. Frames are zero-indexed and
reference the global timeline of the request (after segments compose).
The total number of frames is:
sum(segments[].duration_frames)whensegmentsis non-empty, orrequest.duration_frameswhensegmentsis empty (constraints-only).
Frame indices outside [0, total_frames - 1] cause frame_out_of_range.
World frame
Positions in constraints are in the client's world coordinate frame.
Servers MAY internally re-center the motion (for example, translating
constraint positions so the earliest-frame root pin sits at (x=0, z=0)
to stay inside the model's training distribution) as long as the response
is un-translated back to the client's frame before encoding.
Clients MUST NOT assume generated motion starts at world origin — it starts wherever your constraints place the root.
Best-effort
Constraints are best-effort: the backbone honors them as closely as it can within the prompt and the model's training distribution. There is no protocol-level guarantee of exact satisfaction.
root_path
Floor-plane trajectory for the character's root.
{
"type": "root_path",
"frames": [0, 30, 60, 90],
"positions_xz": [[0.0, 0.0], [1.0, 0.0], [2.0, 1.0], [2.0, 2.0]],
"heading_radians": [0.0, 0.0, 0.5, 1.0]
}
positions_xz is the horizontal world position at each frame.
heading_radians is optional; when present it specifies the body's facing
angle as a right-handed rotation about the +Y axis, where 0 faces
the +Z direction and positive values rotate +Z toward −X.
effector_target
World-space targets for a named joint, typically a hand or foot.
{
"type": "effector_target",
"joint": "LeftHand",
"frames": [40, 60, 80],
"positions": [[0.5, 1.2, 0.3], [0.6, 1.4, 0.4], [0.5, 1.2, 0.3]],
"rotations": [[0,0,0,1], [0,0,0,1], [0,0,0,1]]
}
positions are world-space (x, y, z). rotations, if given, are
local-to-parent quaternions for the joint at each frame (same
convention as pose_keyframe.joint_rotations). rotations is optional.
The joint name MUST exist in the request's skeleton.joints.
pose_keyframe
A pose at a single frame.
{
"type": "pose_keyframe",
"frame": 30,
"joint_rotations": {
"LeftArm": [0.707, 0.0, 0.707, 0.0],
"RightArm": [0.707, 0.0, -0.707, 0.0]
},
"root_position": [1.0, 0.95, 0.0],
"fill_mode": "generate"
}
joint_rotations is a sparse map of {joint_name: local_rotation_quat}.
root_position is optional.
| Field | Type | Default | Notes |
|---|---|---|---|
fill_mode | "rest" | "generate" | "generate" | Behavior for joints not listed in joint_rotations |
Fill mode semantics:
rest— unspecified joints are pinned to theirrest_rotationat this frame (identity, i.e. the rest pose, when identity rest rotations are sent, as clients SHOULD; see Rest rotations).generate— unspecified joints are unconstrained; the backbone generates them as part of the motion. The constraint pins only the listed joints.
If you want "key pose A at frame 30, key pose B at frame 60, model fills
the middle on specified joints only," densify by emitting one
pose_keyframe per intermediate frame with slerped joint rotations
(linear in frame index) and fill_mode: "generate". This pattern is
intentionally client-side; the server does not collate keyframes.
ground_height
MMCP 1.3, optional. The ground the character moves over, as points on its surface: a roof, a stair, the lower street the character drops onto.
{
"type": "ground_height",
"points": [[0.0, 0.0, 0.0], [0.0, 3.0, 0.0], [0.0, 4.5, -0.6], [0.0, 7.0, -0.6]]
}
Each point is [x, z, y]: a place on the floor plane and the world height
(metres) of the surface there, in the same frame as root_position. Without
it a model assumes one flat floor at Y = 0, so a route that drops off one
roof onto a lower one is walked at the old height, in the air.
It describes the ground, not the character, and places, not frames. A server keeps what the character does over it (a walk, a crouch, a jump) and stands whatever is planted on the ground found under it, wherever the motion actually puts it; it does not pin the root to a standing height or the take to a schedule.
- Sampling: along the route and a little either side of it, at a few centimetres' spacing where the ground changes. A server uses the nearest point to each planted foot and ignores points too far away to be under it.
- Gaps: leave them out. Where there is no point there is nothing to stand on, and the character is in the air.
- Opt-in: servers that understand it list
"ground_height"insupported_constraints; others refuse it withunsupported_constraint, so only send it where it is advertised.