feat(facades): 0.1.5 — hero detail, scene audit, material orphaning fixed #32

Merged
zwitschi merged 5 commits from facade-finishing-0.1.5 into main 2026-11-08 22:56:08 +01:00
5 Commits
Author SHA1 Message Date
zwitschi 73635df1a1 release: v0.1.5 — changelog entry, TODO pruning, roadmap
- CHANGELOG: full 0.1.5 entry (scene audit, ue_placement, hero fluting, recessed
  motto band, kit layout fix, the 604-unmaterialed-actors fix, the 13 m hero
  placement drift, 363 fps re-measure, limitations).
- TODO: 0.1.5 section removed; blocked retail frontage carried into a new 0.1.6
  patch with the reason recorded, rather than letting the release wait on missing
  reference photography.
- ROADMAP status updated.
2026-11-08 22:54:41 +01:00
zwitschi 600633cd5b fix(materials): stop orphaning references; add a scene audit gate
The blockout cleaning pass found the map was rendering with 604 of 620 mesh actors
unmaterialed - every kit piece and all theatre trim.

Cause: ensure_material() deleted and recreated each /Game/Hollywood/Site/M_* asset on
every run, so actors staged by other tools kept references to deleted assets and fell
back to the default material. Nothing errored; the map looked merely slightly flat.

- Materials are now updated IN PLACE (load, delete_all_material_expressions, rebuild
  the graph, recompile, save). Material.expressions is protected from Python, so the
  editing library's deleter is used.
- 53 duplicated kit actor labels fixed (both shop piers of a bay shared one name).
- New Tools/ue_audit_scene.py gates the scene: every mesh actor has a material, every
  verified frontage span is within +/-1 m (via ue_placement), no duplicate labels.
- render_screenshots.sh now runs the chain in the required order (demo map -> kit ->
  theatre -> audit -> cameras -> capture) and exits non-zero on an audit failure,
  because the demo builder rebuilds materials and later staging must follow it.

Scene audit: 0 failures. Packaged QA PASS. Spawn-view reference score 0.72.
2026-11-08 22:48:00 +01:00
zwitschi 442d0f3d73 perf: 1440p re-measured with the kit - 363 fps, ~12% cost
Closes the 0.1.5 performance task. Same route and preset as 0.1.0 (packaged
Development, Epic scalability, TSR, VSync off, no frame generation, 2560x1440):

  0.1.0                2.42 ms (414 fps)  p99 3.01
  0.1.5 (kit)          2.76 ms (363 fps)  p99 3.64

The 625 kit actors and 8 generated textures cost about 12% of frame time and still
leave roughly six times the 60 fps floor. Frame-time series committed at
Docs/perf/0.1.5-kit-walk-frametimes.csv; comparison table added to
Docs/release-checks.md.

Records the measurement trap once more: runs showing ~105 fps were two overlapping
game instances, not the build - 363 fps reproduced twice on a clean single instance.
2026-11-08 22:38:04 +01:00
zwitschi 92b477d340 feat(hero): fluting and a recessed motto band; placement gets one source of truth
Hero detail:
- Fluting: 20 grooves per column as thin shadow-tone cylinders set into the shaft
  (120 pieces) rather than boolean cuts - readable in silhouette and grazing light
  at a fraction of the cost.
- Motto band: real recess with a moulded surround 6 cm proud and the panel 12 cm
  behind, replacing the 8 cm dark stripe.
  Hero 148 parts/3044 tris -> 271/5492, still 14.50 m.

Placement bug this exposed (a real one, invisible in a render):
- ue_hero_facade_import.py carried its own hero position (-12024.5, -1450) from
  before the 0.1.0 frontage fix, so running the importer alone moved the hero 13 m
  east and onto the north side of the boulevard. Only symptom: the reference score
  fell 0.69 -> 0.56 and the 3x3 composition correlation flipped +0.54 -> -0.08.
- New Tools/ue_placement.py is the single source of truth (hero position, verified
  frontage spans, span validators). Both the importer and the demo builder use it;
  the import asserts the staged span and logs PLACEMENT ERROR otherwise.
- 11 new tests, including one that fails if the stale literal returns. 78 total.

Spawn-view score recovered to 0.72 (best yet); screenshots verified 4/4, packaged QA
all PASS.
2026-11-08 22:12:44 +01:00
zwitschi bc5da3a8ab fix(kit): cap bay count and fill the storey spread; fetch the retail reference
Kit layout, found while starting the retail pass:
- Bays were round(width / 4.96), so 6922 (65.8 m wide) got 13 bays - a window every
  4.96 m across a 37 m block. Capped at MAX_BAYS = 9, widening the module instead.
- Storeys were assumed exactly 310 cm apart, leaving ~1.6 m of bare wall under the
  cornice on a tall building. The spread is now derived from the available height
  (usable / storeys), so the top band lands inside the volume.
  Result: 6922 9x11 (was 13x11), theatre 8x6, 6806 7x3, 6800 4x3, TCL 9x5.

Retail references: fetched Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg
(Gb321, CC BY-SA 4.0) - 6800 and its neighbour at street level, confirmed to show
shopfronts and parapets. Commons has nothing for 6822 or 6806-6820, so those two
remain blocked on reference photography; recorded in TODO.

Re-applied the kit, repackaged, screenshots re-rendered and verified 4/4, packaged
QA all PASS.
2026-11-08 22:05:08 +01:00