Files
gig-line/Docs/reviews/0.1.4-review.md
T
zwitschi 567ca0e4c7 docs(review): comprehensive 0.1.4 review for the owner
Consolidates the branch: what changed (9 commits, 89 files), the evidence that
holds up (packaged -qaselftest, coordinate probes, budgets, 67 tests), all 15
defects found this cycle with severity/root cause/how each was caught, the
iteration toolchain and its current measurements, known limitations, and an
explicit list of what is NOT verified and needs a human.

Also records two things the earlier QA doc did not: the QA self-test is time-based
and can flake (one run reported walk 246 cm and pause FAIL; an immediate re-run
reported 761 cm and PASS with identical content), and the visual-loop scores are a
trend across iterations rather than an absolute quality number, because a wide
block view compared with a tight facade crop always scores low on edge similarity.
2026-11-08 20:21:10 +01:00

250 lines
16 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.
# Review — `0.1.4` building façades
A consolidated review of the work on branch **`facades-0.1.4`**, written for the project owner. It states what changed, what is actually verified, what is only claimed, the defects found on the way, and the decisions that need a human.
Written 2026-11-09. Branch `facades-0.1.4`, 9 commits ahead of `main` (`ba68dcf`), tags `v0.1.0`–`v0.1.3` already released.
---
## 1. Executive summary
The façades went from **flat extruded boxes with flat colours** to **coursed, textured surfaces assembled from a reusable 16-piece module kit**, with a theatre that finally reads as the El Capitan Theatre (marquee, fascia, blade sign). All build and behaviour checks pass, and 67 tool tests pass.
**One thing this document cannot do:** tell you the buildings _look_ right. Every defect that survived more than one render in this cycle was a **placement** error that rendered convincingly — a 119 m frame shift, a kit 12 km off, a mirrored marquee. So the visual verdict below is explicitly marked as pending, and there is a toolchain section (§6) for turning it into measurements.
| Area | State |
| --- | --- |
| Build (editor + game targets, packaged) | **PASS** |
| Behaviour (`-qaselftest`: walk, reset, pause, transect, wall probe, façade probe) | **PASS** (see §7 on flakiness) |
| Tool tests | **67 pass** |
| Geometry placement (verified by coordinate probes) | **PASS** |
| Materials (graph + textures + per-slot) | **Implemented**, visual verdict pending |
| Module kit + assembly on 8 buildings | **Implemented**, visual verdict pending |
| Theatre marquee + blade sign | **Implemented**, visual verdict pending |
| Reference match | **NOT verified** — needs your eyes |
| Release | **Not tagged** — `v0.1.4` waits on review |
---
## 2. Where the project stands
| Version | Date | Content |
| --- | --- | --- |
| `v0.1.0` | 2026-11-08 | Walkable demo: hero façade, block frontage, first-person controls, ODbL HUD, all release checks |
| `v0.1.1` | 2026-11-08 | Collision patch: sidewalk edge flush, crossing ramps graded to 8 %, QA probes |
| `v0.1.2` | 2026-11-09 | Scale + façade: 3.1 m storey height (Mapbox-calibrated), colonnade 47.6 → 53.1 %, window plane, medallions, hero collision |
| `v0.1.3` | 2026-11-09 | Packaging/setup: importers clear the LFS read-only bit; docs match the pipeline |
| `0.1.4` | **in review** | Façade kit, materials, textures, theatre trim, visual loop |
---
## 3. What `0.1.4` changed
**89 files, +2 565 / −180.** Nine commits, in order:
1. **Materials** — masonry coursing and roughness variation in the material graphs; new `M_FacadeStoneShadow`, `M_FacadeGlass` (specular 0.62 ≈ IOR 1.5), `M_FacadeBanner`; **per-slot** material assignment (it was slot-0 only, which on the hero is the banner, so stone and glass were still flat).
2. **Texture maps** — `Tools/generate_facade_textures.py`: deterministic stdlib-only PNGs for ashlar, stucco, asphalt, concrete (base colour + roughness), sampled world-aligned with per-material tiling.
3. **Module kit** — `Tools/facade_kit_build.py`: 16 pieces at the measured **4.96 m bay** / **3.10 m storey**; `ue_import_facade_kit.py`, `ue_apply_facade_kit.py` assemble **625 pieces across 8 buildings**.
4. **Blockout frame correction** — the `0.1.2` regeneration had run without `--origin`; regenerated with the affine fit and re-verified every frontage span.
5. **Kit hygiene** — `SM_` asset naming, per-piece topology validation (all 16 manifold, 12 tris each), stale-asset removal.
6. **QA verdict** — `Docs/qa/0.1.4-facade-qa.md` with budgets, evidence, severities.
7. **Visual loop** — `Tools/visual_loop.py` + `visual_targets.json`: verify captures, measure against references, emit skill-addressed feedback. Iterations gitignored.
8. **Screenshots** — demo-map only; per-shot expectations and a verified column.
9. **Theatre trim** — marquee canopy, illuminated fascia, soffit, blade sign.
New tools: `facade_kit_build`, `generate_facade_textures`, `theatre_trim_build`, `ue_apply_facade_kit`, `ue_import_facade_kit`, `ue_stage_theatre_trim`, `visual_loop` (+ `visual_targets.json`). New test files: `test_visual_loop`, plus the earlier `test_fbx_export_preset`, `test_ue_common`, `test_mapbox_buildings`, `test_facade_detail_concepts`, `test_block_height_report`, `test_input_emulation`.
---
## 4. Evidence that holds up
### Behaviour — packaged build, `-qaselftest`
```
start XYZ=(-13336,-1150,600) → settled XYZ=(-13336,-1150,456)
walk moved 761 cm in 2 s PASS (Z 456 → 456)
reset returned 0 cm from spawn PASS
pause / unpause PASS
transect 1456 samples, 0 holes PASS
wall probe 0/35 blockers PASS
facade probe 0/9 missing walls PASS
RESULT PASS
```
### Placement — probed from the live map, not assumed
| Building | World X span | Verified against |
| --- | --- | --- |
| 6922 | −24276…−17700 | `Geo/verification/2026-11-06-el-capitan-block.md` |
| 6902 | −17749…−14591 | same |
| **6840 hero** | **−14644…−12028** | sits between 6902 and 6838 ✔ |
| 6838 theatre | −12082…−8210 | same |
| 6822 / 6806 / 6800 | −7854…−1437 | same |
| TCL / Tussaud's | −22889…−18442 / −27071…−22799 | same |
Blockout affine fit residual **0.0 cm**; kit pieces land inside their building's span (theatre pieces at −12082…−8694).
### Budgets
| Asset | Count | Cost |
| ------------- | --------------- | ------------ |
| Hero façade | 148 parts | 3 044 tris |
| Kit | 16 meshes | 12 tris each |
| Kit instances | 625 actors | ~7 500 tris |
| Theatre trim | 6 pieces | boxes |
| Textures | 8 × 512² | 196 KB total |
| Screenshots | 4 demo captures | 11 MB |
### Tests
67 tests across 7 files: input driver, height classification, Mapbox cross-check, concept generator, FBX preset, `ue_common`, visual loop (metrics on synthetic images, comparison scoring, feedback rules, target spec).
---
## 5. Defects found this cycle
Severity per the `qa-review` scale. **Every one of these rendered convincingly.**
| # | Sev | Defect | Root cause | Caught by |
| --- | --- | --- | --- | --- |
| 1 | Blocker | Frontage shifted ≈119 m X / 2.4 m Y; hero outside its gap | Blockout regenerated **without `--origin`** | Coordinate probe vs verification doc |
| 2 | Blocker | Kit pieces ~12 km from their buildings | Used mesh-local bbox; actors carry the offset | Coordinate probe |
| 3 | Blocker | Marquee on the **far side** of the boulevard | Blender +Y = Unreal −Y; used +10.01 not −10.01 | Coordinate probe |
| 4 | Major | Marquee canopy **5 cm above the pavement** | Absolute Z; pavement is 4.56 m above datum | QA wall probe |
| 5 | Major | Window bays invisible (inside the solid wall) | Piece modelled entirely at +Y | Edge-density flat in iteration metrics |
| 6 | Major | Kit had no materials — glazing wasn't glass | Grey `M_Kit_*` from FBX import, never overridden | QA review pass |
| 7 | Major | Windows floated 1.44 m in front of the wall | Wrong Y in the hero builder | Mesh measurement |
| 8 | Major | Medallions were pancakes on the coping | Built with the Z-axis cylinder helper | Mesh measurement |
| 9 | Major | Hero had **no usable collision** — walk through it | Complex-only; traces use simple | New façade probe |
| 10 | Minor | "No smoothing group information" on every import | `mesh_smooth_type="OFF"` in six exporters | Import logs |
| 11 | Minor | `save_map()` returning False silently | LFS `.umap` read-only; importers never chmod'd | Log read (`save_map: False`) |
| 12 | Minor | North-buildings import silently no-op (exit 255) | Missing `import sys` | Import result file |
| 13 | Minor | Kit folder held 24 assets (8 orphan materials) | No stale-asset sweep | Asset probe |
| 14 | Minor | Edge-density metric counted PIL's border ring | `FIND_EDGES` leaves a 128 ring | Unit test on a flat image |
| 15 | Minor | QA wall probe grazed the theatre wall | Scan row 1 cm from the building line | QA FAIL |
**Pattern worth keeping:** 3 of the 4 blockers were _coordinate_ errors caught by probes, not by pictures. The probes are now permanent (`-qaselftest`, kit/asset probes, `visual_loop --verify`).
---
## 6. The iteration toolchain (`Tools/visual_loop.py`)
```
reference photo ─┐
├─ compare ─► metrics + feedback ─► skill-named actions
demo capture ──┘ │
└─ next iteration (uncommitted)
```
- **`--verify`** — gates each capture against its expectation in `Tools/visual_targets.json`: missing, blank, tone-less or wrong-size shots fail.
- **`--compare`** — luminance, RMS contrast, **edge density**, palette distance and a 3×3 luma grid, scored 0–1.
- **`--iteration N`** — writes `Art/reference/iterations/N/{metrics.json,feedback.md}`. **Gitignored** until you confirm a shot; only confirmed shots reach `Screenshots/`.
- Feedback names the skill to consult (`blender-modeler`, `archviz`, `materials`, `lookdev`, `camera-cinematography`).
### Current measurements (iteration 4)
| Shot | Score | Δ luma | Contrast | Edges | Palette | Composition |
| --- | --: | --: | --: | --: | --: | --: |
| demo-spawn-view | **0.68** | −9 | ×0.85 | ×0.28 | 18.2 | r=0.54 |
| demo-street-level | 0.33 | +39 | ×0.70 | ×0.27 | 67.7 | r=−0.91 |
| demo-crossing | 0.42 | +32 | ×0.70 | ×0.34 | 22.2 | r=−0.33 |
| demo-north-buildings | 0.34 | −44 | ×0.77 | ×0.14 | 61.9 | r=−0.46 |
**Read this carefully.** Edge density is **0.14–0.34×** the reference everywhere — the render still carries a fraction of the relief in the photographs. The low scores are not a bug in the metric, but they are also **not a fair verdict on the buildings**: a wide block view compared with a tight façade crop will always report low edge similarity and poor composition correlation. Treat the scores as a _trend across iterations_, not as an absolute quality number.
---
## 7. Known limitations
1. **The QA self-test is time-based and can flake.** One run reported `walk 246 cm` and `pause FAIL`; an immediate re-run reported `761 cm` and `pause PASS` with identical content. Likely a starved process or a second instance. **Do not trust a single FAIL — re-run before acting**, and prefer two consecutive passes before calling a release good.
2. **The vision pre-check is unreliable on this content.** It has rejected shots you have since approved, and it disagreed with itself between runs. It stays advisory; it is never a gate.
3. **Kit pieces are boxes.** No reveals, sills or mouldings beyond the kit's bands. That is the intended fidelity for this patch — the kit is the vocabulary.
4. **`M_Kit_*` materials are deleted at import**; the Unreal material set is authoritative, the Blender materials carry no shading intent.
5. **Textures are generated, not authored.** They are deterministic and repeatable but generic: no decals, no signage text, no weathering maps.
6. **Cornice dentil spacing, abacus and plinth dimensions are assumptions** — the reference photography does not resolve them at our scale.
7. **`Screenshots/` holds 4 demo captures only** by design; the review staging map is no longer rendered for review.
---
## 8. What is _not_ verified (this is what needs you)
- **Does the block look like Hollywood Boulevard?** Compare `Screenshots/demo/*` against `Art/reference/hollywood/` and `Art/reference/el-capitan-*`. The metrics say the render is flatter and lighter than the photographs; only you can say whether it reads as the place.
- **Does the theatre read as the El Capitan?** Marquee proportions (12.0 × 2.6 m at a 4.6 m soffit) and blade sign (1.3 × 5.2 m) are assumptions from the reference set, not measurements.
- **Do the shopfronts and window rhythm look right at street level?**
- **Are the 4 shots in `Screenshots/README.md` approved?** Each row has a verified column for the mechanical check; approval is still yours.
---
## 9. Decisions taken
| Decision | Rationale |
| --- | --- |
| **Adopt Mapbox heights** (3.1 m per level + 3 overrides) | Second independent source; block now 66 matches, 0 disagreements |
| **Blosm `setupScript` style closed as superseded** | The module kit already gives every building an elevation; a second system would duplicate it with different assumptions |
| **Screenshots are demo-map only** | The review staging map is not what ships; a reviewer should see the game |
| **Iterations stay uncommitted** | Prevents unconfirmed geometry becoming "the record" |
| **Vision model advisory, never a gate** | Demonstrably unreliable on this content |
| **Textures generated, not committed** | Deterministic, reproducible, keeps the repo lean (196 KB regenerated on demand) |
---
## 10. Risks for the next cycle
1. **Placement drift is the dominant failure mode** (3 blockers in one patch). Any new asset should be probed for its world span before it reaches a render.
2. **The kit is not yet a _measured_ vocabulary.** Bay and storey are measured; the pilaster depth, sill projection and fascia height are assumptions. Scaling this to the remaining 7 buildings multiplies the assumption count.
3. **QA flakiness** (§7.1) could mask a real regression or manufacture a false one.
4. **Reference coverage is thin for the retail neighbours** — the 18-frame set is the El Capitan Theatre, not 6806/6822/6800.
5. **No performance measurement since `0.1.0`.** 625 kit actors and 8 textures have not been measured against the 60 fps budget (it had enormous headroom: 414 fps).
---
## 11. Recommended next steps
| # | Action | Why |
| --- | --- | --- |
| 1 | **Review `Screenshots/demo/*` and the 4 README rows** | The only unverified claim left |
| 2 | Decide whether to tag `v0.1.4` as-is (kit + materials + trim) and move the remaining geometry to `0.1.5`/`0.2.0` | The remaining items are scope, not fixes |
| 3 | Re-measure 1440p performance with the kit in place | 625 new actors, never measured |
| 4 | Retail neighbours from their own references (not the theatre's 18-frame set) | Prevents misattributed façades |
| 5 | Hero fluting + motto band as geometry | Last hero detail from `0.1.4` |
---
## 12. How to verify any of this yourself
```bash
# build + behaviour
cd /run/media/system/DATA/Engines/UE_5.8.4
Engine/Build/BatchFiles/Linux/Build.sh GigLine Linux Development \
-project=/run/media/system/DATA/Documents/06-games/gig-line/Game/GigLine/GigLine.uproject -WaitMutex
cd /run/media/system/DATA/Builds/GigLineQA/Linux
./GigLine.sh -windowed -ResX=1280 -ResY=720 -nosplash -qaselftest
grep "GigLine QA:" GigLine/Saved/Logs/GigLine.log
# tool tests
cd /run/media/system/DATA/Documents/06-games/gig-line
python3 -m unittest discover -s Tools/tests -t Tools -p 'test_*.py'
# screenshots + verification + measurements
Tools/render_screenshots.sh --verify
python3 Tools/visual_loop.py --compare --iteration 5
```
---
## 13. Appendix — tool inventory added this cycle
| Tool | Purpose |
| --- | --- |
| `facade_kit_build.py` | 16-piece module kit at the 4.96 m bay / 3.10 m storey, with topology validation and a part report |
| `ue_import_facade_kit.py` | Import to `/Game/Hollywood/Kit`, complex-as-simple collision, stale-asset sweep |
| `ue_apply_facade_kit.py` | Assemble the kit from each building's **world** bounds (625 pieces) |
| `generate_facade_textures.py` | Deterministic stdlib PNG generator for 4 surface sets |
| `theatre_trim_build.py` | Marquee, fascia, soffit, blade sign in world coordinates |
| `ue_stage_theatre_trim.py` | Import + stage the theatre trim with site materials |
| `visual_loop.py` / `visual_targets.json` | Verify captures, measure against references, emit skill-addressed feedback |
| `fbx_export_preset.py` | One export preset (was six copies); exports smoothing groups |
| `ue_common.py` | Clear the LFS read-only bit, make save failures loud |
Document written by the agent that did the work; it is deliberately blunt about what it could not check.