Retire the NPC review pages after owner acceptance and repoint every reference
Full build / Import + headless tests (push) Successful in 50s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-06 18:37:17 +01:00
1 parent d5e180e50c
commit fcbeee0db2
25 files changed
+53 -221

No files matched your search

@@ -35,7 +35,7 @@ skill alone:
2. `TODO.md` and `MEMORY.md` — current track, claimed tasks, known gotchas. 2. `TODO.md` and `MEMORY.md` — current track, claimed tasks, known gotchas.
3. `docs/blender-assets.md` — library contract and command reference. 3. `docs/blender-assets.md` — library contract and command reference.
4. `docs/asset-tooling.md` — exact rebuild/bake/capture commands. 4. `docs/asset-tooling.md` — exact rebuild/bake/capture commands.
5. `docs/npc-visual-review.md` and `docs/3d-model-review.md` — accepted limits, 5. `docs/npc-model-sourcing.md` and `docs/3d-model-review.md` — accepted limits,
scorecards and known blockers. scorecards and known blockers.
6. `docs/known-limitations.md` — limits that must not be silently “fixed” into 6. `docs/known-limitations.md` — limits that must not be silently “fixed” into
contract changes. contract changes.
@@ -113,7 +113,7 @@ For each changed variant, inspect at least:
- Day and night/LATE final-context frames. - Day and night/LATE final-context frames.
- Front, three-quarter and profile for a shape change. - Front, three-quarter and profile for a shape change.
Accepted stylized limits are in `docs/npc-visual-review.md` and Accepted stylized limits are in `docs/3d-model-review.md` and
`docs/known-limitations.md`. Do not turn an accepted limit into an unreviewed `docs/known-limitations.md`. Do not turn an accepted limit into an unreviewed
contract change. contract change.
+3
View File
@@ -11,6 +11,9 @@ Semantic Versioning.
- Removed every hat and hood from the NPC roster: the firefighter helmet is the only head gear - Removed every hat and hood from the NPC roster: the firefighter helmet is the only head gear
left, so no character hides its face behind a cap. The street performer no longer wears the left, so no character hides its face behind a cap. The street performer no longer wears the
cone hat and carries the baton and board in the hands instead. cone hat and carries the baton and board in the hands instead.
- Hands, head gear and carried items were re-fitted to the new characters: hand items sit in the
palm instead of floating at the wrist, the lanyard moved up to the sternum, back gear moved up to
shoulder-blade height, and the clipboard is carried by its top edge.
- Every NPC now has a visible mouth; the Quaternius heads shipped without one, so the faces read as - Every NPC now has a visible mouth; the Quaternius heads shipped without one, so the faces read as
brow-and-eye masks. brow-and-eye masks.
- Fixed the modular Worker characters: the guard, delivery, firefighter and crowd roles had holes - Fixed the modular Worker characters: the guard, delivery, firefighter and crowd roles had holes
+4 -4
View File
@@ -1742,10 +1742,10 @@ fallback behavior.
produces 48 frames; `sheet_npc_baseline.jpg` is committed.) produces 48 frames; `sheet_npc_baseline.jpg` is committed.)
- [x] Define acceptance criteria for proportions, face readability, hair, hands, shoes, clothing - [x] Define acceptance criteria for proportions, face readability, hair, hands, shoes, clothing
silhouette, gear fit and animation at the gameplay camera height (1.7 m). (Eight criteria silhouette, gear fit and animation at the gameplay camera height (1.7 m). (Eight criteria
in `docs/npc-visual-review.md`; the current 8,000-triangle/8,000-vertex library contract is explicit; the `npc_base` fallback remains 6,000/4,000.) in the review evidence (since retired with the 0.9.9 roster pages); the current 8,000-triangle/8,000-vertex library contract is explicit; the `npc_base` fallback remains 6,000/4,000.)
- [x] Record the camera/lighting/background used for comparison so model changes can be judged - [x] Record the camera/lighting/background used for comparison so model changes can be judged
consistently; keep the existing portrait capture path deterministic. (Neutral studio, fixed consistently; keep the existing portrait capture path deterministic. (Neutral studio, fixed
orbit cameras, no HUD/crowd/animation; commands recorded in `docs/npc-visual-review.md`.) orbit cameras, no HUD/crowd/animation; commands recorded in the retired review evidence.)
- [x] Identify the highest-impact gaps from the current portraits (e.g. face depth, hair mass, - [x] Identify the highest-impact gaps from the current portraits (e.g. face depth, hair mass,
neck/shoulder transition, hand/foot shape, coat/dress hem) and rank them by player visibility. neck/shoulder transition, hand/foot shape, coat/dress hem) and rank them by player visibility.
(P1: tourist duplicate bag, face depth, backpack straps; P2: hands/grips, clothing tiling, (P1: tourist duplicate bag, face depth, backpack straps; P2: hands/grips, clothing tiling,
@@ -1755,7 +1755,7 @@ fallback behavior.
the side-by-side after sheet without overwriting it.) the side-by-side after sheet without overwriting it.)
Completed 2026-11-02: 48-frame neutral studio baseline, eight criteria, current fit and Completed 2026-11-02: 48-frame neutral studio baseline, eight criteria, current fit and
triangle/vertex measurements, and ranked P1/P2 gaps are in `docs/npc-visual-review.md`. The triangle/vertex measurements, and ranked P1/P2 gaps are in `docs/3d-model-review.md`. The
baseline itself changed no character models; the first P1 gear fixes are recorded under Gear baseline itself changed no character models; the first P1 gear fixes are recorded under Gear
and equipment fit. and equipment fit.
@@ -1768,7 +1768,7 @@ and equipment fit.
- [x] Audit all variants against a shared human proportion guide (head height, shoulder width, - [x] Audit all variants against a shared human proportion guide (head height, shoulder width,
torso length, hip width, limb length, foot length) and correct the worst outliers. torso length, hip width, limb length, foot length) and correct the worst outliers.
(`tools/npc_proportions.py` + `docs/npc-visual-review.md#proportion-audit`: all eight pass; no skeleton or (`tools/npc_proportions.py` + `docs/3d-model-review.md#character-measurements`: all eight pass; no skeleton or
mesh rescue was needed. Head and broad-build silhouettes are nearest their upper bounds.) mesh rescue was needed. Head and broad-build silhouettes are nearest their upper bounds.)
- [x] Improve the neck and shoulder transition so the silhouette reads as one body rather than a - [x] Improve the neck and shoulder transition so the silhouette reads as one body rather than a
thin post on a hanger. (Fuller neck base/top, lower shoulder root, degenerate-face cleanup; thin post on a hanger. (Fuller neck base/top, lower shoulder root, degenerate-face cleanup;
+4 -3
View File
@@ -320,7 +320,9 @@ The owner signed the roster off **with follow-ups** and rejected three review ro
body defects (holes, unibrow, missing eyes) and the head-gear seating are fixed, every hat except body defects (holes, unibrow, missing eyes) and the head-gear seating are fixed, every hat except
the firefighter helmet is removed, and every head has an authored mouth. Gates: `audit` 12/12, the firefighter helmet is removed, and every head has an authored mouth. Gates: `audit` 12/12,
`inspect` clean, `fit` OK, 24-NPC budget 174,976 tris / 0.85 ms, Godot 278/278, Python 167/167. `inspect` clean, `fit` OK, 24-NPC budget 174,976 tris / 0.85 ms, Godot 278/278, Python 167/167.
Owner review page: `docs/npc-visual-review.md`. Release packaging was fixed the same day: The owner **accepted the roster on 2026-11-06** and the review page plus its sheets were then
retired; durable evidence lives in `docs/3d-model-review.md` and `docs/blender-assets.md`. Release
packaging was fixed the same day:
excluding `tmp/`, `build/`, `docs/`, `tools/`, `src/test/` and `.agents/` from the export presets excluding `tmp/`, `build/`, `docs/`, `tools/`, `src/test/` and `.agents/` from the export presets
cut the Linux binary from 426 MB to 273 MB, and `tools/build_releases.sh` writes a SHA256SUMS file. cut the Linux binary from 426 MB to 273 MB, and `tools/build_releases.sh` writes a SHA256SUMS file.
@@ -335,8 +337,7 @@ code on the 62-joint rig, and the procedural rigs are visually unchanged. Verifi
(no issues), `audit` OK (6,206 tris / 12,988 verts, 62 bones), `fit` head 0.201 m, texel density (no issues), `audit` OK (6,206 tris / 12,988 verts, 62 bones), `fit` head 0.201 m, texel density
73–74 px/m, `npc_proportions` measured, 24-NPC budget smoke OK (168 meshes, 162,304 tris, 73–74 px/m, `npc_proportions` measured, 24-NPC budget smoke OK (168 meshes, 162,304 tris,
0.82 ms avg frame). The face/silhouette gate sheet and the three options are in 0.82 ms avg frame). The face/silhouette gate sheet and the three options are in
`docs/screens/npc-face-gate/`; the **owner decision is the only thing left before the 0.9.9 the face-gate decision (owner chose the full swap).
rollout**.
Test counts as of 2026-11-05: Python 167/167, Godot 278/278, `check_docs` OK. Test counts as of 2026-11-05: Python 167/167, Godot 278/278, `check_docs` OK.
+1 -1
View File
@@ -185,7 +185,7 @@ Full setup, every run/test/smoke command, and the controls table are in
- [`CREDITS.md`](CREDITS.md) — Credits, AI/reference provenance and licensing notes. - [`CREDITS.md`](CREDITS.md) — Credits, AI/reference provenance and licensing notes.
- [`PRIVACY.md`](PRIVACY.md) — Local-only data, save files and development API use. - [`PRIVACY.md`](PRIVACY.md) — Local-only data, save files and development API use.
- [`docs/blender-assets.md`](docs/blender-assets.md) — Blender asset library: characters, gear, props, attach points. - [`docs/blender-assets.md`](docs/blender-assets.md) — Blender asset library: characters, gear, props, attach points.
- [`docs/npc-visual-review.md`](docs/npc-visual-review.md) — 0.9.4 NPC baseline, acceptance criteria and ranked visual gaps; 0.9.5 texture comparison is in [`docs/blender_previews/sheet_texture_refinement_0.9.5.jpg`](docs/blender_previews/sheet_texture_refinement_0.9.5.jpg). - [`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md) — character sources, the shipped roster table and the build steps; 0.9.5 texture comparison is in [`docs/blender_previews/sheet_texture_refinement_0.9.5.jpg`](docs/blender_previews/sheet_texture_refinement_0.9.5.jpg).
- [`docs/adr/`](docs/adr/) — Architecture Decision Records. - [`docs/adr/`](docs/adr/) — Architecture Decision Records.
## Development Status ## Development Status
+16 -22
View File
@@ -820,13 +820,12 @@ blocked rig can no longer block the whole release.
`npc_casual`, front / three-quarter / profile. ADR-0018 removed the proportion warp, so `npc_casual`, front / three-quarter / profile. ADR-0018 removed the proportion warp, so
source proportions are accepted by definition (head 13.4 % of height, measured by source proportions are accepted by definition (head 13.4 % of height, measured by
`npc_proportions`). `npc_proportions`).
- [x] Owner review page with the visual signoff sheets and checklist: - [x] Owner visual signoff obtained (2026-11-06) on the roster, the faces, the head gear and the
[`docs/npc-visual-review.md`](docs/npc-visual-review.md) (the procedural-era review text hand/back gear. The review page and its sheets were retired after acceptance; the measurements
that used to live there is retired; its baseline sheets stay in `blender_previews/`). live on in `docs/3d-model-review.md` and `docs/blender-assets.md`.
- [x] Face-fidelity comparison sheet: [`docs/screens/npc-face-gate/`](../../docs/screens/npc-face-gate/README.md) - [x] Face-fidelity comparison was made and the full swap chosen; the comparison sheets were
captures the Quaternius base, the procedural + MakeHuman head and a procedural crowd variant retired with the review pages, and the decision is recorded in the follow-up section of
at front / three-quarter / profile / 8 m. The page records the three options (full swap, [`docs/adr/0018-quaternius-stage2-runtime-rig.md`](docs/adr/0018-quaternius-stage2-runtime-rig.md).
crowd only, add head detail) and recommends the full swap.
- [x] **Owner decision:** option (a) full swap (2026-11-05). Applied: all twelve characters are - [x] **Owner decision:** option (a) full swap (2026-11-05). Applied: all twelve characters are
baked from the three Quaternius sources inside 24,000 tris / 24,000 glTF vertices baked from the three Quaternius sources inside 24,000 tris / 24,000 glTF vertices
(`a6ccd86`), and the gate was re-run. (`a6ccd86`), and the gate was re-run.
@@ -834,7 +833,7 @@ blocked rig can no longer block the whole release.
`docs/npc-model-sourcing.md#shipped-roster-099-owner-chose-the-full-swap` and the `docs/npc-model-sourcing.md#shipped-roster-099-owner-chose-the-full-swap` and the
follow-up decision section of follow-up decision section of
[`docs/adr/0018-quaternius-stage2-runtime-rig.md`](docs/adr/0018-quaternius-stage2-runtime-rig.md). [`docs/adr/0018-quaternius-stage2-runtime-rig.md`](docs/adr/0018-quaternius-stage2-runtime-rig.md).
- [ ] Owner visual signoff on the shipped roster: [`docs/npc-visual-review.md`](docs/npc-visual-review.md). - [x] Owner visual signoff on the shipped roster (2026-11-06): accepted.
### Pilot rollout ### Pilot rollout
@@ -873,9 +872,9 @@ regressing gear fit, budget or readability.
### Owner review findings (2026-11-06) ### Owner review findings (2026-11-06)
Review page: [`docs/npc-visual-review.md`](docs/npc-visual-review.md). The owner signed the roster The owner signed the roster off **with follow-ups** and rejected three review rows (faces at
off **with follow-ups** and rejected checklist rows 3 (faces at portrait), 4 (hands and hand-held portrait, hands and hand-held gear, head gear on the skull). All follow-ups landed and the roster was
gear) and 5 (head gear on the skull). accepted on 2026-11-06; the review page and its sheets were then retired.
- [x] Worker torso holes on `npc_guard`: the build deleted `Worker_Vest`, which on the modular - [x] Worker torso holes on `npc_guard`: the build deleted `Worker_Vest`, which on the modular
Worker *is* the torso. Fixed by mapping it to `cloth` instead of deleting it. Worker *is* the torso. Fixed by mapping it to `cloth` instead of deleting it.
@@ -903,9 +902,9 @@ gear) and 5 (head gear on the skull).
helmet dome covers the hair, and the cap reads as a cap rather than a visor. helmet dome covers the hair, and the cap reads as a cap rather than a visor.
- [ ] The eyes are single-colour quads on every base; a light sclera + pupil texture on the `Eye` - [ ] The eyes are single-colour quads on every base; a light sclera + pupil texture on the `Eye`
slot would finish the face at portrait distance. slot would finish the face at portrait distance.
- [x] Owner review page re-created for the second pass: - [x] Review page re-created for the second pass, then retired after the owner accepted the roster
[`docs/npc-visual-review.md`](docs/npc-visual-review.md), with the hat/head-item table and a (2026-11-06). The durable evidence is `docs/3d-model-review.md`, the measurements in
refreshed eight-row checklist. `docs/blender-assets.md`, and the `capture_npc_gear.gd` / `capture_npc_baseline.gd` scripts.
- [-] Arm/torso intersection on `npc_dress`/`npc_jacket`/`npc_crowd_a`/`npc_crowd_d`: the baked - [-] Arm/torso intersection on `npc_dress`/`npc_jacket`/`npc_crowd_a`/`npc_crowd_d`: the baked
rest now aims the upper arm 7° out from vertical. Verified clear on the `casual` base; a rest now aims the upper arm 7° out from vertical. Verified clear on the `casual` base; a
light clip remains on `worker`, so this needs either a wider angle or a per-base shoulder light clip remains on `worker`, so this needs either a wider angle or a per-base shoulder
@@ -970,15 +969,14 @@ contract.
regenerated) and re-ran the 24-NPC budget smoke (175,264 tris, 0.87 ms). regenerated) and re-ran the 24-NPC budget smoke (175,264 tris, 0.87 ms).
- [x] New [`src/test/capture_npc_gear.gd`](src/test/capture_npc_gear.gd) captures every gear piece - [x] New [`src/test/capture_npc_gear.gd`](src/test/capture_npc_gear.gd) captures every gear piece
**worn by a real avatar** through the runtime attach path, one frame per item, and **worn by a real avatar** through the runtime attach path, one frame per item, and
`docs/blender_previews/sheet_npc_gear_on_character.jpg` collects them. It caught two things the gear-on-character sheet (retired with the review pages) collected them. It caught two things
the asset renders could not: `sunglasses` were hidden inside the hair shell, and the outfit's the asset renders could not: `sunglasses` were hidden inside the hair shell, and the outfit's
own gear double-attached over the tested piece (the capture now clears it first). own gear double-attached over the tested piece (the capture now clears it first).
- [x] Owner feedback on grip height applied: every hand item drops into the palm - [x] Owner feedback on grip height applied: every hand item drops into the palm
(`HAND_ITEM_DROP`, camera 0.085 m, flashlight 0.065, cup 0.050, umbrella 0.045, clipboard and (`HAND_ITEM_DROP`, camera 0.085 m, flashlight 0.065, cup 0.050, umbrella 0.045, clipboard and
board 0.035, phone/radio/wand 0.030), the carried role props drop 0.06 m, and the lanyard board 0.035, phone/radio/wand 0.030), the carried role props drop 0.06 m, and the lanyard
attach moved from y 1.30 to 1.38 for the taller Quaternius sternum. attach moved from y 1.30 to 1.38 for the taller Quaternius sternum.
- [x] `docs/npc-visual-review.md` row 4 now points at the gear-on-character sheet and the - [x] Owner verdict on the hand-held gear: accepted (2026-11-06).
measurement table. Only the owner verdict is outstanding.
**Exit:** every gear piece and role prop has a measured fit against the Quaternius attach points, **Exit:** every gear piece and role prop has a measured fit against the Quaternius attach points,
the hand-held items are within +/-10 % of their authored real-world size, and the review page row 4 the hand-held items are within +/-10 % of their authored real-world size, and the review page row 4
@@ -991,11 +989,7 @@ is signed off.
- [ ] Run `inspect`/`audit`/`fit`/`texels` and `npc_proportions.py report`; record the - [ ] Run `inspect`/`audit`/`fit`/`texels` and `npc_proportions.py report`; record the
12-variant measurement table. 12-variant measurement table.
- [-] Capture the 12 × 6 baseline and get owner approval before replacing the committed GLBs. - [-] Capture the 12 × 6 baseline and get owner approval before replacing the committed GLBs.
**Owner review page: [`docs/npc-visual-review.md`](docs/npc-visual-review.md)** — the Owner signed off on 2026-11-06; the review page was retired afterwards.
full-body roster, front/profile per role, the idle/sit/walk pose sheet and the 8 m crowd
strip, with an eight-row signoff checklist and the six issues found while capturing. The
GLBs are already committed (0.9.9); this signoff either accepts them or turns each rejected
row into a fix task.
- [ ] Re-run the 24-NPC budget smoke and the Web/Compatibility capture; record frame time, - [ ] Re-run the 24-NPC budget smoke and the Web/Compatibility capture; record frame time,
mesh/triangle counts and Web load before/after. mesh/triangle counts and Web load before/after.
- [ ] Retire the procedural variants that are no longer used, keeping one tested fallback; update - [ ] Retire the procedural variants that are no longer used, keeping one tested fallback; update
+4 -4
View File
@@ -5,10 +5,10 @@ Status: **baseline measured; scorecard open.** This is the working document for
Blender skill guidance says the targets are, the ranked candidate gaps, and the decisions that Blender skill guidance says the targets are, the ranked candidate gaps, and the decisions that
still need the project owner. Nothing here re-opens the accepted 0.9.4 limits by itself. still need the project owner. Nothing here re-opens the accepted 0.9.4 limits by itself.
Related documents: [`npc-visual-review.md`](npc-visual-review.md) (accepted 0.9.4 limits and Related documents: [`npc-model-sourcing.md`](npc-model-sourcing.md) (sources, shipped roster and
before/after sheets), [`npc-visual-review.md`](npc-visual-review.md#proportion-audit) (proportion guide), build steps), [`blender-assets.md`](blender-assets.md) (asset contract),
[`blender-assets.md`](blender-assets.md) (asset contract), [`asset-tooling.md`](asset-tooling.md) [`asset-tooling.md`](asset-tooling.md) (commands). The 0.9.4 procedural baseline this page was
(commands). measured against no longer ships; its before/after sheets stay in `blender_previews/`.
## Method and skill routing ## Method and skill routing
-1
View File
@@ -20,7 +20,6 @@ This folder holds the project documentation, visual references and generated QA
- [`../tools/README.md`](../tools/README.md) — tool inventory, categories and test runner - [`../tools/README.md`](../tools/README.md) — tool inventory, categories and test runner
- [`gameplay.md`](gameplay.md) — controls, venues and escalation - [`gameplay.md`](gameplay.md) — controls, venues and escalation
- [`venues.md`](venues.md) — Hollywood, Joke Shop and TV Studio real-site mapping - [`venues.md`](venues.md) — Hollywood, Joke Shop and TV Studio real-site mapping
- [`npc-visual-review.md`](npc-visual-review.md) — NPC visual baseline, acceptance criteria and ranked gaps
- [`3d-model-review.md`](3d-model-review.md) — 3D model re-evaluation: measurements, scorecard and ranked gaps - [`3d-model-review.md`](3d-model-review.md) — 3D model re-evaluation: measurements, scorecard and ranked gaps
- [`development-status.md`](development-status.md) — implemented features, current gaps and active planning - [`development-status.md`](development-status.md) — implemented features, current gaps and active planning
- [`accessibility.md`](accessibility.md) — accessibility statement and known gaps - [`accessibility.md`](accessibility.md) — accessibility statement and known gaps
@@ -79,7 +79,7 @@ rollout.
- **Date:** 2026-11-05 (owner, at the `0.9.9` face/silhouette gate) - **Date:** 2026-11-05 (owner, at the `0.9.9` face/silhouette gate)
The owner chose **option (a) full swap** from The owner chose **option (a) full swap** from
[`docs/screens/npc-face-gate/`](../../screens/npc-face-gate/README.md): every roster character the face/silhouette gate (its sheets were retired with the review pages): every roster character
moves onto the Quaternius base, and the procedural generator plus the MakeHuman head retire to moves onto the Quaternius base, and the procedural generator plus the MakeHuman head retire to
the tested fallback rather than staying in the shipped roster. the tested fallback rather than staying in the shipped roster.
+5 -5
View File
@@ -220,8 +220,8 @@ developer tools only — runtime, tests and CI consume committed GLBs and maps.
| `tools/npc_pipeline.py` | Builds the skinned base avatar, five-slot material maps, palette and AI-fabric preparation (`prepare`/`palette`) | `npc_base.glb`, `assets/textures/npc/*_{albedo,normal,orm}.png`, `palette.json` | `audit_glb` against the 24,000-triangle / 24,000-vertex base contract (13 core bones required; extras allowed) | | `tools/npc_pipeline.py` | Builds the skinned base avatar, five-slot material maps, palette and AI-fabric preparation (`prepare`/`palette`) | `npc_base.glb`, `assets/textures/npc/*_{albedo,normal,orm}.png`, `palette.json` | `audit_glb` against the 24,000-triangle / 24,000-vertex base contract (13 core bones required; extras allowed) |
| `tools/blender_assets.py` | Builds/renders the library: 12 characters, 15 gear pieces, 20 props, plus `manifest.json`; stdlib `audit`/`fit`/`sheet`/`list` | `assets/models/blender/{npc,npc_gear,props}/*.glb` | Character cap 24,000 tris / 24,000 verts, 1,500 per gear, 4,000 per prop; grounding, UV, degenerate-triangle, attach-fit and manifest coverage checks | | `tools/blender_assets.py` | Builds/renders the library: 12 characters, 15 gear pieces, 20 props, plus `manifest.json`; stdlib `audit`/`fit`/`sheet`/`list` | `assets/models/blender/{npc,npc_gear,props}/*.glb` | Character cap 24,000 tris / 24,000 verts, 1,500 per gear, 4,000 per prop; grounding, UV, degenerate-triangle, attach-fit and manifest coverage checks |
| `tools/bake_ao.py` | Bakes per-asset AO maps | `<asset>_ao.png` (256²) | Wired through `Materials.apply_ao()`/`SurfaceMaterials`; cloth/pants opt out (see below) | | `tools/bake_ao.py` | Bakes per-asset AO maps | `<asset>_ao.png` (256²) | Wired through `Materials.apply_ao()`/`SurfaceMaterials`; cloth/pants opt out (see below) |
| `tools/npc_proportions.py` | Measures exported GLB rest pose (height, head, shoulders, hips, torso, limbs, feet) against the stylized guide | report / JSON in `docs/npc-visual-review.md#proportion-audit` | All eight variants must stay inside the guide after a body change | | `tools/npc_proportions.py` | Measures exported GLB rest pose (height, head, shoulders, hips, torso, limbs, feet) against the stylized guide | report / JSON in `docs/3d-model-review.md#character-measurements` | All eight variants must stay inside the guide after a body change |
| `tools/npc_baseline.py` | Assembles neutral-baseline sheets and before/after comparisons | `docs/blender_previews/sheet_npc_baseline*.jpg` | Human review against `docs/npc-visual-review.md` | | `tools/npc_baseline.py` | Assembles neutral-baseline sheets and before/after comparisons | `docs/blender_previews/sheet_npc_baseline*.jpg` | Human review against `docs/3d-model-review.md` |
| `src/test/capture_npc_baseline.gd` | Fixed-camera studio baseline, 8 variants × 6 views | local `tmp/` frames | Neutral silhouette/face/gear review | | `src/test/capture_npc_baseline.gd` | Fixed-camera studio baseline, 8 variants × 6 views | local `tmp/` frames | Neutral silhouette/face/gear review |
| `src/test/capture_npc_review.gd` | Final-context gate: 8 variants × 2 venues × day/night × 3 distances = 96 frames, crowd hidden, review-only `character_override` for the guard | local `tmp/` frames | Pre-build acceptance gate for gear fit and venue lighting | | `src/test/capture_npc_review.gd` | Final-context gate: 8 variants × 2 venues × day/night × 3 distances = 96 frames, crowd hidden, review-only `character_override` for the guard | local `tmp/` frames | Pre-build acceptance gate for gear fit and venue lighting |
| `src/test/capture_realism.gd` | Venue realism stages plus a frozen portrait and surface close-ups | `docs/screens/realism/<run>/` | Optional vision judge; portrait is the only avatar-detail capture | | `src/test/capture_realism.gd` | Venue realism stages plus a frozen portrait and surface close-ups | `docs/screens/realism/<run>/` | Optional vision judge; portrait is the only avatar-detail capture |
@@ -244,8 +244,8 @@ Runtime contracts that must survive any character change:
then run `godot --headless --path . --import`; never commit a no-op full rebuild. then run `godot --headless --path . --import`; never commit a no-op full rebuild.
Evidence and detailed contracts live in [`blender-assets.md`](blender-assets.md), Evidence and detailed contracts live in [`blender-assets.md`](blender-assets.md),
[`npc-visual-review.md`](npc-visual-review.md) and [`3d-model-review.md`](3d-model-review.md) and
[`npc-visual-review.md#proportion-audit`](npc-visual-review.md#proportion-audit); command-level usage is in [`3d-model-review.md#character-measurements`](3d-model-review.md#character-measurements); command-level usage is in
[`asset-tooling.md`](asset-tooling.md). [`asset-tooling.md`](asset-tooling.md).
### Local map development tooling (planned) ### Local map development tooling (planned)
@@ -442,7 +442,7 @@ architecture document.
| [`docs/adr/`](adr/) | Immutable decision records with context and consequences | Decision history linked from §9 | | [`docs/adr/`](adr/) | Immutable decision records with context and consequences | Decision history linked from §9 |
| [`docs/asset-tooling.md`](asset-tooling.md) | Build/audit/capture commands, optional Blender MCP and pipeline usage | Operational appendix to the pipeline section | | [`docs/asset-tooling.md`](asset-tooling.md) | Build/audit/capture commands, optional Blender MCP and pipeline usage | Operational appendix to the pipeline section |
| [`docs/blender-assets.md`](blender-assets.md) | Blender library art direction, roles, layout and checks | Operational asset appendix; contract lives here in §5 | | [`docs/blender-assets.md`](blender-assets.md) | Blender library art direction, roles, layout and checks | Operational asset appendix; contract lives here in §5 |
| [`docs/npc-visual-review.md`](npc-visual-review.md) | NPC baseline views, acceptance criteria, visual gaps and proportion audit | Visual-QA appendix to the character tooling section | | [`docs/3d-model-review.md`](3d-model-review.md) | Character and asset measurements, scorecard and ranked gaps | Visual-QA appendix to the character tooling section |
| [`docs/3d-model-review.md`](3d-model-review.md) | Scorecard, measurements and ranked asset gaps | Working review companion to §5 | | [`docs/3d-model-review.md`](3d-model-review.md) | Scorecard, measurements and ranked asset gaps | Working review companion to §5 |
| [`docs/npc-model-sourcing.md`](npc-model-sourcing.md) | Character-source evaluation and licence/prototype outcome | Supports the character tooling section and ADR-0015 | | [`docs/npc-model-sourcing.md`](npc-model-sourcing.md) | Character-source evaluation and licence/prototype outcome | Supports the character tooling section and ADR-0015 |
| [`docs/getting-started.md`](getting-started.md) | Setup, commands, controls | Developer onboarding | | [`docs/getting-started.md`](getting-started.md) | Setup, commands, controls | Developer onboarding |
+2 -2
View File
@@ -553,7 +553,7 @@ contract.
`tools/npc_proportions.py` checks the eight character GLBs against the shared `tools/npc_proportions.py` checks the eight character GLBs against the shared
height/head/shoulder/hip/torso/leg/arm/foot guide; the current results are in height/head/shoulder/hip/torso/leg/arm/foot guide; the current results are in
[`npc-visual-review.md`](npc-visual-review.md#proportion-audit). It reads the exported GLBs [`3d-model-review.md`](3d-model-review.md#character-measurements). It reads the exported GLBs
and does not require Blender. and does not require Blender.
`capture_npc_pose.gd` is the pose/deformation harness for the 3D re-evaluation: idle, `capture_npc_pose.gd` is the pose/deformation harness for the 3D re-evaluation: idle,
@@ -578,7 +578,7 @@ camera, studio lighting and no venue/HUD/animation. The raw PNGs stay in
`tmp/`; `tools/npc_baseline.py sheet` builds the committed contact sheet, and `tmp/`; `tools/npc_baseline.py sheet` builds the committed contact sheet, and
`tools/npc_baseline.py compare --before DIR --after DIR` builds the review `tools/npc_baseline.py compare --before DIR --after DIR` builds the review
comparison after a model change. See comparison after a model change. See
[`npc-visual-review.md`](npc-visual-review.md). [`3d-model-review.md`](3d-model-review.md).
```bash ```bash
godot --path . --script res://src/test/capture_npc_baseline.gd -- \ godot --path . --script res://src/test/capture_npc_baseline.gd -- \
+2 -2
View File
@@ -9,7 +9,7 @@ replaces the procedural body with a baked CC0 Quaternius base
fallback until the Quaternius 12-variant baseline passes review. `NpcAvatar` selects the fallback until the Quaternius 12-variant baseline passes review. `NpcAvatar` selects the
character variants and attaches the gear; `WorldBuilder` loads the prop library 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 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); acceptance criteria are in [`architecture.md`](architecture.md#character-and-gear-asset-contract);
the committed 8 × 6 contact sheet is the committed 8 × 6 contact sheet is
[`blender_previews/sheet_npc_baseline.jpg`](blender_previews/sheet_npc_baseline.jpg). [`blender_previews/sheet_npc_baseline.jpg`](blender_previews/sheet_npc_baseline.jpg).
@@ -290,4 +290,4 @@ carry baked AO and the shared neutral material maps described above.
chin/cheekbone, nose, lips) but its `seg=18/rings=12` head still reads chin/cheekbone, nose, lips) but its `seg=18/rings=12` head still reads
somewhat faceted at portrait range; a subdivision/deeper-sculpt prototype is somewhat faceted at portrait range; a subdivision/deeper-sculpt prototype is
gated on the owner scorecard review. The full ranked list and measurements are gated on the owner scorecard review. The full ranked list and measurements are
in [`npc-visual-review.md`](npc-visual-review.md). in [`3d-model-review.md`](3d-model-review.md).
+1 -8
View File
@@ -18,13 +18,8 @@ capture harnesses.
| [![sheet_npc_baseline_compare-tex256.jpg](sheet_npc_baseline_compare-tex256.jpg)](sheet_npc_baseline_compare-tex256.jpg) <br> `sheet_npc_baseline_compare-tex256.jpg` | 128 -> 256 px NPC slot maps on the same camera. | | [![sheet_npc_baseline_compare-tex256.jpg](sheet_npc_baseline_compare-tex256.jpg)](sheet_npc_baseline_compare-tex256.jpg) <br> `sheet_npc_baseline_compare-tex256.jpg` | 128 -> 256 px NPC slot maps on the same camera. |
| [![sheet_npc_baseline_compare-texuv.jpg](sheet_npc_baseline_compare-texuv.jpg)](sheet_npc_baseline_compare-texuv.jpg) <br> `sheet_npc_baseline_compare-texuv.jpg` | 4x fabric weave with the baked per-character AO removed. | | [![sheet_npc_baseline_compare-texuv.jpg](sheet_npc_baseline_compare-texuv.jpg)](sheet_npc_baseline_compare-texuv.jpg) <br> `sheet_npc_baseline_compare-texuv.jpg` | 4x fabric weave with the baked per-character AO removed. |
| [![sheet_npc_baseline_compare-torso.jpg](sheet_npc_baseline_compare-torso.jpg)](sheet_npc_baseline_compare-torso.jpg) <br> `sheet_npc_baseline_compare-torso.jpg` | Torso/hip taper without changing the skeleton or build multipliers. | | [![sheet_npc_baseline_compare-torso.jpg](sheet_npc_baseline_compare-torso.jpg)](sheet_npc_baseline_compare-torso.jpg) <br> `sheet_npc_baseline_compare-torso.jpg` | Torso/hip taper without changing the skeleton or build multipliers. |
| [![sheet_npc_roster_0.9.9.jpg](sheet_npc_roster_0.9.9.jpg)](sheet_npc_roster_0.9.9.jpg) <br> `sheet_npc_roster_0.9.9.jpg` | 0.9.9 shipped roster: all twelve roles on the CC0 Quaternius bases, full body. |
| [![sheet_npc_roster_views_0.9.9.jpg](sheet_npc_roster_views_0.9.9.jpg)](sheet_npc_roster_views_0.9.9.jpg) <br> `sheet_npc_roster_views_0.9.9.jpg` | 0.9.9 roster: front and profile per role, for silhouette and gear placement. |
| [![sheet_npc_roster_poses_0.9.9.jpg](sheet_npc_roster_poses_0.9.9.jpg)](sheet_npc_roster_poses_0.9.9.jpg) <br> `sheet_npc_roster_poses_0.9.9.jpg` | 0.9.9 roster: idle, seated and walk-contact poses on six representative roles. |
| [![sheet_npc_roster_crowd_0.9.9.jpg](sheet_npc_roster_crowd_0.9.9.jpg)](sheet_npc_roster_crowd_0.9.9.jpg) <br> `sheet_npc_roster_crowd_0.9.9.jpg` | 0.9.9 roster at the 8 m crowd distance a player actually sees. |
| [![sheet_npc_crowd_prototypes.jpg](sheet_npc_crowd_prototypes.jpg)](sheet_npc_crowd_prototypes.jpg) <br> `sheet_npc_crowd_prototypes.jpg` | Four approved crowd-variety looks queued for the 12-character roster. | | [![sheet_npc_crowd_prototypes.jpg](sheet_npc_crowd_prototypes.jpg)](sheet_npc_crowd_prototypes.jpg) <br> `sheet_npc_crowd_prototypes.jpg` | Four approved crowd-variety looks queued for the 12-character roster. |
| [![sheet_npc_gear.jpg](sheet_npc_gear.jpg)](sheet_npc_gear.jpg) <br> `sheet_npc_gear.jpg` | Fifteen gear pieces authored in attach space: helmet, sunglasses, bags, tank, lanyard and the nine hand items. Caps and hoods are retired (owner, 2026-11-06). | | [![sheet_npc_gear.jpg](sheet_npc_gear.jpg)](sheet_npc_gear.jpg) <br> `sheet_npc_gear.jpg` | Fifteen gear pieces authored in attach space: helmet, sunglasses, bags, tank, lanyard and the nine hand items. Caps and hoods are retired (owner, 2026-11-06). |
| [![sheet_npc_gear_on_character.jpg](sheet_npc_gear_on_character.jpg)](sheet_npc_gear_on_character.jpg) <br> `sheet_npc_gear_on_character.jpg` | Every gear piece worn by a real avatar through the runtime attach path: helmet, sunglasses, lanyard, bags, tank and the nine hand items. |
| [![sheet_npc_hands_compare.jpg](sheet_npc_hands_compare.jpg)](sheet_npc_hands_compare.jpg) <br> `sheet_npc_hands_compare.jpg` | Hand pass: wider palms, segmented fingers and a separate thumb. | | [![sheet_npc_hands_compare.jpg](sheet_npc_hands_compare.jpg)](sheet_npc_hands_compare.jpg) <br> `sheet_npc_hands_compare.jpg` | Hand pass: wider palms, segmented fingers and a separate thumb. |
| [![sheet_npc_hands_grip_compare.jpg](sheet_npc_hands_grip_compare.jpg)](sheet_npc_hands_grip_compare.jpg) <br> `sheet_npc_hands_grip_compare.jpg` | Grip pass: the forward hand-item offset that puts props in the palm. | | [![sheet_npc_hands_grip_compare.jpg](sheet_npc_hands_grip_compare.jpg)](sheet_npc_hands_grip_compare.jpg) <br> `sheet_npc_hands_grip_compare.jpg` | Grip pass: the forward hand-item offset that puts props in the palm. |
| [![sheet_head_proto_before_after.jpg](sheet_head_proto_before_after.jpg)](sheet_head_proto_before_after.jpg) <br> `sheet_head_proto_before_after.jpg` | Head overhaul sign-off: current `_face` vs the s48 connected-shell prototype at 1.85 m front/three-quarter/profile. | | [![sheet_head_proto_before_after.jpg](sheet_head_proto_before_after.jpg)](sheet_head_proto_before_after.jpg) <br> `sheet_head_proto_before_after.jpg` | Head overhaul sign-off: current `_face` vs the s48 connected-shell prototype at 1.85 m front/three-quarter/profile. |
@@ -32,7 +27,5 @@ capture harnesses.
| [![sheet_props.jpg](sheet_props.jpg)](sheet_props.jpg) <br> `sheet_props.jpg` | Twenty street and venue props with baked maps, ground contact and collider footprints. | | [![sheet_props.jpg](sheet_props.jpg)](sheet_props.jpg) <br> `sheet_props.jpg` | Twenty street and venue props with baked maps, ground contact and collider footprints. |
| [![sheet_texture_refinement_0.9.5.jpg](sheet_texture_refinement_0.9.5.jpg)](sheet_texture_refinement_0.9.5.jpg) <br> `sheet_texture_refinement_0.9.5.jpg` | 0.9.5 texture refinement before/after: pavers, awning stripes and NPC fabric. | | [![sheet_texture_refinement_0.9.5.jpg](sheet_texture_refinement_0.9.5.jpg)](sheet_texture_refinement_0.9.5.jpg) <br> `sheet_texture_refinement_0.9.5.jpg` | 0.9.5 texture refinement before/after: pavers, awning stripes and NPC fabric. |
The acceptance criteria for these sheets are in [`../npc-visual-review.md`](../npc-visual-review.md), The measurements are in [`../3d-model-review.md`](../3d-model-review.md) and the asset contract in
the measurements in [`../npc-visual-review.md#proportion-audit`](../npc-visual-review.md#proportion-audit) and
[`../3d-model-review.md`](../3d-model-review.md), and the asset contract in
[`../blender-assets.md`](../blender-assets.md). [`../blender-assets.md`](../blender-assets.md).
Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

+3
View File
@@ -38,6 +38,9 @@ and the active order/gaps in [`TODO.md`](../TODO.md).
sources (casual tee, hoodie, work clothes), 4,458–6,424 triangles each, 62-joint rig at source sources (casual tee, hoodie, work clothes), 4,458–6,424 triangles each, 62-joint rig at source
proportions, arm-down rest, five tint slots, unwrapped UVs and baked 256² AO. The procedural proportions, arm-down rest, five tint slots, unwrapped UVs and baked 256² AO. The procedural
library and the MakeHuman head remain the tested fallback. library and the MakeHuman head remain the tested fallback.
- The roster passed its owner visual review on 2026-11-06: faces, head gear, hand-held and back
gear were all accepted after the follow-up fixes. The review page and its sheets were retired;
the measurements live in `docs/3d-model-review.md` and `docs/blender-assets.md`.
- Roster silhouette variety is narrower than the procedural library (three meshes for twelve - Roster silhouette variety is narrower than the procedural library (three meshes for twelve
roles, differentiated by tint and gear) until the modular part library is added. roles, differentiated by tint and gear) until the modular part library is added.
- Head gear is authored for the shipped Quaternius head; the procedural fallback therefore wears - Head gear is authored for the shipped Quaternius head; the procedural fallback therefore wears
+1 -1
View File
@@ -31,7 +31,7 @@ public release.
- Character faces, hands and fabric use a deliberately low-poly style; the - Character faces, hands and fabric use a deliberately low-poly style; the
>26 m tier remains a two-quad impostor and there is no separate finger-curl >26 m tier remains a two-quad impostor and there is no separate finger-curl
rig. The accepted limits are recorded in rig. The accepted limits are recorded in
[`npc-visual-review.md`](npc-visual-review.md). [`npc-model-sourcing.md`](npc-model-sourcing.md).
- There is no live 3D body-camera replay; the timeline is text-based. - There is no live 3D body-camera replay; the timeline is text-based.
- There is no recorded voice/music track. Ambience and cues are procedural. - There is no recorded voice/music track. Ambience and cues are procedural.
- The game is English-only and does not yet have a translator workflow or - The game is English-only and does not yet have a translator workflow or
+4 -2
View File
@@ -236,7 +236,9 @@ Two source quirks shaped the bake:
- the upstream materials are named `Skin`/`Purple`/`LightBlue`/`White`/`Hair`, so the five-slot - the upstream materials are named `Skin`/`Purple`/`LightBlue`/`White`/`Hair`, so the five-slot
contract is applied as a rename, not a re-author. contract is applied as a rename, not a re-author.
The face and silhouette gate sheet is in [`screens/npc-face-gate/`](screens/npc-face-gate/README.md). The face/silhouette gate that chose the full swap is recorded in the follow-up decision of
[ADR-0018](adr/0018-quaternius-stage2-runtime-rig.md); its comparison sheets were retired with the
review pages.
## Shipped roster (0.9.9, owner chose the full swap) ## Shipped roster (0.9.9, owner chose the full swap)
@@ -320,5 +322,5 @@ from `tmp/` after the pivot; the measurements and decisions remain in
- [ADR-0017: Quaternius NPC base](adr/0017-quaternius-npc-base.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) - [ADR-0016: 24,000-triangle character budget](adr/0016-npc-character-budget-24k.md)
- [Blender asset contract](architecture.md#character-and-gear-asset-contract) - [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) - [`3d-model-review.md`](3d-model-review.md)
- [`asset-tooling.md`](asset-tooling.md) - [`asset-tooling.md`](asset-tooling.md)
-97
View File
@@ -1,97 +0,0 @@
# NPC roster visual review — 0.9.9
**Status: awaiting the owner verdict on row 4.** This is the review point for the Quaternius roster
([ADR-0017](adr/0017-quaternius-npc-base.md), [ADR-0018](adr/0018-quaternius-stage2-runtime-rig.md)).
Four sheets: the twelve roles, two studio views, the animation poses and the crowd distance.
## Where the roster stands
The first pass was signed off **with follow-ups**; all of its findings traced to build defects and
are fixed:
- **Worker bodies** (`npc_guard`, `npc_vest`, `npc_firefighter`, `npc_crowd_d`) had holes in the
torso and an open crown because the build deleted the vest and hat materials — on the modular
Worker the vest *is* the torso and the hat *is* the crown. Nothing is deleted any more; both are
remapped, and the hoodie's brows, eyes and hair are transplanted onto the Worker head.
- **Faces** had a unibrow, oversized eye quads and no mouth. They now have two brows, two eyes and
an authored lip block on every base.
- **Hats** are gone except the firefighter helmet (owner directive), and the performer's cone with
them; carried props ride the hands.
- **Hand and back gear** were authored for the old body (wrist y 0.78 → 1.017, chest 1.30 → 1.38,
back 1.10 → 1.26). Every hand item now drops into the palm; the clipboard grips its top edge.
Per-item numbers: [`blender-assets.md`](blender-assets.md#hand-item-fit-on-the-quaternius-rig).
## 1. Full-body roster (12 roles)
![NPC roster full body](blender_previews/sheet_npc_roster_0.9.9.jpg)
## 2. Front and profile per role
![NPC roster front and profile](blender_previews/sheet_npc_roster_views_0.9.9.jpg)
## 3. Animation poses (idle / sit / walk contact)
Driven by the real `_animate()` path with the FSM frozen: arms hang, the seated pose puts the
forearms on the thighs with the shins down, walk contact keeps contralateral opposition.
![NPC roster poses](blender_previews/sheet_npc_roster_poses_0.9.9.jpg)
## 4. Crowd distance (8 m)
![NPC roster at crowd distance](blender_previews/sheet_npc_roster_crowd_0.9.9.jpg)
## 5. Gear on the character
Every piece worn by a real avatar through the runtime attach path — the sheet to judge row 4 by.
![Gear on the character](blender_previews/sheet_npc_gear_on_character.jpg)
## Signoff checklist
| # | Question | Verdict |
| --- | --- | --- |
| 1 | Do the twelve characters read as distinct people at 8 m? | ☐ yes ☐ no |
| 2 | Is the head size right for the body? | ☐ yes ☐ no |
| 3 | Do the faces hold up at portrait distance — brows, eyes, mouth, hair? | ☐ yes ☐ no |
| 4 | Do the hands and hand-held items (camera, clipboard, board, baton, parcel) read correctly? | ☐ yes ☐ no |
| 5 | Is the firefighter helmet the only head gear, and does it sit correctly? | ☐ yes ☐ no |
| 6 | Are the role outfits believable for a Hollywood-boulevard shift? | ☐ yes ☐ no |
| 7 | Are the seeded tint palettes acceptable? | ☐ yes ☐ no |
| 8 | Do the seated and walking poses hold up? | ☐ yes ☐ no |
**Signoff:** ☐ approved as shipped ☐ approved with follow-ups ☐ rejected
## Still open
1. **Eyes have no whites** — single-colour quads on every base.
2. **Arms still graze the torso on the `worker` base** (accepted as tolerable for now).
3. **Roster variety is three meshes for twelve roles** — the modular part library is the fix.
4. **The wand and phone orientation** read poorly in the gear sheet; both may need re-authoring.
## Measured facts
| Metric | Value |
| --- | --- |
| Characters | 12, all on the Quaternius 62-joint rig |
| Triangles / glTF vertices | 6,218 … 6,436 / 13,012 … 13,459 |
| Budget | 24,000 tris / 24,000 verts each |
| Tint slots | `skin`, `cloth`, `pants`, `hair`, `accessory` + fixed detail |
| Texel density | 73–74 px/m on 256² maps |
| Height | 1.82–1.88 m |
| 24-NPC frame budget | 175,264 tris, 0.87 ms (budget 50 ms) |
| Gates | `audit` 12/12, `inspect` clean, `fit` OK, Godot 278/278, Python 167/167 |
## Reproducing
```sh
godot --path . --script res://src/test/capture_npc_baseline.gd -- --out=res://tmp/npc-signoff
godot --path . --script res://src/test/capture_npc_pose.gd -- --out=res://tmp/p --pose=idle
godot --path . --script res://src/test/capture_npc_gear.gd -- --out=res://tmp/npc-gear
```
## History
This page replaced the 0.9.4 procedural-library baseline (eight hand-built characters, 13-core
proportion audit). Its comparison sheets stay in `blender_previews/` as records. Per-character
sources: [`npc-model-sourcing.md`](npc-model-sourcing.md); the face options that led to the full
swap: [`screens/npc-face-gate/`](screens/npc-face-gate/README.md).
-66
View File
@@ -1,66 +0,0 @@
# NPC face and silhouette gate — Quaternius pilot (2026-11-05)
This page is the owner decision point for
[ADR-0017](../../adr/0017-quaternius-npc-base.md) + [ADR-0018](../../adr/0018-quaternius-stage2-runtime-rig.md)
stage 2. It answers one question: **which head ships?**
`npc_casual` is now the CC0 Quaternius `Casual_Hoodie` base baked to the project contract
(arm-down rest, five tint slots, 62-joint rig at source proportions). The procedural library with
the MakeHuman head is unchanged and still ships for the other eleven characters.
## The sheet
![face gate sheet](sheet_face_gate.jpg)
Rows: the Quaternius base, the procedural library with the MakeHuman head, and a procedural crowd
variant. Columns: front, three-quarter, profile, and the crowd-distance silhouette the player
actually sees from 8 m.
Source frames: `godot --path . --script res://src/test/capture_npc_baseline.gd -- --out=res://tmp/npc-gate`.
## What the sheet shows
| | Head height / body | Face read at portrait | Crowd-distance read |
| --- | --- | --- | --- |
| Quaternius base | 0.134 | clean low-poly brows, nose, jaw, layered hair | slim, upright, clearly a person |
| procedural + MakeHuman head | ~0.20 | oversized head, soft nose, beard slab reads as a bar | bobblehead proportions |
| procedural crowd variant | ~0.20 | oversized head, flat cheeks | bobblehead proportions |
Measured (`python3 -m pytest tools/tests/test_npc_proportions.py -q`,
`python3 tools/npc_proportions.py`):
- `npc_casual` (Quaternius): head 13.4 % of height, arm-down rest, 6,206 tris, 12,988 glTF
vertices, texel density 73–74 px/m on the 256² maps.
- The procedural library: head 16–22 % of height (the stylized band in
`tools/npc_proportions.GUIDE`).
The Quaternius head is *smaller and more realistic* than the stylized library head, which is
exactly the trade the owner has to accept or reject. The vision judge that reviewed the earlier
head rework reads the Quaternius face as the cleaner silhouette of the three at both distances.
## The three options
1. **Full swap.** Every character rebaked onto the Quaternius base in `0.9.10`; the procedural
library and the MakeHuman head retire to the tested fallback. Consistent look, real anatomy,
no further head work.
2. **Crowd only.** Quaternius for the anonymous crowd roles, procedural + MakeHuman for the named
roles the player talks to. Keeps two art styles in one frame.
3. **Add head detail.** Keep the Quaternius body and author a higher-detail head (subdivision and
hair cards) inside the 24,000-triangle / 24,000-vertex budget. Most work; the current head
already reads well at gameplay distance.
## Recommendation
Option 1. The Quaternius head beats the MakeHuman head at portrait distance in this sheet, and it
costs no further authoring; the budget headroom (6.2k of 24k triangles) stays available for the
hands and gear that the review still flags as weak.
## Recorded decision
Status: **option 1 (full swap) accepted by the owner, 2026-11-05.** Every roster character moves
onto the Quaternius base; the procedural library and the MakeHuman head become the tested
fallback. See the follow-up decision section in
[ADR-0018](../../adr/0018-quaternius-stage2-runtime-rig.md#follow-up-decision-full-roster-swap).
Roster silhouettes are less varied than the procedural library until the modular part library
(hair, outfits) is added in the `0.9.10` roster workstream — recorded rather than hidden.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB