How the layers stack
The whole repo follows from one architectural reality: a VRChat avatar is assembled from files in two
distinct formats, and only those two file layers — not the Unity build or the VRChat upload —
are ours to own in Rust. Everything (crate boundaries, what we fix vs. only flag, why upload isn't in
scope) falls out of this split. The conceptual overview lives in docs/overview.md; the
architecture + roadmap of record is PLAN.md.
The crate stack
Hover or focus a crate to highlight it; each box links to its entry on the crates page. Dashed bands are outside the repo. Arrows show where data flows: the tool crates read the two file layers and write only the Unity layer; the runtime rig consumes FBX/glTF meshes; the surface crates wrap the same graph for the terminal, an agent host, and the browser.
avatar-<slug>; the
diagram drops the prefix where it is obvious.The pipeline, end to end
- Unpack —
avatar unitypackage extractturns a shipped.unitypackageinto an FBX + Unity project tree (format). - Diagnose & fix the 3D asset —
fbx inspect,armature check/fix(armature repair). - Lint & rank the project —
avatar lintandavatar stats(rules, metrics). - Generate, edit, migrate —
anim-gen,toggle,asset set,migrate sdk3,physbonewrite Unity YAML with deterministic fileIDs or splice an existing asset in place. - Preview offline —
avatar render/avatar view(render). - You build & upload in Unity via the VRCSDK.
- Drive at runtime —
avatar oscand the analog-gesture daemon (OSC runtime).
This repo is file transformation / analysis / validation / generation plus an OSC runtime daemon — not a Unity replacement.
Layer 1 — the 3D asset (.fbx)
Armature/skeleton, bone names, bind poses, skinning weights, blendshapes. This is where "the armature
isn't set up right" lives. Fully ours in Rust on top of fbxcel — native binary
read and write. The write-back landed in M3 (avatar_fbx::FbxDocument),
resolving the project's long-standing biggest risk.
Ground rules
- FBX support is binary only (FBX 7.x, the Autodesk/Unity/Blender default). ASCII FBX must be re-exported as binary.
- Objects are edited by FBX object id (skin/anim refs are by id, not name), so renames are safe.
- Bind comes from
TransformLink/inverse-bind, never recomposed fromLcl+PreRotation.
Crates: avatar-fbx, avatar-armature. See docs/reference/armature-repair.md and docs/reference/rig-runtime.md.
Layer 2 — the Unity / VRChat project (UnityYAML)
.anim, .controller, .asset, .prefab, scenes,
.meta: the Avatar Descriptor, humanoid bone mapping, animator layers, expression
menus/params, blend trees, gesture keyframes. Three modes of access, in increasing order of risk:
| Mode | Risk | How |
|---|---|---|
| Read / lint | low | Structural recognition of VRChat assets (no hardcoded script GUIDs) + a guid→path .meta index for cross-asset references. avatar-unity-yaml, avatar-unity-asset, avatar-vrc-descriptor. |
| Edit in place | low | EditableUnityFile span-splices value and structural changes into the raw text, so fileIDs, references, key order, and formatting survive round-trip (editing Unity YAML). This is what makes whole-avatar operations safe: migration retypes the descriptor at its existing fileIDs; PhysBone tuning rewrites one component body. |
| Generate | the hard part | Assets Unity accepts need correct fileIDs, field names, and GUID references. Solved (M4) with a faithful hand-written YAML emitter and deterministic FNV-1a-seeded fileIDs; verified by a headless Unity import gate (asset generation). |
11500000.
Layer 4 — runtime & preview
The renderer-agnostic runtime rig (mesh,
gltf, pose, input) loads a rig and drives it; render
draws it headlessly with wgpu or in a window; osc / osc-gestures talk to the
running game. glam (f32) is confined to these crates and never reaches the diagnose /
generate / OSC graph — an invariant cargo tree verifies.
What is not ours — build & upload
The VRCSDK control panel pushes to VRChat servers. It needs interactive VRChat-account login and a Unity
license that is painful in containers — effectively Windows-only. We deliberately stop here: we
generate assets you drop into Unity, you build and upload there, and then the avatar osc
layer drives the running avatar's parameters at runtime.
Milestones
| Milestone | Scope | Status |
|---|---|---|
| M0 | Workspace scaffold | done |
| M1 | Armature diagnosis, hierarchy-aware humanoid mapping | done |
| M2 | Project SDK3 linting (avatar lint) | done |
| M3 | Armature repair + native binary FBX write-back | done |
| M4 | Asset generation (avatar-anim-gen) | done |
| M5 | OSC runtime + analog-gesture daemon | OpenXR input pending |
The runtime rig layer, wgpu preview, Unity-YAML editing, migration + PhysBone tuning, the MCP server, and the browser inspector landed alongside M4/M5. Full detail in PLAN.md.