Recess NPC eyes and sculpt the jaw and cheeks
Full build / Import + headless tests (push) Successful in 38s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-02 19:08:26 +01:00
1 parent 15ab8c686d
commit 03c355e7c1
26 files changed
+117 -70

No files matched your search

+2 -2
View File
@@ -94,8 +94,8 @@ All eight use the `npc_base` contract, so each one can replace
`Materials.npc_slot()` tints them the same way it tints `npc_base`.
- budget ≤ 6000 triangles and ≤ 5000 vertices (glTF vertex count, after seam
splits; `CHAR_MAX_VERTS` in `tools/blender_assets.py`, raised from 4000 for
the 2026-11-01 face/hand pass). The current range is 3,984–4,978 triangles
and 3,793–4,831 vertices.
the 2026-11-01 face/hand pass). The current range is 3,760–4,754 triangles
and 3,556–4,574 vertices.
Construction: the torso and limbs are one continuous Skin-modifier mesh,
subdivided twice, decimated to 26 % with X symmetry, and cut at the waist, cuffs,
+1
View File
@@ -46,6 +46,7 @@ Committed contact sheets and local Blender renders for the character, gear and p
| <img src="sheet_npc_baseline.jpg" width="280" alt="sheet_npc_baseline.jpg"> | [`sheet_npc_baseline.jpg`](sheet_npc_baseline.jpg) |
| <img src="sheet_npc_baseline_compare-p1.jpg" width="280" alt="sheet_npc_baseline_compare-p1.jpg"> | [`sheet_npc_baseline_compare-p1.jpg`](sheet_npc_baseline_compare-p1.jpg) |
| <img src="sheet_npc_baseline_compare-body.jpg" width="280" alt="sheet_npc_baseline_compare-body.jpg"> | [`sheet_npc_baseline_compare-body.jpg`](sheet_npc_baseline_compare-body.jpg) |
| <img src="sheet_npc_baseline_compare-face.jpg" width="280" alt="sheet_npc_baseline_compare-face.jpg"> | [`sheet_npc_baseline_compare-face.jpg`](sheet_npc_baseline_compare-face.jpg) |
| <img src="sheet_npc_gear.jpg" width="280" alt="sheet_npc_gear.jpg"> | [`sheet_npc_gear.jpg`](sheet_npc_gear.jpg) |
| <img src="sheet_props.jpg" width="280" alt="sheet_props.jpg"> | [`sheet_props.jpg`](sheet_props.jpg) |
| <img src="shoulder_bag.png" width="280" alt="shoulder_bag.png"> | [`shoulder_bag.png`](shoulder_bag.png) |
Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

+1
View File
@@ -40,6 +40,7 @@ Implemented so far:
- Visual alignment: start/venue menu, pause, settings, shift review, radio, wand, inspection, timeline, HUD target chip/escalation bar, and radial menu now use or match their AI references in `assets/images/ui/`. The runtime art loader (`src/game/ui/art.gd`) falls back cleanly when a file is missing. The wand panel lists the guest's carried items, and multiline HUD/wand strings render real line breaks.
- NPC neck/shoulder transition (0.9.4 work): the body graph now uses a fuller neck base, a slightly tapered neck top and a lower shoulder root, giving the head/neck/shoulder line a trapezius slope instead of a thin post. The full character library was rebuilt with a final degenerate-face cleanup; the baseline comparison is `sheet_npc_baseline_compare-body.jpg`.
- NPC face-depth pass (0.9.4 work): sclera are recessed and capped by a thin upper lid, and the separate jaw/cheek spheres are replaced by a chin plate and cheekbones sculpted into the head mesh. The full library was rebuilt; the comparison is `sheet_npc_baseline_compare-face.jpg`.
- NPC proportion audit (0.9.4 work): `tools/npc_proportions.py` measures all eight GLBs against a stylized height/head/shoulder/hip/torso/leg/arm/foot guide. All variants pass; the head and broad-build silhouettes are the nearest upper bounds. Results are in [`npc-proportion-audit.md`](npc-proportion-audit.md).
- NPC P1 portrait fixes (0.9.4 work): tourists now hide their photo-pose camera bag outside `photo`/`film` poses, removing the duplicate-backpack silhouette; the backpack gear was rebuilt with flattened, forward chest straps and a fresh AO map. The before/after sheet is [`blender_previews/sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg); the face and remaining clothing/hand work stay open.
- NPC visual baseline (0.9.4 work): `src/test/capture_npc_baseline.gd` captures all eight library characters from front, three-quarter, profile, back, full-body and crowd views in a neutral studio (48 frames). The criteria, measurements and ranked gaps are in [`npc-visual-review.md`](npc-visual-review.md); the committed sheet is [`blender_previews/sheet_npc_baseline.jpg`](blender_previews/sheet_npc_baseline.jpg). No model changes were made in this baseline step.
+35 -30
View File
@@ -1,10 +1,12 @@
# NPC visual baseline and acceptance criteria
Status: baseline captured 2026-11-02; the first P1 fixes were applied the same
day (tourist photo-prop visibility and backpack strap geometry). The face pass
and the remaining body/clothing work are still open. The baseline remains the
reference for the 0.9.4 NPC visual optimization; the post-fix comparison is
[`blender_previews/sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg).
Status: baseline captured 2026-11-02. The first P1 fixes (tourist photo-prop
visibility, backpack straps), the neck/shoulder transition and the face-depth
pass are applied. Remaining body/clothing work is open; the baseline remains the
reference for 0.9.4. Comparison sheets:
[`sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg),
[`sheet_npc_baseline_compare-body.jpg`](blender_previews/sheet_npc_baseline_compare-body.jpg)
and the latest [`sheet_npc_baseline_compare-face.jpg`](blender_previews/sheet_npc_baseline_compare-face.jpg).
## What was captured
@@ -98,20 +100,19 @@ From `python3 tools/blender_assets.py fit` and the manifest:
| Character | Tris | Verts | Head width | Clothing radius | Notable gear clearances |
| --- | ---: | ---: | ---: | ---: | --- |
| `npc_casual` | 3,984 | 3,793 | 0.315 m | 0.191 m (hip) | backpack x −0.041, radial −0.162 |
| `npc_jacket` | 4,384 | 4,130 | 0.315 m | 0.191 m (hip) | lanyard x −0.116, radial +0.023 (runtime +4 cm forward) |
| `npc_coat` | 4,978 | 4,776 | 0.315 m | 0.225 m (skirt) | sunglasses width ratio 0.641; bag x +0.037, radial −0.130 |
| `npc_vest` | 4,496 | 4,271 | 0.315 m | 0.191 m (hip) | cap width ratio 1.067 |
| `npc_dress` | 4,400 | 4,075 | 0.315 m | 0.260 m (skirt) | bag x +0.002, radial −0.095 |
| `npc_hoodie` | 4,816 | 4,425 | 0.315 m | 0.190 m (hip) | — |
| `npc_firefighter` | 4,848 | 4,831 | 0.315 m | 0.255 m (skirt) | helmet width ratio 1.651; SCBA x −0.105, radial −0.076 |
| `npc_guard` | 4,558 | 4,652 | 0.315 m | 0.194 m (hip) | cap width ratio 1.067 |
| `npc_casual` | 3,760 | 3,556 | 0.315 m | 0.191 m (hip) | backpack x −0.041, radial −0.162 |
| `npc_jacket` | 4,160 | 3,930 | 0.315 m | 0.191 m (hip) | lanyard x −0.116, radial +0.023 (runtime +4 cm forward) |
| `npc_coat` | 4,754 | 4,574 | 0.315 m | 0.225 m (skirt) | sunglasses width ratio 0.641; bag x +0.037, radial −0.130 |
| `npc_vest` | 4,272 | 4,186 | 0.315 m | 0.191 m (hip) | cap width ratio 1.067 |
| `npc_dress` | 4,176 | 3,863 | 0.315 m | 0.260 m (skirt) | bag x +0.002, radial −0.095 |
| `npc_hoodie` | 4,592 | 4,187 | 0.315 m | 0.190 m (hip) | — |
| `npc_firefighter` | 4,624 | 4,487 | 0.315 m | 0.255 m (skirt) | helmet width ratio 1.651; SCBA x −0.105, radial −0.076 |
| `npc_guard` | 4,334 | 4,456 | 0.315 m | 0.194 m (hip) | cap width ratio 1.067 |
The widest character is `npc_firefighter` at 4,848 triangles and 4,831 vertices, so
the current headroom is 1,152 triangles and 169 vertices per character. Any face
or hand refinement must come out of that budget or replace existing detail. The
refit backpack measures 380 triangles / 406 vertices; the character and gear
table above remains valid because the character meshes did not change.
The widest character is `npc_coat` at 4,754 triangles and 4,574 vertices, so the
current headroom is 1,246 triangles and 426 vertices per character. Any hand or
clothing refinement must come out of that budget or replace existing detail. The
refit backpack measures 380 triangles / 406 vertices.
## Baseline findings, ranked
@@ -124,11 +125,12 @@ table above remains valid because the character meshes did not change.
photo prop is now hidden outside `photo`/`film` poses
(`photo_prop_visible_for_pose()`), so it only appears when the character is
actually taking a picture; the after frame confirms one bag at rest.
2. **The face is the largest portrait gap.** The eyes, nose and lips are
readable but sit on a shallow, faceted head: the eye whites protrude, the
eyelid/cheek transition is missing, and the mouth is a dark slot. This is
intentionally stylized, but the head volume and eye socket are the first
things a player sees at conversation range.
2. **Face depth. Fixed 2026-11-02.** The sclera was recessed into the socket and
wrapped with a thin upper lid; the separate jaw/cheek spheres were replaced
by a chin plate and cheekbones sculpted into the head mesh. That removes the
dark intersection rings that read as a beard shadow and keeps the mouth on
the surface. The mouth bar and low-poly brows remain stylized, but the eye
socket and jaw/cheek transition now read as one head volume.
3. **Backpack straps read as rigid black bars. Refit 2026-11-02.** The straps
were thin round tubes whose chest/waist points sat inside the torso, so only
fragments showed from the front. They are now flattened bands whose front path
@@ -182,17 +184,20 @@ python3 tools/npc_baseline.py compare \
```
The comparison sheet places the before/after pair for each view side by side.
The first run is committed as
[`sheet_npc_baseline_compare-p1.jpg` and `sheet_npc_baseline_compare-body.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg);
keep the baseline sheet as the before artifact and add a new numbered/after
sheet rather than replacing it.
The committed runs are
[`sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg),
[`sheet_npc_baseline_compare-body.jpg`](blender_previews/sheet_npc_baseline_compare-body.jpg)
and [`sheet_npc_baseline_compare-face.jpg`](blender_previews/sheet_npc_baseline_compare-face.jpg).
Keep the baseline sheet as the before artifact and add a new comparison sheet
rather than replacing it.
## Next implementation order
1. Refine the head/eye socket/jaw volume without changing the face direction or
the five tint slots.
1. Improve the torso/hip transition and the remaining body-shape variation.
2. Add a conversation-distance hand/grip capture and fix hand geometry before
judging hand items.
3. Audit hems and footwear in walk/sit/block poses.
4. Re-run the 48-frame baseline, the 96-frame final-context review, the 24-NPC
4. Refine nose/lip/ear shapes only if the portrait pass still flags them after
the hands and clothing read cleanly.
5. Re-run the 48-frame baseline, the 96-frame final-context review, the 24-NPC
budget and `blender_assets.py audit/fit`; publish the next comparison sheet.