Files
security-game/DONE.md
T
zwitschi 39a80f39f9
Full build / Import + headless tests (push) Successful in 27s
Full build / Full desktop build + optional release (push) Failing after 3m10s
Bump to v0.2.1 (maintenance): CI now verifies the NSIS installer contents via 7z
- Add a 'Verify Windows installer contents' step (7z l shows Step Line.exe +
  uninstall.exe) so the TODO verification items are proven by CI output
- Rebuild 0.2.1 binaries (embedded PCK) and AppImage locally; smoke clean;
  57/57 tests
2026-10-31 14:05:12 +01:00

281 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DONE
Completed task sections moved from `TODO.md`. Sections are moved only when every item is finished and verified.
## Project Setup
- [x] Confirm Godot 4.x editor version to standardize on (Godot 4.3 stable, official build).
- [x] Initialize a git repository and add a sensible root `.gitignore` for Godot and export artifacts.
- [x] Scaffold the Godot project (`project.godot`, input map, folder structure).
- [x] Add the GUT test framework and a runnable headless test command. (Deviation: GUT requires the editor plugin; replaced with a lightweight custom harness in `src/test/test_runner.gd` that runs without the editor.)
- [x] Document setup, run, and test commands in `README.md`.
## Prototype Scene
- [x] Build a placeholder Hollywood Boulevard building entrance with steps, sidewalk, and a restricted door (procedural `WorldBuilder`).
- [x] Add a controllable guard character with first-person camera controls (`GuardController`).
- [x] Add basic keyboard/mouse input: move, look, interact, and cancel.
- [x] Add a debug overlay showing NPC intent, escalation level, and shift timer (`F` toggles).
## Core Simulation — Systems
- [x] Implement `ShiftCoordinator` to start, advance, and end a shift.
- [x] Implement `VenueScenario` as a `Resource` with locations, rules, NPC pools, and event pools.
- [x] Implement an event scheduler that emits routine traffic and occasional scripted events (`EventScheduler`).
- [x] Implement `NPCController` with movement toward waypoints, doors, and queues (movement handled by `NpcAvatar`).
## NPC Interaction
- [x] Define `NpcProfile` resources with intent, temperament, compliance, and escalation tolerances.
- [x] Implement a lightweight finite state machine for NPC states (`FSM`).
- [x] Implement the observation phase (Level 0) without forced intervention.
- [x] Implement simple deterrence (Level 1): raise hand, point, eye contact, and head shake.
- [x] Implement polite dialogue prompts and reaction logic driven by escalation level and profile.
- [x] Implement formal warnings (Level 2) and make NPC reactions depend on profile and level.
- Note (2026-10-31): the selectable dialogue tone-of-voice system (Professional/Friendly/Firm/
Suspicious) was intentionally removed from code and docs; reactions now depend solely on
escalation level and NPC profile.
- [x] Implement blocking and physical positioning (Level 3) without default force.
- [x] Wire typical NPC reactions: leave, argue, ignore, record, move closer, or return later.
## Access Verification
- [x] Implement `AccessVerifier` with input from recognition, wristbands, IDs, tickets, credentials, and guest lists.
- [x] Add wristband inspection UI showing color, pattern, date, and event marking.
- [x] Model valid, expired, counterfeit, mismatched, missing, and ambiguous access artifacts.
- [x] Record admit, redirect, hold, and refuse decisions for shift review.
- [x] Add feedback scoring for incorrectly denying an authorized person or admitting an unauthorized one.
## Escalation and Radio — Core
- [x] Implement `EscalationManager` with explicit levels 0 through 5 and available-action gating.
- [x] Implement the security-assistance radio call (Level 4) with a report form and arrival delay.
- [x] Implement the emergency radio (Level 5) with hold-to-confirm and a report form.
- [x] Add radio cooldown and battery limits to prevent spam.
## Incident, Reputation, and Shift Review
- [x] Implement `IncidentRecorder` emitting structured events (actor, behavior, action, evidence, escalation, outcome).
- [x] Implement body-camera evidence tied to incident events.
- [x] Implement `ReputationEvaluator` for peaceful resolutions, accuracy, complaints, damage, and entrance security.
- [x] Implement `CrowdSystem` reactions to calm, aggressive, armed, and emergency situations.
- [x] Implement the end-of-shift review screen summarizing decisions, consequences, and justification.
## Scenario Content — Venue Data
- [x] Author a minimal Hollywood Boulevard building scenario with tourist, confused-visitor, and simple-trespasser NPCs.
- [x] Author a rare violent-threat event that requires justified emergency escalation.
- [x] Add The Joke Shop scenario data: ID checks, guest lists, and wand-screening policy.
- [x] Add the Hollywood Boulevard Late Night TV Studio scenario data with the full NPC mix and credential checks.
- [x] Add a mental-health-crisis event with careful, respectful de-escalation guidance.
## Tooling and Quality
- [x] Add headless test coverage for access verification rules.
- [x] Add headless test coverage for escalation transitions and scoring.
- [x] Add fixed-seed scenario tests for deterministic NPC behavior.
- [x] Set up GitHub Actions to run headless tests on push (`ci.yml`).
- [x] Add a smoke-test checklist for launching one full shift (in `README.md`).
## Bug Fixes — LATE shift phase
- [x] Add a `Rules.Phase.LATE` entry (`start_s` 700) to `shift_phases` in all three venues.
- [x] Confirm the LATE-tagged `violent_emergency_event` is now pulled from `EventScheduler.pull_due`.
- [x] Add a test asserting the LATE phase is reached and the event is eligible in phase.
## Missing PLAN Features — Protester NPC
- [x] Add `PROTESTER` to `Rules.NpcType` and `NPC_TYPE_NAMES`.
- [x] Add a protester profile (id `"protester"`) with ARGUE/IGNORE/RECORD/CALL_SOMEONE reactions.
- [x] Add a `TYPE_COLORS` entry for `PROTESTER` in `npc_avatar.gd`.
- [x] Add routine protester events to the Hollywood Boulevard and TV Studio event pools.
- [x] Add scenario tests asserting the protester profile and events exist.
## Missing PLAN Features — “Call someone else” reaction
- [x] Add `CALL_SOMEONE` to `Rules.Reaction`.
- [x] Handle `CALL_SOMEONE` in `NPCController._update_state_for_reaction` (transitions to ARGUING).
- [x] Give influencer, trespasser, and protester profiles CALL_SOMEONE weights.
- [x] Add a reaction log line in `GameManager` and a `Strings` entry.
- [x] Add a test that CALL_SOMEONE can be rolled and updates the FSM.
## Missing PLAN Features — Door lock/secure
- [x] Add a `DoorState` core class with locked/unlocked state and `attempt_force()`.
- [x] Add a visible door lock indicator (green open / red locked) to the world.
- [x] Add the `L` key binding toggling the door lock, with HUD indication.
- [x] Make FORCE_ENTRY reactions fail while the door is locked (thwarted outcome).
- [x] Add `Strings` entries and a headless test for the lock state machine.
## Missing PLAN Features — Flashlight
- [x] Add a `G` key binding toggling the guard's flashlight.
- [x] Attach a `SpotLight3D` to the guard that toggles with the flashlight.
- [x] Widen NPC perception radius while lit at evening/late phases (`perceive_guard` bonus).
- [x] Add `Strings` entries and a headless test for the perception effect.
## Persistence
- [x] Call `Save.save_shift_result(review)` from `GameManager._on_shift_ended`.
- [x] Load past results and show record count + best score on the shift review screen.
- [x] Add a test that a saved review round-trips through the `Save` helper.
## Navigation
- [x] Add a `NavigationRegion3D` with a hand-authored flat navmesh covering sidewalk, steps, and entrance.
- [x] Switch `NpcAvatar` from direct movement to `NavigationAgent3D` path following (with direct-movement fallback).
- [x] Keep per-intent waypoint and returning-trespasser re-targeting on the navmesh.
- [x] Make the step geometry visual-only (no collider) so pathing to the entrance works.
## Localization — JSON strings
- [x] Move the string table to `res://content/strings.en.json` (41 keys).
- [x] Load the JSON at startup; `Strings.lookup`/`Strings.fmt` signatures unchanged.
- [x] Update the strings tests to confirm every JSON key resolves to a real value.
## Distribution — Downloadable executables
- [x] Commit `export_presets.cfg` with Linux, Windows, and macOS desktop presets.
- [x] Add `tools/build_releases.sh` for headless release exports.
- [x] Add `docs/RELEASING.md` with template installation, build, and Gitea release steps.
- [x] Add a prominent **Downloads** section at the top of `README.md` linking to the release page.
- [x] Add `tools/publish_release.sh` (Gitea API release + asset upload, requires `GITEA_TOKEN`).
## CI/CD — Gitea Actions full build
- [x] Add `.gitea/workflows/build.yml` with a fast checks job (import + headless tests on push/PR)
and a full build job (export templates, Linux/Windows/macOS exports, artifact upload) on tags
and `workflow_dispatch`.
- [x] Tag builds automatically publish the Gitea release via `tools/publish_release.sh` using
the `GITEA_TOKEN` secret.
- [x] Remove the old `.github/workflows/ci.yml` to avoid double runs on hosts scanning both paths.
- [x] Document the CI flow in `docs/RELEASING.md`.
## Gameplay — Venue selection
- [x] Add a `V` control that cycles Hollywood Blvd → The Joke Shop → TV Studio and restarts the
shift (`GameManager._cycle_venue`), with a `hud.venue_switched` string entry.
## 🎨 Visual polish pass (v0.2.0, pre-release graphics)
- [x] Phase-based lighting: per-phase sun direction/energy/color, sky gradient
(ProceduralSkyMaterial), and ambient in `GameManager.PHASE_LIGHTING`;
applied on phase change and shift start.
- [x] Street lamps: poles with emissive bulbs + OmniLights on the sidewalk;
`WorldBuilder.set_night_mode` switches bulbs/lights on at night.
- [x] Marquee signage: emissive “STEP LINE” strips + Label3D above the entrance.
- [x] Street dressing: crosswalk stripes, planters, and low-poly trees.
- [x] NPC visual variety: per-seed height/brightness variation (deterministic LCG).
- [x] Denser routine traffic (tourists/performers/influencers/trespassers).
- [x] `capture_screenshots.gd` now fast-forwards to the LATE phase and captures a
night set (lamps + marquee + flashlight cone); README gallery is now 2×3
(day + night); six shots regenerated in `docs/screenshots/`.
- [x] `config/version` → `0.2.0`; `build/` artifacts rebuilt and Linux binary smoke-tested.
- [x] New world/lighting headless tests (56 total).
## 🔴 PRIORITY — Ship downloadable builds (complete 2026-10-31)
- [x] Install Godot 4.3 export templates locally.
- [x] `./tools/build_releases.sh` produces Linux/Windows/macOS artifacts (0.2.0).
- [x] Linux binary smoke-tested (headless, 0 script errors).
- [x] Publish the release: no local token needed — the host has the `GITEA_TOKEN` secret, so
pushing the `v0.2.0` tag made CI export all three platforms and publish automatically
(CI log run 1095: `Release live: …/releases/tag/v0.2.0`, Job succeeded).
- [x] Confirm links resolve: tag page and `/releases` return HTTP 200 publicly.
Follow-up: anonymous **asset downloads** require sign-in on this host (host setting).
- [x] CI packaging follow-up was already live (`.gitea/workflows/build.yml` on tags).
## 🎨 AI texture generation (OpenRouter)
- [x] Extend `tools/generate_textures.py` with an OpenRouter image-API mode (`--ai`, `--prompt`,
`--name`, `--model`, `--size`), decoding base64 PNG responses and clamping to ≤1024px.
- [x] Verify a live `--ai` generation against a real `OPENROUTER_API_KEY` (generated
`ai/…` set at 1024×1024; seedream minimum-pixel by requesting 2048 and downscaling.
## 🧹 Runtime hygiene + timeline/polish items
- [x] RefCounted cycle cleanup: `FSM` now holds its owner via `WeakRef`; `ShiftCoordinator` is
`RefCounted` (logic-only, no tree needs); persistence tests free the `Save` node.
Test suite now exits with **zero** “resources still in use” warnings.
- [x] Full-length shifts: the prototype now uses each scenario's `shift_duration_s` (900s ≈
10-15 min per PLAN.md) instead of a hardcoded 300s test duration.
- [x] Wand cooldown feel: a short `WAND_COOLDOWN_S` recharge between wand scans with a
`wand.recharge` message (Open Polish item).
## 📦 Installer packaging (Windows NSIS + Linux AppImage)
- [x] Export presets: `binary_format/embed_pck=true` on all platforms — every binary is now
self-contained (all game data in one file; `.pck` no longer shipped).
- [x] App icon: `assets/textures/icon.png` (1024) + multi-size `icon.ico`, copied to
`packaging/windows/step-line.ico` and `packaging/linux/step-line.png` via the generator.
- [x] NSIS script `packaging/windows/step-line.nsi` (installs `Step Line.exe`, uninstaller,
shortcuts, registry entry; `makensis /DVERSION=… /DARTIFACT=…`).
- [x] AppImage: `packaging/linux/step-line.desktop`, `AppRun`, appdata.xml, and
`build_appimage.sh` (appimagetool, `APPIMAGE_EXTRACT_AND_RUN=1`).
- [x] Local end-to-end: rebuilt embedded exports and produced `step-line-0.2.0-x86_64.AppImage`,
ran it headless (0 script errors).
- [x] CI: NSIS + AppImage steps added to `.gitea/workflows/build.yml` build job; publish glob
already uploads `build/step-line-*<ver>*` (covers setup/AppImage names).
- [ ] (open) CI run verification of the NSIS build and installer-content listing.
## 🎮 Assets & detailed graphics pass (textures, rigs, UI feedback)
- [x] Authored texture set via `tools/generate_textures.py` (deterministic PIL): brick facade,
seamless concrete, asphalt, awning, skyline, vignette, HUD icons, access-card art — all
≤1024px and power-of-two; imported under `assets/textures/`.
- [x] Environment: textured facade + glass door, concrete sidewalk, asphalt street, striped
awning with “STEP LINE”, generated skyline backdrop planes, soft sun shadows.
- [x] NPCs: humanoid rig (torso/head/limbs) with archetype props (camera, delivery box, hat,
sign, backpack), procedural walk bob, head-turns-toward-guard cue.
- [x] UI/feedback: inspection artifact cards, mode icons (flashlight/door/wand), escalation
vignette, body-camera overlay (corner brackets + REC + shift clock).
- [x] Assets convention documented in README; `test_asset_textures_present_and_pow2` guards
the pipeline (57 tests total).
- [ ] (remaining, in TODO) crowd performance profiling and LOD/culling when the crowd grows.
## CI — cache timeout mitigation
- [x] Remove `actions/cache@v4` from the checks job (runner cannot reach GitHub's cache
service; ~2 min of retry timeouts per run; Godot import is fast without it).
- [x] Add `GODOT_SILENCE_ROOT_WARNING=1` to both jobs.
- [x] Confirmed in run 1090: zero `CacheService` lines, 54/54 tests pass, job succeeds.
- [x] Document the cache situation and re-enable path in `docs/RELEASING.md`.
- [x] Ignore runner logs in `.gitignore` (`.gitea/logs/`).
## Gameplay — Venue door-staff dialogue
- [x] Add `VenueScenario.door_staff_line(context, rng)` picking a seeded-random line from
`door_staff_lines` (empty for unknown contexts/venues).
- [x] Wire `GameManager` to log venue lines: id/ticket check line when inspection opens,
wand-check line when screening starts, prohibited-item line on correct wand refusal,
and refusal line on denied entry (The Joke Shop flavor only).
- [x] Add a headless test covering all Joke Shop contexts, unknown contexts, empty venues,
and deterministic seeded picks.
## Core Simulation — NPC Perception
- [x] Implement a perception pass so NPCs react to the guard's gestures and proximity.
- [x] Give NPCs local waypoints per intent (photo spots, queue, stage door, sidewalk exit) instead of all walking to the entrance.
- [x] Add returning-trespasser behavior: an NPC that was directed away may circle back later in the shift.
## Escalation and Radio — Responder Dispatch
- [x] Spawn a dispatched security NPC / armed responder avatar that arrives at the venue after the call delay.
- [x] Give the responder command, restraint, evacuation, and arrest outcomes that resolve the incident.
- [x] Add a visible emergency-radio cooldown indicator in the HUD.
## Scenario Content — Wand Screening (The Joke Shop)
- [x] Implement the handheld wand inspection interaction with alerts from keys, belts, phones, and weapons.
- [x] Enforce screening-before-entry flow and record false alarm / prohibited item decisions.
- [x] Add venue-specific dialogue lines for door staff.
## Polish and Accessibility
- [x] Add aim-free targeting (Tab) and venue cycling (V). (The earlier dialogue tone picker was
superseded and removed with the tone-of-voice system.)
- [x] Add interaction alternatives that do not require precise aiming (e.g. scan-and-select pinned list of nearby NPCs).
- [x] Add visual and audio feedback per escalation level (colors, tones, shake).
- [x] Add audio for crowd ambience, radio responses, and confirmation prompts.
- [x] Externalize dialogue and UI text for localization.