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

7.8 KiB
Raw Permalink Blame History

E2.M1 — SkillDefinitionRegistry

Summary

Field Value
Module ID E2.M1
Epic Epic 2 — Skills and Progression Framework
Linear (Epic 2 project) Epic 2 — Classless Skill and Progression Framework
Stage target Prototype
Status In Progress (see dependency register)

Linear backlog (Epic 2 Slice 1)

Issues use label E2.M1. Dependency order: NEO-33 → NEO-34 → NEO-35 → NEO-36 (each issues description is canonical).

Order Issue Summary
1 NEO-33 Lock prototype SkillDef trio + CI catalog contract + designer note
2 NEO-34 Server loads catalog at startup (fail-fast)
3 NEO-35 SkillDefinitionRegistry service + lookup tests
4 NEO-36 Read-only skill catalog HTTP projection + Bruno

docs/plans/NEO-*-implementation-plan.md files should be added when implementation kicks off (per planning-implementation-docs).

Purpose

Central catalog for non-combat skill metadata: stable IDs, categories, allowed XP sources, and unlock prerequisites. All prototype activities reference skills by SkillDef.id validated against this registry. Combat role progression is not a SkillDef—use gig progression (docs/game-design/gigs.md).

Data contract (schema)

Artifact Path
JSON Schema content/schemas/skill-def.schema.json
Sample catalog content/skills/prototype_skills.json

SkillDef fields (prototype):

Field Rule
id Lowercase snake_case, immutable after ship. Used in saves, recipes, quests, XpGrantEvent.skillId, telemetry. Never rename to “fix” a skill—add a new id and migrate content if a skill splits.
category One of gather | process | make | tech — aligned with docs/game-design/skills.md roster buckets (not gigs).
displayName Player-facing string; may change without migrating progression data.
allowedXpSourceKinds Non-empty set of grant channels E2.M2 may apply to this skill. Combat encounters must not use skill XP—those award gig XP; mission_reward covers explicit mission/contract skill payouts.

allowedXpSourceKinds values:

Kind Meaning
activity Primary loop (e.g. gather node complete, recipe craft complete, skill-based world interaction)—callers set XpGrantEvent.sourceKind to match.
mission_reward Quest/contract hand-in or other scripted payout (docs/game-design/progression.md Mission rewards vs combat XP).
trainer NPC or teaching beat.
book_or_item Book, chip, training consumable, or similar one-shot grant.

Add new enum values only with a schema version / migration note in CT.M1 when CI enforces catalogs.

Designer note: allowedXpSourceKinds and grant call sites

Every SkillDef row must include a non-empty allowedXpSourceKinds array (enforced by JSON Schema). Designers use it to agree with engineering which systems may ever grant XP to that skill:

  • activity — wire gather nodes, recipe completions, skill-based world objectives, and similar primary-loop payouts; set XpGrantEvent.sourceKind (or successor) to activity on those code paths.
  • mission_reward — wire explicit mission/contract hand-ins or scripted bonuses only; not a stand-in for combat encounter XP (docs/game-design/progression.md — mission vs combat).
  • trainer / book_or_item — wire NPC teaching beats and consumable/one-shot grants respectively; do not use for combat kills.

Combat encounters award gig XP, not skill XP. If a grant channel is missing from a skills list, E2.M2 rejects the grant at apply time (NEO-38 HTTP grant path)—keep catalogs honest so call sites do not drift.

Prototype Slice 1 freeze (NEO-33)

The first shipped trio under content/skills/*.json is frozen for downstream references (quests, recipes, E2.M2, E3) until a deliberate migration or follow-up issue expands the roster.

SkillDef.id category Role
salvage gather Prototype Gather anchor
refine process Prototype Process anchor (satisfies “Process or Make” for Slice 1)
intrusion tech Prototype Tech anchor

Rules: Do not rename these id values to “fix” wording—change displayName only, or add a new id and migrate content. CI (scripts/validate_content.py) enforces exactly these three ids across all skill JSON files and category coverage (gather + tech + at least one of process/make). Relaxing or changing that gate belongs in a new Linear issue once the catalog intentionally grows.

Responsibilities

  • Load and validate SkillDef from data; expose SkillCategory and UnlockRequirement for gating.
  • Reject unknown skillId or XP grants whose sourceKind is not listed on the target skills allowedXpSourceKinds (enforced in E2.M2 at grant time).

Key contracts

Contract Role
SkillDef Per-skill metadata: id, category, displayName, allowedXpSourceKinds (+ future unlock fields).
SkillCategory gather | process | make | tech for UX and balance.
UnlockRequirement Prerequisites before XP or use counts apply.

Acceptance criteria (E2.M1 / Slice 1)

  • Every loaded SkillDef validates against skill-def.schema.json in CI (CT.M1scripts/validate_content.py in PR gate) or at server boot.
  • Duplicate id in a catalog fails validation.
  • Roster freeze for prototype: Slice 1 locks salvage, refine, and intrusion; their id values are stable—downstream content (recipes, quests) may reference them; changing an id requires a migration or new row.
  • Document for designers: each new skill row must declare allowedXpSourceKinds so engineers know which systems may grant XP (gather/craft hooks vs E7.M2 mission rewards only, etc.).

Module dependencies

  • None

Dependents (by design)

  • E2.M2 — XpAwardAndLevelEngine (primary): validates grants against allowedXpSourceKinds.

Epic 2 Slice 1 — skill registry and prototype non-combat skills; invalid references fail at load or in CI.

Source anchors