Files
gig-line/CHANGELOG.md
T
zwitschi 12272d6b96 release: v0.2.0 — third-person body, animation, stride capture
Writes the 0.2.0 changelog entry with the measured numbers, removes the completed
section from TODO.md (its goal stays in ROADMAP.md) and updates the roadmap status.

Release checks: 8/8 shots verify with 6, 7 and 8 approved; 1440p at 2.64 ms average
(379 fps); -qaselftest passes walk, reset, pause, transect, wall and facade probes;
82 tool tests pass. Known limitations are listed rather than hidden: splayed fingers,
a swept base rotation and unproven camera collision, all marked for later patches.
2026-11-09 12:30:49 +01:00

26 KiB
Raw Blame History

Changelog

All notable changes to this project are documented here.

Format: Keep a Changelog style, versions follow Semantic Versioning. Entries are added when a version section in TODO.md is completed.

Unreleased

Nothing yet.

[0.2.0] — 2026-11-09

Third-person body. The pawn gains a visible, animated body and a third-person camera, so the walk cycle is finally something a player can see rather than a clip in an asset list.

Added

  • Tools/character_anim_build.py: GigLine_Idle (60 frames) and GigLine_Walk (30 frames) at 30 fps, authored as parametric cycles so the loop closes by construction. Limb axes were measured on the rig — a probe rotated upperleg01.L by 0.5 rad on each axis and read foot.L, which showed X swings the limb fore/aft while Y twists and Z abducts.
  • Third-person rig (ADR-9): a visible skeletal body, a USpringArmComponent with collision testing, and a V toggle. One pawn carries both rigs; first person stays the shipped default.
  • Walk capture harness: a per-shot ShotFollow mode that re-places the review camera every frame in the pawn's frame, plus SetReviewWalk / ReturnToStartForReview, so a stride is captured deterministically and the fixed-camera shots still find the pawn at spawn.
  • Review shots 6, 7 and 8 — third-person back, front and mid-stride — embedded in Screenshots/README.md.

Changed

  • Character export preset now bakes animation (bake_anim, all actions). Without it the exporter wrote a static bind pose and Unreal imported a mesh with no clips and no error.
  • Docs/controls.md documents the V toggle and the review switches; the in-game HUD line reads WASD move · Mouse look · Space jump · V view · R reset · Esc pause.

Fixed

  • PlayAnimation on a hidden component never took effect. The body is hidden at construction and only unhidden by the toggle, so the first call could land before the component was ready; the code now sets AnimationSingleNode, calls SetAnimation + Play, and re-asserts while the instance is missing.
  • The animation switch restarted the clip every frame, freezing the body on frame 0.
  • The importer silently refused to replace the existing assets. Changing the arm rotation and rebuilding returned the identical bone quaternion every time; replace_existing and delete_asset both failed because the pawn's constructor hard-references the clips. Importing under a new name (CharacterV2) finally landed the change — that is what unblocked the pose after a dozen failed rebuilds.
  • The review runner copied stale screenshots from Saved/, so a shot retired from the camera list reappeared with byte-identical content from an older run. The folder is cleared before each capture.
  • Walking was never enabled for the stride shot: the call sat in the shot sequencer's BeginPlay, which runs before the player pawn exists, so the cast silently found nothing and speed stayed at 0.

Verified

  • 8 review shots verify; shots 6, 7 and 8 approved by the owner.
  • 1440p, no frame generation, VSync off: 759 frames, avg 2.64 ms (379 fps), p50 2.54, p95 3.39, p99 3.76, max 4.05 ms — about 2 % over 0.1.5 and 6.3× the 60 fps floor. Series: Docs/perf/0.2.0-walk-frametimes.csv.
  • -qaselftest: walk, reset 0 cm from spawn, pause/unpause, transect 1456 samples / 0 holes, wall probe 0/35, façade probe 0/9 — all PASS.
  • 82 tool tests pass.

Known limitations

  • The fingers splay — the bind's finger spread carries into the pose. Deferred to 0.2.2.
  • The arms-down rotation was found by sweeping, not derived: 0.55 rad puts the arms at the sides, 0.65 against the hip, 0.75 into the torso. A derived pose is a 0.2.2 job.
  • Camera collision is implemented but unproven — the spawn point has open space behind it, so no shot exercises the boom shortening.
  • The third-person body has no head or hand IK and no turn-in-place; it is a first playable, not a finished character.

