Files
2026-05-27 23:29:53 +01:00

160 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenSpec Change: enterprise-gaming-crafting
- **Change ID**: enterprise-gaming-crafting
- **Package**: `@suaveplan/crafting`
- **Category**: gaming/narrative
- **Target path**: `gaming/narrative/crafting`
- **Status**: PROPOSED
- **Date**: 2026-04-24
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/crafting.md`
---
## Summary
Deliver `@suaveplan/crafting` on the genesis branch from scratch at enterprise quality. The package provides recipe-based crafting with stations, material requirements, quality tiers, and crafting queues. A `RecipeRegistry` holds typed `RecipeDefinition` objects; `CraftingStation` manages a per-station craft queue with concurrent slot limits and duration timers; `QualityCalculator` computes output quality from input material quality and skill level. Genesis adds Zod recipe schemas, structured errors, OTel craft 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:^`) | `CraftingError`; `CRAFT.*` codes |
| `@suaveplan/types` (`workspace:^`) | `Clock`, `IdGenerator` |
| `@suaveplan/events` (`workspace:^`) | `craft:started`, `craft:complete`, `craft:failed` events |
| `zod` (`catalog:forms`) | `RecipeDefinition` schema |
| `@opentelemetry/api` (`catalog:observability`) | Craft completion counter |
---
## Public API surface
```ts
type QualityTier = 'poor' | 'normal' | 'fine' | 'superior' | 'masterwork'
interface Ingredient {
itemId: string
quantity: number
qualityMin?: QualityTier
}
interface RecipeDefinition {
id: string
name: string
stationType: string
ingredients: Ingredient[]
outputItemId: string
outputQuantity: number
craftTime: number // seconds
skillRequired?: number // 0–100
outputQualityBase?: QualityTier
}
function createRecipeRegistry(): RecipeRegistry
interface RecipeRegistry {
register(recipe: RecipeDefinition): void
get(id: string): RecipeDefinition | undefined
listByStation(stationType: string): RecipeDefinition[]
}
function createCraftingStation(options: StationOptions): CraftingStation
interface StationOptions {
type: string
maxSlots?: number // concurrent crafts, default 1
clock?: Clock
registry: RecipeRegistry
}
interface CraftingStation {
canCraft(recipeId: string, inventory: Map<string, number>): boolean
startCraft(recipeId: string, inventory: Map<string, number>, skill?: number): CraftJob
tick(dt: number): CompletedCraft[]
getQueue(): CraftJob[]
cancelJob(jobId: string): void
}
interface CraftJob {
jobId: string
recipeId: string
startedAt: number
duration: number
skill: number
}
interface CompletedCraft {
jobId: string
recipeId: string
outputItemId: string
quantity: number
quality: QualityTier
}
```
### Error codes
```ts
type CraftErrorCode =
| 'CRAFT_RECIPE_NOT_FOUND'
| 'CRAFT_MISSING_INGREDIENTS'
| 'CRAFT_STATION_FULL'
| 'CRAFT_SKILL_TOO_LOW'
| 'CRAFT_JOB_NOT_FOUND'
```
---
## New additions for genesis
1. **Quality calculator** — output quality = base + skill bonus; `masterwork` requires skill ≥ 90.
2. **Concurrent slot queue** — `maxSlots` allows parallel crafting at upgraded stations.
3. **Ingredient quality minimum** — recipe can require `qualityMin`; fails if inventory item below tier.
---
## File layout
```text
gaming/narrative/crafting/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
constants/index.ts
types/common.ts
types/common.md
core/
recipe-registry/
recipe-registry.ts
recipe-registry.md
recipe-registry.test.ts
index.ts
crafting-station/
crafting-station.ts
crafting-station.md
crafting-station.types.ts
crafting-station.test.ts
index.ts
utils/
quality-calculator.ts
quality-calculator.md
quality-calculator.test.ts
tests/
integration.test.ts
```
---
## Impact
**Downstream**: `@suaveplan/react-crafting` displays station queue and recipe list. Prerequisites: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`.