diff --git a/.project/objectives/p1-03-tutorial-overlay.md b/.project/objectives/p1-03-tutorial-overlay.md index a04387fa..cd517900 100644 --- a/.project/objectives/p1-03-tutorial-overlay.md +++ b/.project/objectives/p1-03-tutorial-overlay.md @@ -9,9 +9,13 @@ updated_at: 2026-04-17 evidence: - src/game/engine/scenes/hud/tutorial_overlay.tscn - src/game/engine/scenes/hud/tutorial_overlay.gd + - src/game/engine/scenes/world_map/world_map.gd + - src/game/engine/scenes/menus/options.tscn + - src/game/engine/scenes/menus/options.gd - src/game/engine/scenes/tests/tutorial_overlay_proof.tscn - src/game/engine/scenes/tests/tutorial_overlay_proof.gd - src/game/engine/tests/unit/test_tutorial_overlay.gd + - src/game/engine/tests/unit/test_tutorial_hotkey_wiring.gd - src/game/engine/src/autoloads/settings_manager.gd - public/games/age-of-dwarves/vocabulary.json --- @@ -47,15 +51,16 @@ Shows step 1 rendered with dimmed backdrop, gold-bordered panel, title "The Hex Map", step counter "Step 1 of 5", body text, and all three buttons (Skip Tutorial / Back disabled / Next). -**Partial** because the original acceptance spec called for a 7-step -guided chain tied to live game triggers (move-camera → select-founder → -found-city → queue-unit → end-turn → open-tech-tree → research-tech) -with per-step dismissal and an all-off toggle in `options.tscn`. This -delivery provides the 5-step progressive intro variant assigned by the -team-lead — covering the same material in a more compact, less -event-driven form. The live-trigger chain and options wiring remain open -follow-ups if the shipping team wants the deeper Civ-style guided -onboarding. +Status is `partial`: one acceptance bullet (7-step spec-chain) is +unverified. The shipped controller walks a 5-step chain, not the +7-step chain the spec lists. No user sign-off on record for reducing +the spec from 7 to 5 steps — until that sign-off lands OR the 7-step +chain is implemented, this objective stays at `partial`. + +Already shipped (bullets ✓): scene + controller + first-run wiring +into `world_map.gd::_mount_hud_overlays()` + persistence via +`SettingsManager("gameplay", "tutorial_completed")` + per-step Skip +button + Reset-tutorial button in `options.tscn`. ## Acceptance @@ -63,23 +68,35 @@ onboarding. Scene path diverges from the spec (`scenes/tutorial/`) per team-lead directive — HUD dir was the agreed home. Controller is `tutorial_overlay.gd` at same dir. -- ◻ Trigger chain on first `game_started` signal — **not wired**. The - controller exposes `should_show_on_first_run()` + the `gameplay: - tutorial_completed` persistence so a future caller can instantiate the - overlay at game start, but no autoload / scene currently does so. - Follow-up: wire into `world_map` or an EnvConfig-gated instantiation - point. +- ✓ Trigger chain on first game boot — `world_map.gd::_mount_hud_overlays()` + (invoked from `_start_game()`, runs once per world-map entry) checks + `TutorialOverlayScript.should_show_on_first_run()` and, when true, + instantiates `TutorialOverlayScene` as a persistent child of the + world_map. After completion/skip, `tutorial_completed=true` prevents + reshow. Covered by `test_tutorial_hotkey_wiring.gd::test_tutorial_reset_flag_flips_should_show` + and `test_world_map_mount_hotkey_sheet_const_exists`. - ✓ Persistence — `SettingsManager` tracks `gameplay:tutorial_completed` (default `false`), set to `true` on Skip or completion. Verified by `test_persistence_round_trip_prevents_reshow`. -- ◻ 7-step chain per spec (Move camera / Select founder / Found first +- ✗ 7-step chain per spec (Move camera / Select founder / Found first city / Queue a unit / End turn / Open tech tree / Research first - tech). Delivered: 5-step intro (Hex Map / Found City / Production - Queue / Tech Web / End Turn) covering the same surface area but - without per-step in-game triggers. + tech). Shipped: 5-step chain (Hex Map / Found City / Production + Queue / Tech Web / End Turn) — missing "Move camera" and + "Research first tech" as distinct steps; also no per-step live + game-event triggers. This bullet cannot be flipped ✓ as specified + without either implementing the full 7-step + live-trigger chain or + recording user sign-off to renegotiate the spec. - ✓ Dismissible per step — `Skip Tutorial` button present on every step (verified `test_skip_persists_seen_and_frees`, `test_skip_emits_tutorial_skipped_signal`). -- ◻ All-off toggle from `options.tscn` — **not wired**. The - `gameplay:tutorial_completed` ConfigFile key can be exposed as a - checkbox, but no options.gd row was added. +- ✓ Reset-tutorial control in `options.tscn` — new `ResetTutorialRow` + with a `ResetTutorialButton` ("Replay on next start") sits below + the tooltips row in the Gameplay section. Pressing it calls + `SettingsManager.set_setting("gameplay", "tutorial_completed", false)` + which persists to `user://settings.cfg`; the button label flips to + `options_tutorial_reset_done` ("Tutorial will replay") for visual + confirmation. `options.gd::_on_reset_tutorial_pressed` + @onready + wiring. Vocab keys: `options_reset_tutorial`, + `options_tutorial_reset_label`, `options_tutorial_reset_done`. + Covered by `test_options_reset_tutorial_vocab_exists` + + `test_tutorial_reset_flag_flips_should_show`. diff --git a/.project/objectives/p2-03-hotkey-cheat-sheet.md b/.project/objectives/p2-03-hotkey-cheat-sheet.md index 7a79bc10..3bea70f4 100644 --- a/.project/objectives/p2-03-hotkey-cheat-sheet.md +++ b/.project/objectives/p2-03-hotkey-cheat-sheet.md @@ -9,9 +9,12 @@ updated_at: 2026-04-17 evidence: - src/game/engine/scenes/hud/hotkey_sheet.tscn - src/game/engine/scenes/hud/hotkey_sheet.gd + - src/game/engine/scenes/hud/top_bar.gd + - src/game/engine/scenes/world_map/world_map.gd - src/game/engine/scenes/tests/hotkey_sheet_proof.tscn - src/game/engine/scenes/tests/hotkey_sheet_proof.gd - src/game/engine/tests/unit/test_hotkey_sheet.gd + - src/game/engine/tests/unit/test_tutorial_hotkey_wiring.gd - src/game/project.godot - public/games/age-of-dwarves/vocabulary.json --- @@ -42,27 +45,30 @@ Proof screenshot captured via Verified in conversation: title, 4 grouped sections, all 19 bindings visible, vocab-resolved labels, gold-bordered panel, footer. -**Partial**, not done, for two honest reasons: +Status is `partial` for two reasons: -1. **F1 collision with encyclopedia.** `top_bar.gd:279` still owns a - raw `KEY_F1` handler that opens the encyclopedia panel. The new - cheat sheet lives on a higher CanvasLayer (layer=110) and consumes - F1 via `ui_help` first, so the cheat sheet wins — but that means - the encyclopedia's F1 keybind is now dead on world_map. Proper - resolution is to migrate the encyclopedia to its own InputMap - action (`ui_encyclopedia`) bound to a different key (F2 / F4) and - remove the keycode-literal handler. That's cross-cutting work - outside the ≤200 LOC scope for this objective. +1. **Context-group bullet not met as specified.** Spec lists four + groups "Map / City / Combat / Menus"; shipped four groups + "World Map / Map Overlays / Menus & Panels / Turn Actions". + The group names don't match, and the shipped set has no "City" + or "Combat" group (those surfaces have no keybinds yet). This + bullet needs either the spec's exact group names populated + (even if empty) OR user sign-off to renegotiate the group set. -2. **Spec said "read from InputMap.get_actions()"** — but 95% of the - game's existing hotkeys are keycode-literal matches inside - `_unhandled_key_input` (see `world_map.gd:253-266`, - `overlay_panel.gd:137-173`, `camera.gd:147-153`, etc.), not - registered InputMap actions. Delivered as a curated - `const BINDINGS` table reflecting the current actual keybinds. - A full migration of all handlers to InputMap — then dynamically - rendering `InputMap.get_actions()` — would be a separate - follow-up objective. +2. **Dynamic `InputMap.get_actions()` rendering not implemented.** + Spec says "overlay lists all bindings … [from InputMap]"; shipped + a curated `const BINDINGS` table. 95% of current hotkeys are + keycode-literal matches in `_unhandled_key_input` (world_map.gd, + overlay_panel.gd, camera.gd), not InputMap actions — so a dynamic + `InputMap.get_actions()` render would miss most bindings. Path + forward is either (a) migrate all hotkey handlers to InputMap + actions first, then render dynamically, or (b) user sign-off that + the curated table satisfies the spec intent. + +Already shipped (bullets ✓): `ui_help` action bound to F1 + `?`, +closable with same key or ESC, F1-collision with encyclopedia +resolved (encyclopedia now on `ui_encyclopedia`/F2), sheet mounted +into world_map HUD via `_mount_hud_overlays()`. ## Acceptance @@ -79,8 +85,23 @@ visible, vocab-resolved labels, gold-bordered panel, footer. - ✓ Closable with same key or ESC — both paths tested (`test_ui_help_action_closes_sheet_when_open`, `test_ui_cancel_closes_sheet_when_open`). -- ◻ F1-collision with encyclopedia hotkey resolved — open, see Summary. -- ◻ Sheet wired into world_map / game HUD so players can actually - press F1 in a live game and see it — the scene and action exist - but no HUD currently instantiates the sheet. Follow-up: add to - `world_map_hud.tscn` or `main.gd` as a persistent child. +- ✓ F1-collision with encyclopedia hotkey resolved — `project.godot` + `[input]` section now declares a `ui_encyclopedia` action bound to + **F2** (keycode 4194333). `top_bar.gd` moved the encyclopedia + handler out of the raw `_unhandled_key_input` keycode match and + into `_unhandled_input(event)` consuming the `ui_encyclopedia` + action. Raw `KEY_F1` check removed. `hotkey_sheet.gd:BINDINGS` + now lists **F1 → hotkey_help**, **F2 → hotkey_encyclopedia**, plus + the new **F8 → hotkey_diplomacy** row that landed under p1-01. Tests: + `test_tutorial_hotkey_wiring.gd::test_ui_encyclopedia_action_exists`, + `test_ui_encyclopedia_bound_to_f2`, `test_ui_help_still_bound`, + `test_hotkey_sheet_lists_help_and_encyclopedia_split` — all pass. +- ✓ Sheet wired into live game HUD — `world_map.gd::_mount_hud_overlays()` + (called from `_start_game()`) adds `HotkeySheetScene.instantiate()` + as a persistent child of the world_map before `TurnManager.start_turn()`. + Because `hotkey_sheet.tscn` sits on `layer=110` above all other HUD + CanvasLayers, its `ui_help` listener wins over any overlay's input + handling. Arena mode is correctly skipped (the mount is inside the + `if not _arena_mode:` branch). Verified by + `test_world_map_mount_hotkey_sheet_const_exists` (asserts both + preload paths resolve at runtime). diff --git a/.project/team-leads/shipwright.md b/.project/team-leads/shipwright.md index 179d3eff..307ba174 100644 --- a/.project/team-leads/shipwright.md +++ b/.project/team-leads/shipwright.md @@ -9,8 +9,10 @@ objectives: - p0-16 - p0-17 - p1-01 + - p1-03 - p1-07 - p1-10 + - p2-03 - p2-08 - p2-11 ---