The forge, bake and decimate stages are shared. The pipeline forks only at the end, in how the finished mesh attaches to the skeleton.
A machine can't skin: a metal plate bent across a joint tears. So a mech / power-armor suit is composed rigid-per-part — each plate bound to one bone (a dark collar + hinge-stub closes the joint, the Iron-Man trick) so armour rotates but never stretches. Raw parts self-intersect, so they're cut at the joints, fused + remeshed into a watertight shell, then recolored per-unit. One shared walker skeleton drives the whole roster.
Flesh and fabric do bend, so organic parts are skinned to the skeleton instead of mounted. Fitted garments track the torso; loose garments ride a sway chain so they drape and swing. Hair splits both ways — caps mount rigidly, long hair is skinned.
Every finished part lands in exactly one tier. The tier decides which skinning tool runs and how the part attaches at runtime.
| Tier | For | Forged by | Runtime attach |
|---|---|---|---|
| rigid mount | mech plates, armour, eyewear, jewelry, gadgets, weapons | blender_skin_armor.py (fitted) · rigid compose (plates) |
rigid BoneAttachment — bound to one bone (neural_gear.gd) |
| skinned | shirt, vest, undersuit, boots, long hair, species tails | blender_skin_armor.py · blender_skin_hair.py |
skinned sibling — weighted to the shared skeleton, deforms with the body |
| loose cloth | greatcoat, cape, skirt, reptilian tail | blender_skin_cloth.py — own cloth_0..N chain, skinned by height |
cloth sibling — damped sway chain, cloth_sway.gd (ClothSway) |
Rigid never stretches; skinned bends with the joints; loose cloth lags-and-settles like a
real garment. ClothSway is deliberately not a cloth solver — one cheap damped
follow per bone (a spring back to rest, kicked by body velocity), an order of magnitude cheaper than
PBD/XPBD and good enough to sell "cloth".
A text description becomes one clean driving image, leveraging every txt2img tool
best-per-subject: agy (OAuth Pro, no cost) for the final clean driver; FLUX, SD3.5 and
SDXL for fast local exploration. Only one image feeds the forge; cached
<slug>_fullbody.png drivers are reused, never regenerated.
agy_character.sh · flux_fullbody.py ·
sd_fullbody.py · sd_ipadapter.py · gate: single_subject_check.pyThe driver becomes a high-detail textured mesh: shape at grid 1024 (dual-contouring 512) with the full PBR set baked into a UV atlas — base-color, metallic, roughness, opacity. Output is a ~150k-face hero mesh: real materials, but no normal map and far too heavy for gameplay (stage 3 fixes both).
trellis2_gen.py · forge_one.sh (characters) ·
forge_garment_trellis.py (apparel) · reforge_*.sh (batch)Decimate-COLLAPSE the hero mesh to a per-type game poly budget — collapse interpolates the existing UVs, so the baked PBR still maps correctly (no re-bake). Then bake a tangent-space normal map from the hi mesh onto the decimated mesh (Cycles selected-to-active), carrying the detail the decimation drops, and wire it into the game material. Result: a game-budget mesh with base-color + metallic + roughness + opacity + normal.
bake_decimate_normal.py — the "1024³ → bake FULL PBR →
decimate to budget" standardThe game mesh is bound to the shared 19-bone skeleton so it can animate. The tool depends on
the deform tier: fitted parts → blender_skin_armor.py; hair →
blender_skin_hair.py (caps mount rigidly, long hair skins); loose cloth →
blender_skin_cloth.py, which builds the garment its own cloth_0..N mid-line
chain and skins it by height so it drapes as one sheet (never split L/R onto the thigh bones).
Characters and mechs share the skeleton — which is why one baked walk clip drives the whole roster.
blender_skin_armor.py · blender_skin_hair.py ·
blender_skin_cloth.py · libraries: apparel_library.py,
hair_library.pyThe finished part is attached in one of three ways, matching its tier. Rigid BoneAttachment —
hard gear bound to one mount bone; NeuralGear auto-calibrates seats per body and exposes
mounts (head, face, shoulder_l/r, back, hip_l/r, chest, foot_l/r, neck, wrist_l/r).
Skinned sibling — a fitted garment added as a second skinned mesh sharing the skeleton.
Cloth sibling — a loose garment mounted by ClothSway.attach_cloth, re-rooting its
cloth_0 onto the torso and installing the self-driving sway.
neural_gear.gd (rigid + skinned) ·
cloth_sway.gd (loose)The composed character is live in gameplay: neural_gear.gd composes the rigid + skinned
parts (with per-faction kit accents from content/faction_styles.json), and
onfoot.gd is the on-foot controller that walks and animates the assembled body. Assembled
at load time from the recipe — base body + parts + material + equipment — never a single baked glb.
neural_gear.gd · onfoot.gddocs/art-asset-forge/pipeline.md.