119 lines
7.6 KiB
Markdown
119 lines
7.6 KiB
Markdown
# NEO-143 — Manual QA checklist
|
||
|
||
| Field | Value |
|
||
|-------|-------|
|
||
| Key | NEO-143 |
|
||
| Title | E7M3-11: Playable faction reputation + gate capstone (Godot) |
|
||
| Linear | https://linear.app/neon-sprawl/issue/NEO-143/e7m3-11-playable-faction-reputation-gate-capstone-godot |
|
||
| Plan | `docs/plans/NEO-143-implementation-plan.md` |
|
||
| Branch | `NEO-143-playable-faction-reputation-gate-capstone` |
|
||
|
||
## Preconditions
|
||
|
||
- **Fresh dev player:** stop any running server, then start a new instance so in-memory quest progress, faction standing, **`IRewardDeliveryStore`**, inventory, skill progression, encounter progress, NPC HP, and resource-node depletion reset.
|
||
- **No Bruno/curl** for this checklist — accept uses **Q** / **Shift+Q**; gameplay uses **R**, **Tab** + **1**, and Economy HUD **Craft** buttons only.
|
||
- NEO-133–NEO-142 faction spine and NEO-132 reward capstone landed on `main`.
|
||
- **`Economy HUD`** toggle **on** for inventory + skill verification.
|
||
|
||
## Faction + quest freeze (E7M3-01)
|
||
|
||
| Quest id | Display name | Rep grant on completion | Expected standing after |
|
||
|----------|--------------|-------------------------|-------------------------|
|
||
| `prototype_quest_operator_chain` | Operator Chain | **Grid Operators +15** (plus item/skill bundle — see NEO-132) | Grid Operators **15**, Rust Collective **0** |
|
||
| `prototype_quest_grid_contract` | Grid Contract | **Rust Collective +10** | Grid Operators **15**, Rust Collective **10** |
|
||
|
||
**Gate (component QA — not main capstone path):** accept **`prototype_quest_grid_contract`** at Grid Operators standing **0** with operator-chain prerequisite met ⇒ **`faction_gate_blocked`** with readable copy. Verified in [NEO-142](NEO-142.md) GdUnit (`client/test/faction_standing_hud_test.gd`) and optional dev fixture — organic Godot gameplay grants **+15** on operator-chain completion, so live capstone accept succeeds at standing **15**.
|
||
|
||
## Quest roster (five ids, catalog order)
|
||
|
||
| Quest id | Display name |
|
||
|----------|--------------|
|
||
| `prototype_quest_combat_intro` | Intro: Clear the Pocket |
|
||
| `prototype_quest_gather_intro` | Intro: Salvage Run |
|
||
| `prototype_quest_grid_contract` | Grid Contract |
|
||
| `prototype_quest_operator_chain` | Operator Chain |
|
||
| `prototype_quest_refine_intro` | Intro: Refine Stock |
|
||
|
||
**Shift+Q after operator chain:** only **`prototype_quest_grid_contract`** is eligible (**`not_started`**, prerequisite **`completed`**). Grid contract has one step — **`inventory_has_item`** **`survey_drone_kit` ×1** — satisfied from operator-chain reward; expect **`completed`** immediately on accept (no extra player action).
|
||
|
||
## Expected HUD progression
|
||
|
||
| Phase | `FactionStandingLabel` | `QuestProgressLabel` | `QuestRewardDeliveryLabel` |
|
||
|-------|------------------------|----------------------|----------------------------|
|
||
| Boot | Grid Operators **0**, Rust Collective **0** | Five quests **`not started`** | `Quest rewards:` / `—` |
|
||
| Operator chain **`completed`** | Grid Operators **15**, Rust Collective **0** | Four intros + operator chain **`completed`**; grid contract **`not started`** | Operator chain grants + **`Grid Operators +15 rep`** |
|
||
| Grid contract **`completed`** | Grid Operators **15**, Rust Collective **10** | All **five** **`completed`** | Grid Contract + **`Rust Collective +10 rep`** |
|
||
| Godot restart | Unchanged | All five still **`completed`** | `—` (transition-only) |
|
||
| Duplicate accepts | Unchanged | Unchanged | Unchanged |
|
||
|
||
## Checklist
|
||
|
||
Follow [NEO-132](NEO-132.md) steps **1–19** for the four-quest reward path (accept order, anchors, material math, reward + economy verification through operator chain). **Extend** with faction + fifth-quest steps below.
|
||
|
||
### Boot (faction baseline)
|
||
|
||
1. Start server: `cd server/NeonSprawl.Server && dotnet run`.
|
||
2. Run Godot main scene (**F5**). Confirm **`FactionStandingLabel`** shows **`Grid Operators: 0`**, **`Rust Collective: 0`**; **`QuestProgressLabel`** lists **five** quests all **`not started`**.
|
||
|
||
### Slice 2 reward path (inherit NEO-132)
|
||
|
||
3. Complete [NEO-132](NEO-132.md) steps **3–19** — four intros + operator chain with reward/economy checks at each completion.
|
||
|
||
### Faction standing after operator chain
|
||
|
||
4. Verify **`FactionStandingLabel`**: **`Grid Operators: 15`**, **`Rust Collective: 0`** — may lag reward label rep line by one faction-standing GET round-trip; confirm both within a moment after operator-chain completion.
|
||
5. Verify **`QuestRewardDeliveryLabel`** on operator-chain completion includes **`Grid Operators +15 rep`** (alongside item/skill lines).
|
||
6. Verify **`InventoryLabel`** still lists **`survey_drone_kit`**.
|
||
7. Verify **`QuestProgressLabel`**: grid contract **`not started`**; four prior quests **`completed`**.
|
||
|
||
### Grid contract accept + complete (faction-gated success path)
|
||
|
||
8. Press **Shift+Q** to accept **`prototype_quest_grid_contract`**. Verify **`QuestAcceptFeedbackLabel`** shows accept success (not **`faction_gate_blocked`**).
|
||
9. Verify **`Grid Contract: completed`** on **`QuestProgressLabel`** (instant complete — kit already held).
|
||
10. Verify **`QuestRewardDeliveryLabel`**: `Grid Contract` + **`Rust Collective +10 rep`**.
|
||
11. Verify **`FactionStandingLabel`**: **`Rust Collective: 10`** (Grid Operators still **15**).
|
||
|
||
### Capstone snapshot (record for idempotency)
|
||
|
||
12. **Record** final state:
|
||
- **`FactionStandingLabel`**: Grid Operators **15**, Rust Collective **10**
|
||
- **`QuestProgressLabel`**: all **five** quests **`completed`**
|
||
- **`SkillProgressionLabel`** / **`InventoryLabel`**: match NEO-132 step 20 totals
|
||
|
||
### Idempotency (no duplicate rep delivery)
|
||
|
||
13. **Godot restart:** stop Godot (**Shift+F5**); **F5** again **without** stopping the server.
|
||
14. Verify all five quests still **`completed`**; **`QuestRewardDeliveryLabel`** is **`—`** (transition-only).
|
||
15. Verify **`FactionStandingLabel`** counts **match step 12** exactly.
|
||
16. Press **Shift+Q**. Verify **`Quest accept: no eligible quest`** (or equivalent deny).
|
||
17. Verify faction standing and economy HUD counts **still match step 12** — no duplicate rep grants.
|
||
|
||
### Regression
|
||
|
||
18. Component faction HUD + gate deny: [NEO-142 manual QA](NEO-142.md) (GdUnit gate deny; optional dev fixture).
|
||
19. Slice 2 reward idempotency: [NEO-132 manual QA](NEO-132.md).
|
||
20. Slice 1 onboarding chain: [NEO-123 manual QA](NEO-123.md).
|
||
|
||
### Server AC (optional — not Godot gameplay)
|
||
|
||
```bash
|
||
cd /path/to/neon-sprawl && dotnet test NeonSprawl.sln \
|
||
--filter "FullyQualifiedName~ReputationOperationsTests|FullyQualifiedName~FactionGateOperationsTests|FullyQualifiedName~RewardRouterOperationsTests"
|
||
```
|
||
|
||
Expect all pass — auditable **`ReputationDelta`** apply + fail-closed gate evaluation. Content CI (`scripts/validate_content.py`) and server startup catalog cross-ref deny unknown faction ids at load (tamper fail-closed).
|
||
|
||
## Notes
|
||
|
||
- **Gate deny** is not exercised on the main capstone success path — see [NEO-142](NEO-142.md) step 6.
|
||
- Rep grants apply on quest **completion**, not accept; faction standing refreshes after in-session completion transition (NEO-142).
|
||
- Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper ([epic_07 Slice 3](../decomposition/epics/epic_07_quest_faction.md#slice-3---faction-ledger-pre-production)).
|
||
|
||
## Acceptance
|
||
|
||
- [ ] Steps 1–17 completable in one session without Bruno/curl.
|
||
- [ ] Operator chain grants Grid Operators **+15**; grid contract grants Rust Collective **+10** — visible on HUD.
|
||
- [ ] Faction-gated grid contract accept succeeds at standing **15** and completes with kit in bag.
|
||
- [ ] Godot restart + duplicate accepts leave faction standing unchanged (no double-claim).
|
||
- [ ] Epic 7 Slice 3 AC satisfied in Godot (gate deny regression via NEO-142; server AC via automated tests).
|