# NEO-132 — Manual QA checklist | Field | Value | |-------|-------| | Key | NEO-132 | | Title | E7M2-09: Playable quest reward delivery capstone (Godot) | | Linear | https://linear.app/neon-sprawl/issue/NEO-132/e7m2-09-playable-quest-reward-delivery-capstone-godot | | Plan | `docs/plans/NEO-132-implementation-plan.md` | | Branch | `NEO-132-playable-quest-reward-delivery-capstone` | ## Preconditions - **Fresh dev player:** stop any running server, then start a new instance so in-memory quest progress, **`IRewardDeliveryStore`**, inventory, skill progression, encounter progress, NPC HP, and resource-node depletion reset. - **No Bruno/curl** for this checklist — accept uses **Q** / **Shift+Q**; gameplay uses **R**, **Tab** + **1**, and Economy HUD **Craft** buttons only. - NEO-124–NEO-131 reward spine and NEO-123 onboarding capstone landed on `main`. - **`Economy HUD`** toggle **on** for inventory + skill verification. ## Quest completion reward freeze (E7M2-01) | Quest id | Display name | Bundle grants | Expected **`QuestRewardDeliveryLabel`** | |----------|--------------|---------------|----------------------------------------| | `prototype_quest_gather_intro` | Intro: Salvage Run | `salvage` **+25** XP | `Salvage +25 XP` | | `prototype_quest_combat_intro` | Intro: Clear the Pocket | `salvage` **+25** XP | `Salvage +25 XP` | | `prototype_quest_refine_intro` | Intro: Refine Stock | `refine` **+25** XP | `Refine +25 XP` | | `prototype_quest_operator_chain` | Operator Chain | `survey_drone_kit` ×1 + `salvage` **+50** XP | `Survey Drone Kit ×1` + `Salvage +50 XP` | **Encounter loot (unchanged — E5.M3):** combat pocket still grants **`scrap_metal_bulk` ×10** + **`contract_handoff_token` ×1** on **`EncounterCompleteLabel`**, not quest bundles. ## Skill XP verification method Record **`SkillProgressionLabel`** salvage/refine **`xp`** values **immediately before** each quest completion transition and **after** the HUD refreshes. Assert the **delta** matches the freeze table (+25 or +50 for salvage; +25 for refine). Gather/craft activity XP may also change totals — deltas per quest completion are authoritative. ## Expected HUD progression (extends NEO-123) | Phase | `QuestProgressLabel` | `QuestRewardDeliveryLabel` | Economy HUD | |-------|----------------------|----------------------------|-------------| | Boot | All four **`not started`** | `Quest rewards:` / `—` | salvage/refine xp **0** (fresh server) | | Gather intro **`completed`** | Salvage Run **`completed`** | `Intro: Salvage Run` + `Salvage +25 XP` | salvage xp **+25** delta | | Combat intro **`completed`** | Clear the Pocket **`completed`** | `Intro: Clear the Pocket` + `Salvage +25 XP` | salvage xp **+25** delta | | Refine intro **`completed`** | Refine Stock **`completed`** | `Intro: Refine Stock` + `Refine +25 XP` | refine xp **+25** delta | | Operator chain **`completed`** | Operator Chain **`completed`** | `Survey Drone Kit ×1` + `Salvage +50 XP` | bag has **`survey_drone_kit`**; salvage xp **+50** delta | | Godot restart | All four still **`completed`** | `—` (no transition replay) | counts **unchanged** | | Duplicate accepts | Unchanged | Unchanged | counts **unchanged** | ## Checklist Follow [NEO-123](NEO-123.md) for accept order, anchors, material math, and quest steps **1–15**. **Extend** each completion with reward + economy checks below. ### Boot 1. Start server: `cd server/NeonSprawl.Server && dotnet run`. 2. Run Godot main scene (**F5**). Confirm four quests **`not started`**, **`QuestRewardDeliveryLabel`** shows **`Quest rewards:`** / **`—`**, and **`SkillProgressionLabel`** shows salvage/refine xp **0** (fresh server). ### Intro: Salvage Run (gather + skill XP reward) 3. Press **Q**; gather at **gamma** **(12, 0)** once (+3 scrap) until **`Intro: Salvage Run: completed`**. 4. Verify **`QuestRewardDeliveryLabel`**: `Intro: Salvage Run` + **`Salvage +25 XP`**. 5. Verify **`SkillProgressionLabel`**: salvage xp increased by **25** vs value recorded before completion (activity gather XP may also apply — quest bundle delta is **+25**). ### Intro: Clear the Pocket (combat + skill XP reward) 6. Press **Shift+Q**; defeat all three prototype NPCs (**Tab** + **1**, any order). 7. Verify **`EncounterCompleteLabel`** still lists encounter loot (**`scrap_metal_bulk ×10`**, **`contract_handoff_token ×1`**) — separate from quest bundle. 8. Verify **`Intro: Clear the Pocket: completed`** on **`QuestProgressLabel`**. 9. Verify **`QuestRewardDeliveryLabel`**: `Intro: Clear the Pocket` + **`Salvage +25 XP`**. 10. Verify **`SkillProgressionLabel`**: salvage xp **+25** delta since step 5. ### Intro: Refine Stock (craft + skill XP reward) 11. Press **Shift+Q**; craft **`refine_scrap_standard`** when **≥5** scrap in bag. 12. Verify **`Intro: Refine Stock: completed`**. 13. Verify **`QuestRewardDeliveryLabel`**: `Intro: Refine Stock` + **`Refine +25 XP`**. 14. Verify **`SkillProgressionLabel`**: refine xp **+25** delta since step 10. ### Operator Chain (item + skill XP reward) 15. Press **Shift+Q**; complete chain steps 1–4 per [NEO-123](NEO-123.md) (gather ×5 → refine → stim → token held). 16. Verify **`Operator Chain: completed`**. 17. Verify **`QuestRewardDeliveryLabel`**: **`Survey Drone Kit ×1`** (or raw id fallback) + **`Salvage +50 XP`**. 18. Verify **`InventoryLabel`** lists **`survey_drone_kit`** (display name when item defs loaded). 19. Verify **`SkillProgressionLabel`**: salvage xp **+50** delta since step 14. ### Capstone snapshot (record for idempotency) 20. **Record** final state: - **`QuestProgressLabel`**: all four **`completed`** - **`SkillProgressionLabel`**: salvage + refine xp totals - **`InventoryLabel`**: includes **`survey_drone_kit`**; note scrap/plate/token/stim counts ### Idempotency (no duplicate reward delivery) 21. **Godot restart:** stop Godot (**Shift+F5**); **F5** again **without** stopping the server. 22. Verify all four quests still **`completed`**; **`QuestRewardDeliveryLabel`** is **`—`** (transition-only). 23. Verify **`SkillProgressionLabel`** and **`InventoryLabel`** counts **match step 20** exactly. 24. Press **Q** on gather intro. Verify **`Quest accept: denied — already_completed`** (or **`already_active`**). 25. Press **Shift+Q**. Verify **`Quest accept: no eligible quest`** (or equivalent deny). 26. Verify economy HUD counts **still match step 20** — no duplicate skill XP or items. ### Regression 27. Component reward HUD: [NEO-131 manual QA](NEO-131.md). 28. Slice 1 quest chain: [NEO-123 manual QA](NEO-123.md). 29. Encounter loot independence: [NEO-110 manual QA](NEO-110.md). ## Notes - **Shift+Q catalog order** matches NEO-123 — combat intro before refine intro after gather completes. - Quest completion bundles are **idempotent** server-side (`{playerId}:quest_complete:{questId}`); Godot restart must not replay grant copy on **`QuestRewardDeliveryLabel`** (NEO-131 transition-only). - Economy HUD auto-refreshes on quest completion transition (NEO-132); no manual **I** required for reward verification. - Epic 7 Slice 2 AC: idempotent reward delivery; replays cannot double-claim ([epic_07 Slice 2](../decomposition/epics/epic_07_quest_faction.md#slice-2---reward-and-unlock-routing)). - **Faction standing + grid contract:** defer to [NEO-143](NEO-143.md) Slice 3 capstone (extends this checklist through **`prototype_quest_grid_contract`**). ## Acceptance - [ ] Steps 1–26 completable in one session without Bruno/curl. - [ ] All four quest completion bundles visible on **`QuestRewardDeliveryLabel`** during in-session transitions. - [ ] Skill XP deltas and **`survey_drone_kit`** in bag match freeze table. - [ ] Godot restart + duplicate accepts leave economy counts unchanged (no double-claim). - [ ] Epic 7 Slice 2 AC satisfied in Godot.