182 lines
5.0 KiB
Markdown
182 lines
5.0 KiB
Markdown
# OpenSpec Change: enterprise-gaming-fauna
|
||
|
||
- **Change ID**: enterprise-gaming-fauna
|
||
- **Package**: `@suaveplan/fauna`
|
||
- **Category**: gaming/ai
|
||
- **Target path**: `gaming/ai/fauna`
|
||
- **Status**: PROPOSED
|
||
- **Date**: 2026-04-24
|
||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/fauna.md`
|
||
|
||
---
|
||
|
||
## Summary
|
||
|
||
Deliver `@suaveplan/fauna` on the genesis branch from scratch at enterprise quality. The package provides wildlife AI with herding behavior (Reynolds boids), predator-prey state machines, territorial zones, and taming mechanics. `HerdSimulator` runs separation/alignment/cohesion forces for a group of fauna instances; `PredatorPreyFsm` manages hunt/flee/rest state transitions; `TerritoryZone` defines a radius around a home position that triggers defend behavior when intruders enter; `TamingManager` tracks taming progress and trust state. Genesis adds Zod species definition schemas, structured errors, OTel population gauge, injectable clock and RNG, 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:^`) | `FaunaError`; `FAUNA.*` codes |
|
||
| `@suaveplan/types` (`workspace:^`) | `Clock`, `Rng` |
|
||
| `@suaveplan/events` (`workspace:^`) | `fauna:hunt`, `fauna:flee`, `fauna:tamed` events |
|
||
| `@suaveplan/npc` (`workspace:^`) | `SpawnPool` extended for wildlife instances |
|
||
| `@suaveplan/spatial-hash` (`workspace:^`) | Neighbor queries for boid steering |
|
||
| `zod` (`catalog:forms`) | `SpeciesDefinition` schema |
|
||
| `@opentelemetry/api` (`catalog:observability`) | Herd size gauge, hunt counter |
|
||
|
||
---
|
||
|
||
## Public API surface
|
||
|
||
```ts
|
||
interface SpeciesDefinition {
|
||
id: string
|
||
name: string
|
||
role: 'prey' | 'predator' | 'neutral'
|
||
maxSpeed: number
|
||
perception: number // detection radius (meters)
|
||
territory?: number // home territory radius
|
||
herds?: boolean
|
||
canBeTamed?: boolean
|
||
tamingDifficulty?: number // 1–10
|
||
}
|
||
|
||
// Boid herding
|
||
function createHerdSimulator(options: HerdOptions): HerdSimulator
|
||
|
||
interface HerdOptions {
|
||
separationRadius: number
|
||
alignmentRadius: number
|
||
cohesionRadius: number
|
||
separationWeight?: number
|
||
alignmentWeight?: number
|
||
cohesionWeight?: number
|
||
spatialHash?: SpatialHash3D
|
||
}
|
||
|
||
interface HerdSimulator {
|
||
update(agents: HerdAgent[], dt: number): HerdUpdate[]
|
||
}
|
||
|
||
interface HerdAgent {
|
||
id: string
|
||
position: Vec3
|
||
velocity: Vec3
|
||
}
|
||
|
||
interface HerdUpdate {
|
||
id: string
|
||
steering: Vec3 // force to add to velocity
|
||
}
|
||
|
||
// Predator-prey FSM
|
||
type FaunaState = 'rest' | 'wander' | 'alert' | 'hunt' | 'flee' | 'defend'
|
||
|
||
function createPredatorPreyFsm(def: SpeciesDefinition, clock?: Clock): PredatorPreyFsm
|
||
|
||
interface PredatorPreyFsm {
|
||
update(context: FaunaContext): FaunaState
|
||
readonly state: FaunaState
|
||
}
|
||
|
||
interface FaunaContext {
|
||
nearbyPrey: string[]
|
||
nearbyPredators: string[]
|
||
nearbyPlayers: string[]
|
||
distanceToHome?: number
|
||
health: number
|
||
hungerLevel: number // 0–1
|
||
}
|
||
|
||
// Taming
|
||
function createTamingManager(clock?: Clock): TamingManager
|
||
|
||
interface TamingManager {
|
||
startTaming(playerId: string, faunaId: string, difficulty: number): void
|
||
applyTamingAction(playerId: string, faunaId: string, action: TamingAction): TamingResult
|
||
getProgress(playerId: string, faunaId: string): number // 0–1
|
||
isTamed(faunaId: string): boolean
|
||
}
|
||
|
||
type TamingAction = 'feed' | 'pet' | 'speak' | 'bribe'
|
||
|
||
interface TamingResult {
|
||
progress: number
|
||
tamed: boolean
|
||
failed: boolean
|
||
}
|
||
```
|
||
|
||
### Error codes
|
||
|
||
```ts
|
||
type FaunaErrorCode =
|
||
| 'FAUNA_SPECIES_NOT_FOUND'
|
||
| 'FAUNA_NOT_TAMEABLE'
|
||
| 'FAUNA_TAMING_FAILED'
|
||
| 'FAUNA_TERRITORY_INVALID'
|
||
```
|
||
|
||
---
|
||
|
||
## New additions for genesis
|
||
|
||
1. **Boid steering** — separation/alignment/cohesion using `@suaveplan/spatial-hash` neighbor queries.
|
||
2. **Hunger drive** — `hungerLevel` escalates over time (injectable clock); at threshold, switches FSM to `hunt`.
|
||
3. **Taming trust decay** — idle taming sessions lose progress over time; `feed`/`pet` actions advance faster at low fear.
|
||
4. **OTel** — `fauna.herd_size` gauge; `fauna.hunts_total` counter; `fauna.tamed_total` counter.
|
||
|
||
---
|
||
|
||
## File layout
|
||
|
||
```text
|
||
gaming/ai/fauna/
|
||
package.json
|
||
tsconfig.json
|
||
vitest.config.ts
|
||
src/
|
||
index.ts
|
||
error-codes.ts
|
||
constants/index.ts
|
||
types/common.ts
|
||
types/common.md
|
||
core/
|
||
herd-simulator/
|
||
herd-simulator.ts
|
||
herd-simulator.md
|
||
herd-simulator.types.ts
|
||
herd-simulator.test.ts
|
||
index.ts
|
||
predator-prey-fsm/
|
||
predator-prey-fsm.ts
|
||
predator-prey-fsm.md
|
||
predator-prey-fsm.types.ts
|
||
predator-prey-fsm.test.ts
|
||
index.ts
|
||
taming-manager/
|
||
taming-manager.ts
|
||
taming-manager.md
|
||
taming-manager.types.ts
|
||
taming-manager.test.ts
|
||
index.ts
|
||
tests/
|
||
integration.test.ts
|
||
```
|
||
|
||
---
|
||
|
||
## Impact
|
||
|
||
**Downstream**: `@suaveplan/r3f-npc` renders fauna instances using the same pipeline as NPCs. Prerequisites: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/npc`, `@suaveplan/spatial-hash`.
|