import { type FlockStepAgent } from "../ai/flock.js"; import type { EditorDocument } from "../editor/types.js"; import { type AuthoredWeatherSample, type WeatherExposure, type WeatherExposureSnapshot, type WeatherExposureSurface } from "./authoredWeather.js"; import { type FireCell, type FireGrid } from "./weather.js"; import type { ParticleDirector } from "../vfx/particleDirector.js"; import type { Vec3 } from "../vfx/particles.js"; /** A watched surface is sampled in metres. Its accumulation survives runtime save/restore. */ export interface AuthoredSurface extends WeatherExposureSurface { y?: number; } /** Appearance adapters consume these units without owning weather state or its clock. */ export interface EnvironmentAppearanceSignals { timeSeconds: number; wind: Vec3; wetness: number; snow: number; exposure: number; /** Normalized local fire heat, independent of the temperature offset in degrees Celsius. */ heat: number; temperatureOffsetC: number; } /** Runtime state excludes authored configuration and cosmetic particle pools. */ export interface AuthoredSimulationSnapshot { surfaces: WeatherExposureSnapshot; watched: AuthoredSurface[]; fires: { id: string; cells: FireCell[]; }[]; flocks: { id: string; agents: FlockStepAgent[]; routeIndex: number; }[]; } /** A habitat's live poses; game species determine appearance and gameplay actor policy. */ export interface AuthoredFlockState { readonly id: string; readonly species: string; readonly role: "cosmetic" | "gameplay"; readonly agents: readonly Readonly[]; readonly routeIndex: number; } /** Engine-owned authority uses the caller's simulation clock; render quality cannot change it. */ export interface AuthoredSimulationRuntime { sample(x: number, z: number): AuthoredWeatherSample; appearanceAt(surfaceId: string, position: Vec3): EnvironmentAppearanceSignals; /** Fraction of open sky from bounded authored shelter volumes. World Y points up. */ exposureAt(x: number, y: number, z: number): number; readonly surfaces: WeatherExposure; watch(surface: AuthoredSurface): void; forget(id: string): void; /** XZ wind adapted to [x,0,z]; response is 1/second, cap is metres/second² (both 0..1e12). */ windAcceleration(position: Vec3, response: number, maxAcceleration: number): Vec3; /** Sum authored fields and wind (response 1/second), capped in metres/second² by game policy. */ accelerationAt(position: Vec3, timeSeconds: number, windResponse: number, maxAcceleration: number, mask?: number, out?: [number, number, number]): Vec3; fire(id: string): FireGrid | undefined; /** Cosmetic poses render directly; gameplay habitats are consumed by game actor adapters. */ flocks(): readonly AuthoredFlockState[]; step(gameDt: number): void; retune(document: EditorDocument): void; snapshot(): AuthoredSimulationSnapshot; restore(state: AuthoredSimulationSnapshot): void; dispose(): void; } /** Compose authored weather, shelter, accumulation, named effect intents and fire with one clock. * @capability authored-environment compose authored weather, shelter, accumulation, fire, flocks and effects using one simulation clock */ export declare function createAuthoredSimulation(options: { document?: EditorDocument; timeSeconds: () => number; particles?: ParticleDirector; maxSurfaces?: number; }): AuthoredSimulationRuntime;