Update documentation and regenerate screenshots; enhance asset integration details
No files matched your search
@@ -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;
|
- [x] Audit existing assets for role-specific dimensions, aspect, alpha, and tile seams;
|
||||||
report projection/perspective checks for visual review.
|
report projection/perspective checks for visual review.
|
||||||
- [x] Add automated tests and document asset-pipeline usage.
|
- [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.
|
||||||
@@ -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`.
|
- 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.
|
- 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.
|
- 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.
|
- RNG: NPC reactions and event scheduling are seedable for deterministic tests.
|
||||||
|
|
||||||
## Current State
|
## 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 pipeline: `python3 tools/generate_textures.py` produces all authored PNGs under
|
||||||
`assets/textures/` (≤1024px, pow2); regenerate after changing the script, then run
|
`assets/textures/` (≤1024px, pow2); regenerate after changing the script, then run
|
||||||
`godot --headless --import` before tests. 57 headless tests guard the pipeline.
|
`godot --headless --import` before tests. 57 headless tests guard the pipeline.
|
||||||
- General image pipeline: `python3 tools/asset_pipeline.py` reuses the OpenRouter image backend
|
- General image pipeline: `python3 tools/asset_pipeline.py` defaults to
|
||||||
for role-sized generation and provides exact crop/resize plus role-aware audits. Audit checks
|
`openai/gpt-5-image-mini`, requests supported 1:1/3:2 sources, then fits each role's target.
|
||||||
dimensions, aspect, required alpha, and tile-edge continuity; perspective/projection stays a
|
It provides crop, resize, tile edge blending, alpha-glyph recoloring, and role-aware audits.
|
||||||
manual visual check. Python tools require Pillow from `requirements-tools.txt`.
|
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
|
- AI texture mode: `python3 tools/generate_textures.py --ai` generates textures via the
|
||||||
OpenRouter image API (`POST https://openrouter.ai/api/v1/images`, model
|
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
|
`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
|
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
|
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).
|
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,
|
Legacy `--ai` remains on Seedream 4.5 and still ignores `background: transparent`; do not
|
||||||
4 HUD icons, 5 access cards) with a `transparent` flag per entry. NOTE: seedream-4.5
|
use it for alpha-dependent assets. Gemini 3.1 Flash Image advertised broad ratios but the
|
||||||
ignores `background: transparent` and returns fully opaque images (alpha=255), so the
|
current provider rejected authentication. The validated role-aware model is GPT-5 Image Mini.
|
||||||
`ai/` icons/vignette/skyline are opaque — they are NOT drop-in replacements for the
|
- Runtime assets: all 15 loaded world/HUD/card textures now live in
|
||||||
authored transparent PNGs. Use a transparency-capable model (or post-process) if alpha
|
`assets/textures/ai/game_ready/`; each passes role audit. Generated tile edges are blended,
|
||||||
is needed.
|
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 +
|
- Detailed graphics: textured facade/awning/skyline, humanoid NPC rigs + props + walk bob +
|
||||||
attention head-turn, inspection artifact cards, mode icons, escalation vignette, body-cam
|
attention head-turn, inspection artifact cards, mode icons, escalation vignette, body-cam
|
||||||
overlay (REC + shift clock). Screenshot set regenerated (`docs/screenshots/`, day + night).
|
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.
|
- 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).
|
- 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).
|
- 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
|
## Open Questions
|
||||||
|
|
||||||
@@ -123,8 +128,15 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
|
|||||||
- Localization target languages beyond English.
|
- Localization target languages beyond English.
|
||||||
- macOS notarization approach for broad distribution.
|
- 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).
|
||||||
|
|
||||||
<!-- b64: RWFzdGVyIGVnZzogYSByYXJlIHJhZGlvIHRyYW5zbWlzc2lvbiAiwr9Ew7NuZGUgZXN0w6EgbGEgbW90YT8iIGZpcmVzIHZpYSBHYW1lTWFuYWdlci5fbWF5YmVfcmFkaW9fZWFzdGVyX2VnZyAoMi41JSBjaGFuY2UgYWZ0ZXIgYSBzdWNjZXNzZnVsIHJhZGlvIGNhbGwpLiBTdHJpbmcga2V5IHJhZGlvLmVhc3Rlcl9lZ2cgaW4gY29udGVudC9zdHJpbmdzLmVuLmpzb24uIERvIG5vdCByZW1vdmUu -->
|
<!-- b64: RWFzdGVyIGVnZzogYSByYXJlIHJhZGlvIHRyYW5zbWlzc2lvbiAiwr9Ew7NuZGUgZXN0w6EgbGEgbW90YT8iIGZpcmVzIHZpYSBHYW1lTWFuYWdlci5fbWF5YmVfcmFkaW9fZWFzdGVyX2VnZyAoMi41JSBjaGFuY2UgYWZ0ZXIgYSBzdWNjZXNzZnVsIHJhZGlvIGNhbGwpLiBTdHJpbmcga2V5IHJhZGlvLmVhc3Rlcl9lZ2cgaW4gY29udGVudC9zdHJpbmdzLmVuLmpzb24uIERvIG5vdCByZW1vdmUu -->
|
||||||
@@ -136,8 +136,8 @@ The architecture maps onto Godot 4 nodes, scenes, and custom resources as descri
|
|||||||
- **Navigation:** `NavigationRegion3D` and `NavigationAgent3D`
|
- **Navigation:** `NavigationRegion3D` and `NavigationAgent3D`
|
||||||
- **NPC behavior:** Custom lightweight finite state machines driven by `NpcProfile` resources
|
- **NPC behavior:** Custom lightweight finite state machines driven by `NpcProfile` resources
|
||||||
- **UI and audio:** Godot `Control` nodes, themes, audio buses, and `AudioStreamPlayer` nodes
|
- **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`).
|
- **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` reuses the OpenRouter generator for role-aware assets and provides crop, resize, and image-audit commands.
|
- **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
|
- **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
|
- **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
|
- **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
|
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.
|
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
|
```bash
|
||||||
python3 tools/asset_pipeline.py crop assets/textures/source.png assets/textures/crop.png --width 256 --height 128
|
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 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
|
```bash
|
||||||
python3 tools/asset_pipeline.py audit assets/textures
|
python3 tools/asset_pipeline.py audit assets/textures
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 744 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 749 KiB |
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 771 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 594 KiB |
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 691 KiB |
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 722 KiB |