Skip to content

XState animation metadata format

VGAI Reference 0.3

Planned versioned generated-schema truth covering Native XState animation state machines and blend trees, Masked and additive animation layers.

planned · generated · immutable Reference 0.3

Lifecycle and constraints

Detailed constraints will publish with the generated or reviewed entry.

Runnable Learn material

Generated format inventory

Inventory only — AC-REF-002 is not passed. Valid parser-verified examples, narrative guidance, complete cross-field/runtime constraints, and version history remain deferred. This page must not be treated as a complete format contract.

Source: packages/engine/src/animation/xstate-animation-meta.ts · 57 branch-sensitive field records · 38 source-described.

StateAnimationMeta · state-meta · 57 fields
Field / branchTypeRequiredDefaultConstraintsDescription
# $ anyOf (2) yes none none Missing source description
# $anyOf[0] object yes none {"additionalProperties":false} Missing source description
# $.clipanyOf[0] string yes none {"minLength":1} Single clip to play while this XState state is active
# $.loopanyOf[0] boolean yes true none Loop the clip (THREE.LoopRepeat) vs play once (THREE.LoopOnce, clamped on last frame)
# $.speedanyOf[0] number yes 1 {"exclusiveMinimum":0} Playback speed multiplier (AnimationAction.timeScale)
# $.crossfadeanyOf[0] object no none {"additionalProperties":false} Blend-in/out/crossfade timing for entering this state
# $.crossfade.durationanyOf[0] number yes 0 {"minimum":0} Seconds to blend from the previously active clip into this state on entry, applied via native `AnimationAction.crossFadeTo`/`fadeIn` (E2). 0 = instant activation, no fade.
# $.crossfade.warpanyOf[0] boolean yes false none Passed through to AnimationAction.crossFadeTo's `warp` param — linearly warps timeScale across the two clips during the blend so differing clip lengths line up. Default false.
# $.layeranyOf[0] string no none {"minLength":1} Composition layer name; omitted means the single base layer
# $.weightanyOf[0] number no none {"minimum":0,"maximum":1} Layer weight multiplier from 0 to 1; defaults to 1
# $.blendModeanyOf[0] enum (2) no none {"enum":["override","additive"]} Native Three normal/override or additive action blending; defaults to override
# $.boneMaskanyOf[0] object no none {"additionalProperties":false} Optional include/exclude filter applied to every clip track in this state
# $.boneMask.includeanyOf[0] array no none {"minItems":1} Bone/object names whose complete descendant subtrees are retained
# $.boneMask.include[]anyOf[0] string yes none {"minLength":1} Missing source description
# $.boneMask.excludeanyOf[0] array no none {"minItems":1} Bone/object names whose complete descendant subtrees are removed
# $.boneMask.exclude[]anyOf[0] string yes none {"minLength":1} Missing source description
# $anyOf[1] object yes none {"additionalProperties":false} Missing source description
# $.blendTreeanyOf[1] oneOf (3) yes none none Multiple clips blended by a live context/selector-driven parameter
# $.blendTreeanyOf[1] oneOf[0] object yes none {"additionalProperties":false} Missing source description
# $.blendTree.typeanyOf[1] oneOf[0] const "1D" yes none {"const":"1D"} Interpolates linearly between sorted children by threshold
# $.blendTree.parameteranyOf[1] oneOf[0] string yes none {"minLength":1} Context/selector value driving the blend
# $.blendTree.childrenanyOf[1] oneOf[0] array yes none {"minItems":2} Missing source description
# $.blendTree.children[]anyOf[1] oneOf[0] object yes none {"additionalProperties":false} Missing source description
# $.blendTree.children[].clipanyOf[1] oneOf[0] string yes none {"minLength":1} Animation clip name this child plays
# $.blendTree.children[].thresholdanyOf[1] oneOf[0] number yes none none 1D/2D blend position on the primary parameter axis
# $.blendTree.children[].thresholdYanyOf[1] oneOf[0] number no none none 2D blend position on the secondary parameter axis (2D blend trees only)
# $.blendTree.children[].weightanyOf[1] oneOf[0] number no none {"minimum":0} Explicit weight for "direct" blend trees (ignored by 1D/2D)
# $.blendTreeanyOf[1] oneOf[1] object yes none {"additionalProperties":false} Missing source description
# $.blendTree.typeanyOf[1] oneOf[1] const "2D" yes none {"const":"2D"} Inverse-distance-weights children by (parameter, parameterY) position
# $.blendTree.parameteranyOf[1] oneOf[1] string yes none {"minLength":1} Primary axis context/selector value
# $.blendTree.parameterYanyOf[1] oneOf[1] string yes none {"minLength":1} Secondary axis context/selector value
# $.blendTree.childrenanyOf[1] oneOf[1] array yes none {"minItems":1} Missing source description
# $.blendTree.children[]anyOf[1] oneOf[1] object yes none {"additionalProperties":false} Missing source description
# $.blendTree.children[].clipanyOf[1] oneOf[1] string yes none {"minLength":1} Animation clip name this child plays
# $.blendTree.children[].thresholdanyOf[1] oneOf[1] number yes none none 1D/2D blend position on the primary parameter axis
# $.blendTree.children[].thresholdYanyOf[1] oneOf[1] number yes none none Missing source description
# $.blendTree.children[].weightanyOf[1] oneOf[1] number no none {"minimum":0} Explicit weight for "direct" blend trees (ignored by 1D/2D)
# $.blendTreeanyOf[1] oneOf[2] object yes none {"additionalProperties":false} Missing source description
# $.blendTree.typeanyOf[1] oneOf[2] const "direct" yes none {"const":"direct"} Each child has an explicit weight, normalized to sum to 1
# $.blendTree.parameteranyOf[1] oneOf[2] string yes "" none Missing source description
# $.blendTree.childrenanyOf[1] oneOf[2] array yes none {"minItems":1} Missing source description
# $.blendTree.children[]anyOf[1] oneOf[2] object yes none {"additionalProperties":false} Missing source description
# $.blendTree.children[].clipanyOf[1] oneOf[2] string yes none {"minLength":1} Animation clip name this child plays
# $.blendTree.children[].thresholdanyOf[1] oneOf[2] number yes none none 1D/2D blend position on the primary parameter axis
# $.blendTree.children[].thresholdYanyOf[1] oneOf[2] number no none none 2D blend position on the secondary parameter axis (2D blend trees only)
# $.blendTree.children[].weightanyOf[1] oneOf[2] number yes none {"minimum":0} Missing source description
# $.crossfadeanyOf[1] object no none {"additionalProperties":false} Blend-in/out/crossfade timing for entering this state
# $.crossfade.durationanyOf[1] number yes 0 {"minimum":0} Seconds to blend from the previously active clip into this state on entry, applied via native `AnimationAction.crossFadeTo`/`fadeIn` (E2). 0 = instant activation, no fade.
# $.crossfade.warpanyOf[1] boolean yes false none Passed through to AnimationAction.crossFadeTo's `warp` param — linearly warps timeScale across the two clips during the blend so differing clip lengths line up. Default false.
# $.layeranyOf[1] string no none {"minLength":1} Composition layer name; omitted means the single base layer
# $.weightanyOf[1] number no none {"minimum":0,"maximum":1} Layer weight multiplier from 0 to 1; defaults to 1
# $.blendModeanyOf[1] enum (2) no none {"enum":["override","additive"]} Native Three normal/override or additive action blending; defaults to override
# $.boneMaskanyOf[1] object no none {"additionalProperties":false} Optional include/exclude filter applied to every clip track in this state
# $.boneMask.includeanyOf[1] array no none {"minItems":1} Bone/object names whose complete descendant subtrees are retained
# $.boneMask.include[]anyOf[1] string yes none {"minLength":1} Missing source description
# $.boneMask.excludeanyOf[1] array no none {"minItems":1} Bone/object names whose complete descendant subtrees are removed
# $.boneMask.exclude[]anyOf[1] string yes none {"minLength":1} Missing source description