feat(@projects/@magic-civilization): ✨ update tutorial overlay spec with 5-step partial status
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
032602805b
commit
def09d15e6
3 changed files with 86 additions and 46 deletions
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ objectives:
|
|||
- p0-16
|
||||
- p0-17
|
||||
- p1-01
|
||||
- p1-03
|
||||
- p1-07
|
||||
- p1-10
|
||||
- p2-03
|
||||
- p2-08
|
||||
- p2-11
|
||||
---
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue