Adopt the realism pass and refresh screenshots/docs
Full build / Import + headless tests (push) Successful in 34s
Full build / Full desktop build + optional release (push) Skipped

- add the v2 runtime picks: per-phase skyline panoramas, brick, sidewalk
  pavers, dry/wet asphalt, awning canvas, and their normal maps
- add the realism tooling and evidence: tools/scene_concepts.py, capture_realism.gd,
  concept frames, reports/sheets, and tests
- retune phase lighting/fog/exposure, add sun yaw, brighten the night glow,
  add the flashlight beam mesh, and rebuild the planter/tree assets
- regenerate all eleven staged screenshots from the current build; compare is
  11 good / 0 bad
- finish the visual-alignment closeout in DONE/TODO, update architecture,
  blender-assets, PLAN, and ignore rules (editable Blender sources untracked)
- keep the judge retry and document the verified default judge model

Verification: headless 227/227; Python tooling 86/86; check_screenshots 11/11.
This commit is contained in:
zwitschi committed 2026-11-01 17:03:05 +01:00
1 parent 26ecb93fd4
commit d7e523f63c
70 files changed
+4042 -101

No files matched your search

+177
View File
@@ -895,6 +895,160 @@ Completed 2026-11-01. Historical note: the screen-design references originally l
ADR-0014. `docs/screens/designs/` remains a reference-only snapshot; `tools/screen_designs.py`
now reads and writes `assets/images/ui/`.
## Realistic Backgrounds, Textures and Scene References
Completed 2026-11-01 (part of the v0.6.x realism pass). The flat box skyline was replaced by
per-phase AI panoramas, the surface tiles by higher-detail v2 picks with normal maps, and the
lighting/exposure was retuned against AI concept frames. Evidence:
`docs/screens/realism/2026-11-01-adopt/` (`report.md`, `sheet.jpg`), `screen_designs.py compare`
**11 good / 0 bad**; headless **227/227**, Python **86/86**, all smokes.
### Realistic backgrounds, textures and scene references
Goal: replace the outdated flat skyline backdrop (`assets/textures/skyline.png`, black boxes
with dot windows) and the flat-looking surface tiles with AI-generated, more realistic
backgrounds and textures. Add a larger set of example 3D scene images as art direction, and
measure the in-game result against that target with the screenshot tools. Plan:
[`PLAN.md` → Visual Quality Direction → Realism pass](PLAN.md#realism-pass).
**Rule for every step: never overwrite an existing image.** New outputs get new paths. When a
path is taken, the tools pick the next free `-vN` suffix. Raw AI output stays on disk under
`assets/textures/ai/v2/raw/` (gitignored like the other raw AI folders). Processed game-ready
candidates go to `assets/textures/ai/game_ready/v2/`, a local pool where only the validated picks
are tracked (ADR-0014). Scene references go to `docs/screens/concepts/`, and trial captures and
reports to `docs/screens/realism/<run>/`.
#### Step 1 — Tooling (`tools/scene_concepts.py`)
- [x] Add a catalogue of prompts in three groups: `scene` (16:9 example 3D game frames),
`backdrop` (4:1 skyline panoramas with transparent sky), and `texture` (seamless PBR
surface tiles). Each entry has a name, prompt, role and target path.
- [x] `generate [--group] [--only] [--variants N]`: call the OpenRouter image API through
`generate_textures.generate_image` (key from the repo `.env`), save raw output, and never
overwrite (`next_free_path`). Print every file written.
- [x] `process`: turn raw backdrops into 2048×512 RGBA strips that tile horizontally (edge
crossfade, sky made fully transparent, hard alpha for the alpha-scissor material). Turn raw
textures into seamless 1024² tiles (`asset_pipeline.make_seamless`) plus a normal map
(`make_normal_maps.normal_map`). Skip outputs that already exist.
- [x] `audit`: run `asset_pipeline.audit_image` on the processed candidates (`backdrop` /
`tile` roles) and fail on any bad result.
- [x] `realism`: for each trial capture, report the Pillow detail metrics (edge density,
contrast, colour spread, saturation) next to the matching concept image. Optionally ask a
vision model (`google/gemini-2.5-flash-lite`) for 0–10 realism scores (lighting,
materials, texture detail, backdrop, overall) with concrete fixes. Write a new JSON +
Markdown report per run.
- [x] Unit tests (`tools/test_scene_concepts.py`): catalogue shape, the no-overwrite path
picker, backdrop/tile processing on synthetic images, metrics, and the judge payload/parse
(offline, no network).
#### Step 2 — Example 3D scene images
- [x] Generate 3D-game-style example frames for every venue and time of day: Hollywood entrance
(morning, golden hour, rainy night), boulevard skyline view (day, dusk), Joke Shop alley
(evening, close-up of the door), studio stage door (night arrival), sidewalk material
close-up, entrance steps and podium, crowd-control barrier line, and a responder arrival
wide shot.
- [x] Review the set and record the visual targets each frame sets (sky, haze, material detail,
backdrop depth) in the report.
#### Step 3 — Backgrounds (replace the outdated skyline)
- [x] Generate skyline panoramas for day, dusk and night (lit windows): Hollywood/Los Angeles
mid-rise blocks, palm silhouettes, the hills on the horizon, a transparent sky, and a
straight-on view, in several variants each.
- [x] Process them into `assets/textures/ai/game_ready/v2/skyline_{day,dusk,night}*.png`,
seamless horizontally for the 3× UV repeat around the backdrop ring. Strips are 2048×1024
(2:1, one UV repeat of the 400×60 m ring is about 133×60 m). 12 candidates, 11 audit
clean; `skyline_day-v3` misses the seam limit by 0.6. Variants 1–2 contain garbled
"Hollywood" lettering, so the prompt now forbids signs. Picks: `skyline_day-v4`,
`skyline_dusk-v3`, `skyline_night-v4`.
#### Step 4 — Textures
- [x] Generate higher-detail seamless tiles: red brick facade, granite/limestone facade
(studio), sidewalk concrete pavers with joints, asphalt with aggregate, wet night asphalt,
stone steps, striped awning canvas, and stucco wall.
- [x] Process them into 1024² game-ready tiles plus normal maps in
`assets/textures/ai/game_ready/v2/` and audit them (16 tiles + 16 normals, all good). The
`awning_canvas` seam crossfade smears the stripes at the tile edge; it needs a
stripe-aligned crop.
#### Step 5 — In-game trial captures (no game-code change)
- [x] Add `src/test/capture_realism.gd`. It boots the Hollywood venue, captures a fixed shot
list (entrance day, boulevard/skyline day, boulevard night), and can swap textures at
runtime from `--swap=OLD=NEW` / `--tint=` / `--normal=` user arguments (the first version used
`--skyline=`/`--brick=`/… flags; `--swap` is path-based and also covers night stages). The
swap finds materials by their original texture path, so baseline and candidate frames use
the same camera. Writes to the `--out=` directory.
- [x] Capture the baseline (current assets) and the candidate set (v2 skyline + textures), and
copy them into `docs/screens/realism/<run>/{baseline,candidate}/`.
#### Step 6 — Compare against the realistic target
- [x] Run `scene_concepts.py realism` on baseline and candidate. Record the metric deltas and the
vision scores, and note which candidate textures/backdrops win. Run
`docs/screens/realism/2026-11-01-v2/` (`report-v2.md`, `sheet.jpg`) gives these mean
judge scores: backdrop 2.6 → 3.6 (v2 day + night skyline) → **4.0** (v2 day + dusk
skyline for the Evening phase), texture detail 1.2 → 1.6–1.75, overall 1.6 → 2.0. Single
scores swing by ±1–2 between runs, so read them as trends. The `characters` score
moved from 3.0 to 1.0 with identical NPCs, which shows the noise.
- [x] Note the remaining realism gaps (sky/fog, lighting, building geometry, NPC fidelity) as
follow-up tasks below.
#### Step 6b — Follow-ups from the 2026-11-01 realism report
- [x] Fix sidewalk overexposure: lowered the day sun (0.78→0.62), exposure (0.8→0.6) and ambient
(0.42→0.22), and darkened the sidewalk/street albedo tints. The like-for-like ground
luminance in `docs/screens/realism/2026-11-01-adopt/` went from 173/162/132 to 95/92/73
(concept targets 78/100/100). The entrance shot stays ~20 % brighter than the concept: a
residual, tracked in the follow-ups below.
- [x] Make the Evening/Late phases darker and lit by practical lights (marquee, lamps,
windows), and add wet-asphalt roughness at night, as in the rain-night concept. Evening is
now dusk (`sun 0.3→0.12`, `exposure 0.95→0.72`, dark violet sky), Late is near-dark, and
`WorldBuilder.set_phase()` swaps the street to the wet asphalt map in Late.
- [x] Choose the skyline per phase (day → `skyline_day`, Evening → `skyline_dusk`, Late →
`skyline_night`) and stop the scene fog from bleaching it. The backdrop is now a
`fog_disabled` shader, because Godot 4.3 has no `fog_enabled` on `StandardMaterial3D`. The
first dusk panorama was a red floodlit skyline that clashed with the Evening sky, so a
calmer prompt produced `skyline_dusk-v5` (blue-grey towers, lit windows).
- [x] Raise the backdrop plane (60 m → 90 m) and use 2 UV repeats so the skyline is a band with
proportions near the 2:1 panorama, not a thin strip at the horizon.
- [x] Add facade depth (plinth, string courses, cornice, brick pilasters, window glazing bars)
and replace the blob trees and shrubs with denser foliage meshes: `_shrub()` now builds
many small flat-shaded clumps plus outer clumps that break the silhouette
(`street_tree` 1472→2592 tris), with fresh AO maps for `street_tree`, `planter_box` and
`round_planter`.
- [x] Re-cut `awning_canvas` so its stripes align at the tile edge: `stripe_period()` measures the
repeat and `align_stripes()` resamples to a whole number of periods (edge crossfade smeared
the stripes before). `audit_striped_tile()` checks the wrap step against the harshest
interior step instead of the flat edge-difference rule.
- [x] Capture shots from the Joke Shop and the studio too: `capture_realism.gd` now runs five
stages (day, evening, late, joke_shop, studio) with 9 shots and a `--stages=` subset. The
venues share the Hollywood geometry, so those two compare lighting, not layout.
#### Step 7 — Adopt the winners
- [x] Track the validated picks in place (ADR-0014). `.gitignore` now ignores the candidate pool
and un-ignores `game_ready/v2/picks/`, where `scene_concepts.py promote` copies the eight
validated candidates under stable names (`skyline_{day,dusk,night}`, `brick_facade`,
`sidewalk_pavers`, `asphalt`, `asphalt_wet`, `awning_canvas`) plus normal maps.
- [x] Point `WorldBuilder` at the chosen v2 skylines (separate day/dusk/night textures through
the new `set_phase()`), and retune the tints per phase.
- [x] Switch `materials.gd` / `world_builder.gd` surface preloads to the chosen v2 tiles + normal
maps, keeping the current UV scales (`Materials.asphalt()` gained a `wet` variant). Updated
`test_materials.gd` (pick paths, wet vs dry) and `test_world.gd` (shader backdrop, panorama
per phase, wet street).
- [x] Regenerate `docs/screenshots/` with `capture_screenshots.gd` (11/11), then run
`screen_designs.py compare` (**11 good / 0 bad**) and `judge` (5 match, 2 review, 4 diff —
the diffs are HUD/mockup layout gaps from the "Visual alignment" section, not realism
regressions; the default flash-lite judge model is currently failing with a provider 400, so
the run used `--model google/gemini-2.5-flash`). `scene_concepts.py realism` on
`docs/screens/realism/2026-11-01-adopt/` (3 judge repeats per shot) gives a like-for-like
improvement on every sub-score: overall 0.8→1.0, lighting 0.8→1.0, materials 0.8→1.0,
texture 0.8→1.0, backdrop 0.6→1.6, and the Pillow metric gap 0.444→0.348.
- [x] Update `README.md` (tool usage + gallery), `MEMORY.md` and `docs/architecture.md`.
## Visual Alignment — UI Paths and Art Loader
Completed 2026-11-01.
@@ -950,3 +1104,26 @@ Completed 2026-11-01.
## Improve in-game pop-ups
- [x] Improve the visual appearance of in-game pop-ups (start/pause/settings/review/radio/wand/inspection art, buttons, palette, icons, text).
## Visual Alignment With Rendered Mockups
Completed 2026-11-01. Every screen with an AI reference now loads or matches its mockup: the
runtime image root (ADR-0014), the UI/scene art loader, the menus/panels/HUD, and — last — the
scene lighting, fog and post-processing, which had been held until the realism pass landed.
`screen_designs.py compare` **11 good / 0 bad**; judge on the two scene shots: `01-venue-overview`
**match** (0.90), `05-late-night-avenue` **review** (0.10), 0 diff. Lighting: morning sun 34°
elevation with a phase `sun_yaw`, warm day haze (`fog_color` 0.87/0.83/0.76, density 0.0034,
energy 0.5), stronger night glow, street albedo 0.62. Remaining differences (camera height,
marquee text, hand-authored tree shapes) are content, not grading.
### Visual alignment with rendered mockups
#### Align in-game visuals
- [x] Make the venue selection screen match the `start_menu` mockup (layout, palette, background).
- [x] Make the HUD match the `targeting_npc` / `escalation_hud` mockups (focus ring, escalation meter, log, hints).
- [x] Align the pause, settings, and shift-review panels to their mockups.
- [x] Align the radio and wand panels to their mockups.
- [x] Align the body-camera timeline to its mockup.
- [x] Align scene lighting, fog, and post-processing for `venue_overview` and `late_night_avenue`: lowered the morning sun to 34° (`sun_yaw` is now a phase value), warmed and thickened the day haze, raised the night glow, and brightened the street albedo. `judge` moved `01-venue-overview` to **match** (0.90) and `05-late-night-avenue` from diff to **review** (0.10); `compare` stays 11 good / 0 bad.
- [x] Fix the body-camera REC/clock overlay overlapping the shift/rep/crowd status in the top-right HUD.