Remove every hat except the firefighter helmet, drop the performer cone, rewrite the review page
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-06 17:52:46 +01:00
1 parent 98f618c501
commit 30d145079a
10 files changed
+125 -160

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 214 KiB

+84 -100
View File
@@ -1,14 +1,44 @@
# NPC roster visual review — 0.9.9 signoff
# NPC roster visual review — 0.9.9
**Status: awaiting owner visual signoff.** This page is the single review point for the
Quaternius roster swap that shipped in 0.9.9
([ADR-0017](adr/0017-quaternius-npc-base.md), [ADR-0018](adr/0018-quaternius-stage2-runtime-rig.md)).
Every character name the game ships is captured here at gameplay distance, in three studio views,
and in the three animation poses the runtime drives.
**Status: revised after owner feedback; awaiting a second signoff.** This page is the single
review point for the Quaternius roster in
[ADR-0017](adr/0017-quaternius-npc-base.md) and
[ADR-0018](adr/0018-quaternius-stage2-runtime-rig.md). Every character name the game ships is
captured here at gameplay distance, in two studio views, and in the three animation poses the
runtime drives.
Until this page is signed off, the roster swap is reversible: the procedural library and the
MakeHuman head are still in the tree and still pass `audit`, `inspect`, `npc_proportions` and the
tests (`build --source procedural`).
## What changed since the first review
The first pass was signed off **with follow-ups** and rejected three checklist rows: faces at
portrait distance, hands and hand-held gear, and head gear on the skull. The body findings were
all build defects, not art. This revision covers what was fixed and what is still open.
| Owner finding | Cause | Status |
| --- | --- | --- |
| `npc_guard` holes in the upper body | the build **deleted** the `Worker_Vest` material, and on the modular Worker the vest *is* the torso | fixed — the vest is the `cloth` slot, nothing is deleted |
| `npc_firefighter`, `npc_crowd_d` broken shoulders | same, plus the deleted `Worker_Yellow` hat was the skull crown | fixed — the crown stays and takes the `hair` tint |
| one unibrow on `npc_guard`, `npc_vest`, `npc_crowd_d` | the Worker's `Eyebrows` is one bar across the face and its eye quads are oversized | fixed — the bar is cut, the hoodie's brows are transplanted 20 mm above the eye line |
| Worker roles had **no visible eyes** | the Worker's own eye quads sit inside the head | fixed — the hoodie's eye pair is transplanted with a 4 mm forward offset |
| arms intersecting the body on `npc_dress`, `npc_jacket`, `npc_crowd_a`, `npc_crowd_d` | the baked rest aimed the upper arm straight down, which fails on the narrow bases | reduced — the arm rests 7° out from vertical (mesh width 0.180 → 0.220 on `casual`, 0.228 → 0.262 on `hoodie`) |
| head gear did not sit on the skull | gear is authored around the procedural head centre (1.62); the Quaternius head centre is 1.69 | **resolved by removal** — see below |
| performer cone swallowed the head | a 0.44 m cone authored for the old body | removed — the performer carries a baton and board in the hands |
## Hats and head items
**The firefighter helmet is the only head gear in the roster.** Caps, hoods and the performer cone
were removed from the role table, the per-character gear list and the performer props, so no
character can hide its face behind a hat. That also retired the head-gear lift/scale compensation
the caps needed on the Quaternius head.
| Role | Head gear | Body / hand items |
| --- | --- | --- |
| `npc_firefighter` | firefighter helmet | SCBA tank, flashlight |
| `npc_influencer` | none | sunglasses, shoulder bag, phone |
| `npc_tourist` | none | backpack, camera |
| `npc_authorized_guest` | none | lanyard |
| `npc_performer` | none | baton and board **in the hands** |
| `npc_protester` | none | pole and sign **in the hands** |
| every other role | none | role tint only |
## 1. Full-body roster (12 roles)
@@ -18,133 +48,87 @@ One tile per shipped character, neutral studio, camera at 4.2 m.
## 2. Front and profile per role
Front row set, then profile. Use this to judge the silhouette, the head size and the gear placement
without perspective hiding anything.
Front set, then profile. Use this for silhouette, head size and gear placement without perspective
hiding anything.
![NPC roster front and profile](blender_previews/sheet_npc_roster_views_0.9.9.jpg)
## 3. Animation poses (idle / sit / walk contact)
Six representative roles × three poses, driven by the real `_animate()` path with the FSM frozen.
Check: arms hang instead of holding an A-pose, the seated pose puts the forearms on the thighs and
keeps the shins down, the walk contact keeps limbs in contralateral opposition, and no limb
pinches or detaches at the shoulder, elbow, hip or knee.
![NPC roster poses](blender_previews/sheet_npc_roster_poses_0.9.9.jpg)
## 4. Crowd distance (8 m)
## 3. Crowd distance (8 m)
The distance the player actually sees a passer-by from the sidewalk.
![NPC roster at crowd distance](blender_previews/sheet_npc_roster_crowd_0.9.9.jpg)
## 4. Animation poses (idle / sit / walk contact)
Six roles × three poses, driven by the real `_animate()` path with the FSM frozen. Check that arms
hang instead of holding an A-pose, the seated pose puts the forearms on the thighs with the shins
down, walk contact keeps contralateral opposition, and nothing pinches or detaches at the shoulder,
elbow, hip or knee.
![NPC roster poses](blender_previews/sheet_npc_roster_poses_0.9.9.jpg)
## Signoff checklist
Tick each row. Anything you reject is a concrete task rather than an opinion, so it can go
straight into `TODO.md`.
Tick a verdict per row. A rejected row becomes a concrete `TODO.md` task, not an opinion.
| # | Question | Verdict |
| --- | --- | --- |
| 1 | Do the twelve characters read as distinct people at 8 m? | [x] yes [ ] no |
| 2 | Is the head size right for the body (no bobblehead, no pinhead)? | [x] yes [ ] no |
| 3 | Do the faces hold up at portrait distance? | [ ] yes [x] no |
| 4 | Do the hands and the hand-held gear (camera, cup, clipboard, sign) read correctly? | [ ] yes [x] no |
| 5 | Does the head gear (cap, hood, sunglasses, firefighter helmet) sit on the skull? | [ ] yes [x] no |
| 6 | Are the role outfits believable for a Hollywood-boulevard shift (tourist, delivery, guard, responder)? | [x] yes [ ] no |
| 7 | Are the seeded tint palettes acceptable, or too pastel/saturated? | [x] yes [ ] no |
| 8 | Do the seated and walking poses hold up? | [x] yes [ ] no |
| 1 | Do the twelve characters read as distinct people at 8 m? | ☐ yes ☐ no |
| 2 | Is the head size right for the body (no bobblehead, no pinhead)? | ☐ yes ☐ no |
| 3 | Do the faces hold up at portrait distance — brows, eyes, mouth, hair? | ☐ yes ☐ no |
| 4 | Do the hands and the hand-held items (camera, clipboard, board, baton) 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, or too pastel/saturated? | ☐ yes ☐ no |
| 8 | Do the seated and walking poses hold up? | ☐ yes ☐ no |
**Signoff:** [ ] approved as shipped [x] approved with the follow-ups below [ ] rejected
**Signoff:** ☐ approved as shipped ☐ approved with the follow-ups below ☐ rejected
## Issues visible in the captures
## Still open
The first review pass found three body defects. All three came from the build pipeline,
not the art, and all three are addressed in the second pass (2026-11-06):
Recorded as tasks in `TODO.md` under **Owner review findings**:
| Finding | Cause | Status |
| --- | --- | --- |
| `npc_guard` has holes in the upper body | the build **deleted** the `Worker_Vest` material, and on the modular Worker the vest *is* the torso | **fixed** — the vest is now the `cloth` slot, tinted per role; nothing is deleted |
| `npc_firefighter`, `npc_crowd_d` have a broken shoulder/upper-body area | same cause, plus the deleted `Worker_Yellow` hat was the crown of the skull, leaving the head open | **fixed** — the hat/crown stays in the mesh and only the part above z 1.65 takes the `hair` tint |
| `npc_guard`, `npc_vest`, `npc_crowd_d` have one big unibrow | the Worker's `Eyebrows` material is one continuous bar, and no other upstream head has brows that fit this mesh | **replaced** — the bar is cut out and the hoodie's two brows are transplanted onto the Worker head, lifted above the eye quads |
| `npc_dress`, `npc_jacket`, `npc_crowd_a`, `npc_crowd_d` arms intersect the body | the baked rest aimed the upper arm straight down, which works on the wide bases but not the narrow ones | **reduced** — the arm now rests 7° out from vertical (mesh width 0.180 → 0.220 on `casual`, 0.228 → 0.262 on `hoodie`); a light clip remains on the `worker` bases |
1. **Eyes have no whites.** Every base uses single-colour quads, so eyes read as dark rectangles at
portrait distance. A light sclera plus pupil on the `Eye` slot would finish the face.
2. **Arms still graze the torso on the `worker` base** — the 7° rest tilt cleared the `casual` base
but not this one.
3. **The `npc_vest` clipboard is oversized** on the shorter Quaternius arm.
4. **Roster variety is three meshes for twelve roles.** Tint and gear carry the difference; the
modular part library (hair, outfits) is the fix.
5. `npc_dress` and `npc_hoodie` have no coat or dress geometry — they are the `casual`/`hoodie`
bases with a matching tint.
Follow-up pass (same day) went further on the Worker head, which still read as a hard hat under
the bare tint:
| Finding | Fix |
| --- | --- |
| crown still shaped like a hard hat | the hoodie's **hair** is transplanted onto the Worker head and the hat faces above the collar are cut away, so guard/responder/crowd_d have hair |
| the dark bar was the Worker's *eye* quads, not only the brow bar | the eye quads are removed too; the face now reads brows + moustache |
| performer cone swallowed the head, and the performer/protester props floated beside the body | `_add_props()` now parents carried props to the hand proxies and the cone shrank from a 0.44 m to a 0.25 m base |
Third pass traced the remaining "black bar across the eyes" to the **cap brim**, not to head
geometry: head gear is authored around the procedural head centre (1.62) but the Quaternius head
centre sits at 1.69, so every cap sat 7 cm low with its brim across the brows. `HEAD_GEAR_LIFT`
is now 0.103 and `GEAR_SCALE` grows the cap/hood to clear the 0.228 m hair shell. The vision judge
confirms on `npc_guard`: no bar or visor, eyes and brows separately visible, the cap sits on the
head, no holes.
Re-verified after the fix with the sheets below and the vision judge: no holes or missing geometry
on any of the three Worker-based roles.
**Still open** — checkpoint row 4 (hand-held gear) and the list below: the eye quads have no
whites, the `npc_vest` clipboard is oversized on the shorter arm, and the arms still graze the
torso on the `worker` base.
Found by user:
1. npc_firefighter, npc_guard and npc_crowd_d have errors in the body:
- npc_guard has "holes" in upper body
- npc_firefighter and npc_crowd_d have buggy shoulder and upper body area
2. npc_guard, npc_vest and npc_crowd_d have one large unibrow: use other character's eyebrow geometry instead.
3. npc_dress, npc_jacket, npc_crowd_a and npc_crowd_d arms are too close and intersecting the body
Found while building this page; none blocks the swap, all are queued in `TODO.md`:
1. **`npc_dress` wears the performer cone hat plus the protest sign** because the performer props
are procedural and scaled for the old body. The dress itself has no geometry anymore — the role
is the `casual` base with a dress tint.
2. **`npc_coat` and `npc_hoodie`** are the hoodie base with a coat/hood tint; the raised hood and
the long coat silhouette are gone.
3. **The `npc_vest` clipboard** reads oversized at 0.23 × 0.31 m on the shorter Quaternius arm.
4. **The firefighter helmet brim** is 1.55× the head width — realistic for the helmet, but it reads
as a wide-brim hat next to the small head.
5. **Skin and cloth read pale** on the `hoodie` and `worker` bases; the seeded palette was tuned
against the procedural library's darker cloth.
6. **Roster variety is three meshes for twelve roles.** Tint and gear carry the difference; the
modular part library is the fix.
## Measured facts for this build
## Measured facts
| Metric | Value |
| --- | --- |
| Characters | 12, all on the Quaternius 62-joint rig |
| Triangles per character | 4,458 (`worker` minus vest) … 6,424 (`casual`) |
| Triangles per character | 4,458 (worker, before the head transplant) … 6,424 (`casual`) |
| glTF vertices per character | 9,370 … 13,440 |
| Budget | 24,000 tris / 24,000 verts per character |
| Tint slots | `skin`, `cloth`, `pants`, `hair`, `accessory`, plus fixed detail |
| Texel density | 73–74 px/m on the 256² maps |
| Height | 1.817–1.881 m |
| 24-NPC frame budget | 160,608 tris, 0.84 ms average frame (budget 50 ms) |
| Height | 1.82–1.88 m |
| 24-NPC frame budget | 174,976 tris, 0.85 ms average frame (budget 50 ms) |
| Gates | `inspect` clean, `audit` 12/12, `fit` OK, Godot 278/278, Python 167/167 |
## Reproducing the captures
```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/npc-signoff-pose \
--pose=idle # repeat for sit and walk_contact
godot --path . --script res://src/test/capture_npc_pose.gd \
--out=res://tmp/npc-signoff-pose --pose=idle # repeat for sit and walk_contact
```
## Superseded
## History
This page previously carried the **0.9.4 procedural library** baseline (eight hand-built
characters, the face/hand/neck fixes, the 13-core proportion audit). That mesh no longer ships, so
the text is retired; the comparison sheets stay in `blender_previews/` as history:
The page previously carried the 0.9.4 **procedural library** baseline (eight hand-built characters,
the face/hand/neck fixes, the 13-core proportion audit). That mesh no longer ships; its comparison
sheets stay in `blender_previews/` as records:
`sheet_npc_baseline_compare-p1.jpg`, `-body.jpg`, `-torso.jpg`, `-face-detail.jpg`,
`sheet_npc_hands_compare.jpg`, `sheet_npc_hands_grip_compare.jpg`.
The current source evaluation and per-character build table live in
[`npc-model-sourcing.md#shipped-roster-099-owner-chose-the-full-swap`](npc-model-sourcing.md#shipped-roster-099-owner-chose-the-full-swap);
the face options that led to the full swap are in
Per-character sources and build steps are in
[`npc-model-sourcing.md`](npc-model-sourcing.md); the face options that led to the full swap are in
[`screens/npc-face-gate/`](screens/npc-face-gate/README.md).