neon-sprawl/docs/decomposition/modules/E5_M3_EncounterAndRewardTab...

97 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# E5.M3 — EncounterAndRewardTables
## Summary
| Field | Value |
|--------|--------|
| **Module ID** | E5.M3 |
| **Epic** | [Epic 5 — PvE Combat](../epics/epic_05_pve_combat.md) |
| **Stage target** | Prototype |
| **Status** | In Progress — Slice 3 backlog [E5M3-prototype-backlog.md](../../plans/E5M3-prototype-backlog.md): **E5M3-01** [NEO-100](https://linear.app/neon-sprawl/issue/NEO-100) catalog + CI landed · **E5M3-02** [NEO-101](https://linear.app/neon-sprawl/issue/NEO-101) server load landed · **E5M3-03** [NEO-102](https://linear.app/neon-sprawl/issue/NEO-102) registries landed · **E5M3-04** [NEO-103](https://linear.app/neon-sprawl/issue/NEO-103) HTTP read landed · **E5M3-05** [NEO-104](https://linear.app/neon-sprawl/issue/NEO-104) progress + completion stores landed · **E5M3-06** [NEO-105](https://linear.app/neon-sprawl/issue/NEO-105) completion grants landed · **E5M3-07** [NEO-106](https://linear.app/neon-sprawl/issue/NEO-106) → **E5M3-12** [NEO-111](https://linear.app/neon-sprawl/issue/NEO-111) |
| **Linear** | Label **`E5.M3`** · [E5M3-prototype-backlog.md](../../plans/E5M3-prototype-backlog.md) **E5M3-01** [NEO-100](https://linear.app/neon-sprawl/issue/NEO-100) · **E5M3-02** [NEO-101](https://linear.app/neon-sprawl/issue/NEO-101) · **E5M3-03** [NEO-102](https://linear.app/neon-sprawl/issue/NEO-102) · **E5M3-04** [NEO-103](https://linear.app/neon-sprawl/issue/NEO-103) · **E5M3-05** [NEO-104](https://linear.app/neon-sprawl/issue/NEO-104) · **E5M3-06** [NEO-105](https://linear.app/neon-sprawl/issue/NEO-105) · **E5M3-07** [NEO-106](https://linear.app/neon-sprawl/issue/NEO-106) · **E5M3-08** [NEO-108](https://linear.app/neon-sprawl/issue/NEO-108) · **E5M3-09** [NEO-107](https://linear.app/neon-sprawl/issue/NEO-107) · **E5M3-10** [NEO-109](https://linear.app/neon-sprawl/issue/NEO-109) · **E5M3-11** [NEO-110](https://linear.app/neon-sprawl/issue/NEO-110) · **E5M3-12** [NEO-111](https://linear.app/neon-sprawl/issue/NEO-111) |
## Purpose
Encounter templates, completion criteria, and reward drop routing into items ([E3.M3](E3_M3_ItemizationAndInventorySchema.md)) and quest credit via [E7.M2 — RewardAndUnlockRouter](E7_M2_RewardAndUnlockRouter.md).
## Responsibilities
- Instantiate `EncounterDef`; roll `RewardTable`; emit `EncounterCompleteEvent` for downstream routers and parity checks.
## Key contracts
| Contract | Role |
|----------|------|
| `EncounterDef` | Spawns, objectives, completion rules. |
| `RewardTable` | Loot and currency references validated against item schema. |
| `EncounterCompleteEvent` | Completion signal for quests and telemetry. |
## Module dependencies
- **E5.M1** — CombatRulesEngine.
- **E5.M2** — NpcAiAndBehaviorProfiles (defeat targets).
- **E3.M3** — ItemizationAndInventorySchema.
- **E7.M2** — RewardAndUnlockRouter (quest credit consumer; prototype uses quest-token loot + hook stub).
## Dependents (by design)
- **E5.M4** — GroupCombatScaling.
- **E6.M4** — RewardParityEnforcer.
- **E7.M4** — ContractMissionGenerator.
## Related implementation slices
Epic 5 **Slice 3**`encounter_complete`, reward attribution once.
## Linear backlog (decomposed)
Full story tables, kickoff defaults, and **`blockedBy` graph:** [E5M3-prototype-backlog.md](../../plans/E5M3-prototype-backlog.md).
| Slug | Linear |
|------|--------|
| E5M3-01 | [NEO-100](https://linear.app/neon-sprawl/issue/NEO-100) |
| E5M3-02 | [NEO-101](https://linear.app/neon-sprawl/issue/NEO-101) |
| E5M3-03 | [NEO-102](https://linear.app/neon-sprawl/issue/NEO-102) |
| E5M3-04 | [NEO-103](https://linear.app/neon-sprawl/issue/NEO-103) |
| E5M3-05 | [NEO-104](https://linear.app/neon-sprawl/issue/NEO-104) |
| E5M3-06 | [NEO-105](https://linear.app/neon-sprawl/issue/NEO-105) |
| E5M3-07 | [NEO-106](https://linear.app/neon-sprawl/issue/NEO-106) |
| E5M3-08 | [NEO-108](https://linear.app/neon-sprawl/issue/NEO-108) |
| E5M3-09 | [NEO-107](https://linear.app/neon-sprawl/issue/NEO-107) |
| E5M3-10 | [NEO-109](https://linear.app/neon-sprawl/issue/NEO-109) |
| E5M3-11 | [NEO-110](https://linear.app/neon-sprawl/issue/NEO-110) |
| E5M3-12 | [NEO-111](https://linear.app/neon-sprawl/issue/NEO-111) |
## Prototype Slice 3 freeze (E5M3-01)
The **first shipped encounter + reward spine** is **frozen** for prototype tuning until a deliberate migration issue expands the roster.
| `EncounterDef.id` | `displayName` | `completionCriteria.kind` | `requiredNpcInstanceIds` | `rewardTableId` |
|-------------------|---------------|---------------------------|--------------------------|-----------------|
| **`prototype_combat_pocket`** | Prototype Combat Pocket | **`defeat_all_targets`** | **`prototype_npc_melee`**, **`prototype_npc_ranged`**, **`prototype_npc_elite`** | **`prototype_combat_pocket_clear`** |
| `RewardTable.id` | `fixedGrants` |
|------------------|---------------|
| **`prototype_combat_pocket_clear`** | **`scrap_metal_bulk` ×10**, **`contract_handoff_token` ×1** |
**CI enforcement (NEO-100):** `scripts/validate_content.py` requires **exactly** encounter id **`prototype_combat_pocket`** and reward table id **`prototype_combat_pocket_clear`**; **`requiredNpcInstanceIds`** set must match server **`PrototypeNpcRegistry`** (`prototype_npc_melee`, `prototype_npc_ranged`, `prototype_npc_elite`); **`fixedGrants`** item ids from frozen item catalog with **no duplicate `itemId` per table**, quantities **`scrap_metal_bulk` ×10**, **`contract_handoff_token` ×1**; encounter **`rewardTableId`** cross-ref. Keep **`PROTOTYPE_E5M3_*`** and **`PROTOTYPE_E5M2_NPC_INSTANCE_IDS`** in sync with this table and [NEO-101](https://linear.app/neon-sprawl/issue/NEO-101) server loader. Plan: [NEO-100 implementation plan](../../plans/NEO-100-implementation-plan.md).
**Payout policy:** Per-defeat **gig XP** stays on [NEO-44](../../plans/NEO-44-implementation-plan.md). Encounter complete grants **loot + quest token** **once** per player per encounter id. Full **E7.M2** quest credit routing consumes **`EncounterCompleteEvent`** (E5M3-09 hook stub).
## Implementation snapshot (NEO-101)
**Server catalog load landed ([NEO-101](https://linear.app/neon-sprawl/issue/NEO-101)):** fail-fast startup loaders under [`server/NeonSprawl.Server/Game/Encounters/`](../../../server/NeonSprawl.Server/Game/Encounters/) — `RewardTableDefinitionCatalogLoader` (after item catalog) then `EncounterDefinitionCatalogLoader` (after reward tables); CI-parity E5M3 gates in C#; eager DI resolve in `Program.cs`. Config + discovery: [server README — Reward table catalog](../../../server/README.md#reward-table-catalog-contentreward-tables-neo-101), [Encounter catalog](../../../server/README.md#encounter-catalog-contentencounters-neo-101). Plan: [NEO-101 implementation plan](../../plans/NEO-101-implementation-plan.md).
**Injectable registries landed ([NEO-102](https://linear.app/neon-sprawl/issue/NEO-102)):** `IEncounterDefinitionRegistry` + `IRewardTableDefinitionRegistry` + DI in `AddEncounterAndRewardCatalogs`; game/HTTP callers should inject registries, not catalog types. Plan: [NEO-102 implementation plan](../../plans/NEO-102-implementation-plan.md).
**HTTP read model landed ([NEO-103](https://linear.app/neon-sprawl/issue/NEO-103)):** **`GET /game/world/encounter-definitions`** — `EncounterDefinitionsWorldApi` + DTOs in `Game/Encounters/`; nested **`rewardTable`** summary via **`IRewardTableDefinitionRegistry`**. Plan: [NEO-103 implementation plan](../../plans/NEO-103-implementation-plan.md); [server README — Encounter definitions](../../../server/README.md#encounter-definitions-neo-103); Bruno `bruno/neon-sprawl-server/encounter-definitions/`.
**Progress + completion stores landed ([NEO-104](https://linear.app/neon-sprawl/issue/NEO-104)):** **`IEncounterProgressStore`** + **`IEncounterCompletionStore`** (in-memory) + **`EncounterProgressOperations`** — activation, order-independent defeat tracking, idempotent completion flag; combat/HTTP wiring deferred to NEO-106/108. Plan: [NEO-104 implementation plan](../../plans/NEO-104-implementation-plan.md); [server README — Encounter progress](../../../server/README.md#encounter-progress--completion-stores-neo-104).
**Completion + inventory grants landed ([NEO-105](https://linear.app/neon-sprawl/issue/NEO-105)):** **`EncounterCompletionOperations.TryCompleteAndGrant`** + **`EncounterCompleteEvent`** result payload — reward-table fixed grants via **`PlayerInventoryOperations`**, fail-closed inventory deny, idempotent completion mark; event persistence deferred to NEO-107. Plan: [NEO-105 implementation plan](../../plans/NEO-105-implementation-plan.md); [server README — Encounter completion](../../../server/README.md#encounter-completion--inventory-grants-neo-105).
## Source anchors
- Master plan: [`neon_sprawl_vision.plan.md`](../../../neon_sprawl_vision.plan.md) — Epic 5.
- [Module dependency register](module_dependency_register.md)