[0.1.6] — 2026-11-09

Retail frontage. The two retail buildings beside the hero are modelled from their own photograph instead of the generic kit, and the photograph is treated as evidence: an analysis is written before any geometry, and every dimension the image does not resolve is carried into the part report as an assumption.

Added

  • Tools/retail_frontage_build.py: 6800 Lee Drug and 6806–6820 built from the one usable reference (Art/reference/retail-neighbours/, Gb321, CC BY-SA 4.0). Lee Drug gets a bronze cornice, storefront glazing with mullions, framed portrait panels, a painted lettering band, two-tier parapet with reveals and a fluted corner tower; 6806–6820 gets a burgundy fascia, brown pilasters, white-framed windows with security bars and its own banded parapet. Built in world coordinates from the blockout bounds (Lee Drug X −33.20…−14.37, face Y −14.63, H 12.10 m; 6806–6820 X −66.08…−33.07), joined to one mesh per building with a JSON part report.
  • Tools/ue_import_retail_detail.py: imports the two meshes with complex-as-simple collision — trim decorates a solid the player already collides with and must not add snag points.
  • Art/blender/retail/ref-analysis.md: the reference analysis the references skill pack requires, written before modelling.
  • Tools/_common.py and Tools/tests/test_retail_frontage.py: the bay-layout arithmetic, extracted so it is testable without Blender (4 tests).
  • Review shot 5, demo/review-demo-retail-frontage, embedded in Screenshots/README.md.

Changed

  • The generic façade kit skips the two modelled buildings (MODELLED list in ue_apply_facade_kit.py). It applies to every Frontage_*/North_* actor, so it was pasting a second, contradicting façade language over the new trim.
  • Retail trim stages as RetailTrim_* and is spawned through the demo builder, so it is regenerable rather than hand-placed.
  • Trim stucco, white and glass slots are mapped onto the demo's look-dev materials so the walls sit in the same noise and texture family as the rest of the block; the tones sampled from the photograph (bronze, burgundy, mural, lettering) stay as authored.

Fixed

  • Tools/render_screenshots.sh never captured anything. The capture step called ./Engine/... while every commandlet above it went through run_cmdlet's cd "$ENGINE". Under set -e the script died at exit 127 after rebuilding the maps, so the PNGs silently stayed a day old and --verify never ran.
  • Duplicate RetailTrim_* actors on every rebuild: the demo builder's clear list did not include the new label, so each run stacked another copy. Caught by the scene audit, not by eye.
  • Mural plates were placed 0.20 m inside the solid blockout volume and never rendered; the inset is now faked with a proud frame and a near-flush plate.
  • Trim detail sat 0.05 m off the wall, under a pixel of depth at 40 m, so the wall won the depth test. Trim planes now stand 0.10–0.20 m proud.
  • 6806–6820 parapet started at 0.62 H, leaving a 4.6 m blank band; the window storey and parapet moved up to follow the photograph.
  • Mural panels, parapet and lettering were sized from the photograph's proportions, not the inherited defaults: the first pass left a parapet that read as one blank white band.

Verified

  • render_screenshots.sh --verify: 5/5 shots OK; scene audit 0 failures (every mesh materialed, all spans in tolerance, no duplicate labels).
  • Owner approved demo-retail-frontage (second pass) 2026-11-09; all five demo shots now carry approval.
  • 82 tool tests pass.

Known limitations

  • Wall lettering and the painted band do not read at 40 m. A plate at 0.10 m still vanishes; this is a decal/texture problem, not geometry. Moved to 0.9.0 — Realistic buildings.
  • The parapet has no moulded profile and the corner tower is a fluted cylinder with two cap rings — both need the façade system in 0.9.0.
  • 6822 Budget is untouched: no photograph of it exists. Deferred and blocked in 0.9.0.
  • The only reference for these two buildings is a single street-level oblique with a bus across Lee Drug's shopfront and a car across 6806's; several vertical proportions are assumptions recorded in the part report.

0.1.5 — 2026-11-09

Façade finishing. The kit gets the hero detail it was missing, and a class of silent defect is found and gated: the map had been rendering with 604 of 620 mesh actors unmaterialed without a single error.

Added

  • Scene audit (Tools/ue_audit_scene.py): fails when any staged mesh has no material, when a frontage building is more than ±1 m off its verified footprint, or when two actors share a label. Wired into Tools/render_screenshots.sh, which now runs the whole staging chain in the correct order and stops on an audit failure.
  • Tools/ue_placement.py: one source of truth for staged positions and the verified frontage spans, with span_error / describe_span_failure validators.
  • Hero fluting: 20 grooves per column as shallow shadow-tone cylinders (120 pieces) rather than boolean cuts.
  • Presence of references for the retail run: Art/reference/retail-neighbours/ (6800 Lee Drug and its neighbour). Local only, not committed.

Changed

  • Motto band is a real recess now — moulded surround 6 cm proud, panel 12 cm behind — instead of an 8 cm dark stripe. Hero: 148 parts / 3 044 tris → 271 / 5 492, still 14.50 m.
  • Kit layout for wide and tall buildings: bays are capped at 9 with the module widened (6922 was 13 bays across 65.8 m — a window every 4.96 m on a 37 m block), and the storey spread is derived from the available height so the top band always lands inside the volume.

Fixed

  • 604 of 620 mesh actors rendered untextured. ensure_material deleted and recreated each site material on every run, orphaning every reference held by the kit pieces and the theatre trim; the map looked only slightly flat. Materials are now updated in place.
  • The hero could be teleported 13 m east onto the wrong side of the boulevard. ue_hero_facade_import.py carried its own copy of the pre-0.1.0 hero position; running the importer alone moved the building, invisible in a render and visible only as a reference-score drop. Placement now has one definition and the import asserts the staged span (span ok: X -14644..-12028).
  • 53 duplicated kit actor labels (both shop piers of a bay shared one name).

Verified

  • Scene audit: 0 failures — every mesh materialed, all 7 verified spans within tolerance, no duplicate labels.
  • Packaged -qaselftest: walk, reset, pause/unpause, seam transect 1456 samples / 0 holes, wall probe 0/35, façade probe 0/9 — all PASS.
  • 1440p re-measured with the kit: 2.76 ms average (363 fps), p99 3.64 ms, against 0.1.0's 2.42 ms (414 fps) — the 625 kit actors and 8 textures cost about 12 % and leave roughly six times the 60 fps floor. Series at Docs/perf/0.1.5-kit-walk-frametimes.csv.
  • 78 tool tests pass.

Known limitations

  • Retail neighbours 6822 and 6806–6820 are not modelled: Commons holds no usable reference for either, and substituting the El Capitan Theatre's photographs would misattribute their façades. Tracked in TODO.md.
  • Cornice dentil spacing, abacus and plinth dimensions remain recorded assumptions.
  • Textures are generated, not authored — no decals, signage text or weathering maps.
  • The vision pre-check stays advisory; it has rejected shots the owner approved.

0.1.4 — 2026-11-09

Building façades. The block goes from flat extruded boxes with flat colours to coursed, textured surfaces assembled from a reusable module kit, and the El Capitan Theatre gets the marquee and blade sign that make it read as itself.

Added

  • Façade module kit at the measured 4.96 m bay / 3.10 m storey: pilaster, sill, lintel, window bay, shopfront bay, door bay, cornice, parapet and coping — 16 SM_ meshes, each validated for manifold topology (12 tris each) and assembled onto eight buildings, 625 pieces, from each building's own world bounds.
  • Generated surface textures — deterministic stdlib PNGs for ashlar stone, stucco, asphalt and concrete (base colour + roughness), sampled world-aligned with per-material tiling; byte-identical on re-run.
  • Materials: masonry coursing and roughness variation in the material graphs; M_FacadeStoneShadow, M_FacadeGlass (specular 0.62 ≈ IOR 1.5) and M_FacadeBanner. Material assignment is now per slot, keyed on the imported slot material, instead of slot 0 only.
  • El Capitan Theatre trim: projecting marquee (12.0 × 2.60 m canopy at a 4.60 m soffit), illuminated fascia, recessed soffit, and a vertical blade sign (1.30 × 5.20 m) with frame and wall bracket.
  • Visual review loop (Tools/visual_loop.py + visual_targets.json): verifies every capture against an expectation (missing, blank, tone-less or wrong-size shots fail) and measures each render against its reference photograph, emitting feedback that names the discipline to consult. Iterations are written under Art/reference/iterations/, which is gitignored until a shot is confirmed.
  • Tools/fbx_export_preset.py — one export preset replacing six copies, and it exports smoothing groups (FACE), so round geometry is no longer faceted.
  • Tools/ue_common.py — clears the read-only bit an LFS .umap checks out with and makes a refused save loud.

