Plan focus cone, head ring, and radial action menu; defer host sign-in
Document the next playable pass: WASD/look stop fighting action keys, cone focus with a billboarded head ring, doughnut HUD opened by LMB or Space (click or A/D then Space to confirm, Esc/RMB cancel). Emergency stays on R. Wand leaves W. NPC rigs stay procedural but get a face/hair/neck. Host REQUIRE_SIGNIN_VIEW follow-up deferred.
This commit is contained in:
1 parent
b704a8ed61
commit
5662baa14d
3 files changed
+193
No files matched your search
@@ -452,6 +452,140 @@ The following commands apply once the Godot project is scaffolded:
|
||||
|
||||
Desktop is the first target: Windows, Linux, and macOS. Web export is a later option.
|
||||
|
||||
## Player Control, Focus, and Action Menu (next pass)
|
||||
|
||||
The prototype already walks and looks in first person, but the control scheme fights itself and targeting is a hairline. This pass replaces that with three things that belong together: solid locomotion, a visible focus on a person, and a round action menu for what to do with them.
|
||||
|
||||
### What is wrong today
|
||||
|
||||
- `W` is walk-forward in the input map and wand-screening in `GameManager._handle_key`. Walking at someone with a wand venue fires the wand.
|
||||
- `A` / `D` are strafe and also allow/deny during inspection.
|
||||
- `Q` is polite direction and is also bound as `cancel`.
|
||||
- Focus is an 8 m physics ray from the camera. Missing a capsule by a few pixels clears the target. There is no mark in the world that you have someone.
|
||||
- NPC bodies are colored capsules with props. They read as markers, not people.
|
||||
- Actions live on number keys `1`–`6` plus `Q` / `E` / `W` / `R`. That is a cheat-sheet, not a verb you pick while looking at a person.
|
||||
- `Esc` only toggles mouse capture. There is no "I changed my mind" for an action in progress.
|
||||
|
||||
### Movement and look
|
||||
|
||||
Keep first-person WASD + mouse look. Fix the feel and stop stealing those keys.
|
||||
|
||||
- Body yaw from mouse X, head pitch from mouse Y, pitch clamped (already `-80` to `80`).
|
||||
- Move relative to body yaw only (already). Add short acceleration / deceleration so starts and stops are not instant.
|
||||
- Gravity only when `not is_on_floor()`; `floor_snap_length` so the steps work.
|
||||
- Mouse look runs only while `MOUSE_MODE_CAPTURED` and no modal UI is open (radial, inspection, wand, radio, shift review).
|
||||
- Walk speed stays around 3.2 m/s. No sprint, no crouch in this pass.
|
||||
- While the radial is open: freeze look and WASD so `A` / `D` can cycle the menu. Recapture the mouse when the menu closes.
|
||||
- `Esc` with a modal open closes that modal and does nothing else. `Esc` with nothing open keeps the current capture/release toggle.
|
||||
|
||||
Equipment stays on its own keys because it is not about a person: `G` flashlight, `L` door lock, `Tab` cycle nearby people, `V` venue (debug), `F` debug overlay. `R` stays the dedicated emergency radio (hold-to-confirm on the existing panel). Those do not go on the wheel.
|
||||
|
||||
Wand leaves `W`. It is a slice on the wheel (greyed when the venue has no wand) and an optional extra key that is not WASD, suggested `C`.
|
||||
|
||||
### Focus area
|
||||
|
||||
Replace the hairline ray as the primary picker.
|
||||
|
||||
- A **focus cone** in front of the camera: people within about 10 m whose head projects inside a screen-space circle around the crosshair (about 90 px / 10 degrees).
|
||||
- If several heads sit in the circle, pick the one closest to the center, then the nearer one if tied.
|
||||
- The person must be in front (dot with camera forward > 0) and not fully occluded by the building. A short ray to the head is enough for occlusion.
|
||||
- `Tab` still cycles people inside 12 m as the aim-free path. Cycling sets the same focused person the cone would.
|
||||
- Clearing: look away until the head leaves the circle for a few frames (small grace so a bob does not drop them), or they walk out of range.
|
||||
|
||||
### Head ring
|
||||
|
||||
When a person is in focus, draw a thin ring around their head.
|
||||
|
||||
- Attach to the avatar `Head` node, sitting just above the skull, billboarded to the camera so it stays a circle on screen.
|
||||
- Slow spin is fine; no ping-pong scale spam.
|
||||
- Idle focus: pale gold, modest size. Radial open on that person: brighter, slightly larger.
|
||||
- Optional small name under the ring (`display_name` only, not the archetype cheat `Violent Threat` in the world). The existing HUD target line can keep the archetype for the prototype.
|
||||
- One ring at a time. Everyone else has none.
|
||||
|
||||
Implementation sketch: `MeshInstance3D` torus or a thin unshaded ring mesh on the avatar, toggled from `GuardController` / `GameManager` when focus changes. Screen-space fallback (unproject head, draw a `Control` circle) is acceptable if the 3D torus z-fights on hats.
|
||||
|
||||
### Round action HUD
|
||||
|
||||
A doughnut / pie menu centered on the screen, opened on the focused person.
|
||||
|
||||
**Open**
|
||||
|
||||
- Left mouse button, or `Space`, while someone is in focus and no other modal is open.
|
||||
- If nobody is in focus, log the existing "aim first" line and do not open.
|
||||
- The click that opens the menu must not also pick a slice.
|
||||
|
||||
**While open**
|
||||
|
||||
- Mouse becomes visible. Look and walk freeze.
|
||||
- Center of the doughnut shows the focused person's `display_name`.
|
||||
- Slices, clockwise from the top, de-escalation first:
|
||||
1. Raise hand (stop / wait)
|
||||
2. Point away
|
||||
3. Head shake
|
||||
4. Polite direction (old `Q`)
|
||||
5. Inspect access (old `E`)
|
||||
6. Wand (grey if the venue has no wand)
|
||||
7. Formal warning
|
||||
8. Block
|
||||
9. Radio assist
|
||||
- Emergency is **not** on the wheel (`R` only).
|
||||
- Highlight follows the mouse angle when the cursor is over the ring. `Left` / `Right` or `A` / `D` step the highlight. Wrap around.
|
||||
|
||||
**Confirm**
|
||||
|
||||
- Click a slice: that action runs, menu closes, mouse recaptured.
|
||||
- `Space` while a slice is highlighted: same.
|
||||
- Inspect or wand: close the wheel, then open the existing inspect / wand panel. Allow / deny on that panel stay `A` / `D` (walk is frozen only while the wheel is up; once the inspect panel is open, WASD can move again, so allow/deny on `A` / `D` remains a press handler and must ignore repeats / echo, which it already does). Safer: keep walk frozen for inspect/wand too, until the panel closes. Prefer freeze until the whole interaction ends.
|
||||
- Radio assist: close the wheel, open the existing radio panel.
|
||||
|
||||
**Cancel**
|
||||
|
||||
- `Esc` or right mouse button: hide the menu, no action, no recorder event, recapture mouse.
|
||||
- Focus and the head ring stay as they were.
|
||||
|
||||
Number keys `1`–`6` may remain as shortcuts that skip the wheel so a smoke-test script still works. They must not fire while the wheel is open (the wheel owns `A` / `D` / `Space`). Document both in the README.
|
||||
|
||||
### NPC display
|
||||
|
||||
Stay on the procedural capsule rig (no Mixamo / GLB dependency this pass). Make them read as people at conversation distance.
|
||||
|
||||
- Neck between torso and head; shoes; simple hair cap (color from seed); two dark eye spheres on the face so a head has a front.
|
||||
- Keep archetype props (camera, box, hat, sign, bag). Keep height / brightness variation from the visual seed.
|
||||
- Collision capsule matches the scaled height so the focus ray / cone hits the body you see.
|
||||
- `Head` stays a named node other systems can find (`get_node("Rig/Head")`) for the ring and the cone.
|
||||
- Walk bob and the "look at the guard when noticed" cue stay.
|
||||
- Do not put the internal type name (`Trespasser`, `Violent Threat`) on the body. The player should judge from clothes, props, and behavior. The debug overlay (`F`) can still print the type.
|
||||
|
||||
AI textures in `assets/textures/ai/` stay out of this pass unless a specific map (shirt, hair) is already the right size.
|
||||
|
||||
### Input map (target)
|
||||
|
||||
| Action | Bind |
|
||||
| --- | --- |
|
||||
| Walk | WASD / arrows (arrows **do not** walk while the wheel is open; they step the highlight) |
|
||||
| Look | Mouse, captured |
|
||||
| Open / confirm action menu | LMB, `Space` |
|
||||
| Cancel menu | RMB, `Esc` |
|
||||
| Step highlight | `A` / `D`, left / right arrows |
|
||||
| Emergency radio | `R` |
|
||||
| Flashlight | `G` |
|
||||
| Door lock | `L` |
|
||||
| Cycle nearby people | `Tab` |
|
||||
| Wand shortcut | `C` (not `W`) |
|
||||
| Inspect shortcut | `E` still allowed when the wheel is closed |
|
||||
|
||||
### Files this pass is expected to touch
|
||||
|
||||
- `src/game/guard_controller.gd` — cone focus, no look while modal, accel, floor snap.
|
||||
- `src/game/npc_avatar.gd` — face / hair / neck, head marker, ring toggle.
|
||||
- `src/game/ui/action_radial.gd` — new Control, `_draw` doughnut, slice pick.
|
||||
- `src/game/ui/hud.gd` — host the radial; stop teaching number-key verbs as the only path.
|
||||
- `src/game/game_manager.gd` — input routing, freeze flags, open/confirm/cancel.
|
||||
- `project.godot` — input map.
|
||||
- `src/core/strings.gd` — controls line, aim-first, no new tone-of-voice.
|
||||
- `src/test/tests/test_focus_and_radial.gd` — cone pick, wrap, cancel emits nothing, `W` is not wand.
|
||||
- README controls table and smoke checklist.
|
||||
|
||||
## Design Direction
|
||||
|
||||
The game should feel like a tense workplace simulation with occasional crisis moments. The most satisfying outcome is not overpowering an NPC; it is recognizing the situation early and resolving it calmly.
|
||||
|
||||
Reference in new issue
Block a user