Reorganize docs into category folders and drop the retired head-review page
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped

Group the top-level docs into docs/project, docs/design, docs/assets and
docs/process, each with its own README index. Delete the superseded
docs/screens/head-review page and sheets. Rewrite every markdown link,
absolute docs path and tool/test reference to the new locations, fix the
pre-existing broken anchors and remove the dead Joke Shop photo-board link.
check_docs OK, Python tooling 167/167.
This commit is contained in:
zwitschi committed 2026-11-06 20:13:03 +01:00
1 parent 045ed2a58f
commit 2ba40f3578
57 files changed
+406 -414

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
# Design Documentation
Gameplay, venues, presentation and player-facing constraints.
- [`gameplay.md`](gameplay.md) — the playable loop, escalation mechanics, venues and tutorial.
- [`venues.md`](venues.md) — real-site evidence, game mapping and venue simplifications.
- [`ui-copy.md`](ui-copy.md) — screen, copy and button inventory plus the screen-design judge
record.
- [`accessibility.md`](accessibility.md) — accessibility statement and known gaps.
- [`known-limitations.md`](known-limitations.md) — release blockers and accepted limitations.
Up: [`../README.md`](../README.md) · Product plan: [`../../PLAN.md`](../../PLAN.md) · Tasks:
[`../../TODO.md`](../../TODO.md).
+32
View File
@@ -0,0 +1,32 @@
# Accessibility Statement
Gig Line is a keyboard/mouse-first first-person game with gamepad support. The
current build includes the following accessibility features:
- Remappable keyboard and gamepad bindings, persisted in `settings.json`.
- Keyboard focus rings and explicit default focus in every modal, with A/B
accept/cancel on a gamepad and wrapped Tab/arrow navigation.
- Adjustable HUD font scale up to 1.75× with clipped/ellipsized long labels.
- Reduced-motion mode that disables head bob and motion-sensitive presentation.
- Captions in the HUD log for radio, interaction and event messages.
- Master, SFX and ambience volume controls.
- Shape plus number escalation meter, so escalation is readable without colour.
- Hold-to-confirm emergency action and guarded destructive actions.
- Searchable Help generated from the live input bindings.
- Mouse-transparent HUD, right-click/Esc modal handling, and a predictable
top-panel close path.
Known gaps:
- There is no screen-reader integration or text-to-speech narration.
- The game is English-only; no pseudo-locale or full localization review has
been completed.
- The visual style is stylized and some small environmental detail may be hard
to read at low resolution; a full low-vision/high-contrast audit is pending.
- Audio captions cover gameplay messages, not every ambient sound.
- A formal WCAG conformance claim has **not** been made. External accessibility
review is still a 0.10.0 release-review item.
Test evidence and the manual checklist live in
[`release-qa.md`](../process/release-qa.md#manual-smoke-checklist); settings and save behaviour are
documented in [`getting-started.md`](../process/getting-started.md).
+118
View File
@@ -0,0 +1,118 @@
# Gameplay
The complete design rationale also lives in [`PLAN.md`](../../PLAN.md); this page keeps the playable mechanics close to the README.
## Game Overview
A typical shift lasts 10–15 minutes. The first-person camera stays at the gameplay height of 1.7 m; the concept frames use a lower ~1.55 m reference camera, but gameplay readability and body-camera framing take priority. The player:
1. Watches the entrance, steps, queue, and surrounding sidewalk.
2. Determines why each person is approaching.
3. Uses simple gestures or polite directions first.
4. Verifies authorized access using recognition, wristbands, credentials, tickets, or guest lists.
5. Escalates only when a person refuses directions, attempts unauthorized entry, or presents a genuine threat.
6. Records the incident through body-camera and radio systems.
7. Finishes the shift with a performance review based on safety, judgment, and professionalism.
The game rewards calm resolutions rather than aggressive behavior. Emergency assistance and armed responders are rare last-resort systems with meaningful consequences.
The first shift starts with an in-game tutorial covering movement/look, focus cycling, the action wheel, access inspection, polite direction, formal warning/body camera, radio and shift review. See the tutorial section below. After that a short campaign runs Hollywood → Joke Shop → TV Studio; progress, difficulty and a pause-safe checkpoint are persisted locally. Help (from the venue menu) explains the controls and the current venue policy.
## Venues
### El Capitan Entertainment Centre (6840 Hollywood Blvd)
The map is a stylized reconstruction of the real building and block; the
reference notes and geometry mapping are in
[`venues.md`](venues.md#hollywood-boulevard). The venue menu
offers the same map as **Hollywood Boulevard — Day** and **Hollywood Boulevard
— Night**; the night variant starts directly in the late phase instead of
waiting for the shift clock.
The original scenario — the starting point of the campaign — places the guard at the top of the eight stone steps outside the historic Masonic Temple / El Capitan Entertainment Centre on Hollywood Boulevard, the building that houses the *Jimmy Kimmel Live!* stage and studio. Tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats may approach the entrance.
Authorized people must either be recognized by the guard or present a valid wristband. Wristbands can have different colors, patterns, dates, or event markings. They may be valid, expired, counterfeit, or missing.
### The Joke Shop
The Joke Shop is a Sunset Strip comedy club inspired by the real Comedy Store at 8433 Sunset Blvd: a black hall under a deep signature-covered canopy, a circular blade sign, red velvet curtains, a west-end entrance, neighbouring low-rise frontage and a dry hillside of houses behind. The real-site mapping is in [`venues.md`](venues.md#the-joke-shop). The door person checks IDs, tickets, reservations, and guest-list status, then uses a handheld security wand according to venue policy. The player must interpret wand alerts rather than treating every alert as proof of a weapon; keys, belts, phones, and other harmless objects can trigger false alarms.
### Hollywood Boulevard Late Night TV Studio
This scenario combines the previously defined NPC types with a busy television-studio entrance: the same El Capitan Entertainment Centre block as the Hollywood day shift, restaged as a late-night studio arrival — the stone facade and steps, a bulb-lit canopy, a glossy black car at the curb, and stanchions/barriers holding the arrival line. The player manages audience members, production staff, performers, guests, deliveries, celebrity arrivals, tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats.
The studio uses wristbands, credentials, tickets, guest-list confirmation, and personal recognition to authorize entry. Crowd control, filming boundaries, following authorized guests through the door, and counterfeit credentials are key events.
## Escalation Model
The common escalation model has six levels:
0. **Observation** — Decide whether intervention is necessary.
1. **Simple deterrence and polite direction** — Raise an open hand, make eye contact, point toward the sidewalk or check-in area, shake the head, or give a short instruction.
2. **Formal warning** — Clearly explain the rule and request compliance.
3. **Blocking and physical positioning** — Secure the entrance, maintain distance, preserve an escape route, and deny access without starting a fight.
4. **Radio for security assistance** — Request a supervisor, second guard, building management, or other appropriate support.
5. **Emergency response** — Hold the emergency-radio button and confirm only when there is an immediate threat, such as a weapon, assault, forced entry, or serious threat to occupants.
An off-duty law-enforcement officer or armed emergency responder may arrive during a valid emergency. This character is not intended to be a routine stronger attack. Their role is crisis control, evacuation, restraint, arrest, or other appropriate intervention, with force governed by the situation and meaningful consequences for unjustified calls.
## Core Systems
- **NPC behavior:** NPCs have different motivations, temperaments, compliance levels, and reactions to the player’s approach.
- **Access verification:** Recognition, wristbands, IDs, tickets, credentials, and guest lists determine who may enter.
- **Nonverbal deterrence:** Small actions such as raising a hand can resolve low-risk situations without dialogue or force.
- **Dialogue:** Polite directions and warnings affect outcomes; simple gestures can resolve low-risk situations without dialogue.
- **Escalation:** The player chooses the lowest effective response.
- **Radio assistance:** Calls require useful information and may take time to arrive.
- **Evidence:** Body-camera records support shift review and accountability.
- **Crowd reaction:** Aggressive behavior, visible weapons, and emergency response can create panic or attract a crowd.
- **Reputation:** Peaceful resolutions, accurate reports, low property damage, and justified calls improve performance; unnecessary confrontations and false reports reduce it.
- **Shift review:** The player receives feedback on access decisions, escalation choices, public complaints, injuries, and security outcomes.
## First-shift tutorial
Status: implemented for v0.8.0. The tutorial teaches the real controls and the real
inspection/wheel/radio panels; it is not a fake UI or a separate combat mode.
Scripted test/capture runs bypass it unless `--tutorial` is passed; a windowed
smoke covers completion, replay and skip.
### Rules
- One short, safe, compliant visitor. No emergency, threat, crowd panic or random
event can interrupt the tutorial.
- Prompts advance on the performed action, not on a timer. The player can keep
moving/looking while a prompt is visible.
- The tutorial is skippable at any point (F1). Completion and skip are both
persisted separately; a skipped tutorial can be replayed from Settings.
- The tutorial state machine is independent of the shift FSM. It observes the
same actions as normal play and must be deterministic for tests.
### Beat sheet
| # | Beat | Prompt | Advances when | Notes |
| --- | --- | --- | --- | --- |
| 1 | Arrive | "Walk forward and look around. The entrance is behind you." | The guard has moved at least 1 m and looked away/returned | Start at the normal guard post, facing the street. |
| 2 | Focus | "Look at the visitor. Press Tab or the mouse wheel to cycle targets." | A target is acquired and explicitly cycled | The visitor waits at the foot of the steps; no other guest is required. |
| 3 | Wheel | "Open the action wheel with Space or left click." | The radial wheel opens on the visitor | The wheel is the real de-escalation-first wheel. |
| 4 | Inspect | "Choose Inspect and read the access evidence." | The inspection panel is opened and the policy result is visible | Use a valid wristband so the tutorial can teach both evidence and a safe admit/deny decision. |
| 5 | Direction | "Close the panel and give a polite direction." | A Level 1 polite-direction action is applied | The visitor complies; there is no escalation requirement. |
| 6 | Warning | "Give a formal warning if the visitor persists. It arms the body camera." | A Level 2 warning is applied or the body camera is switched on | Show the REC overlay and the escalation cue. |
| 7 | Radio | "Open the assistance radio and submit a short report." | The assistance report is submitted successfully | A non-emergency assistance call; no responder is required to resolve the tutorial. |
| 8 | Review | "Finish the shift and review what happened." | The shift review opens | The tutorial ends; the real review remains available for inspection. |
### Visitor script
- Display name: `Visitor`.
- Intent: `enter` (approaches the door, then waits for interaction).
- Access: valid wristband evidence; the policy result should be unambiguous.
- Behavior: compliant at every escalation level; never becomes a threat, never
joins a crowd and never triggers an emergency.
- Failure handling: if the player denies admission incorrectly, the tutorial
explains the evidence but does not fail the run; the visitor remains safe and
the review records the decision.
### Persistence and replay
Settings gain `tutorial_completed` and `tutorial_skipped`. A first launch starts
the tutorial after venue selection. Skipping sets `tutorial_skipped`; Settings/
Help offers "Replay tutorial", which clears both flags for the next shift.
+48
View File
@@ -0,0 +1,48 @@
# Known Limitations
This page records the limitations that remain at the 0.10.0 release-candidate
stage. Items marked **blocker** must be cleared or explicitly accepted before a
public release.
## Release blockers
- **External playtest:** at least five first-time-player sessions and the
resulting onboarding/accessibility triage have not been completed. The
tutorial/campaign evidence is currently automated smoke coverage, not player
observation.
- **AI asset provenance:** the image-generation provider terms and commercial
redistribution rights for the committed AI-assisted textures/UI art still need
legal review. See [`../CREDITS.md`](../../CREDITS.md).
- **Storefront/legal approval:** age/content rating, storefront policy, trademark
language and the mental-health-crisis/body-camera representation have not been
externally approved.
- **macOS signing/notarization:** the 0.10.0 release candidate ships unsigned
with right-click/`xattr` quarantine instructions. Signing and notarization are
required before a broad public/storefront release and remain blocked until an
Apple Developer account and signing job exist.
- **Hardware matrix:** Web, Windows and Desktop HQ have been built and checked
structurally; a complete target-hardware performance/launch matrix is still
pending.
## Content and presentation
- The venues are stylized reconstructions, not survey-accurate models. The Joke
Shop is a fictional stand-in for the real Sunset Strip block.
- Character faces, hands and fabric use a deliberately low-poly style; the
>26 m tier remains a two-quad impostor and there is no separate finger-curl
rig. The accepted limits are recorded in
[`npc-model-sourcing.md`](../assets/npc-model-sourcing.md).
- There is no live 3D body-camera replay; the timeline is text-based.
- There is no recorded voice/music track. Ambience and cues are procedural.
- The game is English-only and does not yet have a translator workflow or
pseudo-locale layout sign-off.
## Persistence and platform
- Save migration is covered by synthetic 0.8/0.9 fixtures and failure-mode tests,
not by a real player profile collected from every earlier release.
- Desktop HQ requires a Vulkan-capable GPU/driver; the default Compatibility and
Web builds remain the broad target.
- The manual smoke checklist is completed by developers; external device
coverage (Windows installer, macOS launch, gamepad and Web hosts) is not yet a
complete evidence set.
+244
View File
@@ -0,0 +1,244 @@
# UI copy and button inventory
Status: complete (0.9.3). Retained as the screen/button inventory, copy audit and screen-design judge record.
## Screen inventory
| Screen / panel | Owner | Primary actions | Notes |
| --- | --- | --- | --- |
| Start / venue menu | `start_menu.gd` | Continue shift, choose venue, Help, Settings, Quit | Campaign status and free-play venues share this screen. |
| Tutorial card | `tutorial_overlay.gd` | F1 skip | Non-blocking; no mouse capture. |
| HUD | `hud.gd` | Observe, target, inspect, wheel, radio, flashlight, body camera, door, pause | No interactive controls; must stay mouse-transparent. |
| Action wheel | `action_radial.gd` | Choose de-escalation/access/radio action | Confirm with Space/click; cancel with Esc/RMB. |
| Access inspection | `hud.gd` | A = admit, D = refuse | Real access evidence cards. |
| Wand screening | `hud.gd` | A = admit, D = refuse | Shows alert and carried items. |
| Radio / emergency | `radio_panel.gd` | Send request / hold Send emergency, Cancel | Normal click vs emergency hold. |
| Pause | `pause_overlay.gd` | Resume, restart, Settings, quit to menu | Esc resumes. |
| Settings | `settings_panel.gd` | Apply, Cancel, Replay tutorial, Reset campaign, rebind controls | Both reset and tutorial replay ask for confirmation. |
| Help | `help_overlay.gd` | Filter controls, Close | Policy card and current bindings. |
| Shift review | `shift_review.gd` | Continue campaign, timeline, return to menu, quit | Campaign next step is shown here. |
| Timeline | `event_timeline.gd` | Previous, Next, Close | Review evidence stepper. |
## Canonical terms
- **Admit / refuse** — access decisions. Do not alternate with “allow / deny” or “grant / reject” in player-facing controls.
- **Warning** — Level 2.
- **Blocking** — Level 3 positioning; do not call it “force”.
- **Assistance** — Level 4 radio call; **emergency** is Level 5.
- **Body camera** — always two words.
- **Shift review** — the end-of-shift screen; “review” alone is acceptable in prose.
- **Continue campaign** — advance to the next venue.
- **Return to menu** — leave the review to the venue menu (it does not start a new shift by itself).
- **Send request** — non-emergency assistance; **Send emergency** — emergency call.
- **Hollywood Boulevard — Day / Night** — the two scenery variants in the venue menu. Use an em dash and title case for the variant; do not call them “maps” in player-facing copy.
## Button labels and states
| Surface | Label | Behavior | State audit |
| --- | --- | --- | --- |
| Start menu | Continue shift — <venue> | Resume/advance campaign | Hidden when complete; venue-specific |
| Start menu | Venue rows | Start free-play/campaign venue | Hover/focus/pressed styled |
| Start menu | Help | Open Help overlay | Standard button |
| Start menu | Settings | Open Settings | Standard button |
| Start menu | Quit game | Exit application | Destructive; label clarifies scope |
| Tutorial | F1 skip tutorial | Skip lesson | Keyboard only, non-blocking |
| Action wheel | Stop/Look/Point/No/Ask/Inspect/Wand/Warn/Block/Reason/Recognize/Radio | Choose verb | Hover/selection highlight |
| Inspection | A = admit · D = refuse entry | Access decision | Keyboard hints, policy text |
| Wand | A = admit · D = refuse entry | Screening decision | Keyboard hints, item/alert text |
| Radio | Send request | Submit assistance | Normal click |
| Radio | Send emergency | Submit emergency | Hold-to-confirm; Cancel aborts |
| Radio | Cancel | Close form | Standard button |
| Pause | Resume | Resume shift | Default focus |
| Pause | Restart shift | Restart current shift | Standard button |
| Pause | Settings | Open Settings | Standard button |
| Pause | Quit to menu | Return to venue menu | Standard button |
| Settings | Apply settings | Persist settings | Standard button |
| Settings | Cancel | Discard edits | Standard button |
| Settings | Replay tutorial | Confirm, then clear tutorial flags and restart Hollywood | Confirmation dialog |
| Settings | Reset campaign | Confirm, then reset campaign progress | Confirmation dialog |
| Help | Close | Close overlay | Standard button |
| Review | Continue campaign | Start next venue | Hidden when campaign complete |
| Review | Body camera timeline | Open event timeline | Standard button |
| Review | Return to menu | Return to venue menu | Standard button |
| Review | Quit game | Exit application | Standard button |
| Timeline | Previous / Next / Close | Step/close evidence | Standard buttons |
## Button/label issues found
- HUD inspection and wand used “allow/deny” versus “admit/refuse”; both now use **A = admit · D = refuse entry**.
- Shift review’s old “Run another shift” actually returned to the menu; renamed **Return to menu**.
- Radio emergency action used all-caps while assistance used sentence case; both are now sentence case, with the warning in the panel title/hold hint.
- Normal radio send was previously wired only to the emergency hold handlers; fixed in 0.8.1 and covered by `test_radio_panel.gd`.
- “Quit” was ambiguous between menu and application exit; both application-exit buttons now read **Quit game**.
- Settings “Apply” was made verb+object as **Apply settings**.
## Dialogue audit
The NPC reason verb now uses the authored `reason` context instead of always
falling back to the general dialogue lines. Every shared archetype has at least
one role-specific reason answer, so asking a staff member, guest, delivery
worker or performer no longer produces an unexplained silence. Deliberately
silent profiles can still return an empty context line.
| Surface | Finding | Result |
| --- | --- | --- |
| Shared NPC reasons | `request_reason()` ignored `context_lines["reason"]`; staff, guests, delivery, performers, intoxicated people, crisis and threat profiles had no answer. | Fixed; all 12 shared archetypes now answer in character. |
| Door staff | Only The Joke Shop authored door lines. | Hollywood has wristband lines; the Studio has ticket/credential/guest-list lines; the inspection log selects the venue context. |
| Radio | “Call cancelled” could read as if a call had been sent; the description placeholder was ungrammatical. | “Call not sent — hold the button to confirm.” and “Describe the person and their behavior.” |
| Tutorial / Help | The wheel verb is **Ask**, but help and the HUD key strip called it “polite direction”. | Both now say **Ask**; the tutorial tells the player to choose Ask after closing the panel. |
| Review / campaign | Continue/return/quit labels and campaign-next copy checked. | No ambiguity found; no change. |
| Repetition | Shared tourist/confused/delivery lines recur across venues by design; role-specific reason lines prevent every archetype sounding alike. | Accepted for the shared-archetype model. |
| Localization length | Longest authored NPC/door line is 56 characters; longest UI string is `hud.controls` at 172 characters. | Dialogue fits the HUD log; long-string/font-scale layout is covered below. |
## Button state audit
All `Button` controls now use `src/game/ui/ui_styles.gd`, which defines explicit
**normal**, **hover**, **pressed**, **focus** and **disabled** styles plus the
matching font colours. This removes the engine-theme fallback that previously
appeared when a custom dark button was disabled or focused by keyboard.
| Surface | States / behavior checked | Result |
| --- | --- | --- |
| Start menu | Venue rows, Continue, Help, Settings, Quit; focus clamped to the list; Continue hidden when the campaign is complete. | All buttons styled; hidden state is intentional, not a disabled state. |
| Tutorial | F1 skip is a keyboard shortcut, not a button; its hint is non-interactive. | Keyboard-only by design; no hover/focus state to style. |
| Pause | Resume, Restart, Settings, Quit to menu; Resume receives focus on open. | All four states styled; focus is distinct from hover. |
| Settings | Replay tutorial, Reset campaign, key-binding rows, Apply settings, Cancel; rebinding shows “Press…” while listening. | All action buttons styled; reset-confirmation dialog OK/Cancel styled; fields keep the engine control theme. |
| Help | Close; Esc still closes. | Styled; no disabled state is used. |
| Shift review | Continue campaign, Body camera timeline, Return to menu, Quit game; Continue hidden when the campaign is complete. | All styled; hidden state is intentional. |
| Timeline | Previous/Next/Close; Previous is disabled at the first event, Next at the last, and both when empty. | Disabled state verified in `test_event_timeline.gd`; Close stays enabled. |
| Radio | Send request, Send emergency, Cancel. Emergency hold uses press/release, so the action button stays enabled while holding. | All styled; disabling it during the hold would break confirmation. |
| Toggles | CheckButton/OptionButton controls keep the engine theme. | Intentional: the shared style targets action buttons, not checkbox/radio affordances. |
## Keyboard and gamepad focus
`UiFocus` builds an explicit focus ring for each modal, skips hidden and
disabled controls, and makes Up/Down, Tab/Shift+Tab and the D-pad/stick wrap.
`GuardController._ensure_gamepad_bindings()` adds A to `ui_accept` and B to
`ui_cancel`; the built-in directional UI actions already carry D-pad/stick
events.
| Surface | Default focus | Cancellation / trap check |
| --- | --- | --- |
| Start menu | First visible target: Continue when present, otherwise the first venue. | A/Enter/Space activates the focused row; B/Esc quits; Continue, venue rows and footer actions share one wrapping ring. |
| Pause | Resume. | B/Esc resumes; the four actions wrap. |
| Settings | First slider. | B/Esc cancels; focus ring covers sliders, toggles, difficulty, rebinds, Apply and Cancel; sliders keep Left/Right for value adjustment. |
| Help | Search field. | B/Esc closes; Search and Close share a ring. |
| Shift review | Continue when available, otherwise the timeline. | B/Esc returns to the menu; all four actions are in the ring and hidden Continue is skipped. |
| Timeline | First enabled action: Next when Previous is disabled, Close when empty. | B/Esc closes; Previous/Next leave the ring when disabled so focus cannot land on a dead button. |
| Radio | Send action. | B/Esc cancels; form fields, action and Cancel are linked; A confirms the focused action. |
| Tutorial | None; F1 is the documented skip shortcut. | Keyboard-only by design, no focus trap because the card is mouse-transparent and non-modal. |
## Modal close and pointer recapture
`GameManager._close_top_modal()` is now the single close path for the top
interactive layer. It handles the radial, inspection, wand, radio, timeline,
Help, Settings, Pause and review before Esc/right-click falls back to target
clearing or pause. `_refresh_freeze()` recaptures the mouse when the shift
resumes; `_show_start_menu()` keeps the pointer visible at the menu.
| Surface | Close routes | Result |
| --- | --- | --- |
| Pause | Resume, Esc, right-click | Closes via one path; guard unfreezes and mouse recaptures. |
| Settings | Apply settings, Cancel, Esc, right-click | From the venue menu, both apply and cancel restore the menu. From a shift, cancel returns to the game with the guard unfrozen; apply returns to pause. |
| Help | Close, Esc, right-click | Closes only Help; it no longer opens Pause behind the overlay. Returns to whatever was underneath. |
| Shift review | Return to menu, Esc, right-click | Returns to the venue menu with the pointer visible. |
| Timeline | Close, Esc, right-click | Returns to the review and keeps the pointer visible. |
| Radio | Cancel, Esc, right-click | Closes the form, clears the action hint and recaptures the mouse. |
| Inspection / wand | Esc, right-click | Closes the panel, unfreezes the guard and recaptures the mouse. |
| Action wheel | Esc, right-click | Cancels without a log entry and recaptures the mouse. |
| Start menu | Esc quits the application | Root menu; right-click is intentionally inert. |
| Tutorial | F1 skip | Non-modal card; never blocks the pointer or movement. |
The session smoke now covers menu → Settings → Cancel → menu, Help closing on
right-click, and Settings cancel from pause leaving the guard unfrozen.
## Destructive actions
Campaign reset and tutorial replay both open a `ConfirmationDialog`; pressing
the button again while it is open focuses the existing dialog instead of
stacking a second one. The confirmation is dismissed and the signal is emitted
at most once on OK; Cancel closes without emitting. The emergency radio remains
a press-and-hold action: a normal click does nothing for an emergency, a short
hold cancels, a full 1.6 s hold submits once, and the release after a completed
hold cannot submit again.
Regression coverage:
- `test_session_shell.gd` checks reset reuse/one-shot and replay confirmation/cancel.
- `test_radio_panel.gd` checks normal click, short hold, full hold and post-submit release.
## Font-scale and long-string layout
The HUD scale is tested at its **0.75×** and **1.75×** bounds. HUD top/time labels
clip instead of crossing into each other, and the target chip now measures the
scaled target text: normal long names widen the chip, while an extreme synthetic
name is capped at 420 px and ellipsized. Action-button labels use `clip_text` and
ellipsis in `UiStyles`, so a 1.5–2× pseudo-string cannot push a panel beyond the
viewport. The menu shell intentionally keeps its own fixed typography; the HUD
scale setting only changes HUD text.
Regression coverage lives in `test_accessibility.gd` (target-chip width/cap) and
`test_ui_buttons.gd` (long action-label minimum width). The pseudo-locale
translator workflow remains a 0.10.0 task; this pass uses deterministic long
strings and the maximum supported HUD scale.
## End-to-end interaction flows
`smoke_ui_flows.gd` boots the real scene and verifies, in order:
- inspection opens, then allow and deny both close the panel;
- a normal radio click sends and spends battery;
- an emergency hold sends once, spends battery and starts cooldown;
- Help opens, filters to radio controls and closes;
- the wand opens at The Joke Shop, then allow and deny close it;
- returning from the review restores the venue menu.
`smoke_campaign.gd` covers review continue plus checkpoint resume, and
`smoke_timeline.gd` covers review → timeline → review. These are end-to-end
scene smokes, not just panel-unit tests.
## Visual coverage
`src/test/capture_ui_states.gd` completes the screen-design catalogue by staging
the states that the scene captures did not cover. The gallery now has one
deterministic current-build frame for every reference:
| State | Capture | Design reference |
| --- | --- | --- |
| Start / venue menu | `14-start-menu.png` | `start_menu.png` |
| Pause | `15-pause-overlay.png` | `pause_overlay.png` |
| Settings | `16-settings-panel.png` | `settings_panel.png` |
| Shift review | `17-shift-review.png` | `shift_review.png` |
| Emergency radio | `18-emergency-radio.png` | `emergency_radio.png` |
| Action wheel | `19-radial-menu.png` | `radial_menu.png` |
| Crowd panic | `20-crowd-panic.png` | `crowd_panic.png` |
| Responder arrival | `21-responder-arrival.png` | `responder_arrival.png` |
The crowd-panic frame is taken 70 frames after the panic event so the staged
group is visibly displaced from the steps toward the street; the responder is
parked on the approach with the door locked so the arrival/secure state is
readable. Both are presentation staging, not gameplay changes. `compare`
reports **21 good / 0 bad** and the automatic judge **21/21 match, 0 diff**.
The gallery is regenerated by `tools/check_screenshots.sh`.
## Remaining audit work
- Player-facing labels are now routed through `content/strings.en.json`; numeric
values, empty-state clears and debug-only text remain in code by design.
- Focus/hover/pressed/disabled states and keyboard/gamepad rings are recorded above.
- Pseudo-locale layout and a translator workflow remain scheduled for the
localization milestone, not this UI pass.
## Screen-design judge report
Date: 2026-11-02
Model: automatic cheapest image+JSON selection (`z-ai/glm-5.3-flash` at run time)
Command: `python3 tools/screen_designs.py judge`
Result: **21/21 match, 0 review, 0 diff**
The screenshot gallery was regenerated on the current build before judging, including the eight UI-state captures 14–21 added in `src/test/capture_ui_states.gd`.
Accepted captures are in [`docs/screens/`](../screens/README.md); the committed
gallery is in [`docs/screenshots/`](../screenshots/README.md).
The automatic model selection and retry/spend behavior is documented in
[`docs/assets/asset-tooling.md`](../assets/asset-tooling.md). This report intentionally records
the outcome rather than generated captures, which remain local/gitignored.
+148
View File
@@ -0,0 +1,148 @@
# Venues
The game uses two physical Hollywood blocks across three playable venue rows:
- **Hollywood Boulevard** — the 6840 Hollywood Blvd / El Capitan Entertainment
Centre block, in day and night rows.
- **The Joke Shop** — a fictional comedy club based on the Sunset Strip block
around 8433 Sunset Blvd.
- **Late Night TV Studio** — the same El Capitan block restaged as a studio
arrival.
The runtime implementation contract (facade specs, map budgets, navigation,
colliders, phase behavior and fallback) lives in
[`architecture.md`](../project/architecture.md#venue-implementation-contract). This page
keeps the real-site evidence, mapping decisions and deliberate simplifications.
## Hollywood Boulevard
### Real site
- **Address:** 6840 Hollywood Boulevard, Hollywood, Los Angeles, CA 90028.
- **Coordinates:** 34.10118 N, 118.34009 W; OpenStreetMap way `424024147`.
- **Building:** the 1921 Hollywood Masonic Temple by John C. Austin, now the El
Capitan Entertainment Centre and the home of *Jimmy Kimmel Live!*. It is the
game's starting point for both the Hollywood shift and the TV Studio arrival.
- **Facade:** light stone/render Neoclassical front, six oversized Ionic
columns, a recessed entrance up eight stone steps, ornamental door grilles,
a crosscut transom, two side entrances, and the Masonic parapet motto and
medallions.
- **Neighbours:** the El Capitan Theatre immediately west, a modern retail block
east, and the Ovation Hollywood frontage across the four-lane boulevard.
- **Sidewalk:** the Walk of Fame terrazzo strip with brass stars; red-painted
kerb in the reference photographs.
### Game mapping
| Real feature | In-game representation |
| --- | --- |
| 29.6 m wide, 14.5 m high facade | `VENUE_SPECS["hollywood_building"]`, front at `z = -4` |
| Eight stone steps | 8 steps, 0.10 m rise, 0.38 m tread, 12 m wide |
| Six Ionic columns | `IonicColonnade`, 4.96 m bay spacing |
| Central + two side doors | 4.2 m central door, 2.5 m side doors with transoms |
| Red event banners | three stylized `EL / CAPITAN / LIVE` banners |
| Masonic motto + medallions | `FriezeInscription` and two stone discs |
| El Capitan Theatre / east retail | library-neighbour blocks with marquee/blade or glazed shopfront |
| Ovation Hollywood | arcade with seven arched openings, sign and south sidewalk |
| Walk of Fame | dark terrazzo band with ten stars |
| Four-lane boulevard | double-yellow centre, broken white lanes, red kerb, crosswalk |
| TV Studio arrival | same six-column facade/eight steps plus bulb canopy, sedan, handrail and barriers |
The generated references in
[`screens/concepts/hollywood_boulevard/`](../screens/concepts/hollywood_boulevard/README.md)
are art direction for lighting, material scale and composition; they are not
texture or geometry sources.
### Late Night TV Studio
The third venue is **not a separate real site**. It reuses the El Capitan block
and restages it as a studio arrival: the same stone facade and steps, plus a
bulb-lit canopy, glossy black car, barrier/stanchion line and audience queue.
`VENUE_SPECS["tv_studio"]` is a 30.0 m variant of the Hollywood spec with the
arrival staging; it shares this block's reference board.
## The Joke Shop
### Real site
| Item | Reference |
| --- | --- |
| Address | 8433 Sunset Blvd, West Hollywood, CA 90069 |
| Real venue | The Comedy Store (comedy club and theatre) |
| OpenStreetMap | Way [`428854155`](https://www.openstreetmap.org/way/428854155), centroid 34.095265, -118.373965 |
| Tags | `amenity=theatre`, `building=commercial`, `height=12.2`, `start_date=1940`, `wikidata=Q3520350` |
| Footprint | OSM polygon about 47.1 m × 41.2 m across the club and rear parcels |
| Street | Sunset Boulevard on the Sunset Strip |
| Setting | Dry Hollywood Hills with houses and palms above the roofline |
The building began as **Ciro's** (1940) and became The Comedy Store in the
early 1970s. Its street front is a low black hall under a deep,
signature-covered canopy, with a circular blade sign above the roof, red
curtains along the frontage and the main entrance set toward the west end.
### Game mapping
| Real element | Game implementation |
| --- | --- |
| Low black comedy hall | 27 m × 12 m footprint, 6.0 m street wall, matte black concrete, low plinth and parapet |
| Deep overhanging canopy | 4.9 m sloped slab at 11°, white signature fascia band and club name |
| Signature-covered front | two `Label3D` signature bands plus a wall panel |
| Circular blade sign | 3.9 m white disc on a roof pole, black `THE JOKE SHOP` wordmark |
| Red curtains | seven tied-back velvet drapes with scalloped hems and dark recesses |
| West-end entrance | recessed at x = -8.8 m, low step, brass pulls, door-lock indicator |
| Practicals | sconces, canopy downlights, entrance wash, ground uplights; off by day, switched at night |
| Neighbours | cream Mediterranean block with red awning; `WestHotelTower` mass behind; white commercial block east |
| Hillside | fog-free unshaded ramp with stucco houses, shrubs and palms; dark silhouette at night |
| Opposite Sunset | low retail row, rooftop billboard, neon and palms beyond the far kerb |
| Street dressing | palms, barriers, stanchions, bins, planters, A-frame, hydrant and parked sedan |
Key proportions are reconciled in the map budget and `VENUE_SPECS`; the full
measured table is retained in the 3D review history. The playable frontage is
27 m, the facade centre is at z = -8.0 and the front face at z = -2.0. The
sidewalk is 38 m × 14 m, meeting the kerb at z = 11.9; the street is 90 m × 24 m.
The guard starts west of the entrance at (-4.8, 0.1, 1.4), facing the approach.
## Deliberate simplifications
- Both blocks are stylized reconstructions, not survey models; show branding is
replaced by venue-neutral/fictional text while addresses and landmark
silhouettes are retained.
- Interiors, basements, side streets, the Metro entrance and the Comedy Store's
rear rooms are out of playable bounds.
- The Ovation frontage is one arcade block, not the full mall plan; neighbouring
businesses are generic low-rise masses and no current tenant is claimed.
- The Joke Shop's rounded west corner is kept as a hard 90° corner; its hillside
is a background ramp with simplified houses, not a terrain heightfield.
- Geometry uses boxes, cylinders and a small set of custom arch/star meshes to
stay inside the Compatibility/Web budget; concept frames are photoreal and the
runtime keeps a stylized material treatment.
- Day/night is a phase offset on one geometry/scenario, not a second baked map.
The night row starts in `LATE` while the checkpoint stores the offset.
## References
- [Hollywood Masonic Temple — Wikipedia](https://en.wikipedia.org/wiki/Hollywood_Masonic_Temple)
- [El Capitan Entertainment Centre — OpenStreetMap way 424024147](https://www.openstreetmap.org/way/424024147)
- [El Capitan Theatre — OpenStreetMap way 424024148](https://www.openstreetmap.org/way/424024148)
- [Ovation Hollywood — OpenStreetMap way 151485232](https://www.openstreetmap.org/way/151485232)
- [Hollywood Masonic Temple facade — Wikimedia Commons](https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg)
- [Hollywood Masonic Temple and El Capitan Theatre, 2013 — Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Hollywood_Masonic_Temple_2013-10-13_10-02-25.jpg)
- [Comedy Store — OpenStreetMap way 428854155](https://www.openstreetmap.org/way/428854155)
- Committed photo board: [`screens/refs/hollywood/`](../screens/refs/hollywood/README.md);
three-up boards are in [`screens/boards/`](../screens/boards/README.md). The Joke Shop has no
committed photo board: its reference set stays local-only under `tmp/research/comedy-store/`.
- Local-only research (never committed): `tmp/research/elcapitan-2026/`,
`tmp/research/jimmy-kimmel-entrance/`, `tmp/research/comedy-store/` and
`tmp/research/comedy-store-hillside/`. These are evidence for decisions, not
shipped assets.
## Verification
```bash
godot --headless --path . --script res://src/test/test_runner.gd
godot --path . --script res://src/test/capture_realism.gd -- --out=/tmp/gig-line-venues --stages=day,evening,late,joke_shop_day,joke_shop
python3 tools/check_docs.py
```
The map-budget tests and the venue light-falloff gate are part of the headless
suite; the screenshot/realism gates are optional review evidence.