Changed

  • Elevation cameras are levelled (pitch 0, so verticals stay parallel) and use a 42–55° lens to fill the frame from across the street.
  • Screenshots/ holds demo-map captures only; the review staging map is no longer rendered for review. Each shot carries its expected content and an approval state.

Fixed

  • Blockout frame: the 0.1.2 regeneration had run without --origin, shifting the whole frontage ≈119 m in X and 2.4 m in Y and dropping the hero out of the 6902/6838 gap. Regenerated with the affine fit (residual 0.0 cm) and every span re-verified against the block verification notes.
  • Kit placed ~12 km from its buildings — it used the mesh-local bounding box, which excludes the actor offset.
  • Marquee mirrored across the boulevard (Blender +Y is Unreal −Y) and hanging 5 cm above the pavement (absolute Z instead of pavement-relative).
  • Window bays invisible inside the solid wall; the surround now projects with glazing inset.
  • Glazing was not glass: kit pieces kept the grey material the FBX import creates.
  • Hero windows floated 1.44 m in front of the wall; parapet medallions were flat discs on the coping.
  • Imports could report success while saving nothing (read-only LFS map), and the north-buildings import failed silently on a missing import sys.

Verified

  • Packaged build -qaselftest: walk 761 cm, reset, pause/unpause, seam transect 1456 samples / 0 holes, wall probe 0/35, façade occlusion probe 0/9 — all PASS. Run twice; the harness is time-based and one loaded run reported a false failure.
  • All eight buildings probed against the verified world spans.
  • 67 tool tests pass.

Known limitations

  • Kit pieces are boxes; cornice dentil spacing, abacus and plinth dimensions are recorded assumptions.
  • Textures are generated, not authored: no decals, signage text or weathering maps.
  • The vision pre-check remains advisory — it is unreliable on this content.
  • Retail neighbours, hero fluting and the blockout cleaning pass move to 0.1.5.
  • Performance has not been re-measured since 0.1.0; 625 kit actors are unmeasured.

0.1.3 — 2026-11-09

Packaging and setup fixes. No gameplay or visual scope; this patch makes the pipeline and its documentation tell the truth about what 0.1.x taught.

Fixed

  • Map imports could report success while saving nothing. .umap files are LFS-tracked and check out read-only, so save_map() returned False with no error and the staged actor vanished on the next load. New Tools/ue_common.py (make_writable, require_saved) clears the read-only bit and makes the failure loud; ue_hero_facade_import.py and ue_import_north_buildings.py now use it. Verified from a forced 0o444 map: chmod logged, save_map: True, exit 0.

Changed

  • Docs/build.md: content-pipeline table now lists every step as it exists (seven site FBXs, frontage, north buildings, hero, map) and the shared FBX preset; packaging archive corrected to Builds/GigLineQA; the packaged log location and -qaselftest usage are documented; new traps table covers the read-only save, the hero --out-is-the-FBX mistake, the MPFB add-on path, the shot actor quitting under QA, and the null-RHI trace trap.
  • Docs/setup.md: the fresh-checkout build is marked verified (2026-11-08) and its blocker closed; a new section documents the two optional keys (OPENROUTER_API_KEY, MAPBOX_ACCESS_TOKEN) and that neither is needed by the build, the tests or a release.
  • Docs/Architecture/07_deployment_view.md and the combined architecture.md: build-output path corrected and marked as living outside the repository.

Verified

  • 54 tool tests pass (5 new for ue_common).
  • Packaged build still launches into DemoMap and -qaselftest passes every phase.

0.1.2 — 2026-11-09

Scale and façade correction patch. Buildings and the hero elevation now match the reference photography and the cross-checked height data; no new gameplay scope.

Added

  • Tools/facade_detail_concepts.py — generates frontal building plates (whole elevation, entrance in its façade, building with neighbours) from a local reference photograph through OpenRouter image models. Spec-driven, never overwrites, writes a provenance sidecar per image, output stays in the gitignored Art/reference/ tree. Local working material only.
  • Tools/fbx_export_preset.py — the single FBX export preset (ue_metric_v1 / ue_character_v1). Replaces the argument block that had been copied into six exporters.
  • Façade occlusion probe in -qaselftest: 40 m traces sideways from the road centre at walking height, required wherever a building is staged.
  • Ionic detail on the hero: base moulding at every shaft foot, a square abacus over every capital, and a 52-dentil cornice course.
  • Tool tests: Tools/tests/ now covers the input driver, height classification, the Mapbox cross-check, the concept generator and the FBX preset (49 tests).

Changed

  • Storey height 3.2 → 3.1 m, calibrated against Mapbox building data, with explicit overrides for three rear outbuildings; the block cross-check now reports 66 matches and no disagreements.
  • Hero colonnade 47.6 % → 53.1 % of the 14.50 m elevation, inside the photographed 50–60 % band (thinner entablature and parapet).
  • Blockout regenerated at the new storey height; frontage re-exported and re-imported (6922 42.1 → 39.1 m, El Capitan Theatre 20.0 → 20.5 m).
  • FBX exports now carry smoothing groups (FACE instead of OFF), so round geometry is no longer faceted and imports stop warning.

Fixed

  • Windows floated 1.44 m in front of the wall, ahead of the colonnade; they now sit on the wall plane behind the columns.
  • Parapet medallions were flat discs lying on the coping instead of discs on the parapet face.
  • The hero façade had no usable collision — the player could walk through it. It is now complex-as-simple; auto-generated convex hulls were tried and rejected because they bulged into the street.
  • The three "guessed" block heights were never buildings: two building=roof canopies and a transit shelter. They are classified as non-building volumes and the block now reports zero guessed heights.

Verified

  • Packaged build -qaselftest: walk, reset and pause pass; seam transect 1456 samples / 0 holes; wall probe 0/35; façade probe 0/9.
  • Screenshots re-rendered for every change and approved by the owner.

Known limitations

  • Cornice dentil spacing, the base and abacus dimensions are recorded assumptions: the reference photography does not resolve them at our scale.
  • Façade surfaces remain flat blockout materials; the textured pass is 0.1.4.

0.1.1 — 2026-11-08

Collision-fidelity patch. No new scope: street geometry corrections and the QA tooling that measures them.

Fixed

  • Sidewalk outer edge ledge. The sidewalk stood the full 0.15 m kerb height above the DEM at both edges, leaving a 15.8 cm lip where the walk route crossed from terrain onto the south sidewalk. The upstand now tapers from full at the road-side edge to zero at the building-side edge; the north route's worst step fell from 15.1 cm to 6.9 cm.
  • Crossing ramps too steep. The kerb-flush run was a fixed 1.5 m, giving ~8.7 % (measured 10–13 cm over 1.5 m). The run is now derived from a target grade (--max-ramp-grade, default 8 % ⇒ 1.63 m); the crossing steps 3.4 cm at 0.25 m sampling.

Added

  • Walk pre-check improvements (Art/blender/site/site_assembly.py): sampling coverage is independent of --sample (it previously shrank the route), and the report now prints the grade and the arc-length/offset location of the worst step, so a step can be located rather than guessed.

Changed

  • Kerb height recorded as final at 0.15 m modelled / 0.13 m as built — a standard 6 in LA kerb; neither the 3DEP DEM nor the reference photography can resolve it further (±2 cm), which is far below the character's 45 cm step height.

Verified

  • Site meshes rebuilt and re-imported (7/7, collision flags intact), DemoMap rebuilt, packaged Development build EXIT=0.
  • -qaselftest on the packaged build: walk 761 cm in 2 s at steady Z 456, reset 0 cm, pause/unpause, transect 1456 samples across 16 rows / 0 holes, wall probe 0/35 blocking hits.

Known limitations

  • One residual 13.4 cm surface step at s≈198 m on the south sidewalk (8.0 cm at s≈251 m north). It is not a gap and is below the 45 cm MaxStepHeight, so it does not block traversal; the cause is a sidewalk-strip discontinuity near a centreline vertex, recorded in Art/blender/README.md as a smoothness refinement.
  • Kerb radii at junctions, driveway aprons, drainage inlets and pavement joints remain unmodelled (unchanged from 0.1.0).

Nothing yet.

0.1.0 — 2026-11-08

The first playable release: a walkable exterior demo of the 6840 Hollywood Blvd (El Capitan Entertainment Centre) block in Unreal Engine, built on OpenStreetMap layout data and USGS elevation, with the hero façade and the verified block frontage staged on a walkable street.

Added

  • Unreal project (Game/GigLine) — C++ game module, Enhanced Input, packaged Linux build, and a DemoMap that a plain launch opens directly.
  • Walkable demo level — terrain from the 3DEP DEM, Hollywood Blvd carriageway, both sidewalks and kerbs with collision, the designated mid-block crossing, and fixed daytime lighting (sun, sky light, sky atmosphere, height fog, pinned exposure).
  • Hero façade for 6840 Hollywood Blvd — six-column neoclassical elevation with three genuine portal recesses, entablature, parapet and motto band (Tools/hero_facade_build.py, Tools/ue_hero_facade_import.py).
  • Block frontage — the five verified south-side neighbours (6922, 6902, 6838 El Capitan Theatre, 6822 Budget, 6806–6822, 6800 Lee Drug) and the two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) placed at their OSM positions.
  • First-person player — AGigLineCharacter: 1.75 m capsule, 1.60 m eye camera, 4 m/s walk, mouse look, jump, reset (R) and pause (Escape); controls documented in Docs/controls.md and shown in-game.
  • In-game ODbL attribution — AGigLineHUD draws the OpenStreetMap credit and licence line every frame.
  • QA harness — -qaselftest (walk, reset, pause, seam transect, invisible-wall probe, frame-time capture) and Tools/input_test.py / Tools/input_emulation.py for OS-level virtual keyboard/mouse input.
  • Documentation — setup, build, toolchain, licensing, ODbL review, release checks, and arc42 architecture docs.

Fixed

  • All controls were dead in packaged and PIE builds. The mapping-context generator wrote key bindings to the deprecated mappings array; UE 5.8 reads DefaultKeyMappings.Mappings, so the cooked game had zero runtime mappings and every key resolved to nothing. Tools/ue_create_input_assets.py now populates the current field.
  • "Fall-through" was an 8 m invisible box. Terrain_DEM shipped only a bounding-box collision proxy; forcing complex-as-simple collision (UGigLineAssetTools) put the player on the actual street.
  • Reset returned the player to mid-air — the start position is now captured on the first grounded frame.
  • Plain launch opened the engine template — the default map now lives in DefaultEngine.ini and points at DemoMap.
  • Game target would not compile — removed editor-only API use (UStaticMesh::PostEditChange, AActor::GetActorLabel).
  • demo-north-buildings screenshot framed 85 % sky (camera 9.5 km west of the buildings); re-pointed to the building mass.

Verified

  • Both sides of the demo are traversable: 1456-sample seam transect, 0 holes, no blocking collision or invisible walls (-qaselftest on the packaged build).
  • Placement and street scale match the reference photography and Geo measurements (road 24.3 m, sidewalk offsets 12.5/13.2 m, hero frontage 26.0 m).
  • 414 fps average / p99 3.01 ms at 2560×1440 (Epic preset, TSR, VSync off, no frame generation) — far above the 60 fps target.
  • Fresh checkout builds and packages with the documented external engine (UE 5.8.4).

Known limitations

  • Buildings other than the hero are flat blockout volumes; façade detail, materials and Blosm style scripts are planned for 0.1.4.
  • Kerb height (0.13 m as built vs 0.15 m assumed), kerb radii, driveway aprons and graded crossing ramps are deferred to 0.1.1; crossing ramps are kerb flushes.
  • One block only; no vehicles, NPCs, audio, or settings UI yet.