4.3 KiB
E7.M2 — RewardAndUnlockRouter
Summary
| Field | Value |
|---|---|
| Module ID | E7.M2 |
| Epic | Epic 7 — Quest / Faction |
| Stage target | Prototype |
| Status | Planned — Slice 2 backlog E7M2-prototype-backlog.md: E7M2-01 NEO-124 → E7M2-09 NEO-132. NEO-43 prep landed: MissionRewardSkillXpGrant for bundle skill XP (mission_reward). Upstream: E7.M1 Ready, E2.M2 grant stack, E3.M3 inventory. |
Purpose
Route quest and encounter outputs to XP, items, unlocks, and flags with idempotent delivery (E7.M1 completion, E2.M2, E3.M3). Party: Per-character idempotent grants when party credit completes multiple characters.
Responsibilities
- Apply
QuestRewardBundle; grantUnlockGrant; emitRewardDeliveryEventfor audit.
Key contracts
| Contract | Role |
|---|---|
QuestRewardBundle |
Composite rewards for a step or completion. |
UnlockGrant |
Blueprints, gates, cosmetics. |
RewardDeliveryEvent |
Idempotency key and outcome. |
Module dependencies
- E2.M2 — XpAwardAndLevelEngine.
- E3.M3 — ItemizationAndInventorySchema.
- E7.M1 — QuestStateMachine.
Dependents (by design)
- E5.M3 — EncounterAndRewardTables.
- E6.M4 — RewardParityEnforcer.
Related implementation slices
Epic 7 Slice 2 — reward_delivery, unlock_granted; no double-claim on replay. Backlog: E7M2-prototype-backlog.md.
Prototype Slice 2 freeze (E7M2-01)
completionRewardBundle on each frozen E7.M1 quest id. Grant kinds v1: itemGrants + skillXpGrants only (unlock/flag rows deferred). Skill XP apply uses mission_reward via MissionRewardSkillXpGrant — not stored in content rows.
| Quest id | Item grants (itemGrants) |
Skill XP (skillXpGrants) |
|---|---|---|
prototype_quest_gather_intro |
— | salvage 25 |
prototype_quest_refine_intro |
— | refine 25 |
prototype_quest_combat_intro |
— | salvage 25 |
prototype_quest_operator_chain |
survey_drone_kit ×1 |
salvage 50 |
Idempotency: {playerId}:quest_complete:{questId}. Encounter loot: E5.M3 direct grants unchanged in Slice 2.
CI enforcement (NEO-124): scripts/validate_content.py requires completionRewardBundle on all four frozen quest ids with exact freeze-table contents; cross-checks itemGrants[].itemId against the frozen item catalog and skillXpGrants[].skillId against skills that allow mission_reward in allowedXpSourceKinds.
Source anchors
- Master plan:
neon_sprawl_vision.plan.md— Epic 7. - Module dependency register
Implementation anchor (server)
NEO-43: When applying scripted skill XP from a mission/quest reward bundle, call MissionRewardSkillXpGrant.GrantFromMissionReward (server/NeonSprawl.Server/Game/Skills/) — fixed sourceKind: mission_reward, skillId and amount from reward data — NEO-43 implementation plan.
NEO-107 (E5.M3 producer hook): On encounter completion grant commit, EncounterCompletionOperations.TryCompleteAndGrant records EncounterCompleteEvent in IEncounterCompleteEventStore (idempotency key {playerId}:{encounterId}). Future E7.M2 QuestRewardBundle router consumes this record for reward_delivery quest credit beyond prototype contract_handoff_token item loot — comment-only hook stub; no runtime router yet. See NEO-107 implementation plan; server README — Encounter complete event (NEO-107).