Reorganize docs into category folders and drop the retired head-review page
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:
1 parent
045ed2a58f
commit
2ba40f3578
57 files changed
+406
-414
No files matched your search
@@ -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.
|
||||
Reference in new issue
Block a user