Rewrite NPC plans around the Quaternius base

This commit is contained in:
zwitschi committed 2026-11-05 19:43:35 +01:00
1 parent 2e1bb19e2c
commit 9968bc0a4c
17 files changed
+364 -536

No files matched your search

+2 -2
View File
@@ -9,8 +9,8 @@ Semantic Versioning.
### Changed
- Raised the character mesh budget from 16,000 to 24,000 triangles and glTF
vertices so the MakeHuman head, MPFB body, fused neck and clothing variants
can fit without heavy decimation. Gear and prop budgets are unchanged.
vertices so the Quaternius NPC base, the five-slot clothing variants and the
retargeted animation can fit without heavy decimation. Gear and prop budgets are unchanged.
## [0.9.8] — 2026-11-04
+14 -4
View File
@@ -48,10 +48,20 @@ shipped derivative of CesiumMan or RiggedFigure must keep the attribution above.
The standalone MakeHuman head prototype is derived from the MakeHuman / MPFB base
mesh, **CC0** (`assets/models/blender_src/makehuman_head.glb`; source
`tmp/npc-research/makehuman/base.obj` with its bundled
`LICENSE.md`/`LICENSE.ASSETS.md`). It is cut, retopologised and re-weighted by
project scripts; the exported character GLBs remain project assets. See ADR-0015
and `docs/npc-model-sourcing.md`.
<https://static.makehumancommunity.org/makehuman.html>, MakeHuman base mesh,
CC0 1.0). It is cut, retopologised and re-weighted by project scripts; the exported
character GLBs remain project assets. The development source files were removed
from `tmp/` after the 2026-11-05 pivot to Quaternius. The head is retained as a
tested fallback, not the active NPC base. See ADR-0017 and
`docs/npc-model-sourcing.md`.
### Quaternius NPC base source
The active NPC base migration uses **Quaternius Ultimate Modular Characters** and
**Ultimate Modular Women** (CC0 1.0, <https://quaternius.com/>). The three
researched GLBs are development inputs and are not shipped directly; the baked,
retargeted character GLBs are project assets. See ADR-0017 and
`docs/npc-model-sourcing.md` for the decision, source hashes and rollout status.
The venue geometry is authored procedurally in `src/game/world_builder.gd` as a
stylized reconstruction. The Joke Shop is a fictional stand-in for the real
+14 -85
View File
@@ -10,14 +10,6 @@ canonical implemented-features list in `docs/development-status.md`.
the licence gate. Downloads live in `tmp/research/` (gitignored): DDG image search, street-view
frames, neighbouring buildings — never committed, never shipped. Promotion into
`docs/screens/refs/` always passes the sidecar licence + privacy gate and `CREDITS.md`.
- **MakeHuman head accepted (2026-11-04, owner):** the basic human head is a pass.
`assets/models/blender_src/makehuman_head.glb` is the CC0 MakeHuman-derived head
(12,642 tris / 7,690 split verts). The automated vision gate still records REJECT on
the eye/lid region (globe depth, lid overlap, iris at three-quarter) as deferred
polish, not a blocker. The assembled path (`build_character(head="mh")`) adds a
skull-conforming hair cap derived from the closed head shell, hides the scalp under
that cap, and narrows the neck/shoulder body. Default head source stays `face` until
the owner reviews the hair/body and the 12-variant rollout starts.
- **AI-assisted asset review loop (2026-11-04):** head/face shape decisions use a concept +
judge loop — generate a target concept (`generate_textures.generate_image`, Seedream) and use
`tools/describe_image.py` as the vision judge, iterating on the mesh until the judge's specific
@@ -25,43 +17,6 @@ canonical implemented-features list in `docs/development-status.md`.
(`_head_proto` oscillates between "decorated egg" and "spiky wedges" at ~3/5 on the coarse
sphere). Review page: `docs/screens/head-review/README.md`; methodology note:
`docs/3d-model-review.md` §AI-driven head rework.
- **MakeHuman hair/body prototype (2026-11-04):** `npc_casual --head mh` is
14,753 tris / 12,822 raw / 12,823 seam-split verts / 14 bones / 9 materials,
`inspect` clean. All 12 variants were counted at 14,693–15,987 tris. Hair uses flat
shading normals because the old hair normal map caused dark tangent patches on the
new cap. Scalp faces fully covered by the hair cap are deleted (saves ~950 tris);
the accepted face geometry is untouched. The procedural body was narrowed at the
neck/shoulders (shoulder root z 1.345, chest 0.158, neck 0.060/0.054) and its skin
decimate dropped to 0.21. The local renders are in
`tmp/npc-parts/prototype_mh/renders/`.
- **MPFB full-body prototype (2026-11-04):** the current body candidate is the local MPFB 2.0.18
pipeline at `tmp/npc-research/build_mpfb_npc.py` (dev-only; no `.mhclo` clothing installed).
It creates a macro-driven human, bakes targets, adds the `game_engine` rig, captures arm
points/weights, removes the rig, applies the helper MASK, scales to 1.81 m, retargets the A-pose
arms to the contract wrist, cuts the neck at 1.505, decimates, bisects the clothing boundaries,
paints the five slots, adds a short neck flare, project hands, rounded shoes and cuffs, the
accepted head and the 14-bone contract armature. Current output: **15,317 tris / 13,690 glTF
verts / 13,702 seam-split verts / 1.810 m / 14 bones / 10 materials**; `inspect` clean and feet
grounded. The torso is inflated radially by 12% through z 0.72–1.40 to loosen the shirt. The
neck is a radial cut of the decimated column bridged by a four-ring, 20-segment lathe (lower
rings painted cloth, reads as a crew neck); the ankles are hidden by a bevelled 0.11 m shoe
shell, an inset 0.111 × 0.286 m sole, a tongue and a 0.08 m pant cuff. Sleeve cuffs use the
`cloth` slot and the `accessory` slot is carried by the sole. A light smoothing pass on the
closed thigh/hip region softens the decimated silhouette. Earlier torus collar, cloth cylinder
collar, skin neck-blend sphere and destructive neck `smooth_vert` pass failed: the shells read as a
brace, shelf or donut, and vertex smoothing tore the open collar boundary into a dark hole. An
untucked shirt-hem band at the hips also failed: it read as a hanging white flap at the crotch.
Protruding flat sole plates read as skates/bricks and were replaced by an inset sole under a
rounded shell; laces were dropped for triangle budget. The neck skin rule needed a `z > 1.35`
guard: without it the `radius < 0.08` test painted skin at the crotch. Lowering the hem to
z 0.80 (unitard), tilting it up at the front (high-cut swimwear) and a 13% hem flare (peplum)
were all rejected; the remaining crotch V is the dark hollow under a body-painted shirt. A quick
open, flared solidified tube (0.150→0.196 m, z 1.05→0.80, 24 segments, ~288 tris) also failed:
it read as a hanging apron/tabard. The real fix is a shaped shirt shell with armholes and a
curved hem, not a tube. Remaining polish: crotch V, partly loosened shirt,
angular thigh facets. The prototype uses flat slot colours because the one-shot MPFB UV unwrap
does not match the per-slot NPC atlases. Renders:
`tmp/npc-parts/mpfb_proto/renders84/`; body-only: `body_only.glb`.
- **Project agent skills (2026-11-03):** two tracked skills live in `.agents/skills/`:
`gig-line-blender-asset-contract` and `gig-line-release-qa`. They are guidance only,
add no runtime dependency and are referenced from `tools/README.md`. The third-party
@@ -97,11 +52,6 @@ canonical implemented-features list in `docs/development-status.md`.
(94 skills + shared `references/`), gitignored, kept out of Godot's scanner by
`.agents/.gdignore`. Keep the pack flat when updating (`cp -a <pack>/.claude/skills/. ...`).
Pi gates project `.agents/skills` behind project trust.
- **NPC model sourcing (ADR-0015):** CC0 acceptable for shipped assets; CC-BY only with
attribution in `CREDITS.md`; no service assets with redistribution restrictions. The procedural
generator is the primary path. Quaternius and MakeHuman were evaluated as references only, not
shipped bases (Quaternius: 62-bone T-pose rig mismatch; MakeHuman: needs retopology + custom
rig + clothing).
- **Gaussian splatting (unversioned):** offline/development-only until an ADR proves licence,
privacy, Compatibility/Web cost and mesh collision. Accepted photo channels: team captures,
permissioned user/volunteer photos, clearly licensed downloads; every set needs a
@@ -117,18 +67,18 @@ canonical implemented-features list in `docs/development-status.md`.
- **Character mesh cap (2026-11-05):** all characters use 24,000 tris / 24,000 glTF vertices
(`CHAR_MAX_TRIS`/`CHAR_MAX_VERTS` in `tools/blender_assets.py`; `npc_pipeline.MAX_TRIANGLES`/
`MAX_VERTICES`). The required 13 core bones stay, optional extra bones are allowed, and the
low-poly `npc_base` fallback remains the shipped fallback. The raise funds the MPFB body and a
seamless neck/shoulder junction. Measure the 24-NPC/Web budget after
low-poly `npc_base` fallback remains the shipped fallback. The raise funds the Quaternius base bake and
the 12-variant clothing detail. Measure the 24-NPC/Web budget after
any geometry change; never silently lower the cap without a new decision.
- **MPFB prototype neck (2026-11-05):** a boolean cylinder (r 0.102) cuts the body neck bore; a
smooth lathe covers it. The accepted head keeps a wide flat cut brim at 1.53, so the prototype
trims the head at 1.55 (discarding only the neck stub) and matches the lathe to the smaller
elliptical opening. This removes the square collar, dark notches and wide brim. Remaining: a
thin jaw crease and a hard shirt-shoulder point in three-quarter view. Do not re-add a torus,
flat disk, collar shell or destructive neck smoothing; those were rejected.
- **MPFB prototype count (2026-11-05):** 19,747 tris / 16,851 glTF verts / 1.810 m / 14 bones /
10 materials; `inspect` clean. Body-only head/neck surgery lives in
`tmp/npc-research/build_mpfb_npc.py` (backups in `/tmp/build_mpfb_npc_94.py`).
- **Quaternius is the NPC base (2026-11-05, owner):** ADR-0017 supersedes the generator-first
sourcing decision. The CC0 Quaternius Ultimate Modular character pack is the primary NPC mesh
and animation source. Stage 1 bakes a proportion-warped, 13-core-contract `npc_base` so
`NpcAvatar`, gear and animations keep working; the 62-joint/24-clip source rig is authoring
input, not a runtime dependency. If the warp fails the silhouette gate, Stage 2 needs a new ADR
for a 62-joint runtime, not a hybrid. The MakeHuman head and procedural `npc_base` remain
tested fallbacks until the Quaternius rollout ships. Quaternius source: CC0, attribution in
`CREDITS.md`; the three researched GLBs and licence notes are kept in
`tmp/npc-research/quaternius/`. MPFB/MakeHuman body work is closed; do not add new work there.
- **Engine baseline:** Godot 4.7.2 stable (official editor `~/.local/bin/godot`). The system's
`godot-runner` cannot load arbitrary project paths (compiled without path overrides); use the
official editor binary.
@@ -167,27 +117,6 @@ canonical implemented-features list in `docs/development-status.md`.
out of a portrait frame (park the rest of the crowd away instead).
- Blender: `bisect_plane` and thin bevels leave zero-area triangles (Godot "non-finite normal in
LOD generation"); `_clean()` + a weld after bisect fixes them and the audit rejects them.
- MakeHuman head/hair gotchas: the imported head is broad and flat, so a separate hair
ellipsoid floats or leaves a bald patch; derive the cap from the closed head shell and
boolean-cut the hairline. Do not reuse the skull's UVs with the old `hair_normal.png`
(dark tangent patches) — hair skips the normal map. Generate the cap before deleting
the hidden scalp, or the cap inherits the hole. The flatpak sandbox cannot read `/tmp`;
helper scripts must live under `$PWD`.
- MakeHuman OBJ intake transform (`base.obj`): the source is Y-up, 16.946 units tall. To reach
the project Blender Z-up / metres / front -Y space: scale 0.10739, translate y +0.907 (ground
the feet), then rotate +90° around X (maps +Y→+Z up and +Z→−Y front). The full-res head carries
internal geometry (eyes/teeth/mouth shells) and is non-manifold; voxel-remesh and Catmull-Clark
subdivision both fragment it into shards. On the decimated head, weld first
(`remove_doubles` ~0.0002) then Laplacian `smooth_vert`; subdivision without the weld splits
along the GLB seam vertices.
- MPFB gotchas: call `TargetService.bake_targets(body)` before any decimate (shape-key
modifier error); add the built-in rig and capture arm weights before applying the MASK
modifier, or `build_basemesh_position_info` divides by zero on an emptied bone group;
decimate before bisecting the clothing loops, or the decimator collapses the bisect
into a sawtooth. Clear custom split normals after joining (imported MPFB normals leave
flat-shaded thigh facets). Imported GLBs may include helper `Cube`/`Icosphere` meshes at
±1.0, so select `npc_base` explicitly. Delete the MPFB hands by hand/finger vertex-group
weights, not only by `|x|`, or leftover fingers become pants-coloured fins.
- Image models have per-model size floors/caps (Seedream needs 1920+; `GEN_SIZE=2048`, do not
lower; gpt-5-image-mini caps lower). `generate_image` applies model-specific sizing; concept
generation defaults to `--request-size 1536`.
@@ -269,9 +198,9 @@ canonical implemented-features list in `docs/development-status.md`.
The playable build covers the three venues, tutorial/campaign/checkpoints, the 0.9.3–0.9.6
polish/texture/integration passes and the Blender + realism asset pipeline (see `DONE.md` and
`CHANGELOG.md`). The 12-character library (realistic face + four crowd variants) and the
Comedy Store map rebuild are complete. **Priority (2026-11-04, owner):** 1) the **Blender NPC
model overhaul** (head/face/hands, local part pipeline), 2) finish the MakeHuman character + the
3D model and map improvements, 3) ship it all together in the **0.10.0 minor**. The 0.9.7/0.9.8
Comedy Store map rebuild are complete. **Priority (2026-11-05, owner):** 1) the **Quaternius NPC
base migration** (bake the CC0 Quaternius character to the runtime contract), 2) the 3D model and
map improvements, 3) ship it all together in the **0.10.0 minor**. The 0.9.7/0.9.8
character patches are published; `TODO.md` is the priority source. Test counts as of 2026-11-04:
Godot 277/277, Python 167/167, `check_docs` OK.
+9 -7
View File
@@ -18,11 +18,13 @@ The game is about **judgment, communication, access verification, and proportion
The active planning order is set in [`TODO.md`](TODO.md) and in `AGENTS.md`:
1. **Character development (unversioned).** Expand the owned procedural character library with
crowd, age, build, hair and outfit variety. Keep the frozen bone/tint/gear contract; see
[ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md) and
[`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md). Quaternius is a reference;
MakeHuman is deferred to a separate local pipeline.
1. **Quaternius NPC base (unversioned).** Use the CC0 **Quaternius Ultimate Modular
Characters** as the primary NPC mesh and animation source. Bake a canonical Quaternius base
onto the runtime `npc_base` contract (13 core bones, five tint slots, 24,000/24,000) so the
existing gear, `NpcAvatar` and gameplay poses keep working. If the proportion warp fails the
silhouette gate, stop and decide on the 62-joint source rig in a new ADR. See
[ADR-0017](docs/adr/0017-quaternius-npc-base.md) and
[`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md). MakeHuman/MPFB body work is closed.
2. **Local map development (unversioned).** Move beyond stylized venue reconstruction with
licensed OpenStreetMap and 3D building data, downloaded reference imagery for photoreal
facades, AI-assisted composition, and a Gaussian-splatting evaluation that stays in the
@@ -169,7 +171,7 @@ The action wheel prioritizes de-escalation: Stop, Look, Point, No, Ask, Inspect,
The visual direction is readable stylized realism:
- **Character direction:** 8 skinned NPC variants, 18 gear pieces and 20 street/venue props, with four crowd-variety variants prototyped. The generator-first expansion is the active character track ([ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md)); Quaternius is a reference and MakeHuman is deferred to a local pipeline.
- **Character direction:** 12 skinned NPC variants, 18 gear pieces and 20 street/venue props. The active character track is the Quaternius base migration ([ADR-0017](docs/adr/0017-quaternius-npc-base.md)): use the CC0 Quaternius mesh/animation source, bake it to the runtime contract, and retire the bespoke procedural body work.
- **Realism pass:** AI-assisted per-phase skyline panoramas, v2 surface tiles with normal maps, wet asphalt at night, a warm day haze, phase-specific sun/exposure/fog, a tight flashlight spot (no beam geometry), and denser foliage.
- **Local map direction:** the venues are currently stylized reconstructions. The local-map track evaluates licensed OpenStreetMap/3D building data, licensed reference photography, AI-assisted composition and Gaussian splatting as a development tool; online data and splat rendering are not runtime dependencies.
- **References and QA:** runtime UI art lives in `assets/images/ui/`; reference/art-direction sets live in `docs/screens/designs/` and `docs/screens/concepts/`; captures live in `docs/screenshots/`; realism runs live in `docs/screens/realism/`. `screen_designs.py compare/judge` and `tools/check_screenshots.sh` guard drift.
@@ -177,7 +179,7 @@ The visual direction is readable stylized realism:
The active planning order — unversioned character and local-map development first, then the versioned 0.10.0 release-candidate hardening and later releases — is tracked in [`TODO.md`](TODO.md); this plan stays at the product/design level.
Primary decisions: [ADR-0007](docs/adr/0007-locomotion-and-input-layers.md), [ADR-0008](docs/adr/0008-cone-focus-and-head-ring.md), [ADR-0009](docs/adr/0009-radial-action-menu.md), [ADR-0010](docs/adr/0010-procedural-npc-presentation.md), [ADR-0011](docs/adr/0011-aim-free-selection-and-precision-walk.md), [ADR-0012](docs/adr/0012-surface-materials-and-generated-props.md), [ADR-0013](docs/adr/0013-blender-authored-npc-characters.md), [ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md).
Primary decisions: [ADR-0007](docs/adr/0007-locomotion-and-input-layers.md), [ADR-0008](docs/adr/0008-cone-focus-and-head-ring.md), [ADR-0009](docs/adr/0009-radial-action-menu.md), [ADR-0010](docs/adr/0010-procedural-npc-presentation.md), [ADR-0011](docs/adr/0011-aim-free-selection-and-precision-walk.md), [ADR-0012](docs/adr/0012-surface-materials-and-generated-props.md), [ADR-0013](docs/adr/0013-blender-authored-npc-characters.md), [ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md), [ADR-0017](docs/adr/0017-quaternius-npc-base.md).
## Tech Stack
+8 -7
View File
@@ -11,7 +11,7 @@ The central design goal is simple:
The active planning order lives in [`TODO.md`](TODO.md) and [`AGENTS.md`](AGENTS.md):
1. **3D model and local map re-evaluation** — score every shipped asset, then evaluate licensed OpenStreetMap/3D data, reference-derived photoreal facades, AI-assisted composition and a Gaussian-splatting development evaluation.
2. **Character development** — crowd, age, build, hair and outfit variety on the owned procedural library, keeping the frozen NPC contract. Source evaluation and the licence decision are in [`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md).
2. **Quaternius NPC base** — use the CC0 Quaternius Ultimate Modular character as the primary mesh and animation source, baked to the existing runtime contract. Source evaluation and the licence decision are in [`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md) and [ADR-0017](docs/adr/0017-quaternius-npc-base.md).
3. **Versioned release hardening** — the 0.10.0 release candidate and later semantic versions follow the unversioned development tracks.
Versions are assigned only when a track's scope is accepted into a release. Every major, minor and patch version requires a changelog entry, a local release build and artifact verification before tagging.
@@ -40,7 +40,7 @@ Versions are assigned only when a track's scope is accepted into a release. Ever
> texture/material refinement and integration checkpoint.
>
> **Current source: v0.9.8** — tagged from the same commit. The 0.10.0
> development track remains gated on the NPC overhaul, MakeHuman/local-map work
> development track remains gated on the Quaternius NPC rollout, local-map work
> and release approvals.
> Releases are built automatically when a `vX.Y.Z` tag is pushed
> (see [`docs/RELEASING.md`](docs/RELEASING.md)); manual builds use
@@ -95,8 +95,9 @@ Every capture is rendered from the current build by [`tools/check_screenshots.sh
### 3D asset progress
The character, gear and prop libraries are authored procedurally in Blender and audited before use;
the sheets below track their visual progress.
The current character library is Blender-authored and audited before use. The active character
migration moves the NPC base to the CC0 Quaternius modular character; the sheets below show the
current library and will be replaced after the 12 × 6 baseline review.
| | |
| --- | --- |
@@ -131,7 +132,7 @@ decisions are recorded as ADRs in [`docs/adr/`](docs/adr/).
## Tech Stack
- **Engine:** Godot 4.7.2 · **Language:** GDScript
- **NPCs:** Blender-authored skinned library (`assets/models/blender/`) with procedural fallbacks; lightweight FSMs on `NpcProfile`
- **NPCs:** Blender-authored skinned library (`assets/models/blender/`) with procedural fallbacks; Quaternius CC0 base migration in progress; lightweight FSMs on `NpcProfile`
- **World:** procedural `WorldBuilder` + generated prop models
- **Art:** v2 skyline/surface textures in `assets/textures/ai/game_ready/v2/picks/`; UI/scene art in `assets/images/`
- **Asset tooling:** `asset_pipeline.py`, `model_pipeline.py`, `npc_pipeline.py`, `blender_assets.py`, `scene_concepts.py`, `screen_designs.py`, `check_screenshots.sh`
@@ -190,8 +191,8 @@ v0.9.8 is the current source version: the character-development patch with the
and save-migration/release hardening. It sits on the 0.9.6 integration
checkpoint, 0.9.5 texture refinement, 0.9.4 NPC visual optimization, 0.9.3
UI/accessibility polish, 0.9.2 Hollywood/Joke Shop maps and the 0.9.x engine
baseline. The active priorities are the Blender NPC head/face/hand overhaul,
MakeHuman body intake and the 3D model/map re-evaluation; the 0.10.0 release
baseline. The active priorities are the Quaternius NPC base migration and the 3D
model/map re-evaluation; the 0.10.0 release
candidate follows those tracks. See
[`docs/development-status.md`](docs/development-status.md) for the implemented list
and [`TODO.md`](TODO.md) for the priority-ordered roadmap. Manual verification uses
+82 -304
View File
@@ -3,281 +3,105 @@
Work is grouped by theme. Each item should be small enough to complete and verify on its own;
see `AGENTS.md` for the workflow and `MEMORY.md` for the decisions behind these plans.
**Priority order (2026-11-04, owner):** 1) **Blender NPC model overhaul** — head, face and hands
with a local part pipeline; 2) finish the MakeHuman character + the 3D model and map improvements;
3) ship it together in the **0.10.0 minor**. The 0.9.7/0.9.8 character patches are published. See
`AGENTS.md` §Priority and Versioning and §Local Blender skills.
**Priority order (2026-11-05, owner):** 1) **Quaternius NPC base migration** — use the CC0
Quaternius character as the mesh/animation source and bake it to the runtime contract; 2) the 3D
model and local map improvements; 3) ship it together in the **0.10.0 minor**. The 0.9.7/0.9.8
character patches are published. See `AGENTS.md` §Priority and Versioning and §Local Blender skills.
The MIT Blender skill pack lives locally at `.agents/skills/blender-skills/` (gitignored). Every
3D workstream below names the skills to load; they are guidance only, and the project contract,
`blender_assets.py audit`/`fit`/`inspect` and the capture gates stay authoritative.
## Blender NPC model overhaul (top priority)
## Quaternius NPC base migration (top priority)
Goal: replace the sphere-and-primitive face and hand construction with a local, part-based
development pipeline that can build, inspect and compare the **head/face** and **hands** separately
before assembling them into the shipped character. Prioritise face readability at portrait
distance, then hand silhouette and gear contact. Preserve the `npc_base` contract, the 13 core-bone rig (optional extra bones allowed),
five tint slots, 24,000/24,000 character cap, optional extra bones beyond the required 13, and the Compatibility/Web path.
Goal: replace the generator-first NPC base with the CC0 **Quaternius Ultimate Modular
Characters** as the primary mesh and animation source, while keeping one committed
`npc_base` skinned mesh, the five tint slots and a runtime contract that Godot, gear
and tests can consume. The detailed decision is [ADR-0017](docs/adr/0017-quaternius-npc-base.md);
it supersedes the generator-first sourcing decision in ADR-0015.
*Skill route: `character-artist`, `retopology`, `sculpting`, `rigging`, `uv-workflow`,
`texture-workflow`, `materials`, `lookdev`, `asset-optimization`, `qa-review`.*
**Why:** the research pack already has a coherent low-poly human silhouette, 21 modular
outfits and 24 animations. The current procedural body needs a separate head, hands, neck
and shoe pipeline to look human; using Quaternius as the base removes that bespoke body work.
**Current state:** `assets/models/npc/` contains the tracked frozen `npc_base.blend` and its
gitignored `.blend1`; the 12 production characters are assembled procedurally by
`tools/blender_assets.py` from `_shape_head_mesh`, `_face`, `_hair` and `_hands_and_shoes`.
The MakeHuman head is now a second head source (`build_character(head="mh")`,
`build --head mh`, `npc_parts.py assemble --head mh`) and all 12 variants assemble inside the
24,000-triangle cap with it. The procedural body, hands and clothing remain unchanged. The
MakeHuman body prototype and its temporary head/hand swap live under `tmp/npc-research/` and are
not the shipped path. This overhaul supplies the reusable head/face and hand parts that both the
procedural characters and the MakeHuman body can consume.
**Default path (Stage 1):** retarget and proportion-warp the Quaternius mesh onto the
existing 13-core contract, so `NpcAvatar`, gear attach points and the current animation
composition keep working. The 62-joint Quaternius rig and its 24 clips are an authoring
source, not a new runtime dependency.
This workstream supersedes the face/head and hands items in §C until the prototypes are approved;
the rest of §C remains the broad review checklist.
**Stage 2 gate:** if the proportion warp cannot preserve the Quaternius silhouette and
deformation at an acceptable level, stop the rollout and write a new ADR for adopting the
62-joint rig at runtime. Do not ship a hybrid rig or silently change `NpcAvatar`.
### 1. Baseline and acceptance
**Exit:** one committed Quaternius-derived source GLB produces all 12 variants inside
24,000 tris / 24,000 glTF vertices, with five slots, gear fit, Idle/Walk deformation,
`audit`/`fit`/`inspect` clean, the 24-NPC budget measured, and an owner-approved 12 × 6
baseline sheet.
- [x] Inventory the real starting point: the frozen `assets/models/npc/npc_base.blend`, the 12
generated character GLBs/AO maps, the current `_face`/`_hands_and_shoes` builders and the
temporary MakeHuman head/hand swap. Recorded tris/verts, head subdivision, material slots,
UV layout and the exact locations of eye/mouth/finger geometry in
`docs/3d-model-review.md` §Baseline inventory.
- [x] Define measurable acceptance: face front/three-quarter/profile at 1.5 m and 1.85 m; hands
open and gripping at 0.8 m; silhouette, eye/mouth readability, ear/nose/jaw planes, finger
separation and gear contact. Keep the 24,000/24,000 cap; optional extra bones are allowed, but the required 13 core bones and rest positions must not move.
Recorded in `docs/3d-model-review.md` §Overhaul acceptance criteria.
- [x] Confirm the identity boundary: `npc_base.blend` is the frozen fallback and must not absorb
prototype detail unless a separate contract decision approves it.
Recorded in `docs/3d-model-review.md` §Baseline inventory and
`docs/blender-assets.md` §Frozen fallback boundary.
- [x] Choose a local working-set layout: `tmp/npc-parts/<variant>/` (gitignored) for part `.blend`
and preview GLBs; only the assembled character GLBs, AO/maps, manifest and review sheets are
committed. Do not add a new committed `.blend` source tree without a docs/ADR decision.
Recorded in `docs/3d-model-review.md` §Working-set layout and
`docs/asset-tooling.md` §Recommended part-workflow.
### 1. Intake and canonical base
### 2. Local part pipeline
- [ ] Keep the three researched CC0 GLBs (`Casual`, `Casual_Hoodie`, `Worker`) plus the
licence/mirror notes in `tmp/npc-research/quaternius/`; record the source URL,
licence, SHA-256 and download date in `docs/npc-model-sourcing.md`.
- [ ] Inventory the four meshes, 62 joints, 24 clips and material names in each GLB; map
Quaternius materials to the five project slots (`skin`, `cloth`, `pants`, `accessory`,
`hair`).
- [ ] Choose the initial outfit scope: build the three full GLBs first; only use the 21-part
modular builder if the three looks cannot cover the 12 roles.
- [ ] Build a canonical `quaternius_base.glb`: one welded, triangulated, grounded 1.81 m
humanoid with front on Blender −Y, no animation, and a documented bone/part inventory.
- [x] Add `tools/npc_parts.py` with a small, documented CLI:
`extract` (pull the current head/hands for comparison), `build --part head|face|hand_l|hand_r`,
`assemble --variant <name>`, `inspect`, `compare` and `sheet`. It reuses the existing
builder helpers (`blender_assets.py` `_face`/`_hands_and_shoes`/`_shape_head_mesh`); no
second face/hand implementation. Verified end-to-end: built `head`/`face`/`hand_l`/`hand_r`,
extracted `hand_l` from the shipped GLB, assembled `npc_casual` (contract inspect: no issues).
- [x] Keep the part pipeline local-only and headless: flatpak Blender for authoring, stdlib/Pillow
for inspection and sheets. No Blender MCP dependency, no new runtime dependency, no CI
Blender step.
- [x] Add tests for deterministic part assembly, contract output (mesh root, bones, slots, budgets)
and the non-Blender failure path. `tools/tests/test_npc_parts.py` covers the part-name set,
the clean Blender-required error path, sheet/compare error paths and a real-PNG sheet. The
assembled prototype passes `inspect` (npc_base, 14 bones, skinned, no issues).
- [x] Consider optional Blender MCP for interactive part exploration and document setup/safety.
(`docs/asset-tooling.md#optional-interactive-blender-mcp` covers addon/client setup, Pi `pi mcp add`, flatpak networking,
viewport/`bpy` workflow and the rule that headless audit/fit remains authoritative; MCP is
not a build/CI/runtime dependency.)
- [x] Document the commands, working-set paths and "part source is not a shipped asset" rule in
`docs/asset-tooling.md`, `docs/blender-assets.md` and
`.agents/skills/gig-line-blender-asset-contract/references/verification.md`.
### 2. Contract bake and animation
### 3. Head and face prototype
- [ ] Author the 62-joint → 13-core joint map, including optional finger/face extras if
they survive within 24,000 vertices; record it in `docs/npc-model-sourcing.md`.
- [ ] Bake the rest pose and proportion warp to the contract hip, knee, shoulder, elbow,
wrist and head positions. Measure the warp at every joint and record the silhouette
deltas; do not accept a distorted deltoid or shortened arm.
- [ ] Skin the Quaternius mesh and verify Idle, Walk, seated and arm-down poses. The old
MPFB/arm-retarget warps are not a reference; judge the Quaternius result directly.
- [ ] Retarget Idle and Walk from the 24 Quaternius clips to the contract rig; discard
combat, gun and sword clips. Verify looping, foot contact and frame rate in Godot.
- [ ] Map the five slots, unwrap per slot, bake 256² AO/albedo/normal/ORM maps and check
texel density before any roster build.
- [x] Build one `npc_casual` head/face prototype as a connected head shell plus intentional feature
geometry — not a sphere with floating facial balls. Use loop-based eye sockets/lids, a
readable nose bridge/tip/ala, a mouth with upper/lower lip volumes, ears with concha depth,
and brow/cheek/jaw planes that survive the 256² AO bake.
Outcome (AI-judged, 2026-11-04): the displacement shell oscillated egg/spiky at ~3/5; the
judge picked the **decimated MakeHuman head**. That head is now built as `_makehuman_head`
(`build_character(head="mh")`, `npc_parts.py build --part head_mh`): committed CC0 source
`assets/models/blender_src/makehuman_head.glb` + project sclera/iris/lids/brows/mouth;
assembled `npc_casual` passes `inspect` (14 bones, no issues). Remaining polish: weld the
eye/brow pieces into the head shell and add a skull-conforming hair cap (owner-gated rollout).
- [x] Compare two or three subdivision/loop variants at 1.85 m front/three-quarter/profile and a
1.5 m portrait. Pick the variant that reads best before changing all 12 characters; keep the
rejected variants local.
- [x] Rebuild a standalone MakeHuman-derived head from the researched CC0 base and save it to
`assets/models/blender_src/makehuman_head.glb`; record provenance/review in
`docs/makehuman-head-review.md` and the preview sheet. Final build: 12,642 tris /
7,690 split verts, bounds x −0.094..0.094, y −0.180..0.042, z 1.530..1.803. The owner
accepted the **basic human head** on 2026-11-04; the automated vision gate still records
the eye-region REJECT as deferred polish (globe depth, lid overlap, iris at three-quarter).
The assembled path now adds a skull-conforming hair cap, a hidden-scalp trim and a narrowed
neck/shoulder body. Assembled `npc_casual --head mh`: 14,753 tris / 12,822 raw / 12,823
seam-split verts / 14 bones / 9 materials, `inspect` clean.
- [ ] Build true upper/lower eyelid masses that overlap the globe in front, three-quarter and
profile views (not a socket hole), then re-run the vision gate. Deferred: the owner accepted
the basic head, so this is polish, not a rollout blocker.
### 3. Silhouette gate
Compared `head_proto` at seg 24 (670 verts), 48 (1,558 verts) and 64 (2,470 verts) at 1.85 m
and 1.5 m, front/three-quarter/profile. Vision-judged: **s48 wins** — s24 is too faceted
(nose/lips melt, jagged silhouette), s64 is visually identical to s48 at both distances
(extra ~900 verts wasted). Rejected variants stay in `tmp/npc-parts/`.
- [-] Verify head weights stay on the Head bone, headgear clearance still passes `fit`, and the
face does not bake recessed creases into dark AO patches.
Weight check done: `npc_parts.py assemble --head-proto` passes `inspect` (npc_base, 14 bones,
skinned, no issues) and the head join is weighted 100% Head by construction
(`rigid=lambda p: "Head"`). Headgear clearance and the AO no-blotch check are pending the
§5 rollout (the `fit`/`bake_ao` tools read the committed assets; the ad-hoc AO bake on the
imported GLB came out black and is superseded by the proper `.blend`-source bake). Flag: the
prototype ears reach x ±0.162 vs the 0.1575 head-radius reference, so headgear may clip and
must be re-measured at rollout.
- [-] Owner review of the assembled one-variant prototype (`npc_casual --head mh`) before the
12 shipped GLBs change. The basic human head is accepted (2026-11-04); the review now covers
the skull-conforming hair cap and the narrowed neck/shoulder body silhouette. Local renders:
`tmp/npc-parts/prototype_mh/renders/` (portrait front/three-quarter/profile + full body).
Rollout starts only after this review.
- [ ] Render the base at 1.5 m and 1.85 m in front, three-quarter and profile; compare
against the Quaternius source and the current `npc_casual`. Use the vision judge for a
written verdict, but the owner decides.
- [ ] Confirm gear attach points (head, hand, back, chest) and test cap, helmet, backpack,
shoulder bag, lanyard, clipboard and firefighter tank against the new shoulders/hips.
- [ ] Go/no-go: if the warp fails the silhouette gate, stop and write the 62-joint runtime
ADR (Stage 2). Do not start the 12-variant rebuild.
### 4. Hands and grip prototype
### 4. Roster and rollout
- [x] Build separate left/right hand parts with a connected palm, four multi-segment fingers, a
thumb, knuckles and rounded tips. Support an open palm and a relaxed grip; preserve the
current `HAND_ITEM_FORWARD` behaviour for phone/cup/clipboard/camera/flashlight/wand/radio.
`npc_parts.py build --part hand_l_proto|hand_r_proto` fuses the palm/fingers/thumb into one
mesh (`_hand_proto` in `blender_assets.py`, remove-doubles at 6 mm). Vision-judged at 0.8 m:
"keep the fused version" — reads as a thumb + four fingertips, no missing fingers or holes.
Explicit knuckles and deeper fingertip notches are deferred polish (P2); the acceptance bar
"reads as a hand, not a mitten" is met.
- [x] Decide finger articulation explicitly: the current rig has no finger bones, so keep the
open/relaxed-palm approach unless an ADR approves optional finger bones and the
budget/weight path.
Decided 2026-11-04: keep the open palm + `HAND_ITEM_FORWARD` (no finger bones). Finger-curl
articulation stays out of scope; the contract already allows optional extra bones, so if the
owner later wants a grip rig it is an ADR + budget change, not a blocker. (Recorded in
`MEMORY.md`; re-confirmed here.)
- [-] Verify all hand gear at 0.8 m (contact, clipping, direction) and capture open/grip hand
close-ups for the review sheet.
Open close-up captured (0.8 m). Gear contact is unchanged by construction: `_hand_proto`
reuses the same palm geometry and the same `HAND_ITEM_FORWARD`/Hand-proxy attach, so the
existing `fit` hand-gear clearances carry over. The grip close-up + gear-in-hand context
needs the §5 assembly (hand_proto swapped into the character), so it is verified there.
- [ ] Roll the approved hands into all 12 variants only after the one-variant hand sheet passes.
- [ ] Map the 12 roles to Quaternius outfits/parts, build them in asset-family batches,
and keep every variant inside the 24,000/24,000 cap.
- [ ] Run `audit`, `fit`, `inspect`, `texels` and `npc_proportions.py report`; record the
12-variant table and the warp measurements.
- [ ] Re-run the 24-NPC budget smoke and the Web/Compatibility capture; record frame time
before and after the base swap.
- [ ] Capture the 12 × 6 baseline (`capture_npc_baseline.gd` → `npc_baseline.py sheet`) and
get owner approval before replacing the committed character GLBs.
- [ ] Rebuild AO maps, manifest entries, credits and review docs; commit one asset family per
change and never run a no-op full-library rebuild.
### 5. Assembly and rollout
### 5. Retire the old character tracks
**MakeHuman 12-variant rollout.** - [x] Make the head source selectable from the main builder:
`blender_assets.py build --head mh --only npc_casual,...` and
`npc_parts.py assemble --variant <name> --head mh --out <stem>`. The default stays `face`
until the hair/body review passes.
- [x] Verify every variant assembles with the MakeHuman head inside the 16,000/16,000 cap
(pre-export triangle counts, `inspect` clean; `npc_casual` seam-split verts 12,823):
`npc_casual 14,753`, `npc_jacket 15,153`, `npc_coat 15,817`, `npc_vest 15,579`,
`npc_dress 15,215`, `npc_hoodie 15,837`, `npc_firefighter 15,987`, `npc_guard 15,729`,
`npc_crowd_a 14,947`, `npc_crowd_b 14,693`, `npc_crowd_c 15,433`, `npc_crowd_d 15,833`.
- [x] Recover head budget without touching the accepted face: remove head faces fully covered by
the hair cap, keep boundary faces as a safety band, and trim the hidden neck plug to 12
segments. This saves ~950 tris on every variant.
- [ ] Owner approves the hair cap and full-body silhouette on the local `npc_casual` prototype.
**Status (2026-11-04):** the current body candidate is the MPFB full-body prototype below,
not the narrowed procedural body; the 12-variant rebuild is blocked on that review.
- [ ] Rebuild the 12 committed character GLBs with `--head mh`, in asset-family batches, then
regenerate their AO maps and manifest entries. Never run a no-op full-library rebuild.
- [ ] Run `blender_assets.py audit`, `fit`, `inspect` and `texels`, plus
`python3 tools/npc_proportions.py report`; record the 12-variant proportion table.
- [ ] Re-run the Godot NPC tests and capture the 12 × 6 baseline
(`src/test/capture_npc_baseline.gd` → `python3 tools/npc_baseline.py sheet`); inspect the
sheet for outliers before committing.
- [ ] Update `docs/makehuman-head-review.md`, `docs/3d-model-review.md`,
`docs/blender_previews/README.md`, `docs/npc-model-sourcing.md`, `CREDITS.md` and
`docs/development-status.md` with the accepted head/hair/body state and final counts.
- [ ] Integrate the approved parts into `build_character` with deterministic joins, weights, UVs and
AO. The final output remains one `npc_base` skinned mesh under the existing 13-core armature;
optional extra bones are allowed but the core rest positions stay fixed;
no second rig, no material-slot rename.
- [ ] Keep the MakeHuman body prototype consumable with the same approved head/hands; do not let it
grow a second face/hand implementation while the part pipeline is being proven.
- [ ] Rebuild only the changed character GLBs, AO maps and manifest entries; never run a no-op full
library rebuild. Commit one asset family per change.
- [ ] Re-run `blender_assets.py audit`/`fit`/`inspect`, `npc_proportions.py`, the 24-NPC budget,
Godot and Python tests, the 48-frame baseline and the 96-frame final-context review.
### Full-body MPFB prototype
Goal: assemble the accepted MakeHuman head onto a CC0 MPFB body with project hands, shoes and
14-bone contract rig, inside the 24,000/24,000 character budget. Local development only until the
owner reviews the silhouette and a production integration decision is recorded.
- [x] Build the dev pipeline at `tmp/npc-research/build_mpfb_npc.py`: create a macro-driven MPFB
human, bake targets, add the `game_engine` rig, capture arm points/weights, remove the rig,
apply the helper MASK, scale to 1.81 m, retarget the A-pose arms to the contract wrist
(`x=±0.27`, `z=0.78`), cut the neck at 1.505, decimate, bisect the clothing boundaries, paint
the five slots, add a short neck flare, project hands, rounded shoe shells, cuffs, the
accepted head and the 14-bone armature. Current output: **19,747 tris / 16,851 glTF verts /
1.810 m / 14 bones / 10 materials**; `inspect` clean, feet grounded.
The torso is inflated radially by 12% through z 0.72–1.40 (tapering out at the collar) so the
shirt reads as fabric rather than body paint.
- [x] Raise the character contract to 24,000 triangles / 24,000 glTF vertices so the MPFB body,
the accepted head and a fused neck can coexist with headroom for the 12-variant clothing.
Bumped `CHAR_MAX_TRIS`/`CHAR_MAX_VERTS`, `npc_pipeline.MAX_TRIANGLES`/`MAX_VERTICES`,
the adapt defaults, the tests, `AGENTS.md`, ADR-0016 and the project skills.
- [-] Fix the head/neck/shoulder junction so there are no gaps, square collars or hard rims.
Done: circular boolean bore, smooth lathe, accepted head trimmed at its narrow neck (1.55),
no dark notches or wide brim; prototype at 19,747 tris. Remaining: a thin jaw crease and a
hard shirt-shoulder point in three-quarter view. Next candidate: reshape the shirt shoulder
or a shaped collar that follows the neckline, not a torus or flat disk.
- [x] Replace the spiky decimated MPFB hands with the project palm/finger primitives, straighten the
splayed MPFB feet so the shoes point forward, and use rounded shoe shells + cuffs instead of
flat blocks. Use flat slot colours in the prototype because the one-shot MPFB UV unwrap does
not match the per-slot NPC atlases.
- [x] Fix the neck junction without touching the accepted face: cut the decimated neck column
radially (all-vertex test inside r=0.085) so the shirt shoulder silhouette stays intact,
then bridge the opening with a smooth four-ring lathe neck (r 0.100 → 0.056, 20 segments).
The lower rings are painted cloth so the opening reads as a crew neck rather than bare
chest. No torus, disk shelf, neck brace or sawtooth collar.
- [x] Reject destructive vertex smoothing at the neck: a `smooth_vert` pass moved the open body
boundary away from the neck cone, opening a dark hole. The lathe gives smooth shading
without moving the collar boundary.
- [x] Shrink the shoes and seat the ankles: shoe shell 0.12 × 0.30 × 0.11 m, an inset 0.111 ×
0.286 m black sole, a tongue and shoe centre x=0.17, with a 0.08 m pant cuff (r 0.055/0.061)
bridging leg and shoe. The sleeve cuffs now use the `cloth` slot and the `accessory` slot is
carried by the sole, so the cuffs read as sleeve ends instead of metal bands.
- [x] Replace the bulbous toe/heel spheres with a single bevelled shoe shell (bevel 0.032, 2
segments) plus tongue and inset sole, and add one light smoothing pass to the closed
thigh/hip region. Protruding flat sole plates read as skates or bricks; laces were dropped
for triangle budget after they proved too small to read.
- [x] Reject the untucked shirt-hem band: both the 0.09 m and 0.12 m cloth cylinders read as a
hanging white flap at the crotch. The V hem needs a proper clothing shell, not a band.
- [x] Fix the neck material rule: the `radius < 0.08` skin test had no Z floor, so it painted a
skin patch at the crotch. It is now guarded to `z > 1.35`; the crotch stays pants.
- [x] Reject three cheap hem fixes: lowering the shirt to z 0.80 turns it into a unitard; tilting
the hem up at the front reads as high-cut swimwear; a 13% hem flare reads as a peplum.
The remaining V is the dark crotch hollow under a body-painted shirt, not a slot bug.
- [ ] Owner reviews the updated MPFB body renders (`tmp/npc-parts/mpfb_proto/renders84/`).
Remaining known defects: the crotch hollow still reads as a V under the shirt hem, the
shirt is only partly loosened by the 12% torso inflation, and the 2k-tri body budget leaves
some angular thigh facets. A separate loose shirt shell is the proper fix for the first
two; these are polish, not blockers for the body direction.
- [ ] Build a proper loose shirt shell instead of body-painted cloth. The quick open, flared
solidified tube (0.150→0.196 m, z 1.05→0.80, 24 segments, ~288 tris) read as a hanging
apron/tabard and was rejected. The shell needs a shaped torso, armholes and a curved hem,
not a tube. It must fit in the 683 spare triangles or come with a head/body rebalance.
- [ ] Rebalance the triangle budget before rollout: 683 spare is below the ~1,200 the firefighter
and hoodie variants need. Protect the head budget first; do not lower the accepted face.
- [ ] Fix the low-budget seams before any rollout: weld the torso/hip/arm components after the
bisects, protect the hip/knee loops during decimation (or rebalance head/body triangles).
- [ ] Record the production integration decision: either bake the approved MPFB body to a committed
source GLB (CI and fresh checkouts stay MPFB-free) or keep the procedural body as the shipped
path. Do not add the MPFB extension as a build/CI dependency.
- [ ] If approved, roll the MPFB body into the 12 variants and regenerate AO maps, manifest entries,
`inspect`/`fit`/`audit`/`texels`, the proportion report and the 12 × 6 baseline.
### 6. QA, docs and exit
- [ ] Capture front/three-quarter/profile head comparisons and open/grip hand comparisons; add
durable sheets to `docs/blender_previews/` and link them from the review docs.
- [ ] Update `docs/3d-model-review.md`, `docs/npc-visual-review.md`,
`docs/known-limitations.md`, `MEMORY.md` and the project skills with the accepted limits and
the new part workflow.
- [ ] Exit: head/face and hands are approved on one prototype, rolled out across all 12 variants,
all contract/budget/capture gates pass, the local part pipeline is documented, and no
runtime dependency or skeleton contract changed.
- [x] Remove the MPFB/MakeHuman development scripts, renders and review directories from
`tmp/` (done 2026-11-05). Keep only the Quaternius source pack and its licence notes.
- [x] Keep the committed `makehuman_head.glb` and the procedural `npc_base` only as tested
fallbacks until the Quaternius rollout is complete; do not add new MPFB work.
- [ ] Update `docs/development-status.md`, `CHANGELOG.md` and `CREDITS.md` when the new base
ships. MPFB must never become a CI, build or runtime dependency.
## Fix the Rig pose harness
Goal: `src/test/capture_npc_pose.gd` reports a pose but saves rest frames; the root cause is
narrowed to the skinned mesh ignoring its `Rig` parent transform. Fixing it unblocks the
weights/pose column of the 3D review and the pose/portrait evidence for the MakeHuman intake.
weights/pose column of the 3D review; the evidence now feeds the Quaternius base bake.
*Skill route: `rigging`; evidence in `docs/3d-model-review.md` §"Pose evidence is blocked".*
@@ -295,52 +119,6 @@ weights/pose column of the 3D review and the pose/portrait evidence for the Make
(No separate "wave" theater pose exists; the escalation raise-hand gesture is not a distinct
capture in this harness.)
## MakeHuman character pipeline
Goal: replace the procedural body generator with the CC0 MakeHuman base for the next character
pass — retopologised, rigged and dressed in project-owned clothing — so bodies read more
realistic than the current primitive shapes. This promotes the deferred MakeHuman evaluation to
an active track; ADR-0015 (CC0 / CC-BY with attribution) still governs every intake.
*Skill route: `retopology`, `rigging`, `uv-workflow`, `materials`, `character-artist`,
`asset-optimization`, `godot-export`, `qa-review`.*
### Intake and adaptation
- [x] `adapt` path added to `tools/blender_assets.py` (`adapt --file <in> --out <out>
[--target-tris 24000]`): imports the GLB, applies transforms, grounds the feet, welds seam
splits and decimates to the budget, then exports. The five tint slots + 13-core rig
(optional extra bones allowed) stay a manual step (recorded in the command doc).
- [x] `audit` stays the final gate; `test_adapt_requires_blender` covers the non-Blender error
path (162/162 Python).
- [x] Adapter commands + go/no-go documented in `docs/asset-tooling.md` §Intake adaptation.
### MPFB / MakeHuman body pipeline
- [x] Prototype the local pipeline: `tmp/npc-research/makehuman_intake.py` imports the CC0
`base.obj`, scales to 1.82 m, grounds the feet, triangulates, decimates and exports
`tmp/npc-research/makehuman/makehuman_body.glb` — 3,790 verts / 6,444 tris, bounds
x ±0.53 / y 0–1.82 / z −0.12…+0.35, one neutral material, UVs present, unskinned. The
body (no rig) is the input for the rigging step; the script + mesh stay in `tmp/` (CC0, not
committed).
- [x] Rig strategy decided (owner): **retarget the body to the 13-core contract; optional extra bones are allowed**.
`tmp/npc-research/makehuman_retarget.py` rotates the A-pose arms down (−38°/+38°), scales the
arms 1.63× to the contract 0.70 m length, welds the split vertices, smooth-shades, adds the
contract armature + `_auto_weights`, paints the five slot regions (hair/cloth/pants/accessory/
skin) and exports `makehuman_retargeted.glb`. **Contract passes:** 6,444 / 16,000 tris,
7,726 / 16,000 verts, 14 bones (13 + Hips), skinned, arm-down, grounded, five slots, no issues.
Vision-reviewed: arms hang down and the silhouette + slot regions read, but the 1.63× arm warp
distorts the deltoid/shoulder (spiky/warped), the decimated hands are blocky, and the slot
boundaries are rough — these are the refinement steps below.
- [x] Head/hands/feet swap (`makehuman_final.py`): cut the decimated MakeHuman head/hands/feet and
joined the project's `_face`/`_hair`/`_hands_and_shoes`, then re-weighted/re-UV'd. Contract
passes: 6,407 / 16,000 tris, 6,651 / 16,000 verts, 14 bones, skinned, five slots, no issues.
Vision-reviewed: the head now reads as a realistic face, the hands as detailed fingers and
the shoes as attached. Remaining (manual retopology): a 1.63× arm-scale warp still distorts
the deltoid/shoulder, stray hand blobs linger at the hips, shirt/shirt seams are rough, and
the head-neck junction has a shadow gap. The procedural generator stays the shipped fallback
until these are cleaned in an editor session.
## 3D model and local map re-evaluation
Goal: re-judge every shipped 3D asset against the newly available Blender skill guidance, rank
@@ -356,7 +134,7 @@ rebuilds and the face/foliage prototypes) stay **blocked** until the full local
(H–M) is done **and** a fresh 3D model review runs against the new maps. The measurements and
scorecard in `docs/3d-model-review.md` stand as the pre-rebuild baseline, not a go-ahead to start
character work now. (Character development has since shipped — see `DONE.md` — and the next
character pass is the MakeHuman pipeline above.)
character pass is the Quaternius base above.)
**Map rebuild status (2026-11-03):** H–M are complete — the Joke Shop is now a 6.0 m low hall
(dark stucco, white signature fascia, tied-back curtains, hotel tower) and Hollywood/TV Studio
@@ -966,7 +744,7 @@ published while the gates below remain open.
| Area | Remaining gap | Milestone |
| --- | --- | --- |
| 3D model and local map re-evaluation | Skill-guided asset scorecard/repairs; OSM/3D data, reference-derived facades, AI-assisted composition and map QA | Unversioned |
| Character development | Complete (moved to `DONE.md`); the MakeHuman body pipeline is the next character pass | 0.11.0 |
| Character development | Complete (moved to `DONE.md`); the Quaternius NPC base migration is the next character pass | 0.10.0 |
| Content and balance | External first-time-player evidence, balance sweeps/tuning and content lock | 0.10.0 |
| Audio, accessibility and localization | Accessibility/localization acceptance, caption coverage and pseudo-locale/layout sign-off | 0.10.0 |
| Performance and platform | Target-hardware matrix, Web/Desktop HQ profiling and frame/memory evidence | 0.10.0 |
@@ -979,15 +757,15 @@ The 0.9.3 UI, 0.9.4 animation, 0.9.5 texture, 0.9.6 integration and save-migrati
complete in `DONE.md`; they are not remaining gaps. The 2026-11-01 documentation audit
(architecture ownership, stale-claim cleanup and obsolete-plan removal) is also closed.
**Priority (2026-11-04):** fix the `Rig` pose harness, then the MakeHuman character pipeline,
then re-evaluate the 3D models, then ship the **0.11.0** minor release. The 0.10.0 candidate
**Priority (2026-11-05):** finish the `Rig` pose harness, then the Quaternius NPC base
migration, then re-evaluate the 3D models, then ship the **0.10.0** minor release. The 0.10.0 candidate
still accepts only release-blocking fixes until its external-playtest, legal/storefront, signing
and platform gates clear.
## Milestone 0.10.0 — 3D model and map improvements (minor)
Goal: ship all 3D model and map improvements together as the **0.10.0 minor** — the MakeHuman
body retarget (contract armature + project head/hands), the rebuilt Comedy Store/Hollywood maps,
Goal: ship all 3D model and map improvements together as the **0.10.0 minor** — the Quaternius
NPC base bake (contract armature + five slots), the rebuilt Comedy Store/Hollywood maps,
and the re-evaluated 3D scorecard — plus the external playtest, legal/storefront, signing and
platform gates from the old release candidate. The character-development patch (0.9.7) ships
first; this minor contains the model/map work.
@@ -1157,8 +935,8 @@ variants, the four crowd-variety characters and the per-role pools — as a **pa
launches headless. Tagged `v0.9.7` (CI build/publish follows).
**Exit:** met — 0.9.7 ships the 12-character library (face realism + crowd variety) with the pose
harness fixed; the runtime contract is unchanged. The MakeHuman body and the map rebuild are not
in this patch (they target 0.10.0).
harness fixed; the runtime contract is unchanged. The Quaternius NPC base and the map rebuild are
not in this patch (they target 0.10.0).
## Roadmap dependencies and risks
+8 -6
View File
@@ -85,10 +85,12 @@ Readings:
## Baseline inventory (2026-11-04)
Recorded for the Blender NPC model overhaul track: the exact starting point before the local
part pipeline is built. `npc_base.blend` is the frozen fallback; the 12 characters are assembled
procedurally by `tools/blender_assets.py`; the MakeHuman prototypes live under `tmp/npc-research/`
and are not the shipped path.
Recorded for the character baseline before the Quaternius migration. `npc_base.blend` is the
frozen fallback; the 12 characters are currently assembled procedurally by
`tools/blender_assets.py`. The active plan is now the CC0 Quaternius base bake
([ADR-0017](adr/0017-quaternius-npc-base.md)); this section and the MakeHuman notes below are the
pre-migration record. The MPFB/MakeHuman development files were removed from `tmp/` after the
2026-11-05 pivot.
### `assets/models/npc/npc_base.blend` (frozen fallback)
@@ -143,7 +145,7 @@ width scale.
287–440 px/m via the 4× repeat; runtime tint carries the look. This is a recorded note until a
portrait shows texture starvation.
### MakeHuman prototypes (not shipped; `tmp/npc-research/makehuman/`)
### MakeHuman prototypes (historical, not shipped; research files removed from `tmp/`)
| File | Verts / tris | Bones | Slots | Note |
| --- | ---: | ---: | --- | --- |
@@ -242,7 +244,7 @@ nose/lip/chin relief cleanly.
The judge then compared the displacement head against the **decimated MakeHuman head**
(extracted from `makehuman_retargeted.glb`, 2,009 verts / 1,573 tris, saved as
`tmp/npc-parts/makehuman_head.glb`) and returned a decisive result: **ship the MakeHuman head** —
the local `makehuman_head.glb`) and returned a decisive result: **ship the MakeHuman head** —
it keeps the nose/chin/jaw landmarks at a fraction of the cost, while the procedural head's
"clean ellipse outline instantly screams procedural sphere".
+3 -3
View File
@@ -4,8 +4,8 @@ This folder holds the project documentation, visual references and generated QA
## Current priorities
1. [Blender NPC model overhaul](../TODO.md#blender-npc-model-overhaul-top-priority) — part-based head/face/hands pipeline and 24,000-budget contract.
2. [MakeHuman and 3D model/map improvements](../TODO.md#makehuman-character-pipeline) — body intake, asset re-evaluation and local map reconstruction.
1. [Quaternius NPC base migration](../TODO.md#quaternius-npc-base-migration-top-priority) — CC0 Quaternius mesh/animation source baked to the 24,000-budget runtime contract.
2. [3D model and local map improvements](../TODO.md#3d-model-and-local-map-re-evaluation) — asset re-evaluation and local map reconstruction.
3. [0.10.0 release candidate](../TODO.md#milestone-0100--3d-model-and-map-improvements-minor) — versioned release hardening after the unversioned development tracks.
## Start here
@@ -13,7 +13,7 @@ This folder holds the project documentation, visual references and generated QA
- [`../PLAN.md`](../PLAN.md) — product, design intent and development priorities
- [`../TODO.md`](../TODO.md) — priority-ordered active tasks and roadmap
- [`npc-model-sourcing.md`](npc-model-sourcing.md) — character-source evaluation, licence rules and the character-development plan
- [`makehuman-head-review.md`](makehuman-head-review.md) — local MakeHuman head prototype, provenance and review verdict
- [`makehuman-head-review.md`](makehuman-head-review.md) — retained MakeHuman fallback head, provenance and review verdict
- [`architecture.md`](architecture.md) — arc42 system architecture
- [`getting-started.md`](getting-started.md) — setup, run/test commands and controls
- [`asset-tooling.md`](asset-tooling.md) — image/model pipelines and screenshot gates
+7 -1
View File
@@ -1,8 +1,14 @@
# ADR-0015: NPC model variety sourcing
- **Status:** Accepted (planning)
- **Status:** Superseded by [ADR-0017](0017-quaternius-npc-base.md) (2026-11-05)
- **Date:** 2026-11-03
## Superseded
ADR-0017 replaces the generator-first decision below: Quaternius is now the
primary NPC base. The evaluation, licence rules and consequences remain as the
record of the 2026-11-03 decision.
## Context
The library has eight skinned characters, and role/seed selection reuses them
+69
View File
@@ -0,0 +1,69 @@
# ADR-0017: Quaternius NPC base
- **Status:** Accepted
- **Date:** 2026-11-05
- **Supersedes:** ADR-0015 (generator-first character sourcing)
## Context
The current NPC library is built by the project-owned procedural generator. It
keeps the contract and ships, but the body, neck, hands and shoes need a
bespoke part pipeline to read as human. The MakeHuman head and MPFB body
prototypes improved detail but added a second authoring path, a 19,747-triangle
prototype and unresolved neck/shoulder seams.
The CC0 **Quaternius Ultimate Modular Characters** pack already provides a
coherent low-poly human silhouette, 21 modular outfits and 24 animation clips.
The researched GLBs (`Casual`, `Casual_Hoodie`, `Worker`) measure 4 meshes, 62
joints and 24 clips each. The owner directed that Quaternius become the NPC
base. The full evaluation is in [`docs/npc-model-sourcing.md`](../npc-model-sourcing.md).
## Decision
1. **Quaternius is the primary NPC mesh and animation source.** Keep the
licence and SHA-256 provenance for the three researched GLBs.
2. **Stage 1 keeps the runtime contract.** Bake a canonical Quaternius base onto
the existing 13-core contract, five tint slots, 24,000/24,000 budget,
grounded −Y front and one `npc_base` skinned mesh. Retarget Idle and Walk;
discard the combat/gun/sword clips. `NpcAvatar`, gear attach points and the
pose composition remain the runtime interface.
3. **The 62-joint rig is an authoring source, not a runtime dependency.** It is
not shipped and Quaternius is not loaded by CI, build or runtime.
4. **Stage 2 needs its own ADR.** If the proportion warp fails the silhouette,
deformation or gear gate, stop and decide whether to adopt the 62-joint rig
at runtime. Do not ship a hybrid rig or a second gear offset system.
5. **Close the MakeHuman/MPFB body work.** The accepted MakeHuman head and the
procedural `npc_base` stay as tested fallbacks until the Quaternius rollout
ships. No new MPFB development.
6. **Commit baked assets only.** The release consumes committed GLBs, maps and
the manifest; Quaternius and Blender remain development tools.
## Consequences
### Positive
- A human base, modular outfits and a coherent animation set are already
authored and CC0.
- The bespoke neck, hand and shoe pipelines are no longer on the critical path.
- The runtime contract and gear stay stable during the mesh migration.
### Negative
- A 62-joint T-pose does not share the arm-down 13-core rest pose or
proportions; the proportion warp is the main risk.
- Quaternius' animation quality is only available after retargeting, unless
Stage 2 is accepted.
- The migration touches all 12 variants, their AO maps, manifest entries and
baseline captures at once.
## Alternatives
- **Keep the procedural generator as the primary path.** Rejected by the owner:
the human silhouette remains the weak point and the bespoke part pipeline is
larger than the Quaternius bake.
- **Adopt the 62-joint rig immediately.** Deferred to Stage 2 because it changes
`NpcAvatar`, pose composition and gear offsets at the same time as the mesh.
- **Continue the MPFB body.** Rejected: it needs a separate head/neck/hand
pipeline and still has unresolved surface seams.
- **Use a service character generator (Mixamo, Ready Player Me).** Rejected:
redistribution and runtime terms are not a CC0 basis.
+1
View File
@@ -20,3 +20,4 @@ Each ADR records the context, decision, consequences and alternatives for a dura
- [0014-runtime-image-root](0014-runtime-image-root.md)
- [0015-npc-model-variety-sourcing](0015-npc-model-variety-sourcing.md)
- [0016-npc-character-budget-24k](0016-npc-character-budget-24k.md)
- [0017-quaternius-npc-base](0017-quaternius-npc-base.md)
+10 -9
View File
@@ -81,7 +81,7 @@ The player interacts with NPCs, venue entrances, access artifacts, equipment, st
- `WorldBuilder` assembles the procedural venue from a per-venue `VENUE_SPECS` table (facade, windows, stairs, street, nav bounds, guard spawn, feature flags and prop placements), prefers the Blender prop library in `assets/models/blender/props/`, and falls back to `assets/models/generated/` or primitives. `GameManager` rebuilds only the `World` container when the venue changes, so the guard/UI and their state survive. It also wires the phase-driven library emissives and street dressing.
- `src/game/ui/art.gd` loads runtime UI/scene art from `assets/images/ui/` and `assets/images/scenes/`, with null fallbacks so panels keep their procedural layouts.
- `tools/model_pipeline.py` builds and audits the street-prop `.glb` models and packs their colour atlases.
- `tools/npc_pipeline.py` builds and audits the skinned NPC base model (`assets/models/generated/npc_base.glb`) and its per-slot material maps, with an optional AI fabric override (ADR-0013).
- `tools/npc_pipeline.py` builds and audits the skinned NPC base model (`assets/models/generated/npc_base.glb`) and its per-slot material maps, with an optional AI fabric override (ADR-0013). The active character migration bakes the CC0 Quaternius base onto the same contract (ADR-0017); the procedural base remains the fallback.
- `tools/blender_assets.py` builds, renders and audits the Blender asset library (`assets/models/blender/{npc,npc_gear,props}/` + `manifest.json`): NPC character variants that are drop-in for `npc_base`, attach-point gear, and street/venue props. `NpcAvatar` selects variants/gear by role/seed and `WorldBuilder` loads the prop replacements and new street dressing, with procedural fallbacks (see `docs/blender-assets.md`).
- `tools/scene_concepts.py` generates realism-pass references (`docs/screens/concepts/`), skyline backdrops and surface tiles (raw `assets/textures/ai/v2/raw/` → candidates `assets/textures/ai/game_ready/v2/`), promotes the validated ones to the tracked `v2/picks/` that `SurfaceMaterials`/`WorldBuilder` preload, audits them, and scores `src/test/capture_realism.gd` A/B captures (six stages, runtime texture swaps) against the concepts (`docs/screens/realism/<run>/`).
- `tools/asset_pipeline.py` generates and audits role-aware textures; `tools/screen_designs.py` generates screen references and judges captures; `tools/check_screenshots.sh` renders the staged gallery and runs the compare gate.
@@ -206,14 +206,14 @@ transient input state.
### Character development tooling
Characters have two authored sources and one procedural fallback. The eight-variant
Blender library (`assets/models/blender/npc/`) is the normal presentation path; the
older skinned `npc_base` (`assets/models/generated/npc_base.glb`) remains a frozen
contract and fallback; `NpcAvatar`'s procedural rig is the offline last resort.
Four crowd-variety prototypes have been built and audited locally but are not yet in
the shipped catalogue; generator-first expansion is the active character track
(ADR-0015). Blender is a developer tool only — runtime, tests and CI consume committed
GLBs and maps.
Characters have one active migration, two committed fallbacks and one procedural last
resort. The Quaternius base migration (ADR-0017) bakes the CC0 Quaternius mesh and
Idle/Walk clips onto the existing 13-core contract and produces the next 12-variant
library. Until that ships, the 12-variant Blender library
(`assets/models/blender/npc/`) is the normal presentation path, the older skinned
`npc_base` (`assets/models/generated/npc_base.glb`) is the frozen contract fallback,
and `NpcAvatar`'s procedural rig is the offline last resort. Blender and Quaternius are
developer tools only — runtime, tests and CI consume committed GLBs and maps.
| Tool | Role | Committed artifact | Verification gate |
| --- | --- | --- | --- |
@@ -388,6 +388,7 @@ Architecture decisions are recorded as ADRs:
- [ADR-0008: Cone focus and focus circle](adr/0008-cone-focus-and-head-ring.md)
- [ADR-0009: Radial action menu](adr/0009-radial-action-menu.md)
- [ADR-0010: Procedural NPC presentation](adr/0010-procedural-npc-presentation.md)
- [ADR-0017: Quaternius NPC base](adr/0017-quaternius-npc-base.md)
- [ADR-0011: Aim-free selection and precision walk](adr/0011-aim-free-selection-and-precision-walk.md)
- [ADR-0012: Surface materials and generated props](adr/0012-surface-materials-and-generated-props.md)
- [ADR-0013: Blender-authored NPC characters and baked materials](adr/0013-blender-authored-npc-characters.md)
+14 -12
View File
@@ -82,6 +82,8 @@ tonemapping, glow, fog, colour grading) that the phase lighting applies.
NPCs are moving from the procedural capsule rig to a skinned, UV-mapped base
character authored in Blender ([ADR-0013](adr/0013-blender-authored-npc-characters.md)).
The active base is the CC0 Quaternius modular character, baked to the runtime contract
([ADR-0017](adr/0017-quaternius-npc-base.md)).
`tools/npc_pipeline.py` builds `assets/models/generated/npc_base.glb` plus the
per-slot material maps. `NpcAvatar` instantiates that skinned model, tints its
five material slots from the seed-driven outfit, and drives the bones from the
@@ -129,10 +131,10 @@ with colliders/avoidance and drives their emissive parts from the day/night
cycle. The single `npc_base.glb` and primitive props remain offline fallbacks.
Contract and integration notes: [`blender-assets.md`](blender-assets.md).
Sourcing and expansion research (no external model is shipped yet):
[`npc-model-sourcing.md`](npc-model-sourcing.md) compares Quaternius, Kenney, Khronos and
MakeHuman sources against the character contract and records the 2026-11-03 direction
(procedural generator first, Quaternius reference, MakeHuman deferred).
Sourcing and migration plan: [`npc-model-sourcing.md`](npc-model-sourcing.md) records the
2026-11-05 direction (ADR-0017). Quaternius Ultimate Modular (CC0) is the primary NPC mesh
and animation source, baked to the existing 13-core contract; the procedural generator is
the fallback. Kenney/Khronos/MakeHuman remain evaluated references, not active bases.
| Characters | Props |
| --- | --- |
@@ -146,7 +148,7 @@ python3 tools/blender_assets.py sheet # docs/blender_previews/sheet_*.jpg
python3 tools/blender_assets.py audit # no Blender needed
python3 tools/blender_assets.py fit # gear-vs-body fit report
python3 tools/blender_assets.py texels # per-slot texel density (px/m) of the characters
# `build --head mh` selects the MakeHuman head; the default stays `face` until rollout.
# `build --head mh` selects the retained MakeHuman fallback head; the default is still `face`.
godot --headless --path . --import
```
@@ -188,9 +190,9 @@ Caveats:
### Intake adaptation (`adapt`)
`adapt` is the mechanical first half of an external-mesh intake (MakeHuman,
MPFB, downloaded GLB): import, apply transforms, ground the feet, weld seam
splits, decimate to the character budget, and export a GLB. It does **not** map
`adapt` is the mechanical first half of an external-mesh intake (Quaternius,
MakeHuman fallback, downloaded GLB): import, apply transforms, ground the feet,
weld seam splits, decimate to the character budget, and export a GLB. It does **not** map
the five tint slots or rebuild the 13-core-bone `npc_base` armature (optional extra bones are allowed) — those stay a
manual `retopology`/`rigging` step with a recorded second-rig contract if the
source rig cannot be retargeted:
@@ -198,14 +200,14 @@ source rig cannot be retargeted:
```bash
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- adapt \
--file "$PWD/tmp/npc-research/makehuman_base.glb" \
--out "$PWD/tmp/npc-research/makehuman_adapted.glb" \
--file "$PWD/tmp/npc-research/quaternius/Casual.glb" \
--out "$PWD/tmp/npc-research/quaternius_adapted.glb" \
--target-tris 24000
# prints: adapted makehuman_adapted.glb: 36972 -> 24000 tris (bones=N, meshes=1)
# prints: adapted quaternius_adapted.glb: <source> -> 24000 tris (bones=N, meshes=1)
```
Run `inspect` on the adapted GLB before and after, and keep the procedural
generator as the fallback until a MakeHuman variant passes `audit`/`fit` and the
generator as the fallback until a Quaternius variant passes `audit`/`fit` and the
24-NPC budget.
- Numbers are Blender-side measurements. Triangles match `audit` on project assets; the seam-split
vertex count can differ by ±1 because the importer rounds normals. `audit` stays the single final
+7 -3
View File
@@ -3,7 +3,10 @@
Architecture context: the asset contracts and fallback path are summarized in
[`architecture.md`](architecture.md#content-and-asset-pipeline-architecture).
Status: built, audited, and integrated (2026-11-01). `NpcAvatar` selects the
Status: built, audited, and integrated (2026-11-01). The active character migration
replaces the procedural body with a baked CC0 Quaternius base
([ADR-0017](adr/0017-quaternius-npc-base.md)); the current library remains the shipped
fallback until the Quaternius 12-variant baseline passes review. `NpcAvatar` selects the
character variants and attaches the gear; `WorldBuilder` loads the prop library
with colliders and phase-driven emissives. The 0.9.4 neutral baseline and its
acceptance criteria are in [`npc-visual-review.md`](npc-visual-review.md);
@@ -63,7 +66,7 @@ flatpak run org.blender.Blender --background \
flatpak run org.blender.Blender --background \
--python "$PWD/tools/npc_parts.py" -- extract --part hand_l --variant npc_casual \
--out "$PWD/tmp/npc-parts/npc_casual/hand_l.glb"
# Assemble a variant (currently rebuilds the procedural character)
# Assemble a variant (current fallback path; Quaternius migration in progress)
flatpak run org.blender.Blender --background \
--python "$PWD/tools/npc_parts.py" -- assemble --variant npc_casual \
--out "$PWD/tmp/npc-parts/npc_casual/assembled.glb"
@@ -139,7 +142,8 @@ render about 2.5 min.
## Characters
All library variants share the [character and gear asset contract](architecture.md#character-and-gear-asset-contract):
All library variants, including the incoming Quaternius-derived base, 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, 24,000/24,000 character budget and the same 256²
slot-map/AO rules. Role selection and look notes:
+3 -2
View File
@@ -34,8 +34,9 @@ and the active order/gaps in [`TODO.md`](../TODO.md).
## Known gaps
- External first-time-player sessions and balance sweeps are not completed.
- The NPC head/face/hand overhaul and MakeHuman body pipeline are planned, not
shipped.
- The Quaternius NPC base migration is planned, not shipped. The current 12-character
procedural library and the MakeHuman head remain fallbacks until the Quaternius
12-variant baseline passes review.
- Accessibility/localization acceptance, target-hardware profiling, macOS
signing/notarization and AI/storefront legal approval remain open.
- Live 3D replay, recorded VO/music, more venues and seasonal content are future
+13 -12
View File
@@ -1,19 +1,19 @@
# MakeHuman head prototype
Status: **owner-accepted head, assembled prototype, not yet shipped.**
The owner accepted the basic human head on 2026-11-04. The automated vision gate
Status: **retained fallback; superseded as the active NPC head by the Quaternius
base (ADR-0017).** The owner accepted the basic human head on 2026-11-04. The automated vision gate
still records REJECT on the eye/lid region as deferred polish. The asset is a
standalone head/neck extracted from the CC0 MakeHuman base in
`tmp/npc-research/makehuman/base.obj`; the assembled path now adds hair, a hidden
scalp trim and the procedural body. The 12 shipped GLBs have not been rebuilt
with it yet.
standalone head/neck extracted from the CC0 MakeHuman base. The assembled path
adds hair, a hidden scalp trim and the procedural body. The 12 shipped GLBs have
not been rebuilt with it, and the Quaternius migration replaces it as the active
base. The development source files were removed from `tmp/` on 2026-11-05.
## Asset
- GLB: [`assets/models/blender_src/makehuman_head.glb`](../assets/models/blender_src/makehuman_head.glb)
- Review sheet: [`blender_previews/sheet_makehuman_head.jpg`](blender_previews/sheet_makehuman_head.jpg)
- Source workflow (development-only): `tmp/npc-research/build_makehuman_head.py`
— extracts the MakeHuman head, cuts it at the neck, keeps the head/eye/mouth
- Source workflow (development-only, files removed after the Quaternius pivot;
retained here as the historical method) — extracts the MakeHuman head, cuts it at the neck, keeps the head/eye/mouth
components, cuts an almond aperture through a skin eyelid mask, adds recessed
eyeballs with flat iris/pupil discs, anchors brows to the face surface, renders
front/three-quarter/profile and exports the standalone GLB.
@@ -53,10 +53,11 @@ with it yet.
## Provenance
- Base mesh: MakeHuman / MPFB base, CC0, from the local research set
`tmp/npc-research/makehuman/`; see [`CREDITS.md`](../CREDITS.md).
(development source files removed after the 2026-11-05 Quaternius pivot); see
[`CREDITS.md`](../CREDITS.md).
- The head is a **derived prototype**, not a shipped NPC. It does not enter
`assets/models/blender/npc/`, `npc_base`, the runtime `NpcAvatar` path, CI, or
a release package until the NPC overhaul plan accepts it.
a release package. It is retained as a fallback, not the active NPC base.
- Source photographs/proportions are not used as textures here; this is a
geometry-only head built from the researched model data.
@@ -123,8 +124,8 @@ than a body-welded seam.
- The procedural body was narrowed at the neck and shoulders (chest 0.158,
neck base 0.060, neck top 0.054, shoulder root z 1.345) and its skin decimate
dropped to 0.21 so all 12 variants fit the 16,000 cap.
- Local review renders: `tmp/npc-parts/prototype_mh/renders/` (portrait
front/three-quarter/profile and full-body front/three-quarter).
- Local review renders were removed with the 2026-11-05 `tmp/` cleanup; the
committed review sheet above is the retained evidence.
## Deferred polish
+100 -79
View File
@@ -1,93 +1,114 @@
# NPC Model Sourcing
This page records the source evaluation behind [ADR-0015](adr/0015-npc-model-variety-sourcing.md).
The shipped path is the project-owned Blender/procedural library; external sources
remain references or local prototypes unless a later ADR accepts them.
This page records the source evaluation and the active character plan. The
decision is [ADR-0017](adr/0017-quaternius-npc-base.md), which supersedes the
generator-first sourcing decision in [ADR-0015](adr/0015-npc-model-variety-sourcing.md).
## Evaluation
## Active direction
The library needs variety beyond the original eight silhouettes while preserving
the `npc_base` contract: mesh node, 13 required core bones (optional extras
allowed), five tint slots, −Y/+Z front, grounded feet and the 24,000/24,000
character budget.
**Quaternius Ultimate Modular Characters (CC0) is the primary NPC mesh and
animation source.** The project-owned procedural library remains the shipped
fallback until the Quaternius migration passes the silhouette and gear gates.
| Source | Licence | Result |
The migration keeps the runtime contract that Godot, gear and tests already
consume:
- one `npc_base` skinned mesh under the 13 required core bones (optional extras
allowed);
- five tint slots: `skin`, `cloth`, `pants`, `accessory`, `hair`;
- front on Blender −Y / Godot +Z, feet grounded, height about 1.81 m;
- 24,000 triangles / 24,000 glTF vertices per character;
- gear stays at 1,500 triangles and props at 4,000;
- committed GLBs and maps only; no Quaternius, Blender or network dependency in
CI, build or runtime.
### Stage 1 (default)
1. Import the researched Quaternius GLBs and choose a canonical base.
2. Map the 62 source joints to the 13-core contract and bake a proportion warp.
3. Skin the mesh, retarget Idle and Walk, and verify seated/arm-down poses.
4. Map the five slots, unwrap and bake 256² maps.
5. Fit the existing gear and render the silhouette gate.
6. Build the 12 variants, audit, and capture the 12 × 6 baseline.
The Quaternius 62-joint rig and its 24 animation clips are an **authoring
source**. They are not loaded at runtime.
### Stage 2 gate
The 62-joint T-pose source does not share the project's arm-down rest pose or
proportions. If the Stage 1 proportion warp cannot preserve the Quaternius
silhouette and deformation, stop the rollout and write a new ADR for adopting
the 62-joint rig at runtime. Do not ship a hybrid rig, a second gear offset
system or a silent `NpcAvatar` change.
## Research findings
The researched files are the three converted Quaternius outfits used by the
Ducz Character Creator: `Casual`, `Casual_Hoodie` and `Worker`. They are kept
locally in `tmp/npc-research/quaternius/` with the licence and mirror notes.
| File | SHA-256 | Structure |
| --- | --- | --- |
| Quaternius Ultimate Modular | CC0 | Good silhouette/decimation material, but a 62-bone T-pose realistic rig and different proportions; not a drop-in. Kept as a reference/prototype. |
| Kenney Blocky Characters | CC0 | No matching rig; style is much blockier than the project look. |
| Khronos CesiumMan / RiggedFigure | CC BY 4.0 | Different bone names/rest pose and no five-slot materials; not a drop-in. |
| MakeHuman / MPFB base | CC0 | Useful body-shape base, but requires retopology, a custom rig, clothing and part integration. Active local pipeline, not the shipped path. |
| `Casual.glb` | `bc2d84fba249ebaa0629cb9d133ad37234196e4b8004aa205a6397abed04e05c` | 4 meshes, 62 joints, 24 clips, 7 materials |
| `Casual_Hoodie.glb` | `f5b722199f7628b24550989af4230f65d5230727df9c326fd2b3e360effe5249` | 4 meshes, 62 joints, 24 clips, 7 materials |
| `Worker.glb` | `8d0f454336c2effc5c08f63a177af3a82d1a7af025ca9588b40e4c90c4703534` | 4 meshes, 62 joints, 24 clips, 11 materials |
The contract mismatch is the expensive part, not decimation: retargeting a
different rig or rebuilding slots/weights can distort the body and invalidate
gear placement. Any future second-rig path needs its own ADR and animation/gear
offsets.
Source: [Quaternius Ultimate Modular Characters](https://quaternius.com/packs/ultimatemodularcharacters.html)
and [Ultimate Modular Women](https://quaternius.com/packs/ultimatemodularwomen.html),
CC0 1.0. The Ducz mirror is a browser builder over the same packs; it adds 21
outfits and a shared skeleton. The three full GLBs are the initial scope; the
21-part builder is a fallback for role coverage, not the default.
## Decision and outcome
The first prototype measured 12,518 imported vertices, 3,199 after welding and
2,423 vertices / 4,654 triangles after a 0.75 decimate. Idle and Walk read well.
The source is a T-pose with a 62-joint realistic rig, roughly 0.96 m hip,
1.68 m arm span and 0.153 m shoulder offset, so a contract bake is required.
- Extend the project-owned procedural generator as the primary shipped path
(12-character library, crowd variants, role pools).
- Keep Quaternius as a studied reference, not a shipped base.
- MakeHuman is a local development pipeline for body-shape diversity; it must
consume the same head/hand parts as the procedural library and never become a
CI/build dependency.
- Record CC0/CC-BY provenance; CC-BY previews require attribution in
The 24,000 cap leaves room to stay much closer to the source LOD than the
prototype's 4,654 triangles. Do not decimate to the old 7,000-triangle target
before the silhouette gate.
## Contract mismatch
The expensive part is the rig and proportions, not the mesh. The source has a
T-pose and a realistic skeleton; the runtime expects an arm-down 13-core rig,
fixed gear attach points and the existing pose composition. The Stage 1 bake
must therefore:
- rotate the arms down and match the contract wrist positions;
- warp the hips, knees, shoulders and head without collapsing the deltoid,
shortening the arms or changing the silhouette;
- keep one skinned `npc_base` mesh and the five slots;
- verify gear against the new shoulder, hip and head positions.
If those constraints distort the model, Stage 2 is the correct next decision,
not a local workaround.
## Licence and provenance
- CC0 preferred. CC-BY is allowed only with attribution in
[`CREDITS.md`](../CREDITS.md).
- No service asset whose terms restrict redistribution may be shipped.
- Keep the source URL, author, licence, download date and SHA-256 in this page
and in `CREDITS.md`.
- Research files and generated previews stay in `tmp/` (gitignored). Only final
audited assets and committed review sheets enter the repository.
- Quaternius models and animations are CC0; the existing credits entry already
names Quaternius. Keep it accurate if the shipped source set changes.
## MakeHuman prototype notes
## Closed tracks
The local prototype (`tmp/npc-research/`, never committed) scaled the base to
1.82 m, grounded it, triangulated/decimated it and retargeted it to the 13-core
armature. The first retarget measured **6,444 / 16,000 tris and**
**7,726 / 16,000 verts**, 14 bones, skinned, arm-down, five slots. It exposed
the expected issues: a 1.63× arm-scale warp at the deltoid/shoulder, blocky
decimated hands, rough slot boundaries and a head/neck shadow gap. The later
project head/hands swap reduced this to **6,407 / 16,000 tris and**
**6,651 / 16,000 verts**, but manual shoulder/neck retopology and part cleanup
remain before it can be considered shippable.
The MakeHuman/MPFB body pipeline is closed for the NPC base. The accepted
MakeHuman head and the procedural `npc_base` remain tested fallbacks until the
Quaternius rollout is complete. Their research scripts and renders were removed
from `tmp/` after the pivot; the measurements and decisions remain in
[`DONE.md`](../DONE.md), [`MEMORY.md`](../MEMORY.md) and the review docs.
A standalone MakeHuman head is recorded in
[`makehuman-head-review.md`](makehuman-head-review.md). The owner accepted the basic
human head on 2026-11-04; the assembled path (`build_character(head="mh")`) adds a
skull-conforming hair cap and hides the scalp under it. The 12 shipped GLBs still use
the procedural head until the hair/body review and rollout in [`TODO.md`](../TODO.md).
The MakeHuman body should reuse the approved local head/hand parts rather than forking
a second face implementation.
## Related documents
The current local MPFB full-body prototype (`tmp/npc-research/build_mpfb_npc.py`) assembles the
accepted head on an MPFB 2.0.18 body at **19,747 / 24,000 tris**, 1.810 m, 14 bones and 10
materials, with project hands, bevelled shoe shells with inset soles and tongues, pant cuffs,
cloth sleeve cuffs and flat slot colours. The torso is radially inflated by 12% through z 0.72–1.40
to loosen the shirt. It is a review candidate, not a shipped asset. The neck is a boolean-cut
circular bore bridged by a smooth lathe; the accepted head is trimmed at the narrow neck (z 1.55)
so its wide flat cut brim is discarded, and the lathe flares to cover the bore, then tucks inside
the jaw. This removed the square collar, dark notches and wide brim; a thin jaw crease and a hard
shirt-shoulder point in three-quarter view remain. The ankles are hidden by 0.11 m shoe shells and
0.08 m pant cuffs, and a light smoothing pass softens the closed thigh/hip region. The neck skin
test is guarded to z > 1.35 so it cannot paint the crotch. Remaining polish: the crotch hollow still reads as a V under
the shirt hem, a partly loosened shirt and angular thigh facets; a separate loose shirt shell is
the fix. Lowering the hem to z 0.80, tilting it up at the front and a 13% hem flare were rejected
as a unitard, high-cut swimwear and a peplum respectively. A quick open, flared solidified tube
(0.150→0.196 m, z 1.05→0.80, 24 segments) read as a hanging apron/tabard; the shell needs a shaped
torso, armholes and a curved hem.
A torus collar, cloth cylinder collar, skin neck-blend sphere, destructive vertex-smoothing pass
and untucked shirt-hem band were tried and removed because they read as a brace, shelf, donut or
hanging flap, or tore a hole at the collar. Protruding flat sole plates read as skates or bricks,
so the shoe detail is an inset sole and tongue under a rounded shell; laces were dropped for
triangle budget. The production integration decision (bake a committed source GLB or keep the
procedural body) and the owner review are tracked in `TODO.md`; MPFB itself must not become a
CI/build dependency.
## Provenance rules
- CC0 preferred; CC-BY only with attribution in `CREDITS.md`; no service asset
whose terms restrict redistribution.
- Downloaded research and generated previews stay in `tmp/`/gitignored folders;
only final audited assets and committed review sheets enter the repository.
- Record source URL, licence, author, date and what decision the reference
informed. Never treat a generated concept as licensed map/model data.
Measurements, visual decisions and accepted limits are in
[`3d-model-review.md`](3d-model-review.md) and
[`npc-visual-review.md`](npc-visual-review.md). Commands are in
[`asset-tooling.md`](asset-tooling.md).
- [ADR-0017: Quaternius NPC base](adr/0017-quaternius-npc-base.md)
- [ADR-0016: 24,000-triangle character budget](adr/0016-npc-character-budget-24k.md)
- [Blender asset contract](architecture.md#character-and-gear-asset-contract)
- [`3d-model-review.md`](3d-model-review.md), [`npc-visual-review.md`](npc-visual-review.md)
- [`asset-tooling.md`](asset-tooling.md)