Consolidate documentation into architecture and merged guides
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-04 14:06:23 +01:00
1 parent aec1fb7b69
commit dee939c2ee
39 files changed
+795 -1203

No files matched your search

+7 -46
View File
@@ -39,7 +39,7 @@ captures in `docs/screenshots/`.
Blender MCP can be used for interactive head/face/hand part exploration, but it
is not required. The headless commands below remain the build and audit path;
see [`blender-mcp.md`](blender-mcp.md) for installation, connection and safety.
see [`asset-tooling.md#optional-interactive-blender-mcp`](asset-tooling.md#optional-interactive-blender-mcp) for installation, connection and safety.
## Running it
@@ -91,35 +91,10 @@ render about 2.5 min.
## Characters
All eight use the `npc_base` contract, so each one can replace
`npc_base.glb` without code changes:
- mesh node `npc_base` under an armature that imports as `Skeleton3D`
- bones `Head`, `HipL/R`, `KneeL/R`, `ShoulderL/R`, `ElbowL/R`, `HandL/R`
(plus `Hips`, `Spine`, `Neck`) at the **same rest positions as `npc_base`**.
`test_character_joints_line_up_with_npc_base` checks this within 1 cm, so the
animation proxies in `_build_skinned_body()` stay valid.
- material slots `skin`, `cloth`, `pants`, `accessory`, `hair` carry the same
neutral `assets/textures/npc/<slot>_{albedo,normal}.png` maps at 256², so
`Materials.npc_slot()` tints them the same way it tints `npc_base`. Cloth and
pants repeat the weave 4× (`NPC_FABRIC_UV_SCALE`) and intentionally skip the
per-character baked AO; skin, hair and fixed gear keep it.
- budget ≤ **16,000 triangles and ≤ 16,000 glTF vertices** per character (vertex count after
seam splits; `CHAR_MAX_TRIS`/`CHAR_MAX_VERTS` in `tools/blender_assets.py`). The 13 core bones
remain required; optional extra bones are allowed as long as the core rest positions and
`NpcAvatar` animation proxies are unchanged. The frozen low-poly `npc_base` fallback keeps its
compact geometry but is no longer capped at 6,000/4,000. The current range is 5,038–6,030
triangles and 4,756–5,902 vertices, leaving substantial head/hand headroom.
Construction: the torso and limbs are one continuous Skin-modifier mesh,
subdivided twice, decimated to 26 % with X symmetry, and cut at the waist, cuffs,
sleeves and neck so the material borders are clean edge loops. The head is a
separate part carrying the face detail: brow ridge, sclera/iris/upper-lid per eye,
cheekbones, a nose with a bridge and tip, ears with lobes, and upper and lower
lips. Hands have four fingers plus a thumb; sleeves end in a cuff ring.
Hair, shoes and clothing layers are separate parts. Weights come from distance to
the bone segments, limited by body region. Parts that should stay rigid (head,
hands, shoes) get a single bone.
All library variants share the [character and gear asset contract](architecture.md#character-and-gear-asset-contract):
`npc_base` mesh node, required 13 core bones (optional extras allowed), five
tint slots, +Z visual front, 16,000/16,000 character budget and the same 256²
slot-map/AO rules. Role selection and look notes:
| Character | `layer_for()` / look | Suggested roles | Preview gear |
| --- | --- | --- | --- |
@@ -146,22 +121,8 @@ the role's `TYPE_COLORS`.
## Gear attach points
Gear is authored in attach-point space, so the origin of each GLB is its
attach point:
| Attach | Godot parent / position | Gear |
| --- | --- | --- |
| `head` | `Rig/Head` marker (0, 1.62, 0) | cap, hood, sunglasses, firefighter_helmet |
| `back` | `Rig` at (0, 1.10, 0), spine centre; items sit behind the body (Blender +Y = Godot −Z) | backpack, shoulder_bag, scba_tank |
| `chest` | `Rig` at (0, 1.30, 0), sternum | lanyard |
| `hand` | Hand proxy (±0.27, 0.78, 0.02); grip 5 cm below the origin | phone, cup, clipboard, umbrella, camera, protest_sign, flashlight, wand, radio |
The character previews in `sheet_npc.jpg` are built by importing the gear at
exactly these points, which gives a quick visual check of the convention.
`NpcAvatar.GEAR_OFFSETS` applies two final-context nudges after attachment:
the lanyard moves 4 cm forward so its badge clears the jacket, and the
firefighter helmet moves 3 cm up so its brim sits above the eyes. The
`fit` report remains an asset-space measurement of the untouched GLBs.
Gear is authored in attach-point space; the exact contract and runtime fit offsets are in
[`architecture.md#character-and-gear-asset-contract`](architecture.md#character-and-gear-asset-contract).
## Props