neon-sprawl/docs/plans/NEO-123-implementation-plan.md

15 KiB
Raw Blame History

NEO-123 — Implementation plan

Story reference

Field Value
Key NEO-123
Title E7M1-12: Playable onboarding quest chain capstone (Godot)
Linear https://linear.app/neon-sprawl/issue/NEO-123/e7m1-12-playable-onboarding-quest-chain-capstone-godot
Module E7.M1 — QuestStateMachine · Epic 7 Slice 1 · backlog E7M1-12
Branch NEO-123-playable-onboarding-quest-chain-capstone
Client deps NEO-122 quest progress + accept HUD (Done); NEO-111 encounter clear capstone; NEO-75 economy loop; NEO-110 encounter HUD
Server deps NEO-112NEO-121 quest spine (landed on main)
Pattern Capstone integration — NEO-111 docs + manual QA primary; minimal gap-fill only if capstone QA fails on main
Blocked by NEO-122 (Done)
Server counterpart NEO-112NEO-121 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 mainNEO-111 precedent. Adopted — docs-primary
Capstone intro accept order Scripted order for three onboarding intros? Shift+Q catalog order: Q gather → Shift+Q combat → Shift+Q refine → Shift+Q operator chain — prototype_quest_combat_intro sorts before prototype_quest_refine_intro in defs order; matches quest_hud_controller.gd _find_first_eligible_quest_id(). Adopted — Shift+Q catalog order
Idempotency verification How to prove no duplicate quest completion on replay? Godot stop + F5 restart (server still running) + retry Q / Shift+Q on completed quests; HUD statuses unchanged — mirrors NEO-111. Adopted — Godot restart + duplicate accepts
NEO-122 relationship Supersede component QA? NEO-123 supersedes as Slice 1 capstone; keep NEO-122 as component-level regression (NEO-111 / NEO-110 pattern). Adopted (default; no kickoff question)

Additional defaults (no kickoff question — settled by backlog / precedent):

  • Session baseline: fresh server restart before Godot F5 — resets in-memory quest progress, inventory, encounter state, and resource-node depletion; zero Bruno/curl in main checklist.
  • Economy HUD: toggle on for craft/inventory verification (NEO-75 / NEO-122 precedent).
  • Server changes: none unless capstone QA exposes an authoritative bug (unlikely — covered by server quest tests).

Goal, scope, and out-of-scope

Goal: Prove Epic 7 Slice 1 acceptance in Godot: complete all four prototype quests (three onboarding intros + one four-step operator chain) without Bruno; satisfies vision quest loop gate and epic_07 Definition of Done.

In scope (from Linear + E7M1-12):

  • docs/manual-qa/NEO-123.md: numbered single-session capstone — fresh server restart; accept intros in Shift+Q catalog order; perform gather/craft/combat actions; verify prototype_quest_operator_chain completes when contract_handoff_token held; idempotency via Godot restart + duplicate accept keys.
  • client/README.md: End-to-end onboarding quest loop section — integration flow table; cross-links NEO-112NEO-122 and economy/combat capstones.
  • Module alignment (on story completion): update E7_M1 status, documentation_and_implementation_alignment.md E7.M1 row, module_dependency_register.md E7.M1 note, and E7M1-prototype-backlog.md E7M1-12 checkboxes; mark Epic 7 Slice 1 client capstone complete.
  • Integration fixes only if capstone QA fails on current main wiring (HUD refresh gap, eligible-accept edge case, chain step stall, idempotency breach, etc.).

Out of scope (from Linear + backlog):

  • E7.M2 reward bundles; faction reputation; quest VFX art.
  • Bruno-only verification as prototype-complete proof.
  • New server HTTP routes or Godot HUD features beyond NEO-122.
  • Eligible-quest picker redesign (catalog order is the documented contract for Slice 1).

Acceptance criteria checklist

  • Human completes docs/manual-qa/NEO-123.md with server + client.
  • Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay (idempotency steps pass).
  • Re-read epic_07 Definition of Done for prototype minimums.

Implementation reconciliation (shipped)

Manual QA: docs/manual-qa/NEO-123.md — passed (four-quest Godot capstone, Shift+Q catalog accept order, idempotency steps).

  • docs/manual-qa/NEO-123.md — single-session four-quest capstone with Shift+Q catalog accept order, material math, idempotency steps.
  • client/README.mdEnd-to-end onboarding quest loop (NEO-123) section with flow table and cross-links.
  • docs/manual-qa/NEO-122.md — catalog-order note + capstone cross-link; expected HUD table aligned with Shift+Q picker.
  • docs/plans/E7M1-prototype-backlog.md, E7_M1_QuestStateMachine.md, documentation_and_implementation_alignment.md, module_dependency_register.md — E7M1-12 landed; E7.M1 Ready; Epic 7 Slice 1 client capstone complete.
  • No integration code changes — docs-primary scope; server quest spine verified by existing quest API / wiring tests.

Technical approach

1. Capstone manual QA script (docs/manual-qa/NEO-123.md)

Preconditions: Stop any running server; start fresh (cd server/NeonSprawl.Server && dotnet run) so in-memory dev-local-1 quest progress, inventory, encounter progress, NPC HP, and resource-node depletion reset. Godot F5 with no prior curl/Bruno seeding. Economy HUD toggle on.

Quest catalog (frozen — content/quests/prototype_quests.json):

Quest id Display name Prerequisites Steps
prototype_quest_gather_intro Intro: Salvage Run none gather 3 scrap_metal_bulk
prototype_quest_combat_intro Intro: Clear the Pocket none encounter_complete prototype_combat_pocket
prototype_quest_refine_intro Intro: Refine Stock gather intro craft refine_scrap_standard ×1
prototype_quest_operator_chain Operator Chain all three intros gather ×5 → refine ×1 → make_field_stim_mk0 ×1 → inventory_has_item contract_handoff_token ×1

Accept key contract (NEO-122 / quest_hud_controller.gd):

Key Action
Q Accept prototype_quest_gather_intro
Shift+Q First catalog-order not_started quest with all prerequisiteQuestIds completed

HTTP defs catalog order (ordinal id): combat → gather → operator chain → refine. After gather intro completes, Shift+Q accepts combat (not refine). After combat completes, Shift+Q accepts refine. After all three intros complete, Shift+Q accepts operator chain.

Expected quest HUD progression (QuestProgressLabel):

Phase Action Expected HUD lines (high level)
Boot Godot F5 All four quests not started
Gather intro Q → gather 3 scrap (R at nodes) Salvage Run active → counter → completed
Combat intro Shift+Q → defeat ×3 NPCs (Tab + 1) Clear the Pocket activecompleted; encounter completed (3/3); loot includes contract_handoff_token
Refine intro Shift+Q → craft refine_scrap_standard Refine Stock activecompleted
Operator chain Shift+Q → chain steps Operator Chain active step 1…4completed when token held
Idempotency Godot restart + Q / Shift+Q All four remain completed; accept deny / no eligible quest

Material / action notes for script author:

  • Combat loot grants scrap_metal_bulk ×10 + contract_handoff_token ×1 (NEO-111) — satisfies chain terminal inventory_has_item once combat intro completes (token persists for chain step 4).
  • Chain step 1 requires 5 successful gathers while chain step 1 is active (objective counter; prior bag scrap does not substitute). Use NEO-75 anchor table (alpha +1, beta +2, gamma +3, delta +5).
  • Chain step 3 make_field_stim_mk0 needs 2 refined_plate_stock + 1 scrap — plan extra refine_scrap_standard crafts after combat loot if bag is short on plates.
  • Defeat order for combat pocket is flexible (NEO-111); script asserts 0/3 → completed (3/3) only.

Main checklist spine (to expand in docs/manual-qa/NEO-123.md):

  1. Start server + Godot F5; confirm four quests not started.
  2. Q accept gather intro; gather until Intro: Salvage Run: completed.
  3. Shift+Q accept combat intro; defeat three prototype NPCs; confirm encounter + combat intro completed and bag contains contract_handoff_token.
  4. Shift+Q accept refine intro; craft refine_scrap_standard; confirm refine intro completed.
  5. Shift+Q accept operator chain; complete steps 14 (gather ×5, refine, stim craft, token check); confirm Operator Chain: completed.
  6. Record final quest HUD snapshot (all four completed).
  7. Idempotency — Godot restart: stop Godot; F5 again without stopping server. Quest HUD still shows all four completed.
  8. Idempotency — duplicate accepts: Q on gather → denied — already_completed; Shift+Qno eligible quest (or deny on ineligible pick); HUD unchanged from step 6.
  9. Regression pointers: NEO-122 component HUD, NEO-111 encounter loot, NEO-75 economy craft.

2. Client README (client/README.md)

Add End-to-end onboarding quest loop (NEO-123) section after Quest progress + accept HUD (NEO-122), mirroring NEO-111 / NEO-75 capstone sections:

  • One-line Epic 7 Slice 1 capstone goal.
  • Flow table: fresh restart → Q gather → Shift+Q combat → Shift+Q refine → Shift+Q chain → four-step chain objectives → idempotency.
  • Cross-links: NEO-112 catalog, NEO-118 wiring, NEO-119/120 HTTP, NEO-122 HUD, NEO-75 economy, NEO-111 combat token.
  • Pointer to docs/manual-qa/NEO-123.md.

3. Module / backlog alignment (on land)

When capstone QA passes:

4. Integration fixes (conditional)

Run capstone QA on main (or branch with NEO-122 merged). If any step fails:

Symptom Likely fix surface
Quest HUD stale after gather/craft/defeat main.gd refresh hook or quest_hud_controller.gd
Chain step counter stuck Server wiring (unlikely) — file issue; client displays GET only
Token step not completing Verify encounter loot + quest GET refresh on encounter completed (NEO-110 belt-and-suspenders)
Shift+Q picks unexpected quest Document vs fix picker — out of scope unless script order is impossible

Document any fix in this plans Implementation reconciliation section and add regression note to manual QA.

Files to add

Path Purpose
docs/plans/NEO-123-implementation-plan.md This plan.
docs/manual-qa/NEO-123.md Single-session four-quest capstone checklist with idempotency + regression steps.

Files to modify

Path Rationale
client/README.md End-to-end onboarding quest loop (NEO-123) section with flow table and cross-links.
docs/manual-qa/NEO-122.md Cross-link to NEO-123 capstone; note intro accept order defers to capstone script.
docs/plans/E7M1-prototype-backlog.md E7M1-12 AC checkboxes when capstone lands.
docs/decomposition/modules/E7_M1_QuestStateMachine.md Module status Ready + capstone landed note on completion.
docs/decomposition/modules/documentation_and_implementation_alignment.md E7.M1 row: NEO-123 landed; Slice 1 complete.
docs/decomposition/modules/module_dependency_register.md E7.M1 Ready when capstone lands.

Conditional (only if capstone QA fails): client/scripts/main.gd, client/scripts/quest_hud_controller.gd, or related refresh wiring — minimal gap-fill; document paths in reconciliation.

Tests

Test file What it covers
(none planned) Docs-primary scope — server quest spine covered by QuestProgressApiTests, QuestAcceptApiTests, QuestObjectiveWiringTests, and content CI; client covered by NEO-122 GdUnit suites. Capstone proof is docs/manual-qa/NEO-123.md human QA.

If integration fixes land, add or extend GdUnit only when the fix introduces new client parse/refresh behavior worth locking (follow testing-expectations.md AAA layout).

Open questions / risks

Item Agent recommendation Status
NEO-122 manual QA step 6 (Shift+Q → refine) Capstone adopts catalog order (combat before refine); update NEO-122 cross-link note, not NEO-122 checklist retroactively unless user asks. adopted
Resource node depletion mid-session Script uses four anchors from NEO-75; fresh server gives enough total yield for intro + chain gathers. adopted
Chain step 4 before combat loot Script orders combat intro before chain accept; token in bag before chain step 4. adopted
Docs-only fails capstone Escalate to minimal client refresh fix in same story; record in reconciliation. deferred