6.7 KiB
E2.M3 — Pre-production story backlog (MasteryAndPerkUnlocks)
Working backlog for Epic 2 — Slice 4 (mastery and pacing). Decomposition and contracts: E2.M3 — MasteryAndPerkUnlocks.
Labels (Linear): every issue E2.M3; add server / Feature as listed per issue.
Precursor (do not re-scope): skill level authority lives in E2.M2 (E2.M2 module); SkillDef ids from E2.M1. Gig perks are not SkillDef mastery.
Flagship skill: salvage (gather loop — NEO-41).
Linear issues (created): attach docs/plans/NEO-*-implementation-plan.md on the same branch as implementation work.
| Slug | Linear |
|---|---|
| E2M3-01 | NEO-45 |
| E2M3-02 | NEO-46 |
| E2M3-03 | NEO-47 |
| E2M3-04 | NEO-48 |
| E2M3-05 | NEO-49 |
Dependency graph in Linear: E2M3-02 blocked by E2M3-01. E2M3-03 blocked by E2M3-02 and NEO-38. E2M3-04 blocked by E2M3-03. E2M3-05 blocked by E2M3-03 (may parallel E2M3-04).
Story order (recommended)
| Order | Slug | Depends on |
|---|---|---|
| 1 | E2M3-01 | E2.M1 salvage SkillDef (NEO-33) |
| 2 | E2M3-02 | E2M3-01 |
| 3 | E2M3-03 | E2M3-02, NEO-38 (skill level) |
| 4 | E2M3-04 | E2M3-03 |
| 5 | E2M3-05 | E2M3-03 (parallel OK with E2M3-04) |
E2M3-01 — Prototype salvage mastery catalog + schemas + CI
Goal: Lock content shape and CI validation for one salvage MasteryTrack before any server load.
In scope
content/schemas/mastery-catalog.schema.json(or equivalent single-catalog schema).content/mastery/prototype_salvage_mastery.jsonwith tier 1 @ level 2 (scrap_efficiencyvsbulk_haul) and tier 2 @ level 4 perks.scripts/validate_content.pychecks: unknownskillId, duplicate perk ids, branch integrity.- Module doc designer note (mutually exclusive branches; no respec v1).
Out of scope
- Server loader, perk state, HTTP, client HUD.
Acceptance criteria
- PR gate validates mastery JSON against schema. (Done — NEO-45.)
- Only
salvagehas a track;refine/intrusionnot required. (Done — NEO-45.) - Stable
branchId/perkIddocumented in E2_M3 freeze box. (Done — NEO-45.)
E2M3-02 — Server mastery catalog load (fail-fast)
Goal: Disk → host: startup load of mastery catalog(s) with cross-check against ISkillDefinitionRegistry.
In scope
- Loader +
IMasteryCatalogRegistryunderserver/NeonSprawl.Server/Game/Skills/(orGame/Mastery/if split). - Fail-fast on malformed files, duplicate ids, unknown
skillId. - Unit tests (AAA) for loader happy path and failure modes.
Out of scope
- Per-player state, unlock logic, HTTP.
Acceptance criteria
- Server refuses boot when catalog invalid (mirror E2.M1 catalog behavior).
- Registry resolves track by
skillIdand perk metadata byperkId.
E2M3-03 — Perk unlock engine + PerkState persistence
Goal: Server-authoritative unlock evaluation from skill level + branch selection; persist PerkState; re-run on level-up.
In scope
IPlayerPerkStateStore(in-memory + Postgres + migration), mirroring skill progression stores.- Unlock engine: tier eligibility, mutually exclusive branch pick,
PerkUnlockEventemission. - Hook after
SkillProgressionGrantOperations(or dedicated service) on level-up for affectedskillId. - Integration/unit tests (AAA): eligibility, select branch, deny invalid pick.
Out of scope
- HTTP API, Bruno, client UI.
- Applying
effectKindin gather/craft/combat.
Acceptance criteria
- Player at salvage level 2 can select one tier-1 branch; other branch’s tier-1 perks stay locked.
- Level 4 unlocks tier-2 perks on the chosen branch path only.
- Stable
reasonCodeon deny (unknown tier, branch already chosen, level too low, etc.).
E2M3-04 — Perk state HTTP + Bruno
Goal: Versioned GET snapshot and POST branch selection for manual QA and future client.
In scope
GET /game/players/{id}/perk-state(path finalized in implementation plan).POSTbranch selection endpoint with structured success/deny payloads.- Bruno
bruno/neon-sprawl-server/perk-state/. server/README.mdsection; API tests (AAA).
Out of scope
- Godot HUD (optional future issue).
- Gameplay stat application.
Acceptance criteria
- GET returns unlocked perks + branch picks for prototype salvage track.
- POST select branch persists and matches engine rules from E2M3-03.
- Bruno exercises happy path + at least one deny case.
E2M3-05 — perk_unlock telemetry hook sites
Goal: Comment-only hooks in unlock / branch-select path for future E9.M1 catalog event perk_unlock.
In scope
- Hook placement in unlock engine (and POST path if applicable).
TODO(E9.M1)comments; no production logging.- README + module doc pointer.
Out of scope
- Telemetry ingest, dashboards.
Acceptance criteria
- Hook sites documented in code and
server/README.md. - Matches Epic 2 Slice 4 telemetry vocabulary.
After this backlog
- Track delivery in Linear; keep
blockedBylinks synchronized if scope changes. - For each issue kickoff, add
docs/plans/{NEO-XX}-implementation-plan.mdper story-kickoff. - Add
docs/manual-qa/{NEO-XX}.mdwhen HTTP surfaces land (E2M3-04+).