Commit Graph
11 Commits
Author SHA1 Message Date
zwitschi bb40a98537 Give street props colliders, zoned placements and variants
Full build / Full desktop build + optional release (push) Successful in 4m2s
Full build / Import + headless tests (push) Successful in 31s
Props were decoration: the guard and guests walked straight through benches,
bins, bollards and planters. They now block movement and steer guests around.

Collision
- _add_prop_model() fits a StaticBody3D from the model's mesh bounds in
  holder-local space: a cylinder for bollard/bin/hydrant, a box otherwise, so
  placement rotation and variant scale carry over.
- Fallback primitives go through the same fit, so a missing .glb cannot silently
  remove collision.
- Each prop also publishes a NavigationObstacle3D; NpcAvatar enables agent
  avoidance and moves with the safe velocity from velocity_computed. The navmesh
  stays a flat walkable plane and avoidance does the steering.

Placement
- PROP_PLACEMENTS groups furniture by entrance, mid-block and curb zones, with a
  static placement_problems() validator for bounds, overlap/min-spacing,
  duplicates, and the door/steps/guest-lane exclusions.
- variant_for(index) gives deterministic yaw jitter, subtle scale, and optional
  clutter (bag by the bin, crate by the newspaper boxes, cone by the hydrant).

Verification
- New windowed smoke_props.gd: guard walks into a bench and stops; a guest
  headed beyond the bench routes around it and never enters the collider.
- Headless 182 -> 187: placement validation and its failure modes, variant
  determinism/range, collider + obstacle on every placed prop, fallback collider.
- Other smokes (PLAN verbs, crowd, emergency, timeline) still pass; Python
  tooling 53/53; screenshots recaptured; compare 9 good / 0 bad.
- Version 0.4.0. TODO: collision/placement section moved to DONE; prop pipeline
  checks remain.
2026-11-01 10:16:53 +01:00
zwitschi 3025ba1cef Capture the wand panel, escalation HUD and body-camera timeline
Full build / Import + headless tests (push) Successful in 35s
Full build / Full desktop build + optional release (push) Successful in 3m56s
The three newest catalogue screens had AI mockups but no staged capture, so
compare and judge skipped them. capture_screenshots.gd now continues past the
night set:

- switches to The Joke Shop at 620 s (EVENING still has routine spawns), frames a
  guest, and retries the wand until it alerts; if nobody carries an alerting item
  it stages the documented keys false-alarm case.
- applies a formal warning (arms the body camera) then blocking, jumps to 760 s
  for night lighting, and captures the HUD at L3.
- closes the open incident and opens the body-camera timeline, which now shows
  the warning / body-camera / blocking rows.

Wired the refs for wand_screening, escalation_hud and body_camera_timeline, and
regenerated the escalation mockup as a third-person over-the-shoulder night shot
so the reference matches the game camera. Added Hud.clear_log() to drop
target-cycling noise from staged shots. README gallery lists the three captures.

Verification: headless 182/182, Python tooling 53/53, compare 9 good / 0 bad,
judge: wand match 0.90, timeline match 1.00, escalation review, 0 diff.
Version 0.3.3.
2026-11-01 00:29:58 +01:00
zwitschi f2863abeac Draw prop models with a single atlas material
Full build / Import + headless tests (push) Successful in 33s
Full build / Full desktop build + optional release (push) Successful in 3m39s
Each generated prop used one material per part (body, accent, metal...). The
model pipeline now packs a prop's palette into one power-of-two colour atlas plus a
matching metallic/roughness atlas and emits a single material:

- atlas_for(): 8x8 cells per palette role, colours in sRGB, roughness in the G and
  metallic in the B channel of the second atlas; NEAREST sampling keeps cells flat.
- build_glb(): every part merges into one primitive with constant per-vertex atlas
  UVs; the material uses baseColorTexture + metallicRoughnessTexture with factors 1.0.
- audit_glb(): fails unless a prop has exactly one material, both atlas textures,
  two images, and TEXCOORD_0 on every primitive.
- Removed the now-unused sRGB->linear factor helpers; colour travels in the texture.

Verification: headless 181 -> 182 (new "one material per prop scene" test), Python
tooling 53/53 (atlas determinism/size/UV/palette-override tests replace the old
factor tests), model audit OK for all six props, screenshots regenerated and
screen_designs.py compare still 6 good / 0 bad. Version 0.3.1.
2026-10-31 23:47:15 +01:00
zwitschi afa1d6beec v0.3.0: rendering pass, generated props, selection model and Web build
Full build / Import + headless tests (push) Successful in 36s
Full build / Full desktop build + optional release (push) Successful in 4m17s
Rendering and presentation
- Shared surface-material module (src/game/materials.gd) with per-surface
  roughness/metallic/uv profiles; ACES tonemapping, glow, fog and phase-driven sky
  energy. WorldBuilder rebuilt on those profiles with facade windows that light up,
  door trim/handles, curb, lane dashes, bollards, bench, bin and planter foliage.
- NPC silhouettes: per-role clothing palettes, caps/hoods/backpacks/sunglasses,
  hands and shoes, arm/leg walk swing.
- Six generated low-poly GLB props (bollards, bench, bin, planter, newspaper box,
  hydrant) built by tools/model_pipeline.py, loaded by WorldBuilder with a
  procedural fallback; ADR-0012.

Selection and movement
- Focus ranking by view angle then distance (NpcFocus.rank_indices); Tab and the
  mouse wheel cycle nearby people initially, right click clears focus with a
  re-acquire grace, HUD shows the candidate count, Shift walks at half speed.
  ADR-0011. Windowed smoke extended to cover wheel cycling and clearing.

QA tooling
- screen_designs.py catalogue grown to 19 screens (8 scene, 11 UI) plus a `list`
  subcommand; draft generation keeps existing AI references unless --force.

Web export
- New Web preset using the non-threaded Godot template (static hosting, no
  COOP/COEP). tools/build_releases.sh exports build/web and packages
  build/step-line-web-<ver>.zip; publish_release.sh uploads it with the desktop
  artifacts. test_web_export.gd covers the preset and release wiring.

Verification
- Headless suite 177 -> 181, Python tooling 53 tests, all eight smokes pass
  (including the windowed focus/wheel smoke). Web bundle serves index.html,
  index.wasm (35 MB) and index.pck (30 MB) with HTTP 200 from a static server.
- Version 0.3.0; README, PLAN, RELEASING, TODO/DONE and MEMORY updated.
2026-10-31 23:07:41 +01:00
zwitschi 71b0b53705 Add crowd presentation, fix NPC navigation, refresh screenshots
Full build / Import + headless tests (push) Successful in 27s
Full build / Full desktop build + optional release (push) Failing after 3m37s
NPC navigation (previously dead in the live game)
- Only assign NavigationAgent3D.target_position when it changes: re-assigning every
  frame invalidated the path, so get_next_path_position() kept returning the current
  point and avatars never moved.
- Follow the first path point that is closer to the destination than the avatars are.
  Nav points sit on the navmesh plane (y=0) while bodies stand at y~0.5, so the old
  3D distance test always looked "already there"; path[0] is also the old start point,
  so a naive "far enough away" pick steered backwards and oscillated.
- Fix fsm.state -> fsm.current_state in the idle-lifetime check.

Crowd presentation
- Aggressive behavior, visible weapons, and responder arrivals make idle bystanders
  stop and face the incident for 12 s; someone waiting at the entrance keeps focus.
- Panic (mood >= 0.75) walks people away from the door at 2.4 m/s, then they despawn.
- Wire reactions to EventBus.crowd_changed: CrowdSystem.apply_event() emits on the bus,
  not on its own `changed` signal (the first wiring received nothing).
- Measured a 16-NPC entrance at ~1.2 ms/frame (824 fps, vsync off), so no LOD/culling.

World and HUD
- Skyline is now a ring of four alpha-scissored planes at 200 m instead of a single
  plane; PlaneMesh defaults to horizontal, which is why the backdrop rendered as a band
  overhead. Larger ground plane, mipmapped texture, scissor threshold 0.5 (0.3 left
  mip dashes in the sky), lifted albedo so the city is not pure black.
- Flashlight aims straight ahead and lights the person/door instead of the ground.
- Shorter HUD controls line so it stops overlapping itself.

Tests, tooling, docs
- Headless suite 98 -> 105 (new test_crowd_presentation.gd, 7 tests).
- New smoke_crowd.gd: rubbernecking, panic, and flee-target sanity.
- capture_screenshots.gd starts a shift from the venue menu and stages the night set
  properly; all six README screenshots regenerated.
- README, TODO/DONE (crowd section moved), MEMORY updated. Version 0.2.4.
2026-10-31 20:55:10 +01:00
zwitschi f11b441c07 Implement control pass: focus cone, action wheel, named inputs, boot fixes
Full build / Import + headless tests (push) Successful in 22s
Full build / Full desktop build + optional release (push) Skipped
- Venue-correct access artifacts (AccessLoadout) and screened-aware verify
- Cone focus on NPC heads with billboarded ring + display name (ADR-0008)
- Action wheel with de-escalation-first slices (ADR-0009); Esc/RMB cancel
- Procedural NPC face/hair/neck/shoes (ADR-0010); named input actions
- Fix GameManager parse error (radial typed as ActionRadial)
- Fix first-person camera height and guard spawning inside the building
- Move building volume back so the door/awning/marquee are visible
- Pull the event scheduler once per simulated second; cap live NPCs
- Regenerate README screenshots; update TODO/DONE/MEMORY/README; 77 tests

Adds src/test/smoke_focus_radial.gd for the windowed focus/radial smoke.
2026-10-31 15:58:01 +01:00
zwitschi 53e98cf3fe Update documentation and regenerate screenshots; enhance asset integration details 2026-10-31 15:19:58 +01:00
zwitschi 0f076205af Fix NSIS installer build: absolute paths via defines, space-free installed exe, BMP ICO
Full build / Import + headless tests (push) Successful in 31s
Full build / Full desktop build + optional release (push) Successful in 3m44s
- makensis resolves relative -DICON/-DARTIFACT against the script directory,
  so CI now passes $PWD-based absolute paths (reproduced locally in the same
  ubuntu:24.04 container; installer builds, 7z shows step-line.exe +
  uninstall.exe)
- Install as step-line.exe (no spaces: NSIS /oname splits on whitespace)
- OutFile overridable via -DOUT
- tools/generate_textures.py icon.ico now produced via ImageMagick with
  classic BMP entries (NSIS-compatible); PIL PNG-compressed ICOs rejected by
  NSIS
2026-10-31 14:22:55 +01:00
zwitschi 8bc84c1f36 Harden installer icon + NSIS rebuild path
Full build / Full desktop build + optional release (push) Failing after 3m24s
Full build / Import + headless tests (push) Successful in 27s
- Regenerate icon.ico with classic BMP entries (16/32/48) — PNG-compressed
  ICO entries can fail NSIS' icon loader on some builds
- CI copies assets/textures/icon.ico onto the packaging path right before
  makensis, removing any stale/missing-copy failures
- Recreate v0.2.1 tag after this fix
2026-10-31 14:15:38 +01:00
zwitschi 031503e161 Detailed graphics pass: authored textures, humanoid NPCs, HUD feedback, asset pipeline
Full build / Import + headless tests (push) Successful in 16s
Full build / Full desktop build + optional release (push) Skipped
- tools/generate_textures.py (deterministic PIL) produces all authored PNGs:
  brick facade, concrete, asphalt, awning, skyline, vignette, HUD icons,
  access-card art (all <=1024px, power-of-two)
- WorldBuilder: textured facade/glass door/sidewalk/asphalt, striped awning
  with 'STEP LINE', generated skyline backdrop planes
- GameManager: soft sun shadows (4-split parallel); guard in 'guard' group
- NPC avatars: humanoid rig (torso/head/limbs) with archetype props (camera,
  delivery box, performer hat, protest sign, tourist backpack), procedural
  walk bob, head-turns-toward-guard attention cue
- HUD: inspection artifact cards, mode icons (flashlight/door/wand),
  per-escalation vignette, body-camera overlay (corner brackets + REC + clock)
- assets/ import convention documented; test_asset_textures_present_and_pow2
  guards the pipeline (57 tests pass)
- README tech stack updated for Gitea Actions + asset pipeline; screenshot
  gallery regenerated (day + night)
2026-10-31 13:33:43 +01:00
zwitschi 513f8a0f60 Visual polish pass (v0.2.0): phase lighting, street lamps, marquee, dressing, night screenshots
- Phase-based lighting: sun direction/energy/color, ProceduralSkyMaterial
  gradient, and ambient per shift phase (GameManager.PHASE_LIGHTING),
  applied on phase transitions and shift start
- WorldBuilder: street lamp poles with emissive bulbs + OmniLights,
  set_night_mode(), glowing STEP LINE marquee (Label3D + emissive bars),
  crosswalk stripes, planters, low-poly street trees
- NPC avatars: per-seed height/brightness variation (deterministic LCG)
- Denser routine traffic probabilities
- capture_screenshots.gd: fast-forward to LATE phase and capture night set;
  README gallery is now 2x3 day+night; docs/screenshots regenerated
- Version bumped to 0.2.0; build/ artifacts rebuilt; Linux binary smoke-tested
- New headless tests for phased lighting config and street dressing (56 total)
2026-10-31 13:24:40 +01:00