# NEO-86 — Manual QA checklist | Field | Value | |-------|-------| | Key | NEO-86 | | Title | E5M1-12: Playable tab-target combat capstone (Godot) | | Linear | https://linear.app/neon-sprawl/issue/NEO-86/e5m1-12-playable-tab-target-combat-capstone-godot | | Plan | `docs/plans/NEO-86-implementation-plan.md` | | Branch | `NEO-86-playable-combat-capstone` | ## Preconditions - **Fresh dev player:** stop any running server, then start a new instance so in-memory **`dev-local-1`** dummy HP and gig XP reset. - **No Bruno/curl seeding** for this checklist — hotbar pulse bind is automatic (NEO-85 dev bootstrap). - NEO-85 combat HUD and NEO-44 gig progression GET landed on the same branch or `main`. ## Combat math | Cast # | Expected `CastFeedbackLabel` | `CombatTargetHpLabel` | |--------|------------------------------|------------------------| | 1 | `Cast: 25 dmg → 75 HP` | `75/100` | | 2 | `Cast: 25 dmg → 50 HP` | `50/100` | | 3 | `Cast: 25 dmg → 25 HP` | `25/100` | | 4 | `Cast: 25 dmg → 0 HP — defeated!` | `0/100 (defeated)` | | 5 | `ability_cast_denied: target_defeated` | unchanged defeated | Respect ~3s **`prototype_pulse`** cooldown between casts. ## Checklist 1. Start server: `cd server/NeonSprawl.Server && dotnet run`. 2. Run Godot main scene (**F5**). Confirm **`Economy HUD`** toggle is **on**; **`GigXpLabel`** shows **`breach: L1 · 0 xp`** after boot hydrate. 3. Walk to orange **Dummy α** west of spawn **`(-3, -3)`** (flat lock ring on ground). 4. Press **Tab** to lock **`prototype_target_alpha`** — dummy **brightens**; **`CombatTargetHpLabel`** shows **`Target HP: prototype_target_alpha 100/100`** (or **`…`** briefly until GET completes). 5. Press **1** (hotbar slot 1 → index 0) four times with cooldown between hits. Verify cast feedback and HP label step per table above. 6. After the lethal hit, **`GigXpLabel`** updates to **`breach: L1 · 25 xp`** (event-driven GET refresh). 7. Press **1** again on the defeated dummy: **`CastFeedbackLabel`** shows **`ability_cast_denied: target_defeated`**; gig XP stays **25**. 8. Press **Esc** to clear lock: **`CombatTargetHpLabel`** shows **`Target HP: — (no lock)`**; combat feedback labels remain readable. 9. Uncheck **`Economy HUD`** — gig row hides with inventory/skills/recipes; check again — gig row repopulates. 10. Regression: cast without lock still shows **`ability_cast_denied: invalid_target`** on **`CastFeedbackLabel`** (NEO-28). ## Notes - Shared Postgres dev DB may retain prior gig XP totals — capstone baseline prefers **server restart** on in-memory mode. - Optional mid-session dummy-only reset (Development host): `POST /game/__dev/combat-targets-fixture` — see [NEO-85 manual QA](NEO-85.md). - Component-level combat HUD regression: [NEO-85 manual QA](NEO-85.md). ## Acceptance - [ ] Steps 1–10 completable in one session without Bruno/curl. - [ ] **`prototype_target_alpha`** shows defeated state in HUD after step 5. - [ ] **`breach`** gig XP **25** visible in Godot after step 6. - [ ] No silent cast failures — every deny shows readable reason on **`CastFeedbackLabel`**.