Files
gig-line/Docs/Architecture/09_architecture_decisions.md
T
zwitschi 4132f42ca1 plan: give realistic buildings their own minor milestone (0.9.0)
The facade work started as a patch (0.1.4) and the 0.1.6 retail pass showed what
that costs: a patch has no release gate of its own, so a first pass that does not
yet read as the building can sit inside a done patch series. Realism is also the
leading quality goal, which a patch cannot carry.

New 0.9.0 - Realistic buildings, before the feature freeze: facade system with more
than one order, a profile library, storefront types, signage as decals, per-building
photo-matched models, a measured material library with a texel-density rule, and
LODs plus collision proxies. Former 0.9.0 freeze/beta/audit becomes 0.10.0 with
patches 0.10.1-0.10.3; 1.0.0 moves to weeks 39-44.

Recorded as ADR-8 (append-only) with a measurable gate BR-1..BR-5 in the quality
requirements, mirrored into the combined architecture.md. The 0.1.6 item now says
which of its gaps move to 0.9.0 and why more geometry cannot close them.
2026-11-09 09:54:15 +01:00

4.7 KiB
Raw Blame History

Architecture Decisions

ADR-1: Dynamic-only lighting for the demo

  • Context: The demo is a fixed daytime scene. Stationary lights demand a lighting build and produce "LIGHTING NEEDS TO BE REBUILT" warnings.

  • Decision: r.AllowStaticLighting=False, all lights MOVABLE.

  • Consequences: No bake step, no warning, simpler iteration. Slightly higher GPU cost per frame (no baked shadows) — acceptable for the demo scope.

ADR-2: Materials authored in Unreal, not imported from Blender

  • Context: FBX→Unreal import maps all Blender diffuse colours to white. Flat colour materials do not survive the pipeline.

  • Decision: Build all materials (asphalt, concrete, stucco, façade stone, road paint) directly in Unreal with procedural nodes.

  • Consequences: Materials cannot be previewed in Blender look-dev. Must round-trip to Unreal for visual check. But: full PBR control, world-space noise, no import surprise.

ADR-3: Complex-as-simple collision on terrain via C++ helper

  • Context: UE 5.8 removed bUseComplexAsSimpleCollision. Python cannot set CollisionTraceFlag on StaticMesh/BodySetup at all. The Interchange default is bbox-only simple collision, which placed an invisible lid 8 m above the street.

  • Decision: UGigLineAssetTools::SetComplexCollisionAsSimple (C++) forces CTF_UseComplexAsSimple and saves the asset.

  • Consequences: One C++ helper class. The flag must be saved on the asset (not just the map). No Python workaround exists.

ADR-4: Reset captures StartLocation on first grounded frame

  • Context: BeginPlay captures StartLocation at the PlayerStart, which is above grade (Z 600) so the capsule does not spawn embedded. Every reset dropped the player 1.4 m back into the air.

  • Decision: Repeating 0.25 s timer captures StartLocation once the character reports IsMovingOnGround(), then clears itself.

  • Consequences: Reset is correct. A one-shot timer at 2 s is wrong (fires after walking begins, records mid-stride position).

ADR-5: Core ticker for QA self-test, not world timer

  • Context: Pausing the game stops world timers. A timer-driven test freezes exactly when it proves pause works.

  • Decision: FTSTicker::GetCoreTicker() drives the -qaselftest harness.

  • Consequences: Test runs even while paused. Must be enabled explicitly (-qaselftest), never in normal play.

ADR-6: South = +Y, north = −Y in Unreal

  • Context: The street mesh established this convention: Sidewalk_North has Y range −1912..−1053, Sidewalk_South has +718..+1447.

  • Decision: Adopt it project-wide. Never place a building by assumption; always verify against a street mesh or neighbour.

  • Consequences: Matches Blender’s north→+Y after the Y-flip in the ue_metric_v1 export preset.

ADR-7: Headless Blender via bpy scripts, not MCP

  • Context: Blender skill packs assume an MCP server; the project does not run one.

  • Decision: All Blender work driven by Python scripts in Tools/. Skill packs used as method guides (checklists, naming, proportions) only.

  • Consequences: Scripts are version-controlled and repeatable. No live Blender session needed for CI.

ADR-8: Realistic building façades are a minor milestone, not a patch

  • Context: 0.1.4 carried the first façade pass as a patch, while the release policy says patches contain fixes and refinements and never new scope. The 0.1.6 retail pass then showed what that costs: a façade built in a patch has no release gate of its own, so a first pass that does not yet read as the building (Screenshots/README.md, 0.1.6 gaps) can sit inside a "done" patch series. Realism is also the project's leading quality goal, which a patch cannot carry.

  • Decision: Building realism gets its own minor milestone, 0.9.0 — Realistic buildings, placed before the feature freeze. Its scope is the façade system (orders, profile library, storefront types, signage as decals), per-building photo-matched models, a measured material library with a texel-density rule, and LODs plus collision proxies. Patches keep fixes and refinements only. Renumbered by this decision: the former 0.9.0 freeze/beta/audit milestone becomes 0.10.0, its patches 0.10.1–0.10.3, and 1.0.0 moves to weeks 39–44.

  • Consequences: Façade work now has a release gate — every building measured against its own photograph, every building with a collision proxy and a LOD, no placeholder materials — so "modelled" means verified, not merely present. The price is that realism work stops being sliced into patches, and the schedule shifts by one minor cycle. Blockouts without a photograph stay blockouts and are listed as such, rather than being dressed up to fill the milestone.