What the first pass got wrong, and what changed:
- The mural plates were placed 0.20 m INSIDE the solid blockout volume, so they
never rendered. Nothing can be recessed into a solid we do not cut: the inset is
now faked by a proud frame with a near-flush plate, and the row reads.
- Detail sat 0.05 m off the wall, under a pixel of depth at 40 m. Trim planes now
stand 0.10-0.20 m proud, and the parapet became two tiers with deeper reveals.
- 6806's parapet started at 0.62 H and left a 4.6 m blank band; the window storey
and parapet moved up to follow the photograph.
- Security bars on the upper windows, twelve fluted fins on the corner tower.
- The trim's stucco/white/glass slots are mapped onto the demo's look materials, so
the walls sit in the same noise/texture family as the rest of the block; the
colour slots sampled from the photograph stay as authored.
- Review camera pulled back and widened to 66 deg so the east end is in frame.
- The scene audit caught duplicate RetailTrim_ actors: the demo builder's clear list
did not include the new label, so every rebuild stacked another copy.
Still open and not fixable by geometry: wall lettering. A plate at 0.10 m does not
read at 40 m, so it moves to the 0.9.0 decal route (TODO.md, Screenshots/README.md).
Models the two retail buildings beside the hero from their own photograph rather
than the generic kit: bronze cornice, mural row, lettering band, stepped Deco
parapet and rounded corner tower on 6800 Lee Drug; burgundy fascia, pilasters,
white-framed windows and banded parapet on 6806-6820. Reference analysis written
before any geometry (Art/blender/retail/ref-analysis.md), every unmeasured
proportion carried into the part report as an assumption.
6822 Budget is deferred, not guessed: no photograph of it exists and the 6.0 x 5.5 m
sliver cannot be read out of the neighbour shot.
Pipeline fixes found on the way:
- render_screenshots.sh called ./Engine/... for the capture step while every
commandlet used the absolute path; set -e killed the script at 127 *after* the
maps were rebuilt, so screenshots silently stayed a day old.
- the facade kit applies to every Frontage_*/North_* actor, so it pasted its own
language over the new modelled facades; it now skips them, and the trim stages as
RetailTrim_*.
- pure bay arithmetic moved to Tools/_common.py so it is unit-testable without
Blender (4 new tests, 82 total pass).
Known gaps recorded in Screenshots/README.md, not hidden: the parapet reads as a
blank band, murals and lettering do not resolve at review distance, the tower is a
plain cylinder, and the review camera crops the east end.
The reported fall-through was a misdiagnosis: the player never fell. The
imported Terrain_DEM had only a bounding-box simple collision proxy, so a
downward trace anywhere in the block hit the terrain at Z 819 (the mesh
bbox max) and the street sat under an invisible 8 m lid. Standing on that
box looked plausible, which is why it read as working.
- add UGigLineAssetTools (C++): force CTF_UseComplexAsSimple on a static
mesh. UE 5.8 dropped bUseComplexAsSimpleCollision and Python cannot set
the flag; the builder also saves the asset, since the flag lives there
and a map-only save silently reverts it.
- spawn (-13336, -1150, 600): inside the carved corridor (the cut is a
10.7 m half-width around the road centreline), lands on the road at 456.
- fix ResetToStart returning to the mid-air PlayerStart captured in
BeginPlay: StartLocation is now captured on the first grounded frame.
- HighResShot 1280x720 instead of "1280 720", which is a multiplier.
- add -qaselftest: scripted walk/reset/pause on a core ticker plus a
swept ground transect. Results: walk 746 cm/2 s with Z steady, reset
0 cm from spawn, pause/unpause 1/0, transect 84 samples 0 holes.
- rebase onto main, keeping the frontage materials and placement fixes.
Completes "Fixed daytime lighting and basic ambience" for 0.1.0. All 14
screenshots approved by the owner.
Lighting rig (Tools/ue_build_demo_map.py):
- Sun pitch -50 / yaw 120, intensity 4, warm (255/245/230), atmosphere sun light
- Sky light 2.6 with real-time capture, sky atmosphere, height fog (density 0.008)
- Unbound post-process volume with fixed exposure (min == max brightness) so a
shot cannot wash out or crush to black depending on how much sky it frames
- Dynamic-only: r.AllowStaticLighting=False plus MOVABLE lights and mesh
components, so the editor's "LIGHTING NEEDS TO BE REBUILT" warning no longer
fires and nothing needs baking
Bugs found and fixed on the way:
- Blender diffuse colours do not survive the FBX -> Unreal import: every site
material arrived white and the terrain arrived with WorldGridMaterial, which
is what actually made the scene look blown out. The demo builder now creates
and assigns M_Asphalt, M_Concrete, M_Ground and M_RoadPaint.
- Only one of the three crossings reached the game: each zebra band was its own
object, so Blender renamed the duplicates .001/.002 and exact-name site
assembly skipped them. All bands are now one Crossing_Markings mesh.
- Demo cameras: street-level sat inside the facade body (rendering its unlit
back face) and the crossing camera aimed at the s=36.6 crossing instead of
the designated s=130.1 (UE X -14956).
- The terrain had no material and imported as a bright default grid.
- Cleared a committed Android File Server SecurityToken (plugin disabled and
shipping-excluded; the value must stay empty).
Docs:
- Screenshots/README.md: one consolidated table for all 14 shots with map,
camera view and description; all approved.
- MEMORY.md: records the material-import, exposure, light_color struct,
band-naming, camera-bounds and lighting-build traps.
- TODO.md: lighting item marked done.
Squash of branch gameplay-lighting-0.1.0 (PR #3).
- street_mesh.py: continental zebra markings (0.5 m bars, 0.5 m gaps, 3 m
band) at all three signalised crossings, triangles not quads (FBX SDK
refuses to triangulate the crown-twisted quads), stripes +6 cm above the
DEM so they stay above the road surface; winding flipped so every street
surface faces up (road/sidewalks/markings were 100% down-facing and
invisible in engine once the terrain stopped covering them).
- terrain_from_dem.py: cut a 10.7 m corridor around the Hollywood Blvd
centreline so road, kerbs and sidewalks are not buried under the terrain;
sidewalks themselves cover the transition band, walk-check stays at 0 holes.
- Blender builders save with a writability guard + fatal failure: *.blend
is LFS-lockable and checks out read-only; a failed save previously left
downstream steps building from stale files.
- ue_import_site.py: Crossing_Markings imports with no collision (paint on
the road); ue_build_demo_map.py stages it and chmods the lockable .umap
before saving (save_map silently returned False on read-only maps).
- ue_build_review_map.py: demo-crossing camera moved to the real crossing
(s=130.1 m -> UE -24291,-1340) and fixed the ensure_writable path (was
missing the .umap suffix, so the chmod never fired).
Tools/ue_build_demo_map.py builds /Game/Hollywood/DemoMap: sun, sky, the hero
facade on the building line, six site meshes imported with collision, and a
player start on the north sidewalk. Tools/ue_import_site.py imports the site
FBXs; terrain, road and sidewalks use complex-as-simple so a simple hull cannot
ramp over the kerbs. Art/blender/site/export_site_fbx.py exports one FBX per
object so each can carry its own collision.
Reset (R) and pause (Escape) join the character and the input context: reset
restores the spawn transform and clears momentum, pause is a real game pause that
releases the cursor. DefaultInput.ini captures the mouse on launch.
Three placement defects found by measuring the imported actors rather than
trusting the plan: the spawn was on the wrong sidewalk because the FBX flip
inverts north, a mirror I added to the exporter double-corrected an already
correct sidewalk, and the street meshes only carry part of the north walk - the
rest is terrain.