v0.3.0: rendering pass, generated props, selection model and Web build
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.
This commit is contained in:
1 parent
f763cff744
commit
afa1d6beec
48 files changed
+2602
-147
No files matched your search
@@ -15,19 +15,73 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
|
||||
|
||||
## Handoff (read this first)
|
||||
|
||||
- Repo: `/run/media/system/DATA/Documents/06-games/security-game`. Godot: `~/.local/bin/godot` (4.3.stable).
|
||||
Tests: `godot --headless --path . --script res://src/test/test_runner.gd` → **88/88**.
|
||||
- Repo: `/run/media/system/DATA/Documents/06-games/security-game` (also reachable at
|
||||
`/var/home/zwitschi/Documents/06-games/security-game`). Godot: `~/.local/bin/godot` (4.3.stable).
|
||||
Tests: `godot --headless --path . --script res://src/test/test_runner.gd` → **177/177**.
|
||||
Python tooling tests: `cd tools && python3 -m unittest test_asset_pipeline test_screen_designs test_model_pipeline` → **53**.
|
||||
Session shell smoke: `godot --headless --path . --script res://src/test/smoke_session_shell.gd` → exit 0.
|
||||
Windowed control smoke: `godot --path . --script res://src/test/smoke_focus_radial.gd` → exit 0.
|
||||
Windowed control smoke: `godot --path . --script res://src/test/smoke_focus_radial.gd` → exit 0
|
||||
(now also covers wheel cycling and right-click clearing).
|
||||
- `main` is in sync with origin. **v0.2.2** tags the session-shell + world-follow-up commit;
|
||||
CI builds the portable binaries, NSIS installer, and AppImage on the tag push.
|
||||
- **v0.3.0 (2026-10-31, working tree):** rendering pass (`src/game/materials.gd`, phase-driven
|
||||
environment), generated `.glb` props (`tools/model_pipeline.py`, `assets/models/generated/`),
|
||||
aim-free selection with wheel cycling and Shift precision walk (ADR-0011/0012), and a **Web**
|
||||
export target. `export_presets.cfg` gains a `Web` preset with `variant/thread_support=false`
|
||||
(static hosting, no COOP/COEP); `tools/build_releases.sh` exports `build/web/` and zips it to
|
||||
`build/step-line-web-<ver>.zip`, and `publish_release.sh` uploads it. Covered by
|
||||
`src/test/tests/test_web_export.gd`.
|
||||
- **Backlog complete:** every planned TODO section is done and moved to `DONE.md`; `TODO.md`
|
||||
now only lists optional future ideas (live 3D replay, NPC LOD, more venues, real audio, web
|
||||
export). GUT was consciously not adopted (custom runner covers it without an editor plugin).
|
||||
now only lists optional future ideas (live 3D replay, NPC LOD, more venues, real audio, prop
|
||||
atlas, AI mockups for the new catalogue entries, image-to-mesh props). GUT was consciously not
|
||||
adopted (custom runner covers it without an editor plugin).
|
||||
- Do not re-open `override_access`. Do not bind wand to `W`. Do not remove the radio easter egg.
|
||||
|
||||
## Current State
|
||||
|
||||
- **v0.3.0 pass (2026-10-31, uncommitted):** rendering, generated prop models, screen
|
||||
catalogue, aim-free selection. See ADR-0011 (selection) and ADR-0012 (materials/props).
|
||||
- `src/game/materials.gd` (`SurfaceMaterials`) is now the single source of surface
|
||||
recipes + `configure_environment()`. `GameManager.PHASE_LIGHTING` gained
|
||||
`exposure/glow/fog_color/fog_density/fog_energy/contrast/saturation/ambient_energy`.
|
||||
Renderer is **GL Compatibility**, so SSAO/SSIL are unavailable; glow+fog+ACES are used
|
||||
instead and unsupported settings are ignored rather than gated in code.
|
||||
- World: scaled brick (uv 22,10), framed windows with per-window night emission
|
||||
(`i % 3 != 2` lit), stone base course, door trim/handles, curb, lane dashes (the old
|
||||
loop had `Vector3(i * 0.0, …)` and stacked every dash at x=0), street lamps use the
|
||||
metal profile. The two flat planters that clipped the steps were removed.
|
||||
- `tools/model_pipeline.py` builds `assets/models/generated/*.glb` (bollard, bench,
|
||||
trash_bin, planter_box, newspaper_box, fire_hydrant) from box/cylinder specs;
|
||||
`WorldBuilder._add_prop_model()` loads them with a procedural fallback and records
|
||||
`loaded_models` / `fallback_props`. **Gotcha:** glTF `baseColorFactor` is LINEAR —
|
||||
writing sRGB made every prop pastel; `srgb_to_linear()` is applied in `build_glb`.
|
||||
**Gotcha:** a new/changed `.glb` needs `godot --headless --path . --import` before
|
||||
`ResourceLoader.exists()` / `load()` sees it (test_generated_props fails otherwise).
|
||||
- `model_pipeline.py concept` (OpenRouter, reads repo `.env`) writes per-prop concept
|
||||
sheets to `assets/models/concepts/`; `dominant_colors()` centre-crops and weights by
|
||||
saturation (a grey studio backdrop otherwise wins), `assign_roles()` maps colours by
|
||||
hue/value. Delete a concept file to fall back to the catalogue palette.
|
||||
- NPC avatars: `outfit_for(type, seed)` (pure) gives shirt/trousers/hair/skin +
|
||||
accessory (cap, hood, backpack, sunglasses, lanyard) and height scale; `_arms` and
|
||||
`_legs` now swing (`limb_swing`) while walking. Keep `Rig/Head` named for focus.
|
||||
- Selection: `NpcFocus.rank_indices` (angle then distance) — `pick_index` = first.
|
||||
`GuardController.cycle_target(direction)` walks nearest-first `nearby_candidates()` and
|
||||
sets `target_pinned`, which makes `_update_target()` skip the cone. `clear_target()`
|
||||
sets `focus_suppress_s = 0.75` so the cone does not instantly re-acquire the person.
|
||||
New input actions `walk_slow` (Shift), `cycle_target_next` / `cycle_target_prev`
|
||||
(wheel down / up). Right click with nothing open clears focus (Esc still pauses).
|
||||
- HUD: `nearby_label` + `set_nearby_hint(count)` show `hud.nearby`; `hud.controls` and
|
||||
`hud.targeting` mention the wheel and Shift.
|
||||
- `tools/screen_designs.py`: catalogue now 19 screens (added wand_screening,
|
||||
joke_shop_queue, studio_arrival, crowd_panic, responder_arrival,
|
||||
body_camera_timeline, escalation_hud), new `list` command, `generate --only/--force`
|
||||
(existing designs are kept by default so a draft run cannot clobber AI mockups),
|
||||
and `judge --dry-run` no longer raises `KeyError: 'class'`.
|
||||
- Screenshot tool leak: `capture_screenshots.gd` intermittently prints
|
||||
`ObjectDB instances leaked at exit`. Verified against a `git worktree` of HEAD~ — the
|
||||
baseline leaks more often (3/3 vs 1/3), so it is a pre-existing quit-timing artifact,
|
||||
not a regression. Normal boots are clean.
|
||||
|
||||
- Access artifacts: `src/core/access_loadout.gd` builds from event `override_access` + venue policy.
|
||||
Spawn signal is now `(profile, intent, npc_id, event)`. Recognition is not auto-attached to every
|
||||
guest. `AccessVerifier.verify(..., already_screened=false)` so Joke Shop scoring uses
|
||||
|
||||
Reference in new issue
Block a user