From dd2fef797de4e50b82281cc8139757bde29ab14d Mon Sep 17 00:00:00 2001 From: VinPropane Date: Fri, 3 Apr 2026 21:21:33 -0400 Subject: [PATCH] chore: align game-design docs, SkillDef schema, and docs review agent - Hybrid progression: encounter gig XP, mission skill rewards, Slice 3 split - SkillDef JSON Schema: stable id, gather/process/make/tech, allowedXpSourceKinds - Prototype skills: salvage, refine, intrusion; expand E2.M1/E2.M2 contracts - Add docs-review-agent rule, skills coherence review, AGENTS.md row - gigs/progression/overview/skills cross-links; explicit HTML anchors in skills.md --- .cursor/rules/docs-review-agent.md | 73 +++++++++++++++++++ AGENTS.md | 1 + content/README.md | 2 +- content/schemas/skill-def.schema.json | 30 +++++++- content/skills/prototype_skills.json | 21 +++--- .../epics/epic_02_classless_progression.md | 13 ++-- .../modules/E2_M1_SkillDefinitionRegistry.md | 48 ++++++++++-- .../modules/E2_M2_XpAwardAndLevelEngine.md | 12 +-- docs/game-design/gigs.md | 4 +- docs/game-design/overview.md | 2 +- docs/game-design/progression.md | 7 +- docs/game-design/skills.md | 11 ++- ...2026-03-31-game-design-skills-coherence.md | 60 +++++++++++++++ 13 files changed, 244 insertions(+), 40 deletions(-) create mode 100644 .cursor/rules/docs-review-agent.md create mode 100644 docs/reviews/2026-03-31-game-design-skills-coherence.md diff --git a/.cursor/rules/docs-review-agent.md b/.cursor/rules/docs-review-agent.md new file mode 100644 index 0000000..a62e746 --- /dev/null +++ b/.cursor/rules/docs-review-agent.md @@ -0,0 +1,73 @@ +--- +description: >- + Documentation review agent — coherence, links, and dev-guide fitness for docs/ + (especially game-design and decomposition). @docs-review-agent or ask for a + “docs review” / “review the design docs” using this persona. +globs: docs/**/* +alwaysApply: false +--- + +# Documentation review agent (Neon Sprawl) + +Use this rule when the user is working in **`docs/`** (design, decomposition, plans, architecture notes) and wants a **structured pass** over one or more documents: **coherence**, **cross-links**, **contradictions** with linked files, and **readiness to guide implementation** — not a quick skim. + +## Role + +- Act as a **tech writer + design lead**: trace **definitions**, **seams**, and **dependencies** across files the target doc cites or should cite. +- Be **specific** (path, section, table). Separate **blocking** (wrong or unsafe guidance), **should fix** (stale or confusing), and **nits**. +- Prefer **actionable** edits: suggest exact wording or file-level fixes; apply them only if the user asked to **fix** or **update** docs, not when they asked **review only**. + +## When this applies + +- **Primary:** `docs/game-design/**` — progression, skills, gigs, overview, brainstorm; any new vision artifact. +- **Also:** `docs/decomposition/**`, `docs/plans/**`, `docs/architecture/**` when the user is **connecting** design to implementation or reviewing doc drift. +- **Trigger:** User @-mentions this rule, asks for a **docs review**, **coherence check**, or **design-doc audit**, or has **`docs/**` files** in focus (see `globs`). + +## Ground truth (required to check) + +1. **Same folder and upstream links** — Read every `docs/...` link from the target doc(s); verify paths exist and headings match intent. +2. **Hybrid progression** — `docs/game-design/progression.md`, `skills.md`, `gigs.md`: **Gig** = combat role; **Skill** = non-combat; **Seams** live in `skills.md` unless a dedicated doc supersedes. **Combat encounters** → **gig XP** only (no default skill XP from the fight loop). **Mission/quest rewards** may still grant **skill XP** when explicitly defined—separate from the encounter **gig XP** path. +3. **Decomposition** — Map claims to `docs/decomposition/epics/` and `docs/decomposition/modules/` where relevant; flag **conflicts** (e.g. “combat skill” vs skills-as-non-combat). +4. **Plans** — If work maps to `docs/plans/`, check for **acceptance criteria** vs design doc (same spirit as [code-review-agent](code-review-agent.md) plan alignment). + +## Review checklist + +Work through what applies (skip irrelevant briefly). + +1. **Purpose** — Who is the reader (design, eng, production)? Is the doc scoped correctly? +2. **Definitions** — Terms (gig, skill, seam, category) consistent with `progression.md` / `skills.md`. +3. **Internal coherence** — Tables, decisions log, and body text agree; roster counts vs prose if stated. +4. **Cross-doc coherence** — Linked files don’t contradict; flag **stale** epics or slices. +5. **Implementation hooks** — IDs, modules (E2.M1, …), open vs agreed; what’s missing for tickets. +6. **Links & anchors** — Broken paths; fragile `#anchors` (prefer stable HTML `id` where needed). +7. **Next steps** — Obvious follow-up artifacts or epic/plan updates. + +## Review document (required) + +**Every** invocation must produce a **saved markdown file** under `docs/reviews/`, not only chat (same spirit as [code-review-agent](code-review-agent.md)). + +1. **Directory:** `docs/reviews/` (create if missing). +2. **Filename:** `YYYY-MM-DD-{slug}.md` — use session **Today’s date** when known; slug from topic or ticket (kebab-case). +3. **Preamble:** Date, **Scope** (paths or “full game-design pass”), **Base** branch or “as of date” if relevant. +4. **Body:** Use **Output format** below. For design reviews, use **Documentation checked** instead of only “plan + modules”: list each consulted path and **matches / partially matches / conflicts / N/A**. +5. **Commits:** Write the review file **uncommitted** unless the user asks to commit it. Follow [commit-and-review](commit-and-review.md) — no tool-attribution boilerplate in PR text. + +In the saved file, use **normal fenced code blocks** and **backtick paths** — not IDE line-number citations (GitHub-friendly). + +## Output format (required) + +1. **Verdict** — e.g. `Approve for vision`, `Approve with suggestions`, `Request doc updates`. +2. **Summary** — 2–5 sentences. +3. **Documentation checked** — Table or bullets: path → **matches** / **partially matches** / **conflicts** / **N/A**. +4. **Blocking issues** — Factual errors, unsafe guidance, broken contracts; empty if none. +5. **Suggestions** — Stale links, epic drift, missing seams references. +6. **Nits** — Optional. +7. **Verification** — What humans should re-read or grep after edits. + +**Chat:** Short summary + **path to** `docs/reviews/YYYY-MM-DD-{slug}.md`. + +## Boundaries + +- Do **not** skip writing `docs/reviews/…` unless the user explicitly asks for **chat-only** (then state that exception in chat and **do not** claim full agent output). +- Do **not** rewrite entire doc trees unless asked; review is default. +- **Skills / gigs:** treat `docs/game-design/skills.md` **Seams** as the **authoritative** gig↔skill boundary unless superseded by a newer ADR or epic decision. diff --git a/AGENTS.md b/AGENTS.md index e4552f9..9bdc9f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,6 +5,7 @@ Optional **personas** for Cursor. Enable by **@ mentioning** the rule in chat or | Agent | Rule file | When to use | |--------|-----------|-------------| | **Code review** | [`.cursor/rules/code-review-agent.md`](.cursor/rules/code-review-agent.md) | PR / diff / pre-merge review; **always writes** `docs/reviews/YYYY-MM-DD-{slug}.md` with **Documentation checked** vs `docs/plans/` and `docs/decomposition/modules/`; short chat pointer | +| **Docs review** | [`.cursor/rules/docs-review-agent.md`](.cursor/rules/docs-review-agent.md) | Coherence / links / dev-guide fitness for `docs/` (especially `docs/game-design/` + decomposition); **writes** `docs/reviews/YYYY-MM-DD-{slug}.md`; use when working in **documents** or @ mention | Project-wide conventions live under [`.cursor/rules/`](.cursor/rules/) (many are `alwaysApply`). **Godot client layout** (thin `main.gd`, split by concern): [`.cursor/rules/godot-client-script-organization.md`](.cursor/rules/godot-client-script-organization.md). **PR / push text:** no “Made-with: Cursor” boilerplate — [`.cursor/rules/commit-and-review.md`](.cursor/rules/commit-and-review.md). diff --git a/content/README.md b/content/README.md index a16b047..f286bb1 100644 --- a/content/README.md +++ b/content/README.md @@ -5,6 +5,6 @@ Data-driven definitions (skills, items, recipes, quests) validated in CI with ** | Path | Purpose | |------|---------| | [`schemas/`](schemas/) | JSON Schema files (`*.schema.json`) | -| [`skills/`](skills/) | Skill catalogs and related tables | +| [`skills/`](skills/) | Skill catalogs; each row matches [`schemas/skill-def.schema.json`](schemas/skill-def.schema.json) — **stable `id`**, **`allowedXpSourceKinds`** for [E2.M1](../docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md) / [E2.M2](../docs/decomposition/modules/E2_M2_XpAwardAndLevelEngine.md) | Server load path and hot-reload policy are TBD; keep files versioned here as the source of truth. diff --git a/content/schemas/skill-def.schema.json b/content/schemas/skill-def.schema.json index 9a21a8d..5a2058d 100644 --- a/content/schemas/skill-def.schema.json +++ b/content/schemas/skill-def.schema.json @@ -2,18 +2,40 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://neon-sprawl.local/schemas/skill-def.json", "title": "SkillDef", + "description": "Single skill row for catalogs (e.g. content/skills/*.json). IDs are stable forever—rename display in displayName only. See docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md.", "type": "object", "additionalProperties": false, - "required": ["id", "category", "displayName"], + "required": ["id", "category", "displayName", "allowedXpSourceKinds"], "properties": { "id": { "type": "string", - "pattern": "^[a-z][a-z0-9_]*$" + "pattern": "^[a-z][a-z0-9_]*$", + "description": "Immutable skill key for saves, recipes, quests, telemetry, and XpGrantEvent.skillId. Never change after content ships; add a new id if the skill splits." }, "category": { "type": "string", - "enum": ["gathering", "crafting", "combat", "exploration", "utility", "social"] + "description": "Primary SkillCategory aligned with docs/game-design/skills.md (Gather / Process / Make / Tech).", + "enum": ["gather", "process", "make", "tech"] }, - "displayName": { "type": "string", "minLength": 1 } + "displayName": { + "type": "string", + "minLength": 1, + "description": "Player-facing label; safe to change without migrating character data." + }, + "allowedXpSourceKinds": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Which XpGrantEvent.sourceKind values may increase this skill. E2.M2 rejects grants outside this set. Combat encounters do not use skill XP—use gig progression instead.", + "items": { + "type": "string", + "enum": [ + "activity", + "mission_reward", + "trainer", + "book_or_item" + ] + } + } } } diff --git a/content/skills/prototype_skills.json b/content/skills/prototype_skills.json index bf55cbc..b6d3e9a 100644 --- a/content/skills/prototype_skills.json +++ b/content/skills/prototype_skills.json @@ -2,19 +2,22 @@ "schemaVersion": 1, "skills": [ { - "id": "gathering_scrap", - "category": "gathering", - "displayName": "Scrap Salvaging" + "id": "salvage", + "category": "gather", + "displayName": "Salvage", + "allowedXpSourceKinds": ["activity", "mission_reward"] }, { - "id": "crafting_engineering", - "category": "crafting", - "displayName": "Street Engineering" + "id": "refine", + "category": "process", + "displayName": "Refine", + "allowedXpSourceKinds": ["activity", "mission_reward", "trainer"] }, { - "id": "combat_ballistics", - "category": "combat", - "displayName": "Ballistics" + "id": "intrusion", + "category": "tech", + "displayName": "Intrusion", + "allowedXpSourceKinds": ["activity", "mission_reward", "book_or_item"] } ] } diff --git a/docs/decomposition/epics/epic_02_classless_progression.md b/docs/decomposition/epics/epic_02_classless_progression.md index 372a71b..4248073 100644 --- a/docs/decomposition/epics/epic_02_classless_progression.md +++ b/docs/decomposition/epics/epic_02_classless_progression.md @@ -49,7 +49,7 @@ Provide a data-driven classless progression layer: skill definitions, XP awards, ### Slice 1 - Skill registry and prototype skills -- Scope: E2.M1 with at least three skills (one gathering, one crafting, one combat) loaded from data. +- Scope: E2.M1 with at least three **non-combat** `SkillDef` rows loaded from data—e.g. aligned with **Gather**, **Process** or **Make**, and **Tech** as in [`docs/game-design/skills.md`](../../game-design/skills.md). **Combat role progression** is **gig**-scoped, not a `SkillDef` line (see [`docs/game-design/gigs.md`](../../game-design/gigs.md), [`docs/game-design/progression.md`](../../game-design/progression.md)). - Dependencies: None - Acceptance criteria: - All prototype activities reference skills by stable IDs. @@ -67,11 +67,12 @@ Provide a data-driven classless progression layer: skill definitions, XP awards, ### Slice 3 - XP award integration at activity sites -- Scope: Wire gathering (E3.M1), crafting (E3.M2), and combat (E5.M1) to invoke the E2.M2 award API so the three prototype skill lines gain XP from real play. -- Dependencies: E2.M2, E3.M1, E3.M2, E5.M1 (integration prerequisites; not part of the E2.M2 module dependency list). +- Scope: Wire **gathering** (E3.M1) and **crafting** (E3.M2) to the **E2.M2 skill XP** award API so prototype **`SkillDef`** lines gain XP from real play. Wire **combat** (E5.M1) to **gig XP only** ([`gigs.md`](../../game-design/gigs.md), [`progression.md`](../../game-design/progression.md))—**no** hook that maps **encounter resolution** to **skill** XP or a combat `SkillDef`. **Mission / quest reward** paths may still call the **skill** XP API when the **payout** explicitly includes skill XP (**not** the same as “combat trained this skill”). +- Dependencies: E2.M2, E3.M1, E3.M2, E5.M1 (integration prerequisites; not part of the E2.M2 module dependency list). Gig XP plumbing may live beside E2.M2 or under Epic 5—**split call sites** by progression type (skill vs gig). - Acceptance criteria: - - Visible XP and level-up feedback within first session from real gather/craft/combat actions. -- Telemetry hooks: `xp_grant`, `level_up`, time-to-first-level-up. + - Visible **skill** XP and skill level-up feedback within first session from real **gather/craft** actions. + - Visible **gig** XP and gig progression feedback from **combat** (main gig only, per game-design). +- Telemetry hooks: `xp_grant`, `level_up`, time-to-first-level-up for **skills**; gig progression hooks as agreed when gig model lands (e.g. `gig_xp_grant`, `gig_level_up`). ### Slice 4 - Mastery and pacing (pre-production) @@ -91,6 +92,6 @@ Provide a data-driven classless progression layer: skill definitions, XP awards, ## Definition of Done -- Prototype uses E2.M1 + E2.M2 for all three skill lines. +- Prototype uses E2.M1 + E2.M2 for three **non-combat** `SkillDef` lines (stable **`id`** + **`allowedXpSourceKinds`** per [E2.M1](../modules/E2_M1_SkillDefinitionRegistry.md)); **gig** progression for combat is separate. - Pre-production adds E2.M3/E2.M4 with documented tuning workflow. - Events align with baseline telemetry in master plan. diff --git a/docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md b/docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md index b492124..b9b97df 100644 --- a/docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md +++ b/docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md @@ -5,39 +5,75 @@ | Field | Value | |--------|--------| | **Module ID** | E2.M1 | -| **Epic** | [Epic 2 — Classless Progression](../epics/epic_02_classless_progression.md) | +| **Epic** | [Epic 2 — Classless progression](../epics/epic_02_classless_progression.md) | | **Stage target** | Prototype | | **Status** | Planned (see [dependency register](module_dependency_register.md)) | ## Purpose -Central catalog for skill metadata, category tags, and unlock prerequisites. All prototype activities reference skills by stable IDs validated against this registry. +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`](../../game-design/gigs.md)). + +## Data contract (schema) + +| Artifact | Path | +|----------|------| +| **JSON Schema** | [`content/schemas/skill-def.schema.json`](../../../content/schemas/skill-def.schema.json) | +| **Sample catalog** | [`content/skills/prototype_skills.json`](../../../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`](../../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](E2_M2_XpAwardAndLevelEngine.md) 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`](../../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](CT_M1_ContentValidationPipeline.md) when CI enforces catalogs. ## 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 skill’s `allowedXpSourceKinds` (enforced in [E2.M2](E2_M2_XpAwardAndLevelEngine.md) at grant time). ## Key contracts | Contract | Role | |----------|------| -| `SkillDef` | Per-skill metadata and references. | -| `SkillCategory` | Grouping for UX and balance. | +| `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`](../../../content/schemas/skill-def.schema.json) in CI ([CT.M1](CT_M1_ContentValidationPipeline.md)) or at server boot. +- **Duplicate `id`** in a catalog fails validation. +- **Roster freeze for prototype:** when Slice 1 locks three skills, their **`id`** values are treated as **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). +- **E2.M2** — XpAwardAndLevelEngine (primary): validates grants against `allowedXpSourceKinds`. ## Related implementation slices -Epic 2 **Slice 1** — skill registry and prototype skills; invalid references fail at load or in CI. +Epic 2 **Slice 1** — skill registry and prototype **non-combat** skills; invalid references fail at load or in CI. ## Source anchors +- Game design: [`docs/game-design/skills.md`](../../game-design/skills.md) — roster, **XP philosophy**, gig/skill boundary. - Master plan: [`neon_sprawl_vision.plan.md`](../../../neon_sprawl_vision.plan.md) — Epic 2. - [Module dependency register](module_dependency_register.md) diff --git a/docs/decomposition/modules/E2_M2_XpAwardAndLevelEngine.md b/docs/decomposition/modules/E2_M2_XpAwardAndLevelEngine.md index a75d636..85d5cae 100644 --- a/docs/decomposition/modules/E2_M2_XpAwardAndLevelEngine.md +++ b/docs/decomposition/modules/E2_M2_XpAwardAndLevelEngine.md @@ -11,11 +11,11 @@ ## Purpose -Central server-authoritative engine for classless skill progression: applying XP grants, resolving levels against data-driven curves, and emitting level-up events. Gathering, crafting, and combat integrate **as callers** of this API without being hard dependencies for implementing the engine itself (see Epic 2 Slice 2 vs Slice 3). +Central server-authoritative engine for **classless skill** progression: applying XP grants, resolving levels against data-driven curves, and emitting level-up events. **Gathering** and **crafting** integrate as callers for **skill** XP. **Combat encounters** advance **gigs** (gig XP), not `SkillDef` lines. **Mission rewards** may call this API for **skill** XP when the payout lists a skill grant. Callers are not hard dependencies for implementing the engine core (see Epic 2 Slice 2 vs Slice 3). ## Responsibilities -- Apply `XpGrantEvent` (or equivalent) per skill with validated skill references from [E2.M1](E2_M1_SkillDefinitionRegistry.md). +- Apply `XpGrantEvent` (or equivalent) per skill with validated **`skillId`** from [E2.M1](E2_M1_SkillDefinitionRegistry.md). Reject grants when **`sourceKind`** is not in the target `SkillDef.allowedXpSourceKinds`. - Resolve experience against `LevelCurve` / threshold tables. - Emit `LevelUpEvent` when thresholds are crossed. - Support data-driven curves; **reload policy:** [Data reload and telemetry operations policy](data_and_ops_policy.md#content-and-gameplay-data-reload) (boot load default; optional dev reload). @@ -24,17 +24,17 @@ Central server-authoritative engine for classless skill progression: applying XP | Contract | Role | |----------|------| -| `XpGrantEvent` | Structured XP award (skill id, amount, source, modifiers). | +| `XpGrantEvent` | Structured XP award: **`skillId`** (must exist in registry), **amount**, **`sourceKind`** (must appear in that skill’s **`allowedXpSourceKinds`**), optional modifiers. | | `LevelCurve` | Thresholds or formula per skill or global policy. | | `LevelUpEvent` | Notification for UI, unlocks, and downstream systems. | ## Module dependencies -- **E2.M1** — [SkillDefinitionRegistry](E2_M1_SkillDefinitionRegistry.md): `SkillDef`, categories, and validation of skill IDs. +- **E2.M1** — [SkillDefinitionRegistry](E2_M1_SkillDefinitionRegistry.md): `SkillDef`, categories, **allowedXpSourceKinds**, and validation of skill IDs. ## Dependents (by design) -- **E5.M1** — CombatRulesEngine: combat awards XP via integration (Epic 5 / Epic 2 slices). +- **E5.M1** — CombatRulesEngine: **gig XP** from combat (not `SkillDef` XP via E2.M2). - **E3.M1 / E3.M2** — Gathering and crafting award XP when wired in Slice 3. - **E7.M2** — RewardAndUnlockRouter routes quest rewards including XP through E2.M2. - **E2.M3 / E2.M4** — Mastery and pacing layers build on level/XP state (pre-production). @@ -42,7 +42,7 @@ Central server-authoritative engine for classless skill progression: applying XP ## Related implementation slices - **Epic 2 Slice 2 — XP engine (E2.M2 core)**: implement contracts and tests without requiring Epic 3 or 5 modules. -- **Epic 2 Slice 3 — XP award integration**: wire E3.M1, E3.M2, E5.M1 to the award API for three prototype skill lines. +- **Epic 2 Slice 3 — XP award integration**: E3.M1 / E3.M2 call the skill XP API with **`sourceKind`: `activity`** (where allowed per skill); E7.M2 / mission rewards use **`mission_reward`** (etc.) as configured; combat resolves **gig** progression separately from E2.M2. ## Risks and telemetry diff --git a/docs/game-design/gigs.md b/docs/game-design/gigs.md index ee17c1a..2c604fc 100644 --- a/docs/game-design/gigs.md +++ b/docs/game-design/gigs.md @@ -49,7 +49,7 @@ Names below are **v1** after a theme pass; abilities and lore can still rename a **Still open:** -- **Combat gear:** almost certainly **main-gig–restricted** for equip; sub feeds **abilities** only—confirm in content pass. +- **Combat gear:** **main-gig–restricted** for equip; sub feeds **abilities** only. **Seams** (equip / deploy / activation, crafting): [skills.md — Seams](skills.md#seams-gigs-skills). - **Consumables (passive amp):** **Agreed** — **sub-gig** counts. **Passive** gig-tagged bonuses (e.g. extra healing from a med item when you’re a medic-type gig) apply if **either** **main** or **sub** matches the item’s gig hook. **Open:** if **both** match, **stack vs. single best** vs. **main wins**—pick at balance pass. - **PvP:** **gig rules blocked** until we know **if** and **how much** PvP the game includes—see [PvE vs PvP](#pve-vs-pvp). - **UI:** two gig strips, sub ability styling, loadout summary for party—**open.** @@ -58,7 +58,7 @@ Names below are **v1** after a theme pass; abilities and lore can still rename a **Agreed:** **per-gig** level/XP (and later **mastery/perks** on that gig). No shared **combat rank** that levels every gig at once. **Maining every gig** on one character is allowed; **slow leveling** makes that a long-term goal ([skills.md](skills.md) seams). -**Agreed — gig XP award timing:** only the **main gig** earns **gig XP** from combat (and any other gig-level awards). The **sub-gig** earns **no** XP toward its own progression while equipped as sub—it only **reads** its stored level for ability unlocks. To level a gig you ran as sub, **swap** it to **main** at a hub and play with it primary. **UI** should make clear that **gig XP** (bars, flytext) applies to **main** only. +**Agreed — combat encounter → gig XP, not skill XP:** the **fight loop** (encounters, clears—however combat resolves) grants **gig XP** on the **main gig** only, not **`SkillDef` / skill** XP. **Missions** may still **reward skill XP** on **turn-in** or **bonus** objectives—that is a **separate** payout from **combat → gig XP**, data-defined per contract. **Agreed — gig XP award timing:** only the **main gig** earns **gig XP** from combat (and any other gig-level awards). The **sub-gig** earns **no** XP toward its own progression while equipped as sub—it only **reads** its stored level for ability unlocks. To level a gig you ran as sub, **swap** it to **main** at a hub and play with it primary. **UI** should make clear that **gig XP** (bars, flytext) applies to **main** only. **Open:** diff --git a/docs/game-design/overview.md b/docs/game-design/overview.md index 02cc6d9..ab3c89a 100644 --- a/docs/game-design/overview.md +++ b/docs/game-design/overview.md @@ -23,7 +23,7 @@ Neon Sprawl’s design work here starts from **concrete visions** of progression | Document | Focus | Notes | |----------|--------|--------| | [progression.md](progression.md) | Shared **gig + skill** vision, vocabulary, links | Start here for progression | -| [skills.md](skills.md) | Non-combat **skills**; seams; **v0 skill roster** by category | With [gigs.md](gigs.md) | +| [skills.md](skills.md) | Non-combat **skills**; seams; **v0 skill roster** by category | With [gigs.md](gigs.md); roster encodes **Hardshell** / **Softshell** / **Edgesmith** / **Rigging** equip vs **combat-deploy** rules ([Seams](skills.md#seams-gigs-skills)) | | [gigs.md](gigs.md) | **9-gig roster** (v1 cyberpunk names); hub, sub-gig, party | Recruitment **deferred**; PvP **open indefinite**; niche LFG **if** tool ships | | [brainstorm/hack-bodyguard-missions.md](brainstorm/hack-bodyguard-missions.md) | Split **skill** (hack) + **gig** (bodyguard) instances—idea capture | Brainstorm | | *(add rows as files land)* | | | diff --git a/docs/game-design/progression.md b/docs/game-design/progression.md index 0b94120..6a97168 100644 --- a/docs/game-design/progression.md +++ b/docs/game-design/progression.md @@ -2,7 +2,7 @@ Shared vision for **how characters grow** in Neon Sprawl: **combat** vs **everything else** use different systems that still live on **one avatar**. Detail docs: **[gigs.md](gigs.md)** (combat roles), **[skills.md](skills.md)** (non-combat skills and **gigs ↔ skills seams**). -**Implementation note:** [Epic 2 — Classless progression](../decomposition/epics/epic_02_classless_progression.md) (E2.M1–M4) still describes **skill** XP machinery in decomposition; **gig** XP/levels are **per gig**—module text should be updated when the gig data model is finalized. +**Implementation note:** [Epic 2 — Classless progression](../decomposition/epics/epic_02_classless_progression.md) (E2.M1–M4): **Slice 3** wires **gather/craft** to **skill** XP (E2.M2), **combat encounters** to **gig XP only**, and allows **mission reward** hooks to grant **skill** XP when scripted—**not** via the combat encounter pipe. **Gig** levels stay **per gig**; exact gig XP module ownership may sit beside E2.M2 or under Epic 5 until the gig data model is finalized. ## Vocabulary @@ -11,14 +11,15 @@ Use these terms in **design specs and tools** (fiction may say *job*, *contract* | Term | Means | |------|--------| | **Gig** | The **combat role** (combat “class”): kit, tuning band, party expectations. **Not** for crafting or gathering. | -| **Skill** | A **non-combat** trained capability only (gather, craft, intrusion loops, etc.). **Never** the combat gig. | +| **Skill** | A **non-combat** trained capability only (gather, craft, intrusion loops, etc.). **Never** the combat gig. **Combat encounters** do not grant skill XP by default—only **gig XP** on the **main gig** ([gigs.md](gigs.md)). | | **Sub-gig** | **Secondary gig** on the same loadout as **main**—limited cross-gig abilities ([gigs.md](gigs.md) **Main gig + sub-gig**). Not crafting identity. | ## Why hybrid - **Gigs** answer “what are you on **this fight**?”—readable roles, **hub swap**, cyberpunk **contract** fantasy, without alts for combat variety. -- **Skills** keep **economy and crafting** **classless**: anyone can raise gather/craft over time; “street doc” can mean high **medic fab** **skill** + rep, not only tonight’s gig. +- **Skills** keep **economy and crafting** **classless**: anyone can raise gather/craft over time; “street doc” can mean high **Medtech fab** **skill** + rep, not only tonight’s gig. - **Specialist fantasy:** a player can **under-invest in gigs** and still **mainline the game** through **skills**—top gatherer, crafter, or tech, with **lots of options** to explore. The **skill roster** is meant to **grow** over time; see [skills.md](skills.md) **Pillars** and **Skill roster**. +- **Mission rewards vs combat XP:** **Missions** (contracts, arcs, hand-ins) may **pay skill XP** as an explicit **reward**—separate from the **combat encounter** pipe. Default flow stays **fight → gig XP**; skill XP from an op is **“this job’s payout,”** not **“kills trained my fab skill.”** ## Where to read next diff --git a/docs/game-design/skills.md b/docs/game-design/skills.md index 157bb05..66c4250 100644 --- a/docs/game-design/skills.md +++ b/docs/game-design/skills.md @@ -50,15 +50,17 @@ New skills land here as **design + data** demand; a skill can sit in **multiple | **Gather** | Nodes, yields, field extraction | | **Process** | **Refine**; **Fab tech** (physical fab); **Data scrub** (data/firmware); **Synth-chem prep** (bio/chem); batch; intermediate goods | | **Make** | Finished goods, recipes, bench work—**Gunsmith**, **Edgesmith**, **Hardshell**, **Softshell**, **Rigging (gear)**, **Cybernetics**, **Medtech fab**, **Food synth**, etc. | -| **Tech** | Intrusion, netsec, counter-intrusion, electronics, signal—**not** combat gig kit | +| **Tech** | Intrusion, netsec, counter-intrusion, exploit dev, crypto & identity, electronics, signal—**not** combat gig kit | Optional **secondary category** for UI sorting only—**primary** category in data drives balance defaults. + + ### Skill roster (draft ideas by category) **v0 — for examination, not a commit list.** Each row is a **candidate skill** (or tight cluster we might merge). The tables below are a **solid opening roster**—on the order of **~20–26** names depending on how we **merge or split** clusters—and we **expect to add more** as we approach launch. A **wide** skill set is intentional: it gives design and live ops room to grow **loops**, **biomes**, and **specialist fantasies** without collapsing everything into a tiny tree. -Final roster needs **stable IDs**, **XP sources**, and **gig/skill boundary** checks (especially **Tech** vs combat netrunning). +Final roster needs **stable IDs**, **XP sources**, and **gig/skill boundary** checks (especially **Tech** vs combat netrunning). **Implementation:** [`content/schemas/skill-def.schema.json`](../../content/schemas/skill-def.schema.json) (`id`, `allowedXpSourceKinds`) + [E2.M1 — SkillDefinitionRegistry](../decomposition/modules/E2_M1_SkillDefinitionRegistry.md) acceptance criteria; prototype sample [`content/skills/prototype_skills.json`](../../content/skills/prototype_skills.json). Layout mirrors **[gigs.md](gigs.md) gig roster**: one **table per category**, **Skill** name plus **what it covers** and **open / merge** notes. @@ -169,6 +171,8 @@ Explicit **bonuses** when skill A + B cross a threshold vs **pure fiction** (“ | [gigs.md](gigs.md) | **Craft** combat gear with **skills**; **equip** with **gigs**—[Seams](#seams-gigs-skills) | | [brainstorm/hack-bodyguard-missions.md](brainstorm/hack-bodyguard-missions.md) | **Skill** lane in a group instance (idea only) | + + ### Open questions (skills-only) **Late-stage tuning (intentionally open):** **Failure XP**, **skill mastery respec**, and **cross-skill synergy** math are **not** commitments at this stage. They stay **open** until we understand **skills**, **gigs**, economy, and combat together—then we **fine-tune** in a later balance pass, not as immediate design blockers. See [Decisions log](#decisions-log) **Late-stage tuning**. @@ -202,6 +206,8 @@ Explicit **bonuses** when skill A + B cross a threshold vs **pure fiction** (“ - **Story:** journal or quest UI can separate **character / faction** threads from **gig** threads so players see which arc belongs to which gig. - Use **gig** / **skill** consistently in specs and tools; flavor text can vary. + + ## Decisions log | Topic | Direction | Status | @@ -236,6 +242,7 @@ Explicit **bonuses** when skill A + B cross a threshold vs **pure fiction** (“ | **Food synth** | **Make** skill **kept**—rations, street kitchens, food economy loops | Agreed | | **Gunsmith** vs **Edgesmith** | **Gunsmith** = firearms / ballistics; **Edgesmith** = **non-gun** melee, thrown (non-ballistic), stun batons, monowire-style—same craft/equip **Seams** as other **combat gear** | Agreed | | Gig XP award | **Main gig only**; **sub-gig** earns no XP—see [gigs.md](gigs.md) | Agreed | +| Mission reward skill XP | **Combat encounters** → **gig XP** only. **Skill XP** allowed when a **mission/contract** explicitly **rewards** it (hand-in, bonus)—**separate** payout from encounter **gig XP**, not “fighting levels a `SkillDef`” | Agreed | | Epic 2 doc split | Align modules when gig data model is chosen | TBD | ## Next artifacts diff --git a/docs/reviews/2026-03-31-game-design-skills-coherence.md b/docs/reviews/2026-03-31-game-design-skills-coherence.md new file mode 100644 index 0000000..625d75a --- /dev/null +++ b/docs/reviews/2026-03-31-game-design-skills-coherence.md @@ -0,0 +1,60 @@ +# Game design docs coherence review — skills + links + +**Date:** 2026-03-31 +**Scope:** `docs/game-design/skills.md` and connected game-design + decomposition references (no PR diff; full-document pass). +**Base:** `docs/game-design/` vision set as of this date. + +## Verdict + +**Approve for vision / pre-implementation guidance** — the hybrid **gig + skill** model, **Seams**, and **v0 skill roster** are internally coherent and usable to steer E2/E3/E5 work. **Epic 2** **Slice 1** (non-combat `SkillDef` trio) and **Slice 3** (encounters → **gig XP**, gather/craft → **skill** XP, **mission rewards** may grant **skill** XP) are aligned with game-design. + +## Summary + +`skills.md` is the strongest single artifact: clear **vocabulary**, **domains vs categories**, **roster tables**, **production chains**, **Seams** (combat gear, cybernetics, crafting, deployables, utility Rigging), **decisions log**, and **deferred late-stage tuning** (failure XP, respec, synergy). Linked docs (`progression.md`, `overview.md`, `gigs.md`, `README.md`) and **Epic 2** slices **1** and **3** align with **skills = non-combat**, **combat encounters = gig XP only** (mission **reward** skill XP stays a **separate** payout). + +Remaining gaps are **expected** for vision docs: stable skill IDs, per-recipe data tags, and **gig ↔ item** deploy matrices are not yet specified — call those out for implementation plans rather than blocking the design read-through. + +## Documentation checked + +| Path | Match vs skills.md / hybrid model | +|------|-----------------------------------| +| `docs/game-design/skills.md` | **N/A** (source reviewed) | +| `docs/game-design/progression.md` | **Matches** after **Medtech fab** naming alignment | +| `docs/game-design/overview.md` | **Matches** — index, rating vision, artifact table | +| `docs/game-design/gigs.md` | **Matches** — sub-gig **Combat gear** bullet now links to `skills.md` **Seams** | +| `docs/game-design/README.md` | **Matches** | +| `docs/decomposition/epics/epic_02_classless_progression.md` | **Matches** — **Slice 3**: gather/craft → E2.M2 **skill** XP; **encounters** → **gig** XP; **mission rewards** may grant **skill** XP (no combat `SkillDef` from encounters) | +| `docs/decomposition/epics/epic_03_crafting_economy.md` | **Not re-read in full** — `skills.md` “Where skills meet” cites E3; no contradiction spotted from skills side | +| `docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md` | **Matches** — schema + `allowedXpSourceKinds`, categories `gather`/`process`/`make`/`tech`, Slice 1 acceptance criteria | + +## Blocking issues + +None for **using the docs as design guidance**. (No incorrect security or authority claims found.) + +## Suggestions + +1. ~~**gigs.md — Combat gear:**~~ **Done** — sub-gig section links to `skills.md#seams-gigs-skills`. +2. ~~**epic_02 — Slice 3:**~~ **Done** — **encounters** → **gig XP only**; gather/craft → E2.M2 **skill** XP; **mission rewards** may grant **skill** XP explicitly (`progression.md`, `epic_02` Slice 3). +3. ~~**overview.md artifact table:**~~ **Done** — `skills.md` row notes **Hardshell** / **Softshell** / **Edgesmith** / **Rigging** equip vs combat-deploy + link to **Seams**. +4. ~~**Stable IDs + XP sources:**~~ **Done** — [`content/schemas/skill-def.schema.json`](../../content/schemas/skill-def.schema.json), [`content/skills/prototype_skills.json`](../../content/skills/prototype_skills.json), [E2.M1](../decomposition/modules/E2_M1_SkillDefinitionRegistry.md) + [E2.M2](../decomposition/modules/E2_M2_XpAwardAndLevelEngine.md); [`skills.md`](../game-design/skills.md) links. + +## Nits + +- ~~**Categories table (Tech):**~~ **Addressed** — row now includes exploit dev and crypto & identity. +- ~~**Anchor fragility:**~~ **Addressed** — `skills.md` uses explicit `` for **Skill roster**, **Open questions (skills-only)**, and **Decisions log** (same pattern as **Seams**). + +## Verification + +- Manually re-follow links from `skills.md` intro → `progression.md`, `gigs.md`, `overview.md`, `brainstorm/hack-bodyguard-missions.md`, E2/E3/E7 epics. +- After gig data model work: grep `docs/decomposition` for “combat skill” / “class” and align with hybrid vocabulary. + +## Follow-up (applied in this review pass) + +- `progression.md`: **medic fab** → **Medtech fab** (consistent with roster). +- `epic_02_classless_progression.md` **Slice 1** scope: **non-combat** trio aligned with `skills.md` / gigs hybrid (see commit). +- `skills.md`: **Tech** category row aligned with full Tech roster (exploit dev, crypto & identity). +- `gigs.md`: sub-gig **Combat gear** → link to `skills.md` **Seams**. +- `AGENTS.md`: **Docs review** agent row → `.cursor/rules/docs-review-agent.md`. +- **Combat XP rule:** `progression.md` + `epic_02` **Slice 3** — **encounters** → **gig XP only** (no combat `SkillDef`); **mission reward** skill XP is **separate**. +- `overview.md`: artifact table **skills.md** row — **Hardshell** / **Softshell** / **Edgesmith** / **Rigging** + **Seams** link. +- **SkillDef schema:** `content/schemas/skill-def.schema.json` + `prototype_skills.json`; E2.M1 / E2.M2 docs for **IDs** and **`allowedXpSourceKinds`**.