12 KiB
NEO-98 — Implementation plan
Story reference
| Field | Value |
|---|---|
| Key | NEO-98 |
| Title | E5M2-12: Playable NPC telegraph combat capstone (Godot) |
| Linear | https://linear.app/neon-sprawl/issue/NEO-98/e5m2-12-playable-npc-telegraph-combat-capstone-godot |
| Module | E5.M2 — NpcAiAndBehaviorProfiles · Epic 5 Slice 2 · backlog E5M2-12 |
| Branch | NEO-98-e5m2-12-playable-npc-telegraph-combat-capstone |
| Server deps | NEO-92 aggro + leash (Done); NEO-93 runtime state machine (Done); NEO-94 runtime snapshot GET (Done); NEO-95 NPC attack resolve + player combat HP (Done) |
| Client deps | NEO-97 telegraph HUD + archetype markers (Done); E5.M1 cast + combat-target HUD (NEO-85, NEO-86) (Done) |
| Pattern | Capstone integration — NEO-86 docs + manual QA primary; minimal client gap-fill only if capstone QA fails on main |
| Server counterpart | NEO-92–NEO-95 server spine; Bruno-only verification is not prototype-complete per full-stack epic decomposition |
Kickoff clarifications
| Topic | Question | Agent recommendation | Answer |
|---|---|---|---|
| Implementation scope | Docs-only vs client code? | Docs + manual QA primary; fix integration gaps only if capstone QA fails on main — NEO-86 precedent. |
User: docs-primary; client fixes only if QA fails. |
| Session baseline | Fresh server vs fixture POST? | Fresh server restart before Godot F5 — resets NPC HP, aggro/runtime rows, and player combat HP (NEO-86 / NEO-97 precedent); zero Bruno/curl in main checklist. | User: fresh restart; no Bruno/curl in checklist. |
| Archetype order | Order in single-session script? | Melee → Ranged → Elite — matches E5M2-12 backlog goal prose (“aggro a melee NPC… defeat all three archetypes”). | User: melee → ranged → elite. |
| Verification depth | Full telegraph spine per archetype? | Full telegraph + player HP on Melee; Ranged + Elite defeat + telegraph visible with documented windup/cooldown — keeps one-session script tractable while satisfying Slice 2 AC. | User: melee full; ranged/elite light. |
| NEO-97 relationship | Supersede component QA? | NEO-98 supersedes as capstone; keep NEO-97 as component-level regression reference (NEO-85 / NEO-86 pattern). | Adopted (repo precedent; not asked). |
Goal, scope, and out-of-scope
Goal: Prove Epic 5 Slice 2 acceptance in Godot: aggro a melee NPC, observe readable telegraph timing before damage, take incoming NPC damage, defeat all three archetypes — without Bruno.
In scope (from Linear + E5M2-12):
docs/manual-qa/NEO-98.md: numbered single-session capstone script — fresh dev player, Melee → Ranged → Elite, zero Bruno/curl steps in the main checklist.client/README.md: End-to-end NPC telegraph combat loop section — integration checklist (boot → lock → cast → telegraph → player HP → defeat ×3); cross-links NEO-92–NEO-97.- Module alignment (on story completion): update
documentation_and_implementation_alignment.mdE5.M2 row + E5M2-12 backlog checkboxes; note Epic 5 Slice 2 client capstone complete. - Integration fixes only if capstone QA fails on current
mainwiring (unexpected deny, HUD refresh gap, poll gate, etc.).
Out of scope (from Linear + backlog):
- Encounters/loot (E5.M3), spawn ecology (E4.M2).
- Final VFX art, dodge mechanics, player death flow.
- Bruno-only verification as prototype-complete proof.
- New server APIs or behavior catalog changes.
Acceptance criteria checklist
- Human completes
docs/manual-qa/NEO-98.mdwith server + client; telegraph timing readable before damage on the melee spine. - Epic 5 Slice 2 AC: telegraph timing matches UI feedback; aggro rules feel deterministic in manual QA.
- All three archetypes defeated in one session;
CombatTargetHpLabelshows defeated for each. - Re-read epic_05 Definition of Done for prototype minimums.
Technical approach
1. Capstone manual QA script (docs/manual-qa/NEO-98.md)
Preconditions: Stop any running server; start fresh (dotnet run) so in-memory dev-local-1 NPC HP, aggro/runtime rows, and player combat HP reset. Godot F5 with no prior curl/Bruno seeding (hotbar prototype_pulse bind is automatic — NEO-85 dev bootstrap).
Frozen catalog math (from E5_M2 freeze box; player casts prototype_pulse 25 dmg, ~3 s cooldown):
| Archetype | Instance id | Marker | maxHp | Casts to defeat | attackDamage | windup | cooldown |
|---|---|---|---|---|---|---|---|
| Melee | prototype_npc_melee |
orange west (-3, -3) |
100 | 4 | 15 | 1.5 s | 3.0 s |
| Ranged | prototype_npc_ranged |
purple SE (3, 3) |
80 | 4 | 12 | 2.0 s | 4.0 s |
| Elite | prototype_npc_elite |
gold origin (0, 0) |
200 | 8 | 25 | 2.5 s | 5.0 s |
Melee full spine (telegraph + player HP):
- Walk to Melee marker; Tab lock
prototype_npc_melee—Validity: ok. - Press 1 (damaging cast):
NpcStateLabel→aggro(~1 Hz poll);PlayerCombatHpLabel→100/100. - Wait ≥ 4.5 s from first cast (3.0 s cooldown + 1.5 s windup):
NpcStateLabel→telegraph_windup;TelegraphLabelshows countdown (Telegraph: Melee … · ~1.x s (melee)) ticking between polls. - After windup completes:
PlayerCombatHpLabel→85/100(15 damage). - Press 1 three more times (respect cooldown) until
CombatTargetHpLabel→0/100 (defeated)and cast feedback shows defeat.
Ranged light (defeat + telegraph visible):
- Walk to Ranged marker; lock
prototype_npc_ranged. - First damaging cast → aggro; wait for
telegraph_windup+ readableTelegraphLabel(2.0 s windup after 4.0 s cooldown from first cast). - Cast until defeated (4 pulses); verify deny on re-cast (
target_defeated).
Elite light (defeat + telegraph visible):
- Walk to Elite marker; lock
prototype_npc_elite. - First damaging cast → aggro; wait for
telegraph_windup+ readableTelegraphLabel(2.5 s windup after 5.0 s cooldown). - Cast until defeated (8 pulses); verify deny on re-cast.
Regression spot-checks (end of session):
- Cast without lock →
ability_cast_denied: invalid_target(NEO-28). CombatTargetHpLabel+ cooldown HUD still work (NEO-85 / NEO-32).- Optional deeper telegraph/HP checks: NEO-97 manual QA (elite incoming-threat row).
Notes section (not main checklist steps):
- Optional mid-session reset (Development host):
POST /game/__dev/combat-targets-fixture— see NEO-97 / server README — dev fixture. - Capstone baseline prefers server restart over fixture POST.
2. README integration checklist
New ## End-to-end NPC telegraph combat loop (NEO-98) section after NEO-97 NPC runtime + telegraph HUD subsection in client/README.md:
- Flow in prose: fresh server → boot hotbar sync → Melee lock → cast → telegraph HUD → player HP drop → defeat → repeat Ranged + Elite.
- Table mirroring capstone steps (lock, telegraph labels, defeat cast counts).
- Cross-links: NEO-92 (aggro), NEO-94 (runtime snapshot), NEO-95 (player combat HP), NEO-97 (HUD poll clients).
- Pointer to
docs/manual-qa/NEO-98.mdas authoritative capstone script. - Note NEO-97 manual QA as component-level regression.
3. Module alignment (implementation batch or story end)
When acceptance criteria pass:
documentation_and_implementation_alignment.md: E5.M2 — note NEO-98 landed, Epic 5 Slice 2 client capstone complete.E5M2-prototype-backlog.md: E5M2-12 acceptance checkboxes + landed note.E5_M2_NpcAiAndBehaviorProfiles.md: E5M2-12 row + capstone cross-link if not already marked.
4. Integration fixes (conditional)
Run capstone dry-run on main before doc-only work; if any step fails, fix minimal client bug in this branch and note in plan Decisions. Expected path: docs + README only (NEO-97 HUD wiring landed in PR #136).
Files to add
| Path | Purpose |
|---|---|
docs/plans/NEO-98-implementation-plan.md |
This plan. |
docs/manual-qa/NEO-98.md |
Capstone single-session manual QA (zero Bruno/curl in main checklist). |
Files to modify
| Path | Rationale |
|---|---|
client/README.md |
End-to-end NPC telegraph combat loop section; capstone manual QA link; cross-links NEO-92–NEO-97. |
docs/decomposition/modules/documentation_and_implementation_alignment.md |
E5.M2 row — NEO-98 landed + Slice 2 client capstone complete (on story completion). |
docs/plans/E5M2-prototype-backlog.md |
E5M2-12 acceptance checkboxes + landed note (on story completion). |
docs/decomposition/modules/E5_M2_NpcAiAndBehaviorProfiles.md |
E5M2-12 capstone landed note + manual QA link (on story completion). |
Conditional (only if capstone QA fails on main):
| Path | Rationale |
|---|---|
client/scripts/main.gd |
Minimal HUD / poll / sync fix for failing capstone step. |
Other client scripts under client/scripts/ |
Only if root cause is outside main.gd (document in plan Decisions). |
Tests
| Path | Change |
|---|---|
| (none expected) | Capstone is docs + manual QA; NEO-97 GdUnit suites already cover poll clients, windup interpolation, and HUD helpers. |
If integration fix adds/changes client behavior: add or extend the smallest GdUnit test in the matching NEO-97 suite (npc_combat_hud_refresh_test.gd, etc.) — AAA layout per testing-expectations.md.
Manual verification: docs/manual-qa/NEO-98.md — server + Godot; melee telegraph spine + three-archetype defeat without curl.
Open questions / risks
| Question or risk | Agent recommendation | Status |
|---|---|---|
Capstone dry-run on main |
Run melee spine first before writing final QA copy; fix only if QA fails. | pending |
| Session length (elite ×8 casts) | Document cast counts + cooldown reminders; elite section is defeat + telegraph visibility only (kickoff depth decision). | adopted |
| Player HP drift across three fights | Script asserts melee 85/100 only; later archetype hits optional in Notes — do not require exact final HP in AC. | adopted |
| Overlap with NEO-97 manual QA | NEO-98 supersedes as capstone; NEO-97 stays component regression (elite incoming-threat row). | adopted |
| NEO-97 merge dependency | NEO-97 merged to main (PR #136) — capstone can proceed. |
adopted |