From fce070facfea22e90b8ef3a193db6572284b9fa6 Mon Sep 17 00:00:00 2001 From: autocommit Date: Fri, 17 Apr 2026 21:59:25 -0700 Subject: [PATCH] =?UTF-8?q?docs(objectives):=20=F0=9F=93=9D=20Add=20struct?= =?UTF-8?q?ured=20documentation=20for=20world=20map=20input,=20movement=20?= =?UTF-8?q?mode=20UX,=20and=20tutorial=20opt-in=20feature=20objectives?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../p0-33-world-map-input-and-panel-wiring.md | 24 +++---- .project/objectives/p0-35-movement-mode-ux.md | 69 +++++++++++++++++++ .project/objectives/p1-19-tutorial-opt-in.md | 60 ++++++++++++++++ 3 files changed, 139 insertions(+), 14 deletions(-) create mode 100644 .project/objectives/p0-35-movement-mode-ux.md create mode 100644 .project/objectives/p1-19-tutorial-opt-in.md diff --git a/.project/objectives/p0-33-world-map-input-and-panel-wiring.md b/.project/objectives/p0-33-world-map-input-and-panel-wiring.md index b7a3de57..ffc60998 100644 --- a/.project/objectives/p0-33-world-map-input-and-panel-wiring.md +++ b/.project/objectives/p0-33-world-map-input-and-panel-wiring.md @@ -31,32 +31,28 @@ The world-map is unplayable because basic interaction is broken: clicking a unit ## Acceptance -- ✓ Clicking a player unit on the world map selects it: the unit sprite shows a selection ring/highlight, reachable hexes are overlaid, and the unit info panel appears showing unit name, HP/ATK/DEF/Movement stats and (where applicable) Found City / Build Improvement / Fortify / Skip Turn / Move action buttons. -- ✓ Action buttons that cannot fire (no movement remaining, wrong unit type) appear with red outline + disabled tooltip explaining why. +- ✓ Tutorial dim `ColorRect` no longer blocks mouse input (`tutorial_overlay.gd:84` must be `MOUSE_FILTER_PASS`, not `MOUSE_FILTER_STOP`). +- ✓ Clicking a player unit on the world map selects it: the unit sprite shows a selection ring/highlight, reachable hexes are overlaid, and the `unit_panel.tscn` info panel appears showing unit name, HP/ATK/DEF/Movement stats and action buttons (Found City / Build Improvement / Fortify / Skip Turn). - ✓ Single-clicking a city hex opens the city screen (`city_screen.open_city(city_ref)`). Bombard is removed from the single-click path. -- ✓ **Movement mode**: pressing M or clicking the Move button enters movement mode. The map shows a path preview (orange line of hex outlines) that updates as the cursor hovers. Right-click confirms the move; ESC cancels and returns to selection. Right-click-hold lets the player drag to explore alternate routes; releasing confirms. -- ✓ Multi-turn paths show a turn-count label on the final hex when the path exceeds one turn's movement budget. -- ✓ Fog-of-war-aware pathing: A* through scouted hexes, straight `hex_line()` through unscouted fog. - ✓ Pressing ESC with no panel open opens the in-game menu (Resume / Save / Load / Quit). - ✓ Pressing F10 at any time opens the in-game menu. - ✓ Pressing ESC while the city screen is open closes it without opening the in-game menu. - ✓ Pressing ESC while the tech tree or chronicle is open closes it. - ✓ The in-game menu closes on ESC. +Movement mode UX (Move button, path preview, right-click confirm) is scoped to **p0-35**. +Tutorial opt-in behavior (HUD button, disappears after turn 5) is scoped to **p1-19**. + ## Files to touch | File | Change | |------|--------| | `src/game/engine/scenes/hud/tutorial_overlay.gd` | Line 84: `MOUSE_FILTER_STOP` → `MOUSE_FILTER_PASS` (root cause of all click failures) | -| `src/game/engine/src/autoloads/event_bus.gd` | Add signals: `ingame_menu_requested`, `movement_mode_entered`, `movement_mode_exited` | -| `src/game/engine/scenes/main/main.gd` | Connect `EventBus.ingame_menu_requested`; verify ESC/F10 logic | -| `src/game/engine/scenes/world_map/world_map.gd` | Movement mode state + enter/exit/preview; right-click confirm; M key; `move_pressed` wire; ESC in movement mode; city single-click (already done) | -| `src/game/engine/scenes/world_map/world_map_hover.gd` | Invoke path preview update when movement mode active | -| `src/game/engine/src/rendering/unit_renderer.gd` | `show_path_preview(path, turns)`, `clear_path_preview()`, orange line in `_draw()` | -| `src/game/engine/scenes/hud/unit_panel.tscn` | Add MoveButton to ButtonRow | -| `src/game/engine/scenes/hud/unit_panel.gd` | `move_pressed` signal; Move button wiring; disabled-state tooltips for all action buttons | -| `src/game/engine/src/map/hex_utils.gd` | `hex_line()` static method for fog-of-war straight-line pathing | -| `public/games/age-of-dwarves/data/vocabulary.json` | `"move"`, `"tooltip_move"`, `"tooltip_move_no_movement"` | +| `src/game/engine/scenes/world_map/world_map.tscn` | Add `unit_panel.tscn` instance under a CanvasLayer so it receives `EventBus.unit_selected` | +| `src/game/engine/scenes/world_map/world_map.gd` | Route city single-click → `_city_screen.open_city()` (remove bombard-on-single-click) | +| `src/game/engine/scenes/main/main.gd` | Add KEY_F10 branch; verify ESC path | +| `src/game/engine/scenes/city/city_screen.gd` | Add `_unhandled_key_input` that calls `_on_close_pressed()` on ESC | +| `src/game/engine/scenes/hud/world_map_hud.gd` | Remove the slim programmatic unit panel (avoid double-display with `unit_panel.tscn`) | ## Depends on diff --git a/.project/objectives/p0-35-movement-mode-ux.md b/.project/objectives/p0-35-movement-mode-ux.md new file mode 100644 index 00000000..51ab4969 --- /dev/null +++ b/.project/objectives/p0-35-movement-mode-ux.md @@ -0,0 +1,69 @@ +--- +id: p0-35 +title: Movement mode UX — Move button, path preview, right-click confirm, fog-aware pathing +priority: p0 +scope: game1 +owner: wireguard +status: stub +updated_at: 2026-04-17 +evidence: + - src/game/engine/scenes/world_map/world_map.gd + - src/game/engine/scenes/world_map/world_map_hover.gd + - src/game/engine/src/rendering/unit_renderer.gd + - src/game/engine/scenes/hud/unit_panel.tscn + - src/game/engine/scenes/hud/unit_panel.gd + - src/game/engine/src/map/hex_utils.gd + - src/game/engine/src/autoloads/event_bus.gd + - public/games/age-of-dwarves/vocabulary.json +--- + +## Summary + +Movement is currently a silent left-click on a reachable hex — no path shown, no +confirmation step. Players expect the Civ-style flow: enter movement mode (M key +or Move button), see a path preview, right-click to confirm. This objective +adds the full movement-mode state machine, path rendering, fog-of-war-aware +pathing, and the Move button on the unit action panel with disabled-state +tooltips for all action buttons. + +Depends on **p0-33** (unit panel must be in the scene tree before the Move +button can be wired). + +## Acceptance + +- ✓ Pressing `M` or clicking the Move button on the unit panel enters movement mode (when a unit is selected and has movement remaining). +- ✓ In movement mode, the map shows a path preview (orange hex-outline line) from the unit to the hovered hex, updating as the cursor moves. +- ✓ Right-click confirms the move — unit traverses the previewed path. +- ✓ ESC while in movement mode cancels (returns to selection, does NOT open in-game menu). +- ✓ Left-click while in movement mode cancels (returns to selection). +- ✓ Multi-turn paths show a turn-count label on the final hex when the path exceeds one turn's movement budget. +- ✓ Fog-of-war-aware pathing: A* through scouted hexes, straight `HexUtilsScript.hex_line()` through unscouted fog (player doesn't know what's there). +- ✓ All action buttons (Move / Fortify / Skip / Found City / Build Improvement) that cannot fire show a red outline + disabled tooltip explaining why (e.g. "No movement remaining this turn"). + +## Files to touch + +| File | Change | +|------|--------| +| `src/game/engine/src/autoloads/event_bus.gd` | Add `movement_mode_entered`, `movement_mode_exited` signals | +| `src/game/engine/scenes/world_map/world_map.gd` | `_movement_mode` state, `_enter_movement_mode()`, `_exit_movement_mode()`, `_update_path_preview()`, right-click confirm in `_unhandled_input`, KEY_M in `_handle_hotkeys`, `move_pressed` wire from unit panel | +| `src/game/engine/scenes/world_map/world_map_hover.gd` | Invoke `_update_path_preview(hovered_axial)` when movement mode is active | +| `src/game/engine/src/rendering/unit_renderer.gd` | `show_path_preview(path, turns)`, `clear_path_preview()`, orange line + turn-count label in `_draw()` | +| `src/game/engine/scenes/hud/unit_panel.tscn` | Add `MoveButton` node to `ButtonRow` | +| `src/game/engine/scenes/hud/unit_panel.gd` | `move_pressed` signal; Move button wiring; disabled-state tooltips for ALL action buttons | +| `src/game/engine/src/map/hex_utils.gd` | `hex_line(a, b)` static method (lerp-and-round axial line algorithm) | +| `public/games/age-of-dwarves/vocabulary.json` | `"move"`, `"tooltip_move"`, `"tooltip_move_no_movement"`, tooltip strings for disabled states of other action buttons | + +## Depends on + +- **p0-33** — unit_panel.tscn must be in the world_map scene tree before Move button wiring works. + +## Non-goals + +- Right-click-hold + drag to preview alternate paths (deferred — adds significant input state complexity). +- Intelligence staleness / last-seen enemy state in fog (new P2 objective). + +## Why this is P0 + +Movement is the single most-used action in a 4X. A silent left-click with no +path preview and no confirmation step is a QA showstopper — players move units +onto unintended hexes, cannot see multi-turn paths, and have no cancel affordance. diff --git a/.project/objectives/p1-19-tutorial-opt-in.md b/.project/objectives/p1-19-tutorial-opt-in.md new file mode 100644 index 00000000..d012e9ef --- /dev/null +++ b/.project/objectives/p1-19-tutorial-opt-in.md @@ -0,0 +1,60 @@ +--- +id: p1-19 +title: Tutorial opt-in — HUD button, disappears after turn 5, starts from Step 1 +priority: p1 +scope: game1 +owner: wireguard +status: stub +updated_at: 2026-04-17 +evidence: + - src/game/engine/scenes/hud/tutorial_overlay.gd + - src/game/engine/scenes/hud/world_map_hud.gd + - src/game/engine/scenes/world_map/world_map.gd + - public/games/age-of-dwarves/vocabulary.json +--- + +## Summary + +The first-run tutorial currently auto-shows on game start (gated by +`TutorialOverlay.should_show_on_first_run()`). This is hostile to returning +players and to playtesting — the tutorial interrupts real gameplay every fresh +boot. Assume the player doesn't need a tutorial by default. Offer it as a +button on the world-map HUD that disappears after turn 5. + +Additionally, when the tutorial IS started, it begins at **Step 1** (camera +pan), not Step 2. This is already the authoritative step order in +`tutorial_overlay.gd:_STEPS` — the fix is only to make sure `_current_step` +initializes to `1` (it does) and that no code skips ahead. + +## Acceptance + +- ✓ On game boot, the tutorial overlay does NOT auto-instantiate. Remove the `if TutorialOverlayScript.should_show_on_first_run()` branch from `world_map.gd._mount_hud_overlays`. +- ✓ A "Tutorial" button appears on the world-map HUD top bar on turns 1–5. +- ✓ Clicking the Tutorial button instantiates `tutorial_overlay.tscn` starting at Step 1 (camera pan). +- ✓ The Tutorial button disappears at turn 6 (or on first click). +- ✓ The existing `SettingsManager` persistence of "tutorial_completed" is preserved so that once a player completes the tutorial, it does not reappear in later sessions (the button is suppressed). + +## Files to touch + +| File | Change | +|------|--------| +| `src/game/engine/scenes/hud/world_map_hud.gd` | Add `tutorial_requested` signal; Tutorial button in top bar; `hide_tutorial_button()`; auto-hide in `update_turn()` when turn > 5 | +| `src/game/engine/scenes/world_map/world_map.gd` | Remove auto-instantiation of `TutorialOverlayScene`; add `_on_tutorial_requested()` handler that instantiates on demand | +| `src/game/engine/scenes/hud/tutorial_overlay.gd` | Verify `_current_step = 1` on `_ready()` (already correct — audit only) | +| `public/games/age-of-dwarves/vocabulary.json` | `"tutorial_button"`, `"tooltip_tutorial_button"` | + +## Depends on + +- None. + +## Non-goals + +- Redesigning the tutorial step content. +- Moving the tutorial button elsewhere in the HUD (keep it next to Tech / Chronicle / End Turn). +- "Never show again" checkbox on the button (rely on `SettingsManager` persistence from completing the tutorial). + +## Why this is P1 (not P0) + +This is a UX papercut — the game is playable without it — but it blocks +repeated playtesting and makes every fresh-start feel interrupted. Upgrade to +P0 if QA reports the tutorial auto-show as a primary friction point.