- FSM holds owner via WeakRef; ShiftCoordinator is RefCounted (logic-only); persistence tests free the Save node -> test suite exits with zero 'resources still in use' warnings (was ~13) and 57/57 pass - GameManager uses each scenario's shift_duration_s (900s ~ 10-15 min) for real shifts instead of the 300s test duration - Wand screening gets a 0.8s recharge cooldown with a wand.recharge message - TODO/DONE/MEMORY/README synced
274 lines
16 KiB
Markdown
274 lines
16 KiB
Markdown
# 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).
|
||
|
||
## 🧹 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.
|