neon-sprawl/docs/manual-qa/NEO-111.md

91 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# NEO-111 — Manual QA checklist
| Field | Value |
|-------|-------|
| Key | NEO-111 |
| Title | E5M3-12: Playable encounter clear capstone (Godot) |
| Linear | https://linear.app/neon-sprawl/issue/NEO-111/e5m3-12-playable-encounter-clear-capstone-godot |
| Plan | `docs/plans/NEO-111-implementation-plan.md` |
| Branch | `NEO-111-playable-encounter-clear-capstone` |
## Preconditions
- **Fresh dev player:** stop any running server, then start a new instance so in-memory **`dev-local-1`** NPC HP, encounter progress, inventory, and gig XP reset.
- **No Bruno/curl** for this checklist — defeat chain uses Godot **Tab** + **1** only.
- NEO-110 encounter HUD, NEO-106 combat wiring, and NEO-108 encounter-progress GET landed on `main`.
- **`Economy HUD`** toggle **on** for inventory verification.
## Archetype reference (defeat order flexible)
| Archetype | Instance id | Marker | Pulses to defeat |
|-----------|-------------|--------|------------------|
| Melee | `prototype_npc_melee` | orange west **`(-3, -3)`** | 4 |
| Ranged | `prototype_npc_ranged` | purple SE **`(3, 3)`** | 4 |
| Elite | `prototype_npc_elite` | gold origin **`(0, 0)`** | 8 |
Player casts **`prototype_pulse`** (**25** damage, ~**3 s** cooldown). Defeat all three in **any order** — server tracks an order-independent subset.
## Expected encounter HUD progression
| After | `EncounterProgressLabel` | `EncounterCompleteLabel` |
|-------|--------------------------|---------------------------|
| Boot (no engagement) | `prototype_combat_pocket: not started (0/3)` | `Loot: —` |
| 1st NPC defeated | `prototype_combat_pocket: 1/3` | `Loot: —` |
| 2nd NPC defeated | `prototype_combat_pocket: 2/3` | `Loot: —` |
| 3rd NPC defeated | `prototype_combat_pocket: completed (3/3)` | `scrap_metal_bulk ×10` and `contract_handoff_token ×1` (display names when item defs loaded) |
| After Godot restart (idempotency) | still **`completed (3/3)`** | unchanged grant lines |
## Expected inventory after completion
On a fresh server restart the bag starts empty. After the third defeat, **`InventoryLabel`** should show at least:
| Item id | Quantity |
|---------|----------|
| `scrap_metal_bulk` | **10** |
| `contract_handoff_token` | **1** |
Record these quantities before idempotency steps.
## Expected gig XP after three defeats
**`GigXpLabel`** should show **`breach: L1 · 75 xp`** (NEO-44: **25** gig XP per defeat × **3**). No further gig XP increase during idempotency steps.
## Checklist
### Boot + encounter clear
1. Start server: `cd server/NeonSprawl.Server && dotnet run`.
2. Run Godot main scene (**F5**). Confirm boot lines: **`Encounter: … not started (0/3)`** and **`Loot: —`** on **`EncounterProgressLabel`** / **`EncounterCompleteLabel`** (combat HUD block, below **`PlayerCombatHpLabel`**).
3. Defeat **first** prototype NPC (any archetype): walk to marker, **Tab** lock, press **1** until **`Cast: … — defeated!`**. Verify **`EncounterProgressLabel`** shows **`1/3`** (may lag one GET behind cast — wait ~1 s).
4. Defeat **second** prototype NPC (either remaining archetype): lock, cast until defeated. Verify **`2/3`**.
5. Defeat **third** prototype NPC: lock, cast until defeated (**8** pulses for Elite). Verify **`completed (3/3)`** and **`EncounterCompleteLabel`** lists **`scrap_metal_bulk ×10`** and **`contract_handoff_token ×1`** (or raw ids if defs still loading).
6. Open **`Economy HUD`** body: **`InventoryLabel`** shows **`scrap_metal_bulk`** (**10**) and **`contract_handoff_token`** (**1**) without pressing **I** (auto-refresh on completion GET).
7. Verify **`GigXpLabel`** shows **`breach: L1 · 75 xp`**.
### Idempotency
8. **Record** inventory quantities for **`scrap_metal_bulk`** and **`contract_handoff_token`** from step 6.
9. **Godot restart (re-login):** stop Godot run (**Shift+F5** or stop button); **F5** again **without** stopping the server. After boot hydrate, verify **`EncounterProgressLabel`** still **`completed (3/3)`** and **`EncounterCompleteLabel`** grant lines unchanged.
10. Verify **`InventoryLabel`** quantities **match step 8** — no duplicate loot.
11. Lock a **defeated** NPC (**Tab** at its marker); press **1**. Verify **`CastFeedbackLabel`** shows **`ability_cast_denied: target_defeated`**; encounter HUD and inventory **unchanged** from steps 910.
12. Verify **`GigXpLabel`** still **`breach: L1 · 75 xp`** — no extra gig XP from idempotency casts.
### Regression
13. **`CastFeedbackLabel`** still shows readable deny reasons (NEO-28 / NEO-98).
14. Component encounter HUD detail: [NEO-110 manual QA](NEO-110.md). Component NPC combat: [NEO-98 manual QA](NEO-98.md).
## Notes
- Defeat order may differ from the archetype table — only **0/3 → 3/3** progression is asserted.
- Capstone baseline prefers **server restart** over mid-session fixture POST.
- **`POST /game/__dev/combat-targets-fixture`** is **out of scope** for idempotency — it clears encounter progress/completion alongside NPC HP reset ([server README — dev combat-target fixture](../../server/README.md#dev-combat-target-fixture-brunomanual-qa)).
- Slice 3 Epic AC: completing **`prototype_combat_pocket`** grants expected items + quest token **once** ([epic_05 Slice 3](../../decomposition/epics/epic_05_pve_combat.md#epic-5-slice-3)).
## Acceptance
- [x] Steps 114 completable in one session without Bruno/curl.
- [x] Progress label shows **1/3**, **2/3**, then **completed (3/3)** after three defeats (any order).
- [x] Loot label and inventory show **`scrap_metal_bulk` ×10** + **`contract_handoff_token` ×1**; quantities unchanged after Godot restart + defeated-NPC casts.
- [x] Epic 5 Slice 3 AC satisfied in Godot.