Commit Graph
9 Commits
Author SHA1 Message Date
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 5e2c5e29c0 feat(facades): 0.1.4 — module kit, textured materials, theatre trim (#30)
Merged PR #30: 0.1.4 — facade module kit, textured materials, theatre trim

Co-authored-by: Zwitschi <zwitschi82@gmail.com>
2026-11-08 20:29:11 +01:00
zwitschi 52b1212cf3 qa: make the demo walkable — terrain collision root cause, spawn, scripted QA
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.
2026-11-08 11:56:19 +01:00
zwitschi fee26ade10 frontage: south block frontage, plus the placement bug it exposed
Adds the five remaining verified south-side buildings to the demo block
(6922, 6902, 6838 El Capitan Theatre, 6822 Budget, 6806-6820, 6800 Lee Drug),
exported in place from the OSM blockout by Tools/export_block_frontage.py,
imported to /Game/Hollywood/Frontage/ and staged by the demo builder with the
look material set (stone for the theatres, stucco for the retail run).

Adding neighbours exposed a pre-existing placement bug that was invisible while
the hero facade stood alone in an empty field:

- UE south is +Y here (south sidewalk Y +718..+1447), but the hero sat at
  Y -1450 on the NORTH side of the street.
- It was also at X -12024..-9420, 26 m east of the 6840 footprint; the frontage
  gap between 6902 and 6838 is X -14591..-12082.
- The two north-side buildings were on the SOUTH side, because their exporter
  mirrored Y.

Fixes: hero moved to X -13336 / Y +1307, inside its frontage gap; the frontage
and north-building exporters no longer apply a Y mirror (the FBX preset already
lands Blender -Y south on UE +Y south); player start and demo cameras moved to
the north sidewalk looking south; sun raised to pitch -62 so both frontages read
instead of the north side silhouetting.

Result: the demo is a street - continuous south frontage with the hero in it,
both sidewalks, the road with the designated crossing, and the north-side
buildings across the road.

Screenshots re-rendered and approved by the owner.

Squash of branch frontage-block-0.1.0 (PR #6).
2026-11-08 09:20:11 +01:00
zwitschi 62a41bf904 materials: look-developed surface materials for every exported asset
Completes "Materials and look development for all exported assets". Every
exported surface previously carried a flat Constant3Vector fill, which read as
plastic. ensure_material() in Tools/ue_build_demo_map.py now builds a
procedural material per surface:

- base colour blended between two shades by world-space noise
  (WorldPosition -> Multiply -> Noise -> Lerp -> BaseColor) for large-scale
  variation,
- an explicit roughness and specular so the surface type is readable.

  M_Asphalt 0.92, M_Concrete 0.88, M_KerbConcrete 0.85, M_Ground 0.98,
  M_RoadPaint 0.62, M_FacadeStone 0.72, M_Stucco 0.86

Site meshes take their material by mesh name; the hero facade and the two
north-side buildings take theirs by actor label, so they are covered even
though other scripts stage them. Materials are deleted and rebuilt on every
run, so a look change cannot be masked by a stale asset.

Result: the facade reads as warm stone with surface variation, asphalt as dark
asphalt with grain, concrete and kerbs lighter and matte, and the north
buildings in stucco instead of flat grey.

Screenshots re-rendered and approved by the owner. The richer texture-based
pass (baked/procedural brick_facade, seamless_concrete, glass, material
instances) stays in the 0.1.4 facade patch.

Squash of branch materials-lookdev-0.1.0 (PR #5).
2026-11-07 20:34:57 +01:00
zwitschi accf3a5306 lighting: fixed daytime rig, real surface materials, dynamic lights
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).
2026-11-07 18:22:19 +01:00
zwitschi c9e933376c review: restore character + cubes in ReviewMap, re-render all shots
Root cause of the empty review frames: EditorLevelLibrary.load_level/new_level
are deprecated no-ops in -nullrhi commandlets, so staged actors landed in the
current world and got saved over the wrong map. Switched both map builders to
the LevelEditorSubsystem and reordered the review builder to save ReviewMap
before the DemoMap section (the switch-back to a map that only exists in
memory silently failed, writing demo content over ReviewMap).

Rebuilt both maps, re-rendered every screenshot; user visual check passed.
Screenshots/README.md cube naming corrected (A grounded, B floating), approval
states updated; TODO.md visual-review notes closed. MEMORY.md records the
deprecated-call and save-order traps.
2026-11-07 16:23:59 +01:00
zwitschi bc2e421d33 gameplay: designated street crossing — zebra markings, corridor cut, up-facing street
- 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).
2026-11-07 15:46:45 +01:00
zwitschi cf392a02f7 gameplay: walkable demo map, reset and pause
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.
2026-11-07 13:17:24 +01:00