54 lines
3.0 KiB
Markdown
54 lines
3.0 KiB
Markdown
# 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`**.
|