9.8 KiB
E7.M1 — QuestStateMachine
Summary
| Field | Value |
|---|---|
| Module ID | E7.M1 |
| Epic | Epic 7 — Quest / Faction |
| Stage target | Prototype |
| Status | Planned — Slice 1 backlog E7M1-prototype-backlog.md: E7M1-01 NEO-112 catalog landed (schemas + CI); E7M1-02 NEO-113 server load landed; E7M1-03 NEO-114 registry landed; E7M1-04 NEO-115 HTTP read landed; E7M1-05 NEO-116 player quest state store landed; E7M1-06 NEO-117 QuestStateOperations landed; E7M1-07 NEO-118 QuestObjectiveWiring landed; E7M1-08 NEO-119 per-player GET landed; E7M1-09 NEO-120 accept POST landed; E7M1-10 NEO-121 telemetry hooks landed; client from E7M1-11 NEO-122 → capstone E7M1-12 NEO-123 |
| Linear | Label E7.M1 · E7M1-prototype-backlog.md |
Purpose
Data-driven quest lifecycle: start, step progression, branching, failure/reset, and completion with durable persistence. Integrates crafting and combat outcomes so guided content ties together gather–craft–combat loops without duplicate rewards.
Scope / party: Per-character state by default; optional party credit and turn-in rules via QuestDef and E8.M1.
Responsibilities
- Load and interpret
QuestDef; trackQuestStepStateper character; synchronize party-credit advances per quest_scope_and_party.md. - Apply
QuestStateTransitionrules for advance, abandon, fail, and complete. - Invoke or subscribe to E3.M2 and E5.M1 (or their events) for step completion predicates.
Key contracts
| Contract | Role |
|---|---|
QuestDef |
Steps, prerequisites, objectives, and branching metadata. |
QuestStepState |
Current step progress and internal flags. |
QuestStateTransition |
Valid transitions and side effects (before E7.M2 reward routing). |
Module dependencies
- E3.M2 — RefinementAndRecipeExecution: craft completion, item hand-ins, refine steps.
- E5.M1 — CombatRulesEngine: defeat objectives, encounter-linked steps.
Dependents (by design)
- E7.M2 — RewardAndUnlockRouter: idempotent delivery after completion.
- E7.M3 — FactionReputationLedger: reputation-gated content (pre-production).
- E5.M3 — EncounterAndRewardTables: encounter completion and quest credit.
- E6.M4 — RewardParityEnforcer: quest/PvP reward alignment.
Related implementation slices
See Epic 7 Slice 1 — Quest core and persistence: 3–5 onboarding quests plus one chain across gather/craft/combat; telemetry quest_start, quest_step_complete, quest_complete, funnel times.
Linear backlog (decomposed)
Full story tables, kickoff defaults, and blockedBy graph: E7M1-prototype-backlog.md.
| Slug | Linear |
|---|---|
| E7M1-01 | NEO-112 |
| E7M1-02 | NEO-113 |
| E7M1-03 | NEO-114 |
| E7M1-04 | NEO-115 |
| E7M1-05 | NEO-116 |
| E7M1-06 | NEO-117 |
| E7M1-07 | NEO-118 |
| E7M1-08 | NEO-119 |
| E7M1-09 | NEO-120 |
| E7M1-10 | NEO-121 |
| E7M1-11 | NEO-122 |
| E7M1-12 | NEO-123 |
Prototype Slice 1 freeze (E7M1-01)
The first shipped quest spine is frozen for prototype tuning until a deliberate migration issue expands the roster.
QuestDef.id |
displayName |
prerequisiteQuestIds |
Steps (summary) |
|---|---|---|---|
prototype_quest_gather_intro |
Intro: Salvage Run | (none) | 1× gather_item: scrap_metal_bulk ×3 |
prototype_quest_refine_intro |
Intro: Refine Stock | prototype_quest_gather_intro |
1× craft_recipe: refine_scrap_standard ×1 |
prototype_quest_combat_intro |
Intro: Clear the Pocket | (none) | 1× encounter_complete: prototype_combat_pocket |
prototype_quest_operator_chain |
Operator Chain | prototype_quest_gather_intro, prototype_quest_refine_intro, prototype_quest_combat_intro |
4 steps: gather scrap_metal_bulk ×5 → craft refine_scrap_standard → craft make_field_stim_mk0 → inventory_has_item contract_handoff_token ×1 |
CI enforcement (NEO-112): scripts/validate_content.py requires exactly these four quest ids; objective cross-refs to frozen item/recipe/encounter catalogs; acyclic prerequisiteQuestIds; chain quest terminal step uses contract_handoff_token from E5.M3 encounter loot.
Server load (NEO-113): Host fail-fast load of content/quests/*_quests.json with the same gates — server README — Quest catalog.
HTTP read model (NEO-115): GET /game/world/quest-definitions — QuestDefinitionsWorldApi + DTOs in Game/Quests/ (NEO-115); server README — Quest definitions (NEO-115); Bruno bruno/neon-sprawl-server/quest-definitions/.
Player quest state store (NEO-116): IPlayerQuestStateStore — in-memory + Postgres (V008__player_quest_progress.sql) per-player rows keyed by (playerId, questId); implicit not_started when missing (NEO-116); server README — Quest progress store (NEO-116).
Quest state operations (NEO-117): QuestStateOperations — accept, step advance, complete with QuestStateReasonCodes; prerequisite gate on accept; idempotent complete at operations layer (NEO-117); server README — Quest state operations (NEO-117).
Quest objective wiring (NEO-118): QuestObjectiveWiring — gather/craft/encounter success hooks + inventory_has_item on accept/step advance/inventory mutations; auto advance/complete via QuestStateOperations (NEO-118); server README — Quest objective wiring (NEO-118).
Per-player quest progress GET (NEO-119): GET /game/players/{id}/quest-progress — QuestProgressApi + DTOs; registry + store merge; GET-side inventory_has_item refresh (NEO-119); server README — Per-player quest progress (NEO-119); Bruno bruno/neon-sprawl-server/quest-progress/.
Quest accept POST (NEO-120): POST /game/players/{id}/quests/{questId}/accept — QuestAcceptApi + DTOs; wires QuestStateOperations.TryAccept; structured accepted / reasonCode / optional quest row (NEO-120); server README — Quest accept POST (NEO-120); Bruno accept spine in bruno/neon-sprawl-server/quest-progress/.
Quest telemetry hooks (NEO-121): comment-only quest_start, quest_step_complete, quest_complete, quest_accept_denied hook sites in QuestStateOperations (NEO-121); server README — Quest telemetry hooks (NEO-121).
Reward policy (Slice 1): Quest completion updates QuestStepState only — no duplicate item/XP grants. Gather/craft/encounter paths keep existing payouts; E7.M2 adds QuestRewardBundle apply in Slice 2.
Risks and telemetry
- Scripting weight: keep
QuestDefdata-first; templates in decomposition/tooling path per epic. - Double-claim: design for idempotency before E7.M2; lint bundles vs E6.M4 / E3.M5.
- Epic 7 Slice 1 catalog events (comment-only until E9.M1):
quest_start,quest_step_complete,quest_complete,quest_accept_denied— anchored inQuestStateOperations(NEO-121).
Source anchors
- Master plan:
neon_sprawl_vision.plan.md— Core Epic Map, Epic 7. - Module dependency register