- Drop actions/cache@v4 from the checks job: the Gitea runner cannot reach GitHub's cache service (/twirp/...CacheService timeouts, ~2min retries); Godot import is fast enough without it. Add GODOT_SILENCE_ROOT_WARNING=1. - Document the cache situation and re-enable path in docs/RELEASING.md - VenueScenario.door_staff_line(context, rng): seeded-random venue lines - GameManager logs id/ticket/wand-check, refusal, and prohibited-item lines from the venue scenario (Joke Shop flavor) during inspection/screening - Test coverage: all Joke Shop contexts, unknown contexts, empty venues, deterministic seeded picks (54 tests pass)
8.2 KiB
8.2 KiB
MEMORY
Session memory for durable decisions, state, and gotchas. Keep concise, remove obsolete entries.
Decisions
- Engine: Godot 4.3 stable (official editor build,
~/.local/bin/godot). The system's preinstalledgodot-runner(4.7.2, Fedora) 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 (notclass_nameglobals) so scripts compile in headless--scriptruns 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. - Eventing: no autoload signal bus.
ShiftCoordinatorowns anEventBusinstance (src/core/event_bus.gd) passed to subsystems; subsystems emit only when a bus is assigned. Autoloads at parse time are unreliable under--script. - Static signals are not available in Godot 4.3 GDScript ("Expected func or var after static") — do not use them.
- GDScript lambdas capture local variables by value; mutating a captured local inside a lambda does not affect the outer variable. Use member functions for accumulators in tests.
- Prototype shift duration defaults to 300 s for testing; production targets 10-15 minutes per PLAN.md.
- RNG: NPC reactions and event scheduling are seedable for deterministic tests.
Current State
- Core simulation, three scenarios, headless tests (52 passing), and a first-person prototype with interaction HUD, access inspection, radio (assist + emergency hold-to-confirm), debug overlay, and shift review are implemented and green.
- NPC avatars now walk to per-intent waypoints (
VenueScenario.waypoint_for_intent): enter/trespass/deliver/arrive → entrance, photo/film/perform/wander/roam → sidewalk, sit → steps_end.NpcAvatar.setuptakes an explicitdoor_position. - Returning-trespasser behavior:
NpcProfile.return_probability(trespasser 0.6, mental-crisis 0.4, others 0).NPCController._maybe_schedule_return()moves a directed-away NPC toLOITERING_DISTANT;tick_return(delta)fires after 20-60s and transitions back toAPPROACH.NpcAvatar._advance_fsmre-targets the door on return. - Perception pass:
NPCController.perceive_guard(distance)returns{noticed, band, reaction}with bandsunaware(>6m),aware(2-6m),near(<2m). Near + temperament ≥0.6 → ARGUE, else COMPLY.GameManager._perception_pass()feeds real guard distance each physics tick and logs first-time notice. - Responder dispatch:
RadioSystemtrackspending_callsand decrementsarrival_delay_sintick; emitsresponder_arrivedwhen a call's delay elapses.RadioSystem.responder_outcome(call)maps danger/weapons → command/restraint/evacuation/arrest.GameManager._on_responder_arrivedspawns aRESPONDERavatar at the entrance and logs the outcome. HUD shows an emergency-radio cooldown label via_update_radio_cooldown. - Wand screening (Joke Shop):
WandScreener(newsrc/core/wand_screener.gd) classifies carried items as prohibited (weapon/knife/gun/blade) vs false-alarm (keys/belt/phone/coins/watch/buckle) vs clear.NpcProfile.carried_itemsholds guest items.GameManagerbindsWto_toggle_wand_screeningandA/Dtodecide_wand;decide_accessblocks admission at wand venues untilcontroller.screenedis true.VenueScenario.door_staff_linesholds venue-specific door-staff dialogue (Joke Shop has id/ticket/wand/refusal/prohibited lines). - Design change (2026-10-31): the selectable dialogue tone-of-voice system was removed.
Rules.Tone/TONE_NAMES,NpcProfile.tone_modifiers, and the tone param onNPCController.roll_reaction/apply_player_actionno longer exist;NpcProfile.dialogue_linesis a flatArray[String];GameManageruses_apply_interaction(level, action_name); theTkey is gone. HUDtone_labelremoved andhud.tone_prefixstring deleted from JSON. - Polish/accessibility: venue cycling (
VcyclesVENUE_ORDERand restarts the shift), aim-free targeting (Tabcycles nearby NPCs withinNEARBY_RADIUS), color-coded escalation indicator (Hud.set_escalation), procedural audio (AudioFeedbacknode generates sine tones for confirm/radio/escalation/deny), and a centralizedStringstable (src/core/strings.gd,lookup/fmt) backed bycontent/strings.en.json. NOTE:Strings.getwas renamed toStrings.lookupbecausegetcollides withObject.get. - Newly added: LATE shift phase (start 700s) with a reachability test; PROTESTER archetype + events + colors; CALL_SOMEONE reaction;
DoorStatecore class +Lbinding + visual indicator; flashlight (G, SpotLight3D, perception bonus at evening/late); persistence wired (Save.save_shift_resulton shift end, history + best score on the review screen);NavigationRegion3Dflat navmesh +NavigationAgent3DNPC paths (steps now visual-only); strings moved tores://content/strings.en.json(41 keys, loader keepslookup/fmt);export_presets.cfg(Linux/Windows/macOS) +tools/build_releases.sh+docs/RELEASING.md; README Downloads section. - Run tests:
godot --headless --path . --script res://src/test/test_runner.gd - Boot check:
godot --headless --path . --quit-after 120 - Screenshot tools:
godot --path . -s res://src/test/take_screenshot.gd(single shot touser://screenshot.png);godot --path . -s res://src/test/capture_screenshots.gd(staged README gallery shots touser://screenshots/, copied todocs/screenshots/). - Release build verified locally: export templates for 4.3 installed at
~/.local/share/godot/export_templates/4.3.stable/;./tools/build_releases.shproduced Linux/Windows/macOS artifacts for 0.1.0 inbuild/and the Linux binary passed a headless smoke test. Publishing to Gitea still needs a token (seetools/publish_release.sh,docs/RELEASING.md). - CI: the repo now carries a Gitea Actions workflow at
.gitea/workflows/build.yml(checks on push/PR; full export + artifact upload + optional release publish on tags andworkflow_dispatch). A repo secretGITEA_TOKENis required for tag releases. The old.github/workflows/ci.ymlwas removed so hosts scanning both paths do not double-run. - Venue cycling:
Vswitches Hollywood Blvd → The Joke Shop → TV Studio and restarts the shift. - Venue door-staff dialogue:
VenueScenario.door_staff_line(context, rng)and GameManager logging (id/ticket/wand-check, refusal, prohibited-item) — Joke Shop flavor. - CI cache:
.gitea/workflows/build.ymlno longer usesactions/cache(the runner can't reach the GitHub cache service; import is fast).GODOT_SILENCE_ROOT_WARNING=1set on jobs. Logs live in.gitea/logs/after each run.
Known Issues / Notes
- RefCounted reference cycle:
NPCControllerholds anFSMthat holds a back-reference to its owner, so test suites report "resources still in use at exit". Benign (process exit), but worth breaking later (e.g.WeakRefor explicitdispose()). - Headless (dummy renderer) logs "Parameter m is null" from
mesh_get_surface_count; it does not occur with a real GL driver and does not affect logic. - Steps are visual-only (no collider) so NPCs can path to the entrance; the guard spawns on the landing so it never needs to climb.
- Persistence tests write into the real
user://shift_results.json(harmless local pollution of the demo history). - macOS export required
rendering/textures/vram_compression/import_etc2_astc=trueinproject.godot(universal build demands ETC2 ASTC enabled). - Joke Shop
door_staff_linesauthored but not yet surfaced in the prototype UI (tracked in TODO).
Open Questions
- Whether the responder avatar should be playable/controllable or purely scripted.
- Localization target languages beyond English.
- macOS notarization approach for broad distribution.
Plan vs TODO Gaps (evaluated 2026-10-31, all resolved)
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.