magicciv/packages/engine-ts/src/worker-protocol.ts
Claude Code 9506935f24 feat(engine-worker): Add new worker protocol messages and scenario definitions with supporting types
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-03-29 10:07:32 -07:00

154 lines
4.1 KiB
TypeScript

import type { TurnStats, EcologicalEvent, GridSnapshot, TerrainData, LeyEdge, WonderMarker, RiverSegment, RiverSourceMarker, WindArrow } from './types'
import type { EasterEggSeed } from './easterEggSeeds'
// ---------------------------------------------------------------------------
// Commands: main thread → worker
// ---------------------------------------------------------------------------
export type WorkerCommand =
| InitCommand
| RunCommand
| ExtendCommand
| FrameCommand
| CancelCommand
| TriggerEventCommand
export interface InitCommand {
type: 'init'
terrainData: Record<string, TerrainData>
params: Record<string, number>
spec?: Record<string, unknown>
/** Easter egg seed table from game data (seed_easter_eggs.json). Keys are seed integers as strings. */
easterEggs?: Record<string, EasterEggSeed>
/** Per-planet climate params keyed by planet id. If present, overrides `params` for non-earth scenarios. */
allPlanetParams?: Record<string, Record<string, number>>
/** Per-planet climate spec keyed by planet id. */
allPlanetSpecs?: Record<string, Record<string, unknown>>
}
export interface RunCommand {
type: 'run'
scenarioId: string
turns: number
/** How many frames to pre-encode after simulation completes. */
prebufferFrames: number
/** World seed (default 42). */
seed?: number
}
export interface ExtendCommand {
type: 'extend'
scenarioId: string
turns: number
}
export interface FrameCommand {
type: 'frame'
scenarioId: string
turn: number
lookahead: number
}
export interface CancelCommand {
type: 'cancel'
scenarioId: string
}
/** Inject a specific event tier into the running simulation at its current end. */
export interface TriggerEventCommand {
type: 'trigger_event'
scenarioId: string
/** Event category name matching a key in events/*.json, e.g. 'volcanic', 'impact', 'solar'. */
eventCategory: string
/** Tier number 1-10. */
tier: number
}
// ---------------------------------------------------------------------------
// Responses: worker → main thread
// ---------------------------------------------------------------------------
export type WorkerResponse =
| ReadyResponse
| ProgressResponse
| StatsResponse
| FramesResponse
| DoneResponse
| PrebufferDoneResponse
| ErrorResponse
| EventTriggeredResponse
export interface ReadyResponse {
type: 'ready'
}
export interface ProgressResponse {
type: 'progress'
scenarioId: string
turn: number
total: number
phase: 'generating' | 'geology' | 'scenario' | 'buffering'
}
/** Lightweight per-turn data sent once after simulation completes. */
export interface StatsResponse {
type: 'stats'
scenarioId: string
allStats: TurnStats[]
allEvents: EcologicalEvent[][]
/** Wall-clock milliseconds spent computing each scenario turn (parallel to allStats). */
allTimings: number[]
}
/** Rendered frames with Float32Array textures — sent on demand via 'frame' command. */
export interface FramesResponse {
type: 'frames'
scenarioId: string
startTurn: number
snapshots: FramePayload[]
}
/** Minimal snapshot for rendering — no stats/events (main thread has those already). */
export interface FramePayload {
texA: Float32Array
texB: Float32Array
texC: Float32Array
width: number
height: number
turn: number
global_avg_temp: number
ocean_dead_fraction: number
ley_edges: LeyEdge[]
wonder_positions: WonderMarker[]
riverSegments: RiverSegment[]
riverSources: RiverSourceMarker[]
windArrows: WindArrow[]
}
export interface DoneResponse {
type: 'done'
scenarioId: string
totalTurns: number
}
/** Posted after the initial playback buffer frames have all been sent. */
export interface PrebufferDoneResponse {
type: 'prebuffer_done'
scenarioId: string
}
export interface ErrorResponse {
type: 'error'
scenarioId: string
message: string
}
/** Confirmation that a manually triggered event was applied to the grid. */
export interface EventTriggeredResponse {
type: 'event_triggered'
scenarioId: string
eventCategory: string
tier: number
/** Scenario-relative turn at which the event was injected. */
turn: number
}