- Route the Reason verb through authored reason contexts and give every shared archetype an in-character answer.
- Add Hollywood wristband and TV Studio ticket/credential door-staff lines.
- Clarify radio cancellation, Ask terminology, start hints and campaign-reset copy.
- Record the dialogue audit and length findings in docs/ui-copy.md; add regression tests.
Joke Shop
- Reservation list without ID (guest list valid, ID missing) — denied.
- Borrowed/mismatched ID (ID valid but mismatched) — denied.
- Guest who refuses the wand screen: new `refuses_screening` event flag, copied
onto NPCController, handled in _toggle_wand_screening (logs wand.refused, records
a wand_refused event, small prop hit, panel stays closed).
- Late arrival during the performance (ID + ticket, "arrive" intent).
Studio
- Filming-boundary event and a later repeat, both using the new `film_boundary`
intent which maps to `steps_end` so the influencer stands past the posted line.
- Celebrity arrival now pulls in a small crowd via a new `extra_spawns` event field
(two tourists + an influencer), spawned through the normal path.
Building
- Filming-boundary event whose hint points at the body camera and request-reason
verbs, plus an unclear-intent event that hints at asking for a reason.
Engine support
- Events may carry `hint` (string key logged on spawn), `extra_spawns`, and
`refuses_screening`; 9 new localized hint strings.
Tests/docs
- Headless suite 139 -> 149 (test_scenario_content.gd) and a new
smoke_scenario_content.gd that spawns the refusal and celebrity events through the
real signal path.
- README, TODO section moved to DONE, MEMORY. Version 0.2.13.
Verbs (PLAN levels 1-3)
- Eye contact: own Level 1 radial slice, logged as "eye contact".
- Recognition is a player decision: "Recognize" sets NPCController.player_recognized,
writes access evidence, and GameManager only then appends a RECOGNITION artifact.
It is no longer implied by NPC type.
- Body camera: real flag (off by default) driving the REC overlay; B toggles it and
a formal warning arms it automatically, writing a body_camera incident event.
- Blocking stations the guard 0.9 m from the person toward the entrance and turns
to face them, instead of only emitting the escalation level.
- Request reason: Level 3 ask answered from the NPC's seeded dialogue_lines.
- Radial grows to 12 slices (174 px outer radius, centered labels).
Incident recording fix
- IncidentRecorder.start_incident() was never called, so add_event /
add_access_evidence / add_escalation silently no-opped and the shift review
always reported zero incidents. Incidents now open on focus (guarded by
has_open_incident), verbs call _ensure_incident, and ShiftCoordinator closes
leftovers as "unresolved" before building the review.
Copy and docs
- 9 new string keys (eye contact, body camera, recognition, reason, station).
- README controls, 26-step smoke checklist, test count, status lists.
- TODO section moved to DONE; MEMORY records the verb design and the recorder bug.
Verification: headless 98/98, smoke_plan_verbs.gd + smoke_session_shell.gd +
windowed smoke_focus_radial.gd all pass. Version bumped to 0.2.3.
- Venue-correct access artifacts (AccessLoadout) and screened-aware verify
- Cone focus on NPC heads with billboarded ring + display name (ADR-0008)
- Action wheel with de-escalation-first slices (ADR-0009); Esc/RMB cancel
- Procedural NPC face/hair/neck/shoes (ADR-0010); named input actions
- Fix GameManager parse error (radial typed as ActionRadial)
- Fix first-person camera height and guard spawning inside the building
- Move building volume back so the door/awning/marquee are visible
- Pull the event scheduler once per simulated second; cap live NPCs
- Regenerate README screenshots; update TODO/DONE/MEMORY/README; 77 tests
Adds src/test/smoke_focus_radial.gd for the windowed focus/radial smoke.
- Delete Rules.Tone/TONE_NAMES, NpcProfile.tone_modifiers, tone params on
NPCController.roll_reaction/apply_player_action; dialogue_lines flattened
to Array[String]; HUD tone label, T binding, and hud.tone_prefix removed
- Docs updated everywhere (PLAN, README, DONE, MEMORY); PLAN section heading
'Tone and Design Direction' -> 'Design Direction'
- Add .gitea/workflows/build.yml: checks job (import+tests) on push/PR; full
build job (export templates, Linux/Windows/macOS exports, artifact upload,
and tag-based Gitea release publish via GITEA_TOKEN) on tags/dispatch
- Remove old .github/workflows/ci.yml to avoid double runs
- Add venue cycling (V) across all three scenarios with hud.venue_switched
- Refresh README screenshots to match the new HUD
- 53/53 tests pass, boot smoke clean
- Fix LATE shift phase (start 700s) so the violent-threat event is reachable
- Add PROTESTER archetype (rules, profile, colors, events in public venues)
- Add CALL_SOMEONE reaction (FSM -> ARGUING, influencer/trespasser/protester weights)
- Door lock: DoorState core class, L binding, red/green visual indicator,
locked doors thwart FORCE_ENTRY
- Flashlight: G binding, SpotLight3D, perception radius bonus at evening/late
- Persistence: save shift results via Save autoload, history + best score on
review screen, round-trip test
- Navigation: flat NavigationRegion3D navmesh, NavigationAgent3D path following
with direct-movement fallback; steps made visual-only so NPCs reach entrance
- Localization: strings moved to content/strings.en.json (loader keeps
lookup/fmt signatures; coverage test over all keys)
- Distribution: export_presets.cfg (Linux/Windows/macOS), tools/build_releases.sh,
docs/RELEASING.md, prominent README Downloads section
- Remove stale signal_bus.gd (invalid static-signal experiment)
- Tests: 53 passing across 9 suites