Files
security-game/TODO.md
T
zwitschi bbf4693475 Narrow the sunglasses and fix portrait-type parsing
Move the hinges to +/-0.075 (0.035 box), arms to +/-0.098, and lenses to a
0.024 m radius while keeping the lens plane in front of the eyes. Rebuild the
GLB and AO; fit now measures 0.202 m total width (0.64x head). capture_realism
now parses the documented --portrait-type option instead of ignoring it.
Python tooling 87/87; headless 228/228.
2026-11-01 17:56:10 +01:00

104 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TODO
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.
## NPC gear fit (v0.6.1)
The 2026-11-01 detail pass fixed the bodies but not the props worn on them. In the portrait
capture (`--stages=day,portrait`, see the report in `docs/screens/realism/2026-11-01-npc/`) the
sunglasses span the whole upper face and the shoulder bag cuts through `npc_coat`'s skirt. Blender sources for gear
live in `tools/blender_assets.py` (`_build_gear()`), the contract in `docs/blender-assets.md`
(gear budget 1500 tris, `GEAR_ATTACH` points in `NpcAvatar`).
- [x] Measure the fit in Blender, not by eye: `python3 tools/blender_assets.py fit` prints each
character's measured head width and hip/skirt radius, then every head/back/chest gear
bounding box with head-band status or skirt clearance. Current measurements: head width
0.315 m; coat skirt 0.225 m, dress 0.260 m; sunglasses 0.282 m (0.90x head); shoulder-bag
x-clearance -0.025 m on the coat (radial -0.031 m on the dress).
- [x] Narrow `sunglasses` from 0.28 m to ~0.20 m. The hinges moved to ±0.075 (0.035 box), the
arms to ±0.098, and the lenses are 0.024 m radius at the same `y=-0.152`, `z=0.035` plane.
Rebuilt GLB/AO: measured width **0.202 m** (0.64x head), still inside the head band.
Also fixed `capture_realism.gd` so `--portrait-type=N` is actually parsed (it was documented
but ignored).
- [ ] Fix `shoulder_bag` clipping through `npc_coat`/`npc_dress`: the bag body spans `|x|`
0.17–0.25 at the hip while the skirt flares to 0.225–0.26, so its inner half is inside the
cloth. Move it outboard (or up onto the belt line) until the inner face clears the flare,
and keep the strap tube outside the same radius.
- [ ] Same pass for `cap`/`beanie`/`hood`/`firefighter_helmet`: they must not clip the new
brow/ear geometry, and `hood` must still leave the face readable for hoodie avatars.
- [ ] Rebuild the gear (`build`) and re-bake AO (`tools/bake_ao.py`), then
`godot --headless --path . --import`.
- [ ] Add a regression test: `tools/test_blender_assets.py` checks the glasses width against the
head width, and `src/test/tests/test_npc_character.gd` checks the head/back attach nodes
stay outside the body silhouette radius.
- [ ] Re-capture the portrait (`--stages=day,portrait`) and the gallery shots; record the
before/after in `docs/screens/realism/<date>-gear/`.
- [ ] Consider a second character close-up for a hoodie/winter NPC so headgear is covered too
(`--portrait-type=5` already forces a hooded role for comparison).
## Venue geometry and the committed gallery (v0.6.1)
Today all three venues share the Hollywood `WorldBuilder` geometry, so the Joke Shop and studio
concepts are only compared on lighting (noted in `tools/scene_concepts.py` `SHOTS`). They also
have no stage in the committed `docs/screenshots/` gallery, only in `capture_realism.gd`.
- [ ] Extract a geometry spec per venue instead of branching inline: a `scenario.` (or
`WorldBuilder`) table of facade width/height, door style, window rows, awning/marquee
flags, street furniture set, palette and props, defaulting to the Hollywood values so
nothing regresses.
- [ ] Joke Shop: narrow brick alley (10–12 m wide), one warm wall lantern as the key light,
recessed door with a step, shuttered window, dumpster/AC clutter, no skyline ring — the
alley concept has depth, not a horizon.
- [ ] TV Studio: granite/stone facade, bulb canopy instead of the marquee, glossy black car on
the curb, stanchions and barrier line at the door, no palm trees.
- [ ] Keep navigation working: regenerate/verify the `NavigationRegion3D` bake per venue,
update sidewalk/steps/door waypoints (Joke Shop and Studio already have `sidewalk` and
`steps_end`), and confirm NPCs still reach the door (smoke + `test_venue_*`).
- [ ] Split the concept mapping so each venue is judged on its own frame (`joke_shop_*`,
`studio_*`) and drop the "shared geometry" caveat in `tools/scene_concepts.py`.
- [ ] Add both venues to the committed gallery: two new stages in
`src/test/capture_screenshots.gd` (`12-joke-shop.png`, `13-studio-arrival.png`) reusing the
existing `joke_shop_queue` / `studio_arrival` designs, then `check_screenshots.sh` and a
fresh judge run.
- [ ] Update `docs/architecture.md` (venue geometry), `README.md` (gallery) and the screenshot
table when the stages land.
## Forward+ desktop preset and a volumetric flashlight (v0.7.0)
The Compatibility renderer has no volumetrics, so the flashlight is a tight pool of light with
no visible shaft. A second desktop build can render it properly without touching the CI/default
path.
- [ ] Write the preset as an `override.cfg` (Godot reads it beside the binary/project) that sets
`rendering/renderer/rendering_method="forward_plus"`, enables `volumetric_fog_*` and SDFGI,
and keeps the Compatibility build as the default (`project.godot` unchanged).
- [ ] Gate the effect in code: only give the flashlight a volumetric component when the renderer
is Forward+ (`RenderingServer.get_rendering_device() != null`), so Web/CI builds are
untouched and the existing headless tests keep passing.
- [ ] Tune `light_volumetric_fog_energy`/`fog_density` for the LATE phase and re-check the
entrance so the shaft does not wash the facade again (the reason the wide cone was cut).
- [ ] A/B the two renderers with `capture_realism.gd` (same stages, two `--out` dirs) and record
the diff + judge scores in `docs/screens/realism/<date>-forward-plus/`.
- [ ] Add the preset to `tools/build_releases.sh` and `docs/RELEASING.md` as an optional
"desktop HQ" artifact, and note the runtime requirement (Vulkan driver) in `README.md`.
- [ ] Test: a headless run must still boot when Forward+ is unavailable (the preset must degrade
to Compatibility instead of failing to start).
## Realism follow-ups (deferred)
- [ ] Human-authored tree/hedge silhouettes: the whole scene now reads well except the foliage,
which is still flat-shaded clumps (`_shrub()`/`_tree()` in `tools/blender_assets.py`).
Only worth doing if a higher-poly organic builder is added to the library.
- [ ] Camera height: the concept frames are shot at ~1.55 m with a slightly wider lens; the game
camera sits at 1.7 m. Decide whether the first-person height should match the art direction
or stay at the current gameplay value.
## Future ideas (optional, not scheduled)
- [ ] Live 3D body-camera replay (the timeline is text-only today).
- [ ] Additional venues or seasonal events authored from the new `.tres` files.
- [ ] Real voice/dialogue audio (the crowd bed and radio crackle are procedural).
- [ ] Swap the primitive prop builder for an image-to-mesh model API behind the same
`assets/models/generated/<prop>.glb` contract.