Names lie and anatomy does not — the four VRoid imports each broke role
resolution differently, and the lesson generalises: anything guessing
anatomy from a bone name needs a structural fallback. Also lists what is
shipping and which characters have chains that do not simulate.
Co-Authored-By: Claude Opus 5 <[email protected]>
A third playable character, built with the pipeline skill from a source
that was already in the repo: the animation library ships a rigged
Mannequin mesh on the exact 53-joint reference skeleton, CC0, so it needed
no download and retargets perfectly. 18 clips, 0.3% cross-leg bleed, 7% of
verts at four influences — a clean authored-weight import. Licence
recorded in mannequin.license.json as the other skins do.
It has no cloth chains, correctly: it is a mannequin and has neither hair
nor clothes.
Importing it turned up two real bugs, both of which would have hit any
flat-coloured or single-piece model:
- LevelMaterials.apply_character_look treated ANY untextured surface on a
character as the model's own outline shell and hid it, so the mannequin
rendered as a solid black silhouette — its body and joint materials are
untextured flat colours, not ink. _is_line_work() now asks whether the
surface is named eyes*, is drawn front-face-culled (the inverted-hull
setup), or is near-black. Taila and Miku are unaffected: their materials
are textured and never reach that branch. Verified by render.
- verify_character.py failed the build for having one mesh. That check
cannot tell "the pipeline joined them" from "the artist authored one
mesh" — Quaternius' mannequin is one piece on purpose. It is advisory
now; the join path's two unambiguous signatures, cross-leg bleed and the
4-influences-everywhere spread, are still hard checks.
Also restored Miku's description, which the re-import had blanked.
3 GLB skins selectable (6 with the built-in colour skins). Smoke 0
failures, 11/11 movement tests, cloth idle 0.024-0.078 deg/frame.
Co-Authored-By: Claude Opus 5 <[email protected]>
Miku shipped with 0 cloth chains against Taila's 35, so her twin tails
hung off her skull like a helmet. Nothing downstream could fix it: the
spring solver simulates cloth BONES, and a garment with none is welded to
whatever body bone it was weighted to. Every auto-rigged model is in that
state, and her source was an unrigged mesh.
tools/cloth_bones.py builds them, which is the job a technical artist does
by hand on a model like this. It finds the geometry by MATERIAL SLOT — the
artist already answered which surface is hair, and on a joined mesh (what
the auto-rig leaves behind) the slot is the only separation left. Hair is
split into connected islands, because a strand is a connected piece of
surface and clustering by position would merge two ponytails passing near
each other. A skirt is split into radial wedges instead, because a skirt
is ONE connected surface and islands would return the whole thing as a
single piece — the bell-shaped failure. Each clump gets a polyline fitted
down its middle by binning vertices by distance and taking centroids, so
the chain follows the piece's own curve rather than cutting the corner on
a bend, and vertices are re-weighted onto it while the first 22% keeps its
original body weight so the scalp stays on the skull.
On Miku: 19 chains, 57 bones from one `hair` slot. Sidecar 0 -> 19 chains.
Idle stability 0.007-0.018 deg/frame. Mesh intact, verified by render.
Opt-in, via `pipeline.py --grow-cloth`, and run before the retarget so
describe_rig() finds the chains by name exactly as it would an artist's.
Known limits, recorded in the skill: it cannot find a garment sharing a
material with the body (Miku's skirt is on her `body` slot, so she got
hair and no skirt), and grown chains are a fallback — an artist's chains
carry intent that no geometric fit recovers.
Co-Authored-By: Claude Opus 5 <[email protected]>
The two shipped characters are a controlled comparison: Taila's source
arrived rigged (35 cloth chains, 8 twist bones, 18 meshes, artist
weights), Miku's did not (5 meshes, 0 joints), so Miku was auto-rigged
into one mesh with nearest-bone weights and no cloth chains at all. Her
twin tails and skirt are dead geometry and the destructive load-time
weight repair runs on her every spawn.
None of that is recoverable downstream, which makes picking a source that
already has skirt and hair bones the highest-leverage decision in the
pipeline. Added the no-Blender check for vetting a candidate.
Co-Authored-By: Claude Opus 5 <[email protected]>
Everything about getting an anime-styled character into the game — import,
stylization, the body/garment/hair separation, rigging, retargeting, cloth
and hair physics, and how to measure any of it — collected into
.claude/skills/character-pipeline/.
Organised around the principle the Hoyoverse-class pipelines are built on
and that every failure in this project traced back to: a character is not
one object. It is a body, a set of garments and hair, authored and rigged
separately and moved by different systems. The body is skinned and
animated; the garments and hair are bone chains the animation never
touches and physics moves. The skill's non-negotiables are the four ways
that separation has been destroyed here before — joining meshes, keying
cosmetic bones, skinning cloth to a leg, and running the auto-rig repair
on authored weights.
references/verification.md leads with the trap that invalidated every
cloth measurement ever taken in this repo: Godot restores bone poses after
the modifier pass, so a tool that reads them afterwards measures the
animation and never sees what any modifier did.
Also records what is known-unsolved, with numbers: peak cloth clipping in
a run/slide/dash, no foot IK, no strafe clips.
Co-Authored-By: Claude Opus 5 <[email protected]>