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

6.2 KiB
Raw Permalink Blame History

NEO-63 — Implementation plan

Story reference

Field Value
Key NEO-63
Title E3.M1: Interact path integration + registry expansion + Bruno
Linear https://linear.app/neon-sprawl/issue/NEO-63/e3m1-interact-path-integration-registry-expansion-bruno
Module E3.M1 — ResourceNodeAndGatherLoop · Epic 3 Slice 2 · backlog E3M1-07
Branch NEO-63-e3m1-interact-path-integration-registry-expansion-bruno
Precursors NEO-62GatherOperations + GatherResult (Done on story branch); NEO-41 — inline XP on interact (superseded)

Kickoff clarifications

Topic Question Agent recommendation Answer
New node anchors X/Z for beta, gamma, delta? Beta (18, 6), gamma (12, 0), delta (18, 0) — spread from alpha (12, 6) and terminal (0, 0), same radius 3. Adopted (no blocking questions at kickoff; user said begin).
Gather deny on interact Allowed: false + reasonCode vs NEO-41 silent success? Allowed: false + passthrough gather reasonCode per E3M1-07 backlog. Adopted.
InteractionResponse payload Extend with gather fields? Keep placeholder — verify via GET inventory / skill-progression (module doc). Adopted.

Goal, scope, and out-of-scope

Goal: Wire POST …/interact resource_node path to GatherOperations; register four prototype nodes; Bruno + manual QA for gather → inventory and depletion deny.

In scope: InteractionApi, PrototypeInteractableRegistry expansion, integration tests, Bruno, README, manual QA.

Out of scope: Godot HUD, gather HTTP route, telemetry hooks (NEO-64).

Acceptance criteria checklist

  • In-range interact on fresh node increases inventory quantity and salvage XP.
  • Depleted node returns node_depleted without inventory or XP change.
  • Terminal interact unchanged (no gather side effects).
  • Bruno documents happy path + depletion deny for at least one node.

Technical approach

  1. InteractionApi: On resource_node kind after range check, call GatherOperations.TryGather. Success → Allowed: true; deny → Allowed: false + ReasonCode from GatherResult. Remove NEO-41 inline SkillProgressionGrantOperations block.

  2. Registry: Add beta/gamma/delta ids + anchors (see kickoff table). GET …/interactables returns 5 rows (terminal + four nodes).

  3. Tests: New InteractionResourceNodeGatherIntegrationTests — inventory + XP success, depletion deny, terminal control, stub-registry deny. Update InteractablesWorldApiTests for four nodes. Trim NEO-41 XP-only defensive test (migrated to integration deny test). Fix SalvageActivityDeniedRegistryWebApplicationFactory for gather DI (items + resource nodes + inventory + instance stores).

  4. Bruno: Update alpha gather request; add gather → GET inventory; add depletion deny (pre-request 10 gathers).

  5. Docs: README interaction reason codes + gather subsection; E3.M1 module freeze table anchors; alignment + backlog checkboxes.

Files to add

Path Purpose
server/NeonSprawl.Server.Tests/Game/Interaction/InteractionResourceNodeGatherIntegrationTests.cs HTTP integration: inventory, XP, depletion, terminal, deny registry.
bruno/neon-sprawl-server/interaction/Post interact gather then get inventory.bru Happy path: interact + assert scrap in bag.
bruno/neon-sprawl-server/interaction/Post interact depleted node deny.bru Pre-loop 10 gathers on prototype_urban_bulk_delta (isolated from alpha requests earlier in collection); 11th node_depleted.
docs/manual-qa/NEO-63.md curl gather → inventory + depletion deny.
docs/plans/NEO-63-implementation-plan.md This plan.

Files to modify

Path Rationale
server/NeonSprawl.Server/Game/Interaction/InteractionApi.cs Delegate resource_node to GatherOperations; map denies.
server/NeonSprawl.Server/Game/Interaction/PrototypeInteractableRegistry.cs Three new node anchors + registry entries.
server/NeonSprawl.Server.Tests/Game/Interaction/InteractablesWorldApiTests.cs Assert 5 interactables + new anchor coords.
server/NeonSprawl.Server.Tests/Game/Interaction/InteractionResourceNodeGatherXpTests.cs Remove obsolete NEO-41 silent-deny test; keep terminal + XP smoke.
server/NeonSprawl.Server.Tests/Game/Interaction/SalvageActivityDeniedRegistryWebApplicationFactory.cs Full in-memory gather dependencies for deny test host.
bruno/neon-sprawl-server/interaction/Post interact prototype resource node gather.bru NEO-63 docs (inventory + XP via gather engine).
server/README.md Gather via interact; reason codes; four anchors.
docs/decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md Anchor coords; NEO-63 slice bullet.
docs/decomposition/modules/documentation_and_implementation_alignment.md E3.M1 row — NEO-63 landed.
docs/decomposition/modules/module_dependency_register.md E3.M1 note — E3M1-07 complete.
docs/plans/E3M1-prototype-backlog.md E3M1-07 checkboxes.

Tests

Test file What it covers
InteractionResourceNodeGatherIntegrationTests.cs Success: +1 scrap, +10 salvage XP. Depletion: 10 gathers then node_depleted. Terminal: no side effects. Stub registry: deny + no grants.
InteractablesWorldApiTests.cs 5 descriptors; beta/gamma/delta anchors.
InteractionResourceNodeGatherXpTests.cs Terminal + alpha XP smoke (regression).

Open questions / risks

Question / risk Agent recommendation Status
Branch stacks NEO-62 PR base includes gather engine commits until NEO-62 merges. adopted
Client world props Godot interactable_world_builder picks up new ids from GET; no scene edit required for server QA. deferred

None blocking.