NEO-73: add manual QA and reconcile implementation plan.

Document gather HUD behavior in client README; mark E3S5-02 AC complete.
pull/107/head
VinPropane 2026-05-24 19:07:22 -04:00
parent aa013d4be7
commit adca7befe0
4 changed files with 54 additions and 7 deletions

View File

@ -82,7 +82,7 @@ If the server is **down**, boot **`GET`** fails silently (check Output for warni
On boot, **`InteractablesCatalogClient`** **`GET`s** **`/game/world/interactables`**; **`interactable_world_builder.gd`** spawns **walkable** prototype props plus **two** small glow markers per row under **`World/InteractionMarkers`**. **`interaction_radius_indicators.gd`** compares the snapped **`CharacterBody3D`** **`global_position`** to each descriptors **`anchor`** on **X/Z** with the same **`interactionRadius`** and inclusive **`<=`** rule as the server — **preview only**; **`POST /game/players/{id}/interact`** remains authoritative. On boot, **`InteractablesCatalogClient`** **`GET`s** **`/game/world/interactables`**; **`interactable_world_builder.gd`** spawns **walkable** prototype props plus **two** small glow markers per row under **`World/InteractionMarkers`**. **`interaction_radius_indicators.gd`** compares the snapped **`CharacterBody3D`** **`global_position`** to each descriptors **`anchor`** on **X/Z** with the same **`interactionRadius`** and inclusive **`<=`** rule as the server — **preview only**; **`POST /game/players/{id}/interact`** remains authoritative.
- **`InteractionRequestClient`**: **`interact`** (**E**) → **`prototype_terminal`**; **`interact_secondary`** (**R**) → **`prototype_resource_node_alpha`** (stable ids; must match `PrototypeInteractableRegistry.cs`). **Output** prints `allowed` / `reasonCode` per response (lines prefixed with `Interaction [<id>]: …`). Only one HTTP POST runs at a time; if you press **E** then **R** while the first request is still in flight, the **latest** id is remembered and sent **immediately after** the first completes (last-wins coalescing — not a silent drop). - **`InteractionRequestClient`**: **`interact`** (**E**) → **`prototype_terminal`**; **`interact_secondary`** (**R**) → **nearest in-range** **`resource_node`** from the interactables catalog (falls back to **`prototype_resource_node_alpha`** when none in range). **Output** prints `allowed` / `reasonCode` per response (lines prefixed with `Interaction [<id>]: …`). Only one HTTP POST runs at a time; if you press **E** then **R** while the first request is still in flight, the **latest** id is remembered and sent **immediately after** the first completes (last-wins coalescing — not a silent drop).
- **Inspector:** match **`base_url`** on **`InteractablesCatalogClient`**, **`InteractionRequestClient`**, and **`PositionAuthorityClient`** to the running server. - **Inspector:** match **`base_url`** on **`InteractablesCatalogClient`**, **`InteractionRequestClient`**, and **`PositionAuthorityClient`** to the running server.
- **No server:** catalog **GET** fails → **Output** errors; props and glow markers do not spawn (expected prototype degradation). - **No server:** catalog **GET** fails → **Output** errors; props and glow markers do not spawn (expected prototype degradation).
@ -144,6 +144,16 @@ Full checklist: [`docs/manual-qa/NEO-31.md`](../docs/manual-qa/NEO-31.md) · cas
Full checklist: [`docs/manual-qa/NEO-72.md`](../docs/manual-qa/NEO-72.md). Full checklist: [`docs/manual-qa/NEO-72.md`](../docs/manual-qa/NEO-72.md).
## Gather feedback on interact (NEO-73)
- **`POST /game/players/{id}/interact`** on **`resource_node`** kinds — server gather engine (NEO-63); no separate gather HTTP on client.
- **`GET /game/players/{id}/skill-progression`** — **`salvage`** row on **`SkillProgressionLabel`**; boot hydrate + refresh after successful gather.
- **Scripts:** `scripts/skill_progression_client.gd`, `scripts/prototype_interactable_picker.gd`; **`interaction_request_client.gd`** emits **`interaction_result_received`**; wired from `main.gd`.
- **HUD:** `UICanvas/GatherFeedbackLabel` — success delta **`+N {displayName}`** or deny **`Gather: denied — {reasonCode}`** (including **`node_depleted`**). **`InventoryLabel`** refreshes automatically on successful gather (no **I**).
- **R binding:** nearest in-range **`resource_node`** by horizontal distance to catalog anchors (same radius rule as glow preview).
Full checklist: [`docs/manual-qa/NEO-73.md`](../docs/manual-qa/NEO-73.md).
### Manual check (NEO-24) ### Manual check (NEO-24)
1. Run the server and client as in NEO-7 / NEO-9; confirm spawn snap at `(-5, 0.9, -5)`. 1. Run the server and client as in NEO-7 / NEO-9; confirm spawn snap at `(-5, 0.9, -5)`.

View File

@ -0,0 +1,29 @@
# NEO-73 — Manual QA checklist
| Field | Value |
|-------|-------|
| Key | NEO-73 |
| Title | E3.M1: Client gather feedback on interact (E3S5-02) |
| Linear | https://linear.app/neon-sprawl/issue/NEO-73/e3m1-client-gather-feedback-on-interact-e3s5-02 |
| Plan | `docs/plans/NEO-73-implementation-plan.md` |
| Branch | `NEO-73-e3m1-client-gather-feedback-on-interact` |
## Preconditions
- Server running with default dev player (`dev-local-1`); gather via interact landed (NEO-63); inventory HUD landed (NEO-72).
## Checklist
1. Start server: `cd server/NeonSprawl.Server && dotnet run`.
2. Run Godot main scene (**F5**). Confirm **`SkillProgressionLabel`** shows **`salvage: level …, xp …`** after boot (often **`level 1, xp 0`** on fresh player).
3. **WASD** to **`prototype_resource_node_alpha`** anchor **(12, 6)** until the resource glow pair brightens. Press **R** (do **not** press **I** first).
4. **`GatherFeedbackLabel`** shows **`Gather: +1 Scrap Metal (Bulk)`** (or agreed display name). **`InventoryLabel`** updates scrap quantity without manual refresh. **`SkillProgressionLabel`** **`salvage`** xp increases by **10**.
5. Walk to **`prototype_subsurface_vein_beta`** **(18, 6)**; press **R**. Feedback shows **`+2`** scrap delta; inventory and salvage xp update again.
6. Repeat at **`prototype_bio_mat_gamma`** **(12, 0)** (**+3**) and **`prototype_urban_bulk_delta`** **(18, 0)** (**+5**) if nodes still have capacity.
7. Deplete **`prototype_urban_bulk_delta`**: press **R** ten times while in range, then once more. **`GatherFeedbackLabel`** shows **`Gather: denied — node_depleted`** (inventory unchanged on last press — verify with **I** if needed).
8. Press **E** at terminal: **`GatherFeedbackLabel`** stays on last gather message (terminal does not overwrite gather line).
## Notes
- **R** posts the **nearest in-range** `resource_node` from the interactables catalog; walk to each anchor before pressing **R**.
- Output still prints **`Interaction [<id>]: …`** lines for dev debugging.

View File

@ -101,9 +101,9 @@ Working backlog for **Epic 3 — Slice 5** ([client economy integration](../deco
**Acceptance criteria** **Acceptance criteria**
- [ ] In-range interact on fresh node updates inventory HUD without manual refresh. - [x] In-range interact on fresh node updates inventory HUD without manual refresh.
- [ ] Depleted node shows **`node_depleted`** (or agreed copy) on HUD. - [x] Depleted node shows **`node_depleted`** (or agreed copy) on HUD.
- [ ] **Salvage** skill level or XP visible and changes after successful gather (Epic 2 Slice 3 visibility). - [x] **Salvage** skill level or XP visible and changes after successful gather (Epic 2 Slice 3 visibility).
--- ---

View File

@ -51,9 +51,17 @@ No other blocking decisions — **`node_depleted`** deny copy follows **`CastFee
## Acceptance criteria checklist ## Acceptance criteria checklist
- [ ] In-range interact on fresh node updates **inventory HUD** without manual **I** refresh. - [x] In-range interact on fresh node updates **inventory HUD** without manual **I** refresh.
- [ ] Depleted node shows **`node_depleted`** (or agreed copy) on **`GatherFeedbackLabel`**. - [x] Depleted node shows **`node_depleted`** (or agreed copy) on **`GatherFeedbackLabel`**.
- [ ] **Salvage** skill level/XP visible on **`SkillProgressionLabel`** and changes after successful gather. - [x] **Salvage** skill level/XP visible on **`SkillProgressionLabel`** and changes after successful gather.
## Implementation reconciliation (shipped)
- **Clients:** `skill_progression_client.gd`; `interaction_request_client.gd` emits **`interaction_result_received`** + **`post_interact_id`**.
- **Picker:** `prototype_interactable_picker.gd` — nearest in-range **`resource_node`** on **R** (alpha fallback).
- **HUD:** `GatherFeedbackLabel` (delta / deny); `SkillProgressionLabel` (salvage row); inventory auto-refresh on gather success.
- **Tests:** `skill_progression_client_test.gd`, `prototype_interactable_picker_test.gd`, `gather_feedback_refresh_test.gd`; extended `interaction_request_client_test.gd`.
- **Docs:** `client/README.md` gather section; [`NEO-73` manual QA](../manual-qa/NEO-73.md).
## Technical approach ## Technical approach