Files
suaveplan/openspec/changes/enterprise-gaming-progression/proposal.md
2026-05-27 23:29:53 +01:00

4.7 KiB
Raw Blame History

OpenSpec Change: enterprise-gaming-progression

  • Change ID: enterprise-gaming-progression
  • Package: @suaveplan/progression
  • Category: gaming/narrative
  • Target path: gaming/narrative/progression
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/progression.md

Summary

Deliver @suaveplan/progression on the genesis branch from scratch at enterprise quality. The package provides character progression with XP curves, skill trees, perks, and achievements. A ProgressionManager accumulates XP and triggers level-up events; an XpCurve computes required XP per level from configurable formulas (polynomial, exponential, flat table); a SkillTree represents an acyclic graph of SkillNode objects with prerequisite unlocking; a PerkRegistry holds passive modifiers unlockable at level milestones; an AchievementTracker monitors player statistics and fires unlock events. Genesis adds Zod schemas, structured errors, OTel XP counter, injectable clock, and 100% coverage.


Current-state audit (genesis)

Package does not exist on genesis yet — fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) ProgressionError; PROG.* codes
@suaveplan/types (workspace:^) Clock
@suaveplan/events (workspace:^) prog:level_up, prog:skill_unlocked, prog:perk_unlocked, prog:achievement
zod (catalog:forms) Skill tree + achievement schemas
@opentelemetry/api (catalog:observability) XP counter, level gauge

Public API surface

interface XpCurveOptions {
  formula: 'polynomial' | 'exponential' | 'table'
  base?: number
  coefficient?: number
  exponent?: number
  table?: number[]       // XP required per level (table formula)
}

function createXpCurve(options: XpCurveOptions): XpCurve
interface XpCurve {
  xpForLevel(level: number): number
  levelForXp(xp: number): number
}

function createProgressionManager(options: ProgressionManagerOptions): ProgressionManager

interface ProgressionManagerOptions {
  curve: XpCurve
  maxLevel?: number
  clock?: Clock
}

interface ProgressionManager {
  awardXp(playerId: string, amount: number, source?: string): void
  getLevel(playerId: string): number
  getXp(playerId: string): number
  getProgress(playerId: string): number   // 0–1 toward next level
}

// Skill tree
interface SkillNode {
  id: string
  name: string
  description: string
  cost: number            // skill points required
  prerequisites?: string[]
  effects?: SkillEffect[]
}

interface SkillEffect {
  stat: string
  modifier: number
  type: 'add' | 'multiply'
}

function createSkillTree(nodes: SkillNode[]): SkillTree
interface SkillTree {
  canUnlock(nodeId: string, unlockedIds: Set<string>, availablePoints: number): boolean
  unlock(nodeId: string, unlockedIds: Set<string>, availablePoints: number): Set<string>
  computeEffects(unlockedIds: Set<string>): Map<string, number>
}

// Achievements
interface AchievementDefinition {
  id: string
  title: string
  description: string
  condition: { stat: string; threshold: number; op: '>=' | '<=' | '==' }
}

function createAchievementTracker(definitions: AchievementDefinition[]): AchievementTracker
interface AchievementTracker {
  updateStat(stat: string, value: number): void
  incrementStat(stat: string, by?: number): void
  getUnlocked(): string[]
  isUnlocked(id: string): boolean
}

Error codes

type ProgErrorCode =
  | 'PROG_PLAYER_NOT_FOUND'
  | 'PROG_SKILL_NOT_FOUND'
  | 'PROG_PREREQUISITES_NOT_MET'
  | 'PROG_INSUFFICIENT_POINTS'
  | 'PROG_MAX_LEVEL_REACHED'

File layout

gaming/narrative/progression/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    constants/index.ts
    types/common.ts
    types/common.md
    core/
      xp-curve/
        xp-curve.ts
        xp-curve.md
        xp-curve.types.ts
        xp-curve.test.ts
        index.ts
      progression-manager/
        progression-manager.ts
        progression-manager.md
        progression-manager.types.ts
        progression-manager.test.ts
        index.ts
      skill-tree/
        skill-tree.ts
        skill-tree.md
        skill-tree.types.ts
        skill-tree.test.ts
        index.ts
      achievement-tracker/
        achievement-tracker.ts
        achievement-tracker.md
        achievement-tracker.types.ts
        achievement-tracker.test.ts
        index.ts
  tests/
    integration.test.ts

Impact

Downstream: @suaveplan/economy reads player level for pricing; @suaveplan/react-game-hud shows XP bar. Prerequisites: @suaveplan/error, @suaveplan/types, @suaveplan/events.