Unify the Godot 4.7.2 CI environment and cache it
Full build / Import + headless tests (push) Successful in 2m30s
Full build / Full desktop build + optional release (push) Skipped

Update project features and CI installs/templates to Godot 4.7.2, remove the
old version matrix, and cache the Godot binary and export templates with Gitea
Actions cache. Update release/docs/version references accordingly. Project
import and headless tests pass locally under 4.7.2.
This commit is contained in:
zwitschi committed 2026-11-02 09:25:08 +01:00
1 parent ffd98daf08
commit 87612f2057
11 files changed
+86 -51

No files matched your search

+49 -14
View File
@@ -7,6 +7,10 @@ on:
pull_request: pull_request:
workflow_dispatch: workflow_dispatch:
env:
GODOT_VERSION: "4.7.2"
GODOT_BIN: /usr/local/bin/godot
jobs: jobs:
checks: checks:
name: Import + headless tests name: Import + headless tests
@@ -17,12 +21,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Godot 4.3 - name: Restore Godot binary cache
uses: actions/cache@v4
with:
path: /usr/local/bin/godot
key: godot-${{ runner.os }}-${{ env.GODOT_VERSION }}-v1
- name: Install Godot 4.7.2
run: | run: |
if [ -x /usr/local/bin/godot ]; then
godot --version
exit 0
fi
curl -sL -o /tmp/godot.zip \ curl -sL -o /tmp/godot.zip \
https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_linux.x86_64.zip https://github.com/godotengine/godot/releases/download/4.7.2-stable/Godot_v4.7.2-stable_linux.x86_64.zip
unzip -qo /tmp/godot.zip -d /tmp/godot-bin unzip -qo /tmp/godot.zip -d /tmp/godot-bin
sudo install /tmp/godot-bin/Godot_v4.3-stable_linux.x86_64 /usr/local/bin/godot sudo install /tmp/godot-bin/Godot_v4.7.2-stable_linux.x86_64 /usr/local/bin/godot
godot --version
- name: Import project (build class cache) - name: Import project (build class cache)
run: godot --headless --import run: godot --headless --import
@@ -56,18 +71,38 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Godot 4.3 and export templates - name: Restore Godot binary cache
uses: actions/cache@v4
with:
path: /usr/local/bin/godot
key: godot-${{ runner.os }}-${{ env.GODOT_VERSION }}-v1
- name: Restore export templates cache
uses: actions/cache@v4
with:
path: ~/.local/share/godot/export_templates/4.7.2.stable
key: godot-templates-${{ runner.os }}-${{ env.GODOT_VERSION }}-v1
- name: Install Godot 4.7.2 and export templates
run: | run: |
curl -sL -o /tmp/godot.zip \ if [ ! -x /usr/local/bin/godot ]; then
https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_linux.x86_64.zip curl -sL -o /tmp/godot.zip \
unzip -qo /tmp/godot.zip -d /tmp/godot-bin https://github.com/godotengine/godot/releases/download/4.7.2-stable/Godot_v4.7.2-stable_linux.x86_64.zip
sudo install /tmp/godot-bin/Godot_v4.3-stable_linux.x86_64 /usr/local/bin/godot unzip -qo /tmp/godot.zip -d /tmp/godot-bin
sudo install /tmp/godot-bin/Godot_v4.7.2-stable_linux.x86_64 /usr/local/bin/godot
fi
godot --version
if [ -f "$HOME/.local/share/godot/export_templates/4.7.2.stable/linux_release.x86_64" ]; then
ls "$HOME/.local/share/godot/export_templates/4.7.2.stable" | head -5
exit 0
fi
curl -sL -o /tmp/templates.tpz \ curl -sL -o /tmp/templates.tpz \
https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_export_templates.tpz https://github.com/godotengine/godot/releases/download/4.7.2-stable/Godot_v4.7.2-stable_export_templates.tpz
mkdir -p ~/.local/share/godot/export_templates/4.3.stable rm -rf /tmp/tpl && mkdir -p /tmp/tpl
cd /tmp && rm -rf tpl && mkdir tpl && unzip -qo templates.tpz -d tpl unzip -qo /tmp/templates.tpz -d /tmp/tpl
cp tpl/templates/* "$HOME/.local/share/godot/export_templates/4.3.stable/" 2>/dev/null || true mkdir -p "$HOME/.local/share/godot/export_templates/4.7.2.stable"
ls "$HOME/.local/share/godot/export_templates/4.3.stable" | head -5 cp /tmp/tpl/templates/* "$HOME/.local/share/godot/export_templates/4.7.2.stable/"
ls "$HOME/.local/share/godot/export_templates/4.7.2.stable" | head -5
- name: Import project - name: Import project
run: godot --headless --import run: godot --headless --import
@@ -114,7 +149,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
env: env:
# An explicit repo secret wins. Without one, publish_release.sh reuses # An explicit repo secret wins. Without one, publish_release.sh reuses
# the local git extraheader that actions/checkout configures for the job # the local git extraheader that actions/checkout configures on the job
# (the runner's own credentials), so tag builds still publish. # (the runner's own credentials), so tag builds still publish.
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
VERSION: ${{ github.ref_name }} VERSION: ${{ github.ref_name }}
+14 -14
View File
@@ -33,17 +33,17 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
`outfit_for`/`layer_for`/`hand_item_for` helpers. Blender = flatpak 5.2.0 LTS, sandbox cwd `outfit_for`/`layer_for`/`hand_item_for` helpers. Blender = flatpak 5.2.0 LTS, sandbox cwd
`/app/blender` → absolute paths for `--python`. CI stays offline (committed assets). `/app/blender` → absolute paths for `--python`. CI stays offline (committed assets).
- Engine: Godot 4.3 stable (official editor build, `~/.local/bin/godot`). The system's preinstalled `godot-runner` (4.7.2, Fedora) cannot load projects from arbitrary paths because it was compiled without path overrides; use the official editor binary instead. - Engine: Godot 4.7.2 stable (official editor build, `~/.local/bin/godot`). The system's preinstalled `godot-runner` cannot load projects from arbitrary paths because it was compiled without path overrides; use the official editor binary instead.
- Language: GDScript. All cross-file references use explicit `preload()` constants (not `class_name` globals) so scripts compile in headless `--script` runs without the editor's class cache. - Language: GDScript. All cross-file references use explicit `preload()` constants (not `class_name` globals) so scripts compile in headless `--script` runs without the editor's class cache.
- Test framework deviation: the project uses a custom minimal headless test runner (`src/test/test_runner.gd`) instead of GUT, because GUT needs the editor plugin. CI runs it with `--headless`. - Test framework deviation: the project uses a custom minimal headless test runner (`src/test/test_runner.gd`) instead of GUT, because GUT needs the editor plugin. CI runs it with `--headless`.
- 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 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.
- 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. - 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.
- **Mouse look (v0.7.3):** guard look is handled in `GuardController._input()` (before GUI), not `_unhandled_input`; focus/click-back recaptures the cursor and the HUD is made mouse-transparent recursively. Regression tests cover yaw/pitch and HUD filters. - **Mouse look (v0.7.3):** guard look is handled in `GuardController._input()` (before GUI), not `_unhandled_input`; focus/click-back recaptures the cursor and the HUD is made mouse-transparent recursively. Regression tests cover yaw/pitch and HUD filters.
- **v0.9.0 production pass:** CI/release baseline remains Godot 4.3; local dev is 4.7.2 with the version-adaptive light falloff. Audio settings are `master_volume`/`sfx_volume`/`ambience_volume`; accessibility has `reduce_motion` and `captions_enabled` (HUD log is the caption surface). Budget smoke is 24 NPCs (6.94 ms headless). Coat/dress stride is scaled to 0.76 to reduce hem clipping. Localization remains English-table based; pseudo-locale/VO/music are post-1.0. - **v0.9.0 production pass:** CI/release, local dev and project now use Godot 4.7.2; the version-adaptive light falloff remains for older editors. Audio settings are `master_volume`/`sfx_volume`/`ambience_volume`; accessibility has `reduce_motion` and `captions_enabled` (HUD log is the caption surface). Budget smoke is 24 NPCs (6.94 ms headless). Coat/dress stride is scaled to 0.76 to reduce hem clipping. Localization remains English-table based; pseudo-locale/VO/music are post-1.0.
- **Radio submit fix (v0.8.1):** `RadioPanel.action_button` now connects `pressed` for normal reports; `button_down/up` remains exclusive to emergency hold-to-confirm. Regression test covers both modes. - **Radio submit fix (v0.8.1):** `RadioPanel.action_button` now connects `pressed` for normal reports; `button_down/up` remains exclusive to emergency hold-to-confirm. Regression test covers both modes.
- **Campaign/v0.8.0:** `Campaign` owns Hollywood → Joke Shop → TV Studio progression. `campaign.json`, `shift_results.json`, `settings.json` and versioned `shift_state.json` persist separately; pause saves a checkpoint, review Continue advances, Settings resets with confirmation. Difficulty keys are `easy/normal/hard` (`ai_difficulty`); scripted QA bypasses tutorial unless `--tutorial` is passed. Help is searchable and generated from `InputBindings.REMAPPABLE`. - **Campaign/v0.8.0:** `Campaign` owns Hollywood → Joke Shop → TV Studio progression. `campaign.json`, `shift_results.json`, `settings.json` and versioned `shift_state.json` persist separately; pause saves a checkpoint, review Continue advances, Settings resets with confirmation. Difficulty keys are `easy/normal/hard` (`ai_difficulty`); scripted QA bypasses tutorial unless `--tutorial` is passed. Help is searchable and generated from `InputBindings.REMAPPABLE`.
- **Tutorial (0.8.0 work):** `docs/tutorial.md` is the eight-beat design; `src/game/tutorial.gd` is the pure state machine, `TutorialOverlay` is the non-blocking card, and `GameManager` wires it with a safe visitor, suppressed spawns, persisted completion/skip and Settings replay. Scripted test/capture runs bypass it unless `--tutorial` is passed; `smoke_tutorial.gd` covers completion/replay/skip. - **Tutorial (0.8.0 work):** `docs/tutorial.md` is the eight-beat design; `src/game/tutorial.gd` is the pure state machine, `TutorialOverlay` is the non-blocking card, and `GameManager` wires it with a safe visitor, suppressed spawns, persisted completion/skip and Settings replay. Scripted test/capture runs bypass it unless `--tutorial` is passed; `smoke_tutorial.gd` covers completion/replay/skip.
@@ -58,13 +58,12 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
binaries + override into `gig-line-desktop-hq-<version>.zip`; binaries + override into `gig-line-desktop-hq-<version>.zip`;
`publish_release.sh` uploads it when present. A/B report: `publish_release.sh` uploads it when present. A/B report:
`docs/screens/realism/2026-11-01-forward-plus/` (entrance gap 1.568→1.187). `docs/screens/realism/2026-11-01-forward-plus/` (entrance gap 1.568→1.187).
- **Local Godot toolchain (2026-11-01):** `~/.local/bin/godot` is 4.7.2 stable; - **Godot toolchain (updated 2026-11-01):** local `~/.local/bin/godot`, CI and
4.3 stable is kept as `~/.local/bin/godot-4.3.stable`. Export templates for `project.godot` now use Godot 4.7.2; 4.3 remains only as a local backup binary.
4.7.2 are installed under `~/.local/share/godot/export_templates/4.7.2.stable` Export templates for 4.7.2 are installed under
(4.3 remains). The project and CI still pin 4.3 in `project.godot`/the Gitea `~/.local/share/godot/export_templates/4.7.2.stable`. Godot 4.7 writes
workflow; 4.7.2 imports, runs the 231-test suite, session-shell smoke and a `*.gd.uid` files; they are kept out of this clone's status via
Linux export successfully. Godot 4.7 writes `*.gd.uid` files; they are kept `.git/info/exclude`. CI caches the binary/templates with Gitea Actions cache.
out of this clone's status via `.git/info/exclude` until the project upgrades.
- **Blender invocation (v0.6.0):** `flatpak run org.blender.Blender --background --python - **Blender invocation (v0.6.0):** `flatpak run org.blender.Blender --background --python
/run/media/system/DATA/Documents/06-games/security-game/tools/npc_pipeline.py -- build`. /run/media/system/DATA/Documents/06-games/security-game/tools/npc_pipeline.py -- build`.
The flatpak cannot read `/tmp`; use absolute repo paths. `assets/models/npc/.gdignore` is The flatpak cannot read `/tmp`; use absolute repo paths. `assets/models/npc/.gdignore` is
@@ -145,7 +144,7 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
`npc_pipeline.py` + `asset_pipeline.py` and the confirmed-asset locations. `npc_pipeline.py` + `asset_pipeline.py` and the confirmed-asset locations.
- Repo: `/run/media/system/DATA/Documents/06-games/security-game` (also reachable at - 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). `/var/home/zwitschi/Documents/06-games/security-game`). Godot: `~/.local/bin/godot` (4.7.2).
Tests: `godot --headless --path . --script res://src/test/test_runner.gd` → **177/177**. 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**. 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. Session shell smoke: `godot --headless --path . --script res://src/test/smoke_session_shell.gd` → exit 0.
@@ -194,7 +193,7 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
joke_shop 700 s / studio 700 s; `--stages=` subset) and swaps textures by the material's joke_shop 700 s / studio 700 s; `--stages=` subset) and swaps textures by the material's
*original* albedo path. **Gotcha:** in the SceneTree script, do not overwrite `_phase` after *original* albedo path. **Gotcha:** in the SceneTree script, do not overwrite `_phase` after
`_begin_stage()` sets `done`, or the run loops forever between stage/shoot (`_queue` empty). `_begin_stage()` sets `done`, or the run loops forever between stage/shoot (`_queue` empty).
**Gotcha:** `elapsed_s = 620` is *Evening* (dusk), 700+ is Late. Godot 4.3 **Gotcha:** `elapsed_s = 620` is *Evening* (dusk), 700+ is Late. Godot 4.7
`StandardMaterial3D` has no `fog_enabled`; the skyline is a `ShaderMaterial` with `StandardMaterial3D` has no `fog_enabled`; the skyline is a `ShaderMaterial` with
`render_mode unshaded, cull_disabled, fog_disabled` + `ALPHA_SCISSOR_THRESHOLD` so the `render_mode unshaded, cull_disabled, fog_disabled` + `ALPHA_SCISSOR_THRESHOLD` so the
panorama's own haze shows. Backdrop plane is 90 m tall with 2 UV repeats (~200×90 m per panorama's own haze shows. Backdrop plane is 90 m tall with 2 UV repeats (~200×90 m per
@@ -577,8 +576,9 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
- Venue cycling: `V` switches Hollywood Blvd → The Joke Shop → TV Studio and restarts the shift. - Venue cycling: `V` switches Hollywood Blvd → The Joke Shop → TV Studio and restarts the shift.
- Venue door-staff dialogue: `VenueScenario.door_staff_line(context, rng)` and GameManager logging - Venue door-staff dialogue: `VenueScenario.door_staff_line(context, rng)` and GameManager logging
(id/ticket/wand-check, refusal, prohibited-item) — Joke Shop flavor. (id/ticket/wand-check, refusal, prohibited-item) — Joke Shop flavor.
- CI cache: `.gitea/workflows/build.yml` no longer uses `actions/cache` (the runner can't reach - CI cache: `.gitea/workflows/build.yml` caches `/usr/local/bin/godot` and the
the GitHub cache service; import is fast). `GODOT_SILENCE_ROOT_WARNING=1` set on jobs. 4.7.2 export templates with Gitea Actions cache. `GODOT_SILENCE_ROOT_WARNING=1`
is set on jobs.
Logs live in `.gitea/logs/` after each run. Logs live in `.gitea/logs/` after each run.
- Visual polish (v0.2.0): phase lighting (GameManager.PHASE_LIGHTING + ProceduralSkyMaterial), - Visual polish (v0.2.0): phase lighting (GameManager.PHASE_LIGHTING + ProceduralSkyMaterial),
street lamps + night mode in WorldBuilder.set_night_mode, marquee Label3D, crosswalk/planters/ street lamps + night mode in WorldBuilder.set_night_mode, marquee Label3D, crosswalk/planters/
+1 -1
View File
@@ -159,7 +159,7 @@ Primary decisions: [ADR-0007](docs/adr/0007-locomotion-and-input-layers.md), [AD
## Tech Stack ## Tech Stack
- **Engine:** Godot 4.3 baseline (local dev verified with 4.7.2), GL Compatibility renderer (Web parity); optional Forward+ Desktop HQ build. - **Engine:** Godot 4.7.2, GL Compatibility renderer (Web parity); optional Forward+ Desktop HQ build.
- **Language:** GDScript. - **Language:** GDScript.
- **Architecture:** venue-driven simulation; shared systems plus `Resource`-based scenario data. - **Architecture:** venue-driven simulation; shared systems plus `Resource`-based scenario data.
- **Navigation:** `NavigationRegion3D` / `NavigationAgent3D`. - **Navigation:** `NavigationRegion3D` / `NavigationAgent3D`.
+2 -2
View File
@@ -74,7 +74,7 @@ decisions are recorded as ADRs in [`docs/adr/`](docs/adr/).
## Tech Stack ## Tech Stack
- **Engine:** Godot 4.3 baseline (local dev verified with 4.7.2) · **Language:** GDScript - **Engine:** Godot 4.7.2 · **Language:** GDScript
- **NPCs:** Blender-authored skinned library (`assets/models/blender/`) with procedural fallbacks; lightweight FSMs on `NpcProfile` - **NPCs:** Blender-authored skinned library (`assets/models/blender/`) with procedural fallbacks; lightweight FSMs on `NpcProfile`
- **World:** procedural `WorldBuilder` + generated prop models - **World:** procedural `WorldBuilder` + generated prop models
- **Art:** v2 skyline/surface textures in `assets/textures/ai/game_ready/v2/picks/`; UI/scene art in `assets/images/` - **Art:** v2 skyline/surface textures in `assets/textures/ai/game_ready/v2/picks/`; UI/scene art in `assets/images/`
@@ -119,7 +119,7 @@ Full setup, every run/test/smoke command, and the controls table are in
## Development Status ## Development Status
v0.9.0 adds the production-quality baseline: mixer/accessibility settings, a v0.9.0 adds the production-quality baseline: mixer/accessibility settings, a
24-NPC performance budget and the documented Godot 4.3-CI/4.7-local matrix, on 24-NPC performance budget and the unified Godot 4.7.2 toolchain, on
top of v0.8's tutorial, campaign, checkpoint resume, difficulty and Help. See top of v0.8's tutorial, campaign, checkpoint resume, difficulty and Help. See
[`docs/development-status.md`](docs/development-status.md) for the implemented [`docs/development-status.md`](docs/development-status.md) for the implemented
list and [`TODO.md`](TODO.md) for the v1.0.0 roadmap. Manual verification uses list and [`TODO.md`](TODO.md) for the v1.0.0 roadmap. Manual verification uses
+9 -9
View File
@@ -12,11 +12,11 @@ time you export, either:
matching templates), or matching templates), or
- Install them manually from the - Install them manually from the
[Godot downloads](https://godotengine.org/download/) page by placing the [Godot downloads](https://godotengine.org/download/) page by placing the
`Godot_v4.3-stable_export_templates.tpz` contents into `Godot_v4.7.2-stable_export_templates.tpz` contents into
`~/.local/share/godot/export_templates/4.3.stable/`. `~/.local/share/godot/export_templates/4.7.2.stable/`.
The templates must match the editor binary you use locally. CI pins Godot 4.3; The templates must match the editor binary you use locally. CI and local
the local development machine uses 4.7.2 with its matching templates. Verify with: development both use Godot 4.7.2 with its matching templates. Verify with:
```bash ```bash
godot --headless --export-release "Linux" build/gig-line-smoke.x86_64 godot --headless --export-release "Linux" build/gig-line-smoke.x86_64
@@ -31,7 +31,7 @@ godot --headless --export-release "Linux" build/gig-line-smoke.x86_64
The repository ships a Gitea Actions workflow (`.gitea/workflows/build.yml`): The repository ships a Gitea Actions workflow (`.gitea/workflows/build.yml`):
- Every push/PR runs the **checks** job: Godot 4.3 install, project import, and the - Every push/PR runs the **checks** job: Godot 4.7.2 install, project import, and the
full headless test suite. This is the fast safety net. full headless test suite. This is the fast safety net.
- **Tags (`v*`)** and **manual `workflow_dispatch`** runs additionally execute the - **Tags (`v*`)** and **manual `workflow_dispatch`** runs additionally execute the
**build** job: export templates install, import, `tools/build_releases.sh` for **build** job: export templates install, import, `tools/build_releases.sh` for
@@ -63,10 +63,10 @@ setup, so do not rely on it.
> artifacts. If CI publishing fails again, run > artifacts. If CI publishing fails again, run
> `./tools/publish_release.sh <version>` from a checkout with `~/.git-credentials`. > `./tools/publish_release.sh <version>` from a checkout with `~/.git-credentials`.
> **No `actions/cache` for now:** the runner has no local actions-cache service, so > **Godot cache:** the workflow uses Gitea Actions cache for the Godot binary and the
> `actions/cache` times out against GitHub's cache API. We dropped it (Godot import > 4.7.2 export templates. The first run still downloads them; subsequent runs restore
> is only ~4s). If a host admin later enables Gitea `[cache.actions]` with a cache > from cache. If the host cache service is unavailable, remove the cache steps and
> server, the step can be reintroduced. > let the install steps download fresh copies.
> The workflow lives in `.gitea/workflows/` (Gitea's canonical path). The old > The workflow lives in `.gitea/workflows/` (Gitea's canonical path). The old
> `.github/workflows/ci.yml` was removed to avoid double runs on hosts that scan > `.github/workflows/ci.yml` was removed to avoid double runs on hosts that scan
+5 -5
View File
@@ -25,7 +25,7 @@ This document follows the structure of the arc42 architecture documentation temp
## 2. Constraints ## 2. Constraints
- The first implementation should be small enough for a playable vertical slice. - The first implementation should be small enough for a playable vertical slice.
- The engine is Godot 4 with GDScript; a playable prototype vertical slice is implemented. CI pins Godot 4.3 while local development is verified with 4.7.2; the default renderer stays GL Compatibility for Web parity, with an optional Forward+ Desktop HQ build. - The engine is Godot 4.7.2 with GDScript; a playable prototype vertical slice is implemented. CI, local development and exported builds use 4.7.2; the default renderer stays GL Compatibility for Web parity, with an optional Forward+ Desktop HQ build.
- Venue-specific policies must be configurable rather than hard-coded into individual NPCs. - Venue-specific policies must be configurable rather than hard-coded into individual NPCs.
- The game must preserve the de-escalation-first design described in [`PLAN.md`](../PLAN.md). - The game must preserve the de-escalation-first design described in [`PLAN.md`](../PLAN.md).
- The project uses the repository workflow described in [`AGENTS.md`](../AGENTS.md). - The project uses the repository workflow described in [`AGENTS.md`](../AGENTS.md).
@@ -180,7 +180,7 @@ reputation, crowd reaction and shift review read it rather than resolving gamepl
## 7. Deployment View ## 7. Deployment View
The game is a single-player local client containing presentation, simulation, rules, content, and persistence for local settings and shift results. No online backend is required. A non-threaded Web export ships alongside the desktop builds and can be served from any static host without special headers. The default renderer is GL Compatibility; an optional Desktop HQ zip uses Forward+ with volumetric fog/SDFGI on Vulkan-capable desktops. CI pins Godot 4.3 while local development is verified with 4.7.2, so the light falloff path is version-adaptive until the baseline is unified. The game is a single-player local client containing presentation, simulation, rules, content, and persistence for local settings and shift results. No online backend is required. A non-threaded Web export ships alongside the desktop builds and can be served from any static host without special headers. The default renderer is GL Compatibility; an optional Desktop HQ zip uses Forward+ with volumetric fog/SDFGI on Vulkan-capable desktops. CI, local development and exported builds use Godot 4.7.2; the light-falloff code keeps a compatibility branch for older editors but the supported baseline is unified.
Future options include external analytics, cloud saves, or replay sharing, but they are not part of the current architecture. Future options include external analytics, cloud saves, or replay sharing, but they are not part of the current architecture.
@@ -188,7 +188,7 @@ Future options include external analytics, cloud saves, or replay sharing, but t
A continuous-integration pipeline keeps the headless test suite green on every change and publishes tagged releases. A continuous-integration pipeline keeps the headless test suite green on every change and publishes tagged releases.
- **Workflow:** `.gitea/workflows/build.yml` runs on pushes, pull requests, tags, and manual dispatches. The `checks` job installs Godot 4.3, imports the project, and runs `res://src/test/test_runner.gd`; it fails on a non-zero exit code or any `SCRIPT ERROR` in the output. - **Workflow:** `.gitea/workflows/build.yml` runs on pushes, pull requests, tags, and manual dispatches. The `checks` job restores/caches Godot 4.7.2, imports the project, and runs `res://src/test/test_runner.gd`; it fails on a non-zero exit code or any `SCRIPT ERROR` in the output.
- **Build job:** runs for tags and manual dispatches. It installs export templates, exports Linux/Windows/macOS and the non-threaded Web build, packages the NSIS installer, Linux AppImage and optional Desktop HQ zip, verifies the installer contents, and uploads the artifacts. - **Build job:** runs for tags and manual dispatches. It installs export templates, exports Linux/Windows/macOS and the non-threaded Web build, packages the NSIS installer, Linux AppImage and optional Desktop HQ zip, verifies the installer contents, and uploads the artifacts.
- **Publish job:** tag builds call `tools/publish_release.sh` to create the Gitea release and upload the standard artifacts plus the optional Desktop HQ zip. The script uses `GITEA_TOKEN` when configured and otherwise reuses the runner's checkout extraheader credentials. - **Publish job:** tag builds call `tools/publish_release.sh` to create the Gitea release and upload the standard artifacts plus the optional Desktop HQ zip. The script uses `GITEA_TOKEN` when configured and otherwise reuses the runner's checkout extraheader credentials.
- **Hosting:** the repository lives on Gitea (`https://git.allucanget.biz/zwitschi/security-game`). Export templates must match the pinned Godot version; macOS builds are unsigned and need quarantine guidance or notarization for wider distribution. - **Hosting:** the repository lives on Gitea (`https://git.allucanget.biz/zwitschi/security-game`). Export templates must match the pinned Godot version; macOS builds are unsigned and need quarantine guidance or notarization for wider distribution.
@@ -219,7 +219,7 @@ The release process is: bump the version, run the full test suite and `tools/che
- **Asset provenance and AI usage:** AI-assisted images/concepts are development inputs only; validated outputs are committed, audited and loaded through the same runtime asset contracts. Generated content must not become an offline/CI dependency. - **Asset provenance and AI usage:** AI-assisted images/concepts are development inputs only; validated outputs are committed, audited and loaded through the same runtime asset contracts. Generated content must not become an offline/CI dependency.
- **Campaign and checkpoint state:** `Campaign` owns venue order/progression; settings, campaign, completed shift history and a versioned pause checkpoint are separate JSON documents. The checkpoint snapshots coordinator systems, scheduler RNG and NPC presentation/access state; it deliberately does not serialize the tutorial overlay or transient input state. - **Campaign and checkpoint state:** `Campaign` owns venue order/progression; settings, campaign, completed shift history and a versioned pause checkpoint are separate JSON documents. The checkpoint snapshots coordinator systems, scheduler RNG and NPC presentation/access state; it deliberately does not serialize the tutorial overlay or transient input state.
- **Difficulty:** easy/normal/hard only scale spawn pacing, NPC compliance tolerance and report-credibility strictness; access/escalation rules and emergency rarity are invariant. - **Difficulty:** easy/normal/hard only scale spawn pacing, NPC compliance tolerance and report-credibility strictness; access/escalation rules and emergency rarity are invariant.
- **Settings and accessibility:** volume/motion/caption settings persist through `settings.json`; Help is generated from the input-binding catalogue and the HUD log is the text caption surface. The supported engine matrix is explicit (CI/release 4.3, local 4.7.2) rather than an implicit version drift. - **Settings and accessibility:** volume/motion/caption settings persist through `settings.json`; Help is generated from the input-binding catalogue and the HUD log is the text caption surface. CI/release, local development and exported builds are unified on Godot 4.7.2.
- **Documentation ownership:** `PLAN.md` owns design intent; `docs/gameplay.md` owns playable mechanics; `docs/architecture.md` owns system boundaries, data flow, constraints and cross-cutting decisions; ADRs own decision history; `docs/development-status.md` owns the implemented/gap list; `TODO.md` owns the roadmap; `MEMORY.md` owns gotchas and open questions. Specialized docs link to these rather than becoming competing sources of truth. - **Documentation ownership:** `PLAN.md` owns design intent; `docs/gameplay.md` owns playable mechanics; `docs/architecture.md` owns system boundaries, data flow, constraints and cross-cutting decisions; ADRs own decision history; `docs/development-status.md` owns the implemented/gap list; `TODO.md` owns the roadmap; `MEMORY.md` owns gotchas and open questions. Specialized docs link to these rather than becoming competing sources of truth.
## 9. Architecture Decisions ## 9. Architecture Decisions
@@ -264,7 +264,7 @@ Architecture decisions are recorded as ADRs:
- Mental-health-crisis scenarios require careful writing, playtesting, and respectful presentation. - Mental-health-crisis scenarios require careful writing, playtesting, and respectful presentation.
- The choice of engine may affect navigation, crowd scale, tooling, and content authoring. - The choice of engine may affect navigation, crowd scale, tooling, and content authoring.
- Reference mockups can outpace the runtime art style; compare/judge catch gross drift but not composition errors, so the staged gallery needs human review after large visual changes. - Reference mockups can outpace the runtime art style; compare/judge catch gross drift but not composition errors, so the staged gallery needs human review after large visual changes.
- Godot version skew (CI 4.3 vs local 4.7.2) can change lighting, import sidecars and generated UIDs; a single supported version and a visual smoke matrix are required before 1.0. - Godot 4.7.2 is the unified CI/local/project baseline; future engine bumps still require import, visual and export smoke checks before changing that baseline.
- Content volume and authoring tools are still thin; adding venues/events by editing the factory can become error-prone without schema validation and preview tooling. - Content volume and authoring tools are still thin; adding venues/events by editing the factory can become error-prone without schema validation and preview tooling.
- Save data currently covers settings and shift history, not mid-shift resume; adding saves/replays requires a versioned schema and migration policy. - Save data currently covers settings and shift history, not mid-shift resume; adding saves/replays requires a versioned schema and migration policy.
- The optional judge and image-generation paths depend on an external key, model availability and budget; CI cannot make them a release gate, and keys must never be committed. - The optional judge and image-generation paths depend on an external key, model availability and budget; CI cannot make them a release gate, and keys must never be committed.
+2 -2
View File
@@ -2,7 +2,7 @@
Implemented so far: Implemented so far:
- Godot 4.3 project scaffold, input map, procedural world builder - Godot 4.7.2 project scaffold, input map, procedural world builder
- Venue-driven simulation core: `ShiftCoordinator`, `VenueScenario`, `EventScheduler`, `NPCController` + FSM, `AccessVerifier`, `EscalationManager`, `RadioSystem`, `IncidentRecorder`, `ReputationEvaluator`, `CrowdSystem` - Venue-driven simulation core: `ShiftCoordinator`, `VenueScenario`, `EventScheduler`, `NPCController` + FSM, `AccessVerifier`, `EscalationManager`, `RadioSystem`, `IncidentRecorder`, `ReputationEvaluator`, `CrowdSystem`
- Three authored scenarios (Hollywood Boulevard building, The Joke Shop, Late Night TV Studio) with access policies, NPC archetypes, and event pools - Three authored scenarios (Hollywood Boulevard building, The Joke Shop, Late Night TV Studio) with access policies, NPC archetypes, and event pools
- Headless unit tests: **250 passing** (access rules and venue-correct access loadout, escalation, radio cooldown/battery, NPC reaction determinism, door lock, flashlight perception, persistence round-trip, settings round-trip, input remaps, navmesh, step colliders, skyline alpha, scenario data, full-shift simulation, wand screening, responder dispatch, localization strings, focus cone, action wheel, session shell, PLAN verbs and incident recording, crowd presentation, emergency aftermath, body-camera timeline, NPC theater poses, audio, accessibility, authored scenario content, string formatting, `.tres` venue round-trip, surface materials and environment, focus ranking and outfit/gait helpers, generated prop models, web export preset, prop atlas material, player movement, NPC character layers/LOD/queue, input bindings) - Headless unit tests: **250 passing** (access rules and venue-correct access loadout, escalation, radio cooldown/battery, NPC reaction determinism, door lock, flashlight perception, persistence round-trip, settings round-trip, input remaps, navmesh, step colliders, skyline alpha, scenario data, full-shift simulation, wand screening, responder dispatch, localization strings, focus cone, action wheel, session shell, PLAN verbs and incident recording, crowd presentation, emergency aftermath, body-camera timeline, NPC theater poses, audio, accessibility, authored scenario content, string formatting, `.tres` venue round-trip, surface materials and environment, focus ranking and outfit/gait helpers, generated prop models, web export preset, prop atlas material, player movement, NPC character layers/LOD/queue, input bindings)
@@ -41,7 +41,7 @@ Implemented so far:
- Visual alignment: start/venue menu, pause, settings, shift review, radio, wand, inspection, timeline, HUD target chip/escalation bar, and radial menu now use or match their AI references in `assets/images/ui/`. The runtime art loader (`src/game/ui/art.gd`) falls back cleanly when a file is missing. - Visual alignment: start/venue menu, pause, settings, shift review, radio, wand, inspection, timeline, HUD target chip/escalation bar, and radial menu now use or match their AI references in `assets/images/ui/`. The runtime art loader (`src/game/ui/art.gd`) falls back cleanly when a file is missing.
- Realism adoption (post-v0.6.0): v2 per-phase skylines and surface tiles with normal maps, retuned sun/exposure/fog, wet asphalt, denser foliage, a visible additive flashlight beam, and refreshed staging captures. `tools/check_screenshots.sh` is the repeatable capture/compare gate; judge is clean of `diff` verdicts. - Realism adoption (post-v0.6.0): v2 per-phase skylines and surface tiles with normal maps, retuned sun/exposure/fog, wet asphalt, denser foliage, a visible additive flashlight beam, and refreshed staging captures. `tools/check_screenshots.sh` is the repeatable capture/compare gate; judge is clean of `diff` verdicts.
- Input/reliability fixes: selecting a venue releases the start-menu input lock and recaptures the mouse; the body-camera overlay no longer covers the shift status. Mouse look now reads at `_input`, restores capture on window focus/click-back, and the HUD is mouse-transparent. Normal radio reports submit on click; emergency calls still require the hold-to-confirm path. - Input/reliability fixes: selecting a venue releases the start-menu input lock and recaptures the mouse; the body-camera overlay no longer covers the shift status. Mouse look now reads at `_input`, restores capture on window focus/click-back, and the HUD is mouse-transparent. Normal radio reports submit on click; emergency calls still require the hold-to-confirm path.
- Production-quality pass (v0.9.0): mixer/accessibility settings, audio volume clamping, 24-NPC budget smoke, shortened coat/dress stride, and an explicit Godot 4.3-CI/4.7-local support matrix with documented upgrade/rollback requirements. - Production-quality pass (v0.9.0): mixer/accessibility settings, audio volume clamping, 24-NPC budget smoke, shortened coat/dress stride, and a unified Godot 4.7.2 CI/local support baseline with documented upgrade/rollback requirements.
- Campaign and first-hour pass (v0.8.0): campaign progression, checkpoint resume, difficulty presets, a searchable Help overlay, recovery events, contextual dialogue, policy/debrief lines and tutorial/replay/skip. Scripted QA bypasses the tutorial unless `--tutorial` is passed. - Campaign and first-hour pass (v0.8.0): campaign progression, checkpoint resume, difficulty presets, a searchable Help overlay, recovery events, contextual dialogue, policy/debrief lines and tutorial/replay/skip. Scripted QA bypasses the tutorial unless `--tutorial` is passed.
- Tutorial pass (0.8.0 work): the eight-beat first shift is wired through a non-blocking prompt overlay, a safe compliant visitor, real wheel/inspection/warning/radio panels, persisted completion/skip and a Settings replay action. Scripted tests/captures bypass it unless `--tutorial` is passed; `smoke_tutorial.gd` covers the full flow. - Tutorial pass (0.8.0 work): the eight-beat first shift is wired through a non-blocking prompt overlay, a safe compliant visitor, real wheel/inspection/warning/radio panels, persisted completion/skip and a Settings replay action. Scripted tests/captures bypass it unless `--tutorial` is passed; `smoke_tutorial.gd` covers the full flow.
- Vision judge (v0.7.2): discovers the cheapest current OpenRouter image+JSON model, reports the model/fallbacks used, and clears the full screen-design judge (13/13 match, 0 diff). - Vision judge (v0.7.2): discovers the cheapest current OpenRouter image+JSON model, reports the model/fallbacks used, and clears the full screen-design judge (13/13 match, 0 diff).
+1 -1
View File
@@ -2,7 +2,7 @@
## Setup ## Setup
1. Download the Godot 4.3+ editor (official build) and put `godot` on your PATH. The supported policy is an explicit matrix: CI/release baseline 4.3, local development verified with 4.7.2. Engine upgrades require import, headless, screenshot and Desktop HQ smoke checks before changing the baseline. 1. Download Godot **4.7.2** (official build) and put `godot` on your PATH. The project, local tooling and CI use the same version; engine upgrades require import, headless, screenshot and Desktop HQ smoke checks before changing the baseline.
2. Open or run the project from this directory. 2. Open or run the project from this directory.
## Run and Test ## Run and Test
+1 -1
View File
@@ -39,4 +39,4 @@
37. The F debug overlay lists the next eligible events; recovery events and recently played scripted events behave as authored. 37. The F debug overlay lists the next eligible events; recovery events and recently played scripted events behave as authored.
38. Master/SFX/ambience volume settings clamp at 0/1 and persist; Reduce motion disables head bob; the captions toggle persists. 38. Master/SFX/ambience volume settings clamp at 0/1 and persist; Reduce motion disables head bob; the captions toggle persists.
39. The 24-NPC budget smoke stays inside its frame budget; coats/dresses do not show obvious leg clipping in a normal walk. 39. The 24-NPC budget smoke stays inside its frame budget; coats/dresses do not show obvious leg clipping in a normal walk.
40. Help remains readable with the largest HUD font scale, and the engine matrix (4.3 CI / 4.7.2 local) is used for verification. 40. Help remains readable with the largest HUD font scale, and CI/local verification use the same Godot 4.7.2 baseline.
+1 -1
View File
@@ -14,7 +14,7 @@ config/name="Gig Line"
config/description="Workplace security simulation about observation, access verification, and proportionate escalation." config/description="Workplace security simulation about observation, access verification, and proportionate escalation."
config/version="0.9.0" config/version="0.9.0"
run/main_scene="res://scenes/main.tscn" run/main_scene="res://scenes/main.tscn"
config/features=PackedStringArray("4.3", "GL Compatibility") config/features=PackedStringArray("4.7", "GL Compatibility")
[autoload] [autoload]
+1 -1
View File
@@ -2,7 +2,7 @@
# Build distributable desktop executables with the Godot export pipeline. # Build distributable desktop executables with the Godot export pipeline.
# #
# Requirements: # Requirements:
# - Godot 4.3 (or the version in project.godot `config/features`) on PATH, # - Godot 4.7.2 (or the version in project.godot `config/features`) on PATH,
# with export templates installed (see docs/RELEASING.md). # with export templates installed (see docs/RELEASING.md).
# - Run from the repository root. # - Run from the repository root.
# #