diff --git a/DONE.md b/DONE.md index c2df33a..2f1b16c 100644 --- a/DONE.md +++ b/DONE.md @@ -296,3 +296,9 @@ Completed task sections moved from `TODO.md`. Sections are moved only when every - [x] Audit existing assets for role-specific dimensions, aspect, alpha, and tile seams; report projection/perspective checks for visual review. - [x] Add automated tests and document asset-pipeline usage. + +## Generated Asset Integration + +- [x] Regenerate the AI asset set at role-specific aspect ratios and dimensions. +- [x] Audit, process, and wire every generated asset into the game runtime. +- [x] Add screenshot auditing and refresh the README screenshot gallery. diff --git a/MEMORY.md b/MEMORY.md index 3171f8a..753d6e2 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -10,7 +10,7 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o - Eventing: no autoload signal bus. `ShiftCoordinator` owns an `EventBus` instance (`src/core/event_bus.gd`) passed to subsystems; subsystems emit only when a bus is assigned. Autoloads at parse time are unreliable under `--script`. - Static signals are not available in Godot 4.3 GDScript ("Expected func or var after static") — do not use them. - GDScript lambdas capture local variables **by value**; mutating a captured local inside a lambda does not affect the outer variable. Use member functions for accumulators in tests. -- Prototype shift duration defaults to 300 s for testing; production targets 10-15 minutes per PLAN.md. +- Shift length is the scenario's `shift_duration_s` (900 s in all three venues). Tests and the screenshot tool override elapsed time; they do not change the default. - RNG: NPC reactions and event scheduling are seedable for deterministic tests. ## Current State @@ -78,10 +78,11 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o - Assets pipeline: `python3 tools/generate_textures.py` produces all authored PNGs under `assets/textures/` (≤1024px, pow2); regenerate after changing the script, then run `godot --headless --import` before tests. 57 headless tests guard the pipeline. -- General image pipeline: `python3 tools/asset_pipeline.py` reuses the OpenRouter image backend - for role-sized generation and provides exact crop/resize plus role-aware audits. Audit checks - dimensions, aspect, required alpha, and tile-edge continuity; perspective/projection stays a - manual visual check. Python tools require Pillow from `requirements-tools.txt`. +- General image pipeline: `python3 tools/asset_pipeline.py` defaults to + `openai/gpt-5-image-mini`, requests supported 1:1/3:2 sources, then fits each role's target. + It provides crop, resize, tile edge blending, alpha-glyph recoloring, and role-aware audits. + Screenshot auditing checks 1280x720 minimum, 16:9 aspect, and contrast; visual composition + remains a manual check. Python tools require Pillow from `requirements-tools.txt`. - AI texture mode: `python3 tools/generate_textures.py --ai` generates textures via the OpenRouter image API (`POST https://openrouter.ai/api/v1/images`, model `bytedance-seed/seedream-4.5` by default, base64 PNG in `data[].b64_json`). Requires @@ -90,12 +91,14 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o default batch. Output is downscaled to ≤1024px. NOTE: seedream rejects sizes below 3,686,400 px (1920×1920), so the script requests `GEN_SIZE=2048` and downscales — do not lower `GEN_SIZE` below 1920. Verified end-to-end 2026-10-31 (3 textures generated). - `AI_TEXTURES` now covers all 15 game textures (world surfaces, awning, skyline, vignette, - 4 HUD icons, 5 access cards) with a `transparent` flag per entry. NOTE: seedream-4.5 - ignores `background: transparent` and returns fully opaque images (alpha=255), so the - `ai/` icons/vignette/skyline are opaque — they are NOT drop-in replacements for the - authored transparent PNGs. Use a transparency-capable model (or post-process) if alpha - is needed. + Legacy `--ai` remains on Seedream 4.5 and still ignores `background: transparent`; do not + use it for alpha-dependent assets. Gemini 3.1 Flash Image advertised broad ratios but the + current provider rejected authentication. The validated role-aware model is GPT-5 Image Mini. +- Runtime assets: all 15 loaded world/HUD/card textures now live in + `assets/textures/ai/game_ready/`; each passes role audit. Generated tile edges are blended, + icon alpha masks are recolored white where needed, and the vignette uses the existing + deterministic generator because the API returned an empty transparent image. The six + `docs/screenshots/` captures were regenerated after wiring and pass screenshot audit. - Detailed graphics: textured facade/awning/skyline, humanoid NPC rigs + props + walk bob + attention head-turn, inspection artifact cards, mode icons, escalation vignette, body-cam overlay (REC + shift clock). Screenshot set regenerated (`docs/screenshots/`, day + night). @@ -115,7 +118,9 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o - Steps are visual-only (no collider) so NPCs can path to the entrance; the guard spawns on the landing so it never needs to climb. - Persistence tests write into the real `user://shift_results.json` (harmless local pollution of the demo history). - macOS export required `rendering/textures/vram_compression/import_etc2_astc=true` in `project.godot` (universal build demands ETC2 ASTC enabled). -- Joke Shop `door_staff_lines` authored but not yet surfaced in the prototype UI (tracked in TODO). +- Joke Shop `door_staff_lines` are logged through `GameManager` (inspect / wand / refuse). They are not a separate dialogue UI. +- `GameManager._artifacts_for` ignores event `override_access` and maps artifacts by `NpcType`. Joke Shop guests currently inspect as recognized staff. Tracked in TODO "Access artifacts actually match the venue". +- `Save.SETTINGS_FILE` is declared and unused; no mouse-sensitivity or pause menu yet. ## Open Questions @@ -123,8 +128,15 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o - Localization target languages beyond English. - macOS notarization approach for broad distribution. -## Plan vs TODO Gaps (evaluated 2026-10-31, all resolved) +## Plan vs code (re-evaluated) -All previously identified gaps are now implemented and covered by tests/smoke items: PROTESTER archetype, door lock/secure, flashlight, CALL_SOMEONE reaction, LATE phase fix, shift-result persistence, NavigationAgent3D movement, and JSON-backed localization. Remaining backlog lives in `TODO.md`. +Shipped and tested: simulation core, three venues, 57 headless tests, v0.2.1 installers/AppImage, +procedural world, HUD inspect/wand/radio, shift review (summary only), Tab targeting, V venue cycle. + +Still missing (now in `TODO.md`, control pass first): ADR-0007–0010 input/focus/radial/NPC face; +venue-correct access artifacts (`override_access` unread); startup/pause/settings; eye contact, +recognize-as-verb, body-cam toggle, real blocking, request-reason; crowd rubberneck; emergency +aftermath; body-cam replay timeline; sit/photo/film poses; real crowd audio; a few Joke Shop / +Studio scripted cases; README test-count drift (says 52). diff --git a/README.md b/README.md index 4f85214..08a3d73 100644 --- a/README.md +++ b/README.md @@ -136,8 +136,8 @@ The architecture maps onto Godot 4 nodes, scenes, and custom resources as descri - **Navigation:** `NavigationRegion3D` and `NavigationAgent3D` - **NPC behavior:** Custom lightweight finite state machines driven by `NpcProfile` resources - **UI and audio:** Godot `Control` nodes, themes, audio buses, and `AudioStreamPlayer` nodes -- **Art assets:** authored PNGs in `assets/textures/` (≤1024px, power-of-two) produced by `tools/generate_textures.py` and imported by Godot; structural geometry stays procedural (`WorldBuilder`). The same script can generate textures through the OpenRouter image API (`--ai`, requires `OPENROUTER_API_KEY`). -- **Asset tooling:** `tools/asset_pipeline.py` reuses the OpenRouter generator for role-aware assets and provides crop, resize, and image-audit commands. +- **Art assets:** authored PNGs and the in-game generated set in `assets/textures/ai/game_ready/`; structural geometry stays procedural (`WorldBuilder`). The legacy `tools/generate_textures.py --ai` batch remains available. +- **Asset tooling:** `tools/asset_pipeline.py` generates role-aware assets through OpenRouter and provides crop, resize, seamless-tile, and image-audit commands, including gameplay screenshot checks. - **Testing:** GUT (Godot Unit Test) in headless mode - **Source control:** git on a Gitea host with Gitea Actions (`.gitea/workflows/build.yml`) for headless tests and desktop release builds - **Targets:** Windows, Linux, and macOS desktop first; web later @@ -156,14 +156,20 @@ Generate a role-sized image (generation requires `OPENROUTER_API_KEY`): python3 tools/asset_pipeline.py generate --prompt "weathered red brick" --role tile --output assets/textures/brick_extra.png ``` +Generated images are resized to the selected role profile. Non-square requests use +the validated `openai/gpt-5-image-mini` source ratio and crop to the final role dimensions. +Transparent glyphs can be recolored while preserving their alpha mask with +`--foreground '#ffffff'`. + Crop uses the image center by default; `--x` and `--y` select an explicit crop origin. Resize defaults to aspect-preserving `contain`; use `--fit cover` to crop or `--fit stretch` to distort to the exact dimensions. ```bash python3 tools/asset_pipeline.py crop assets/textures/source.png assets/textures/crop.png --width 256 --height 128 python3 tools/asset_pipeline.py resize assets/textures/source.png assets/images/backgrounds/scene.png --width 1920 --height 1080 --fit cover +python3 tools/asset_pipeline.py seamless assets/textures/rough_tile.png assets/textures/tile.png ``` -Audit accepts image files or directories. `--role auto` infers common roles from paths and filenames; explicit roles include `tile`, `texture`, `icon`, `card`, `banner`, `backdrop`, `background`, `overlay`, and `app_icon`. +Audit accepts image files or directories. `--role auto` infers common roles from paths and filenames; explicit roles include `tile`, `texture`, `icon`, `card`, `banner`, `backdrop`, `background`, `overlay`, `app_icon`, and `screenshot`. ```bash python3 tools/asset_pipeline.py audit assets/textures diff --git a/docs/screenshots/01-venue-overview.png b/docs/screenshots/01-venue-overview.png index 9dceb5e..e8c1964 100644 Binary files a/docs/screenshots/01-venue-overview.png and b/docs/screenshots/01-venue-overview.png differ diff --git a/docs/screenshots/02-targeting-npc.png b/docs/screenshots/02-targeting-npc.png index 95bda8a..37a4143 100644 Binary files a/docs/screenshots/02-targeting-npc.png and b/docs/screenshots/02-targeting-npc.png differ diff --git a/docs/screenshots/03-access-inspection.png b/docs/screenshots/03-access-inspection.png index 7649b16..a730542 100644 Binary files a/docs/screenshots/03-access-inspection.png and b/docs/screenshots/03-access-inspection.png differ diff --git a/docs/screenshots/04-radio-report.png b/docs/screenshots/04-radio-report.png index 7f5ece0..331da68 100644 Binary files a/docs/screenshots/04-radio-report.png and b/docs/screenshots/04-radio-report.png differ diff --git a/docs/screenshots/05-late-night-avenue.png b/docs/screenshots/05-late-night-avenue.png index 4349afd..61d0a23 100644 Binary files a/docs/screenshots/05-late-night-avenue.png and b/docs/screenshots/05-late-night-avenue.png differ diff --git a/docs/screenshots/06-night-flashlight.png b/docs/screenshots/06-night-flashlight.png index 7253a87..7b83767 100644 Binary files a/docs/screenshots/06-night-flashlight.png and b/docs/screenshots/06-night-flashlight.png differ