VRM Motion Authoring
VRM motion in Avatar has two separate paths:
- Runtime motion proof comes from the generated motion provider, capability profiles, mapping sidecars, and admitted backend routes.
.vrmafiles are authoring and interchange assets. They can be loaded as motion presets, but their existence does not prove that a package supports runtime-driven motion.
This distinction matters for authors. A .vrma file is useful when you want a portable skeletal animation preset. It is not a substitute for the runtime provider path that turns Agent activity into live backend output.
When To Author .vrma
Use .vrma when you need:
- a built-in interchange preset under
apps/avatar/assets/vrm-motion-presets/; - a per-model override at
<model_path>/motions/<preset_id>.vrma; - a reference animation that can be loaded by
@pixiv/three-vrm-animation; - a loop-safe idle, breathing, or short gesture clip for inspection or interchange.
Do not use .vrma to claim APML or runtime activity support. Runtime support is proven through generated motion provider evidence.
Tooling
| Tool | Purpose |
|---|---|
| Blender 4.x | Author skeletal animation. |
| UniVRM Blender add-on 2.x | Import .vrm and export .vrma. |
| Reference VRM file | Provides the humanoid skeleton target. |
@pixiv/three-vrm-animation | Runtime loader used by Avatar. |
@pixiv/three-vrm-animation is not a Blender plug-in. Authoring happens in Blender. Avatar loads the exported .vrma as a glTF binary with the VRMC_vrm_animation extension.
Built-In Preset Registry
The current built-in interchange registry admits one physical preset:
| Preset id | File | Loop | Use |
|---|---|---|---|
idle_subtle | idle_subtle.vrma | yes | Subtle idle motion baseline. |
Other motion route ids such as listen_lean, nod_yes, shake_no, and greet_wave are generated-motion routes. They do not require built-in .vrma files.
Blender Pipeline
- Import a reference VRM. Use UniVRM's VRM import path and confirm the humanoid armature appears in the scene.
- Create an Action. In the Animation workspace, open the Action Editor and create an action named after the preset id.
- Animate humanoid bones only. UniVRM exports animation against the humanoid skeleton. Avoid non-humanoid helper bones unless the exporter explicitly supports the target use.
- Avoid root drift. Keep hips translation minimal. Prefer subtle rotation for breathing, leaning, nodding, and looking.
- Close loops exactly. For looping clips, first and last keyframes must match on every animated channel.
- Export
.vrma. Use UniVRM's VRM Animation export path. The file name must match the registryfilefield. - Place the asset. Built-in presets go under
apps/avatar/assets/vrm-motion-presets/. Per-model overrides go under<model_path>/motions/. - Verify loading. The asset must load through
loadVrmAnimationand retarget throughclipFromVRMAnimation.
Loop Closure
Looping presets should scrub cleanly in Blender before export. If the pose jumps when the timeline wraps:
- Open the Graph Editor.
- Find the channel that changed between the first and last frame.
- Copy the first-frame value to the last frame.
- Re-export and test again.
Small drift is visible on a desktop companion because the Avatar window is transparent and the body becomes the user's focus.
Registry And License Requirements
Every built-in .vrma registry entry needs:
- a real file under
apps/avatar/assets/vrm-motion-presets/; - a stable preset id;
- concrete license and source metadata;
- attribution when the asset is based on third-party work;
- tests or manual evidence showing the file loads through Avatar's VRM animation loader.
Placeholder values such as TBD or candidate are not acceptable in the registry.
Per-Model Overrides
A VRM package may include:
<model_path>/motions/<preset_id>.vrmaThe preset_id must already exist in the admitted registry. Unknown override ids are rejected by the registry loader. This keeps package overrides aligned with Avatar's motion ontology instead of letting each model invent incompatible local names.
Reader Scenario: Adding A New Idle Variant
An author wants a softer idle motion for a VRM character.
- They author
idle_subtleagainst the character's humanoid skeleton. - They export
idle_subtle.vrma. - They place it at
<model_path>/motions/idle_subtle.vrma. - Avatar detects the per-model override and uses it for interchange playback.
- Runtime activity support still comes from the generated motion provider. The override does not become runtime proof by itself.
Source Basis
.nimi/spec/avatar/kernel/vrm-backend-contract.md.nimi/spec/avatar/kernel/generated-motion-provider-contract.md.nimi/spec/avatar/kernel/tables/vrm-motion-presets.yaml.nimi/spec/avatar/kernel/tables/generated-motion-routes.yamlapps/avatar/assets/vrm-motion-presets/THIRD_PARTY_LICENSES.mdapps/avatar/src/shell/renderer/vrm/vrm-motion-preset-registry.ts