<!-- GENERATED by scripts/gen-skill-api.ts — do not edit. Regenerate: bun run gen:skill-api -->

# jgengine-world — exported API surface

## @jgengine/core/ai/crowd

- `CrowdField` (interface): interface CrowdField { enter(point: NavPoint): void; leave(point: NavPoint): void; count(point: NavPoint): number; cellCount(col: number, row: number): number; penalty(weight?: number): (col: number, row: number) => number; reset(): void } — ⚠ undocumented
- `FlowField` (interface): interface FlowField { readonly cols: number; readonly rows: number; cost(col: number, row: number): number; reachable(point: NavPoint): boolean; direction(point: NavPoint): NavPoint; next(point: NavPoint): NavPoint | null } — ⚠ undocumented
- `FlowFieldOptions` (interface): interface FlowFieldOptions { clearance?: number; congestion?: (col: number, row: number) => number } — ⚠ undocumented
- `Poi` (interface): interface Poi { id: string; point: NavPoint; appeal?: number; capacity?: number } — ⚠ undocumented
- `SelectPoiOptions` (interface): interface SelectPoiOptions { roll: number; occupancy?: (id: string) => number; distanceBias?: number; distance?: (from: NavPoint, poi: Poi) => number } — ⚠ undocumented
- `VisitorLoop` (interface): interface VisitorLoop — Handle returned by {@link createVisitorLoop}: per-agent seek/travel/dwell/depart state machine.
- `VisitorLoopOptions` (interface): interface VisitorLoopOptions — Config for {@link createVisitorLoop}: the POI catalog, dwell duration, and exit point every agent shares.
- `VisitorPhase` (type): type VisitorPhase = "seeking" | "traveling" | "dwelling" | "departing" | "done" — A many-agent visitor's current step of the seek→travel→arrive→dwell→depart loop.
- `VisitorStep` (interface): interface VisitorStep — One tick's result from a {@link VisitorLoop}: current phase, where to steer, and which POI it concerns.

## @jgengine/core/ai/decisionGraph

- `Blackboard` (type): type Blackboard = Record<string, BlackboardValue> — Named facts available to conditions, utilities, and actions.
- `BlackboardValue` (type): type BlackboardValue = number | boolean | string — Scalar values stored in a decision graph blackboard.
- `DecisionAbort` (type): type DecisionAbort<Context = unknown> = ( action: string, ctx: Context, params: Record<string, BlackboardValue> | undefined, blackboard: Blackboard, ) => void — Called when an action that was running last tick is not reached this tick, so it can release what it holds.
- `DecisionAction` (type): type DecisionAction<Context = unknown> = ( ctx: Context, params: Record<string, BlackboardValue> | undefined, blackboard: Blackboard, ) => DecisionStatus — Callback implementation for an action node.
- `DecisionGraph` (type): type DecisionGraph = DecisionNode — Root node for a serializable AI decision graph.
- `DecisionGraphOptions` (interface): interface DecisionGraphOptions<Context = unknown> — Optional hooks and injected randomness for {@link createDecisionGraphRuntime}.
- `DecisionGraphRuntime` (interface): interface DecisionGraphRuntime<Context = unknown> — Stateful evaluator for a serializable decision graph.
- `DecisionGraphSnapshot` (interface): interface DecisionGraphSnapshot — Serializable state retained by an active decision graph. Fields besides `runningPath` are absent in older saves.
- `DecisionNode` (type): type DecisionNode = | { kind: "selector"; children: DecisionNode[]; memory?: boolean } | { kind: "sequence"; children: DecisionNode[]; memory?: boolean } | { kind: "condition"; key: string; op: DecisionOperator; value: BlackboardValue } | { kind: "action"; action: string; params?: Record<string, Bla… — Serializable decision node. - `selector` runs children in order until one does not fail; `sequence` until one does not finish. With `memory`, a composite whose child was running last tick resumes at that child instead of re-checking earlier ones. - `condition` compares a blackboard key; `action` calls a registered action. - `utility` runs the option with the highest weighted blackboard score. - `invert` swaps `done` and `failed`; `cooldown` fails for `seconds` after its child finishes; `wait` stays running for `seconds`; `random` picks a child by `weights` from the runtime's `rng` and keeps it while it runs.
- `DecisionNodeMemory` (interface): interface DecisionNodeMemory — Progress of a memory composite, `random` choice, or `wait` timer, keyed by node id (depth-first order).
- `DecisionOperator` (type): type DecisionOperator = "=" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "eq" | "ne" | "lt" | "lte" | "gt" | "gte" — Comparison operators supported by decision conditions.
- `DecisionStatus` (type): type DecisionStatus = "running" | "done" | "failed" — Outcome reported when a decision graph evaluates.
- `createDecisionGraphRuntime` (function): function createDecisionGraphRuntime<Context = unknown>(graph: DecisionGraph, actions: Record<string, DecisionAction<Context>>, options: DecisionGraphOptions<Context> = {}): DecisionGraphRuntime<Context> — Creates a deterministic runtime for a serializable decision graph.

## @jgengine/core/ai/difficulty

- `DIFFICULTY_TIERS` (const): const DIFFICULTY_TIERS: Readonly<Record<DifficultyTier, DifficultyProfile>> — The canonical easy/standard/expert profiles. Frozen — use {@link difficultyProfile} to derive a tweaked copy instead of mutating.
- `DifficultyProfile` (interface): interface DifficultyProfile — Serializable decision-quality data. All fields are plain numbers so a profile can live in a save, an encounter definition, or a per-entity spawn record.
- `DifficultyTier` (type): type DifficultyTier = "easy" | "standard" | "expert" — Difficulty is decision *quality*, owned in one place: a serializable {@link DifficultyProfile} describing how fast, how accurately, and how far ahead an agent decides, plus appliers at the universal decision seams every opponent shares — reacting to new information, choosing among scored options, executing with error, spending abilities, and planning ahead. The same profile tunes an RTS grunt, a street enemy, a boss's special-ability discipline, or a turn-based lookahead player; the game supplies the domain (candidates, scores, moves) and this module degrades or sharpens the choice. Three canonical tiers ({@link DIFFICULTY_TIERS}) cover "kinda dumb / smart / super smart"; per-game overrides stay data.
- `LookaheadDomain` (interface): interface LookaheadDomain<S, M> — The game-owned decision domain {@link planLookahead} searches. States and moves are caller types; the planner never inspects them.
- `ReactionGateState` (interface): interface ReactionGateState<T> — Serializable reaction-gate state: the value the agent is currently acting on plus the newer value it has noticed but not yet committed to. `T` should be serializable (ids, positions as tuples) if the gate lives in saved state.
- `ScoredOption` (interface): interface ScoredOption<T> — One candidate with a caller-computed score; higher is better.
- `advanceReactionGate` (function): function advanceReactionGate<T>(state: ReactionGateState<T>, dt: number, desired: T, profile: DifficultyProfile): T — Advance one reaction step and return the value to act on. `desired` is what a perfect agent would act on this frame (current best target, latest known player position); the gate holds the previously committed value until `desired` has been stable for `profile.reactionSeconds`, restarting the delay whenever `desired` changes again (compared with `Object.is`). Feed the returned value — not `desired` — into pursuit/aim/ability logic. Mutates `state` in place; allocation-free.
- `createReactionGate` (function): function createReactionGate<T>(initial: T): ReactionGateState<T> — A fresh gate already committed to `initial`.
- `difficultyProfile` (function): function difficultyProfile(tier: DifficultyTier, overrides?: Partial<DifficultyProfile>): DifficultyProfile — A fresh profile from a canonical tier with optional per-game overrides — e.g. an "easy" boss that still reacts fast: `difficultyProfile("easy", { reactionSeconds: 0.2 })`.
- `executionError` (function): function executionError(profile: DifficultyProfile, rng: () => number, scale = 1): number — Symmetric execution error in `[-scale * executionJitter, +scale * executionJitter]` — add it to a yaw, a lead time, a throw power, or a release timestamp. `scale` maps the unitless jitter onto the caller's units (e.g. pass max miss radians).
- `pickScored` (function): function pickScored<T>(options: readonly ScoredOption<T>[], profile: DifficultyProfile, rng: () => number): T | null — Choose from a scored option list at the profile's quality: with probability `profile.decisionNoise` the pick is uniform over all options (the "wrong target / bad move" mistake), otherwise it is the best score (first wins ties). Works over any decision the game can score — acquisition candidates, ability choices, retreat routes, chess moves. Returns `null` for an empty list. Allocation-free scan; one rng draw plus one more on a noisy pick.
- `planLookahead` (function): function planLookahead<S, M>(root: S, domain: LookaheadDomain<S, M>, profile: DifficultyProfile, rng: () => number): M | null — Pick the agent's next move by bounded lookahead: a depth-limited negamax (or single-perspective sequence search when `adversarial: false`) over the caller's {@link LookaheadDomain}, exploring at most `profile.planWidth` moves per ply to `profile.planDepth` plies, with the final root choice run through {@link pickScored} so `decisionNoise` still injects tier-appropriate blunders. Depth `1` is greedy — an easy profile literally cannot see the fork coming; an expert profile finds multi-ply tactics. Work is bounded by `planWidth ** planDepth` domain calls; run it at decision cadence (turns, ability windows, order re-evaluation), not per frame.
- `shouldUseAbility` (function): function shouldUseAbility(opportunity: number, profile: DifficultyProfile, rng: () => number): boolean — Should the agent spend an ability now? `opportunity` is the caller-scored quality of this moment in `0..1` (targets clumped for the AoE, player mid-animation, burn phase). The perceived opportunity is fuzzed by `decisionNoise` and compared against `abilityDiscipline`: an easy profile (low discipline, high noise) wastes cooldowns on weak moments and sometimes sits on a perfect window; an expert profile fires exactly on strong windows. One rng draw when noisy.

## @jgengine/core/ai/director/boss

- `BossBehaviour` (type): type BossBehaviour = Omit<SquadRole, "id" | "count"> — The role shape a boss fights with in one phase: the same dials a squad role uses.
- `BossPhase` (interface): interface BossPhase — One authored phase: the health it starts at, how the boss fights, and its tell.
- `BossState` (interface): interface BossState — Serializable boss state: which phase holds, how long it has held, and the tell still on screen.
- `BossStep` (interface): interface BossStep — One step of the boss clock.
- `BossTell` (interface): interface BossTell — The warning a boss gives while it changes phase, and how long the player has to read it.
- `advanceBoss` (function): function advanceBoss(phases: readonly BossPhase[], state: BossState, health: number, dt: number): BossStep — Advance the boss by `dt` at a health fraction and return the phase in effect.
- `bossPhase` (function): function bossPhase(phases: readonly BossPhase[], health: number): BossPhase — The phase a boss fights with at a health fraction. Pure read for a HUD; never mutates.
- `createBossState` (function): function createBossState(phases: readonly BossPhase[]): BossState — Fresh boss state for a phase list, opening in phase 0 with no tell showing.

## @jgengine/core/ai/director/encounter

- `Encounter` (interface): interface Encounter — Live encounter: opens waves, emits timed spawn orders, and round-trips through a save.
- `EncounterConfig` (interface): interface EncounterConfig — Construction options for {@link createEncounter}.
- `EncounterDefinition` (interface): interface EncounterDefinition — A whole encounter, authored as data instead of spawned in game code.
- `EncounterGroup` (interface): interface EncounterGroup — One authored group inside a wave: what arrives, how many, where from, and when. `unit` and `entry` are game-owned ids — the engine never resolves them.
- `EncounterOrder` (interface): interface EncounterOrder — One unit the director says should enter now.
- `EncounterPressure` (interface): interface EncounterPressure — The subset of a pressure plan the encounter layer applies.
- `EncounterState` (interface): interface EncounterState — Serializable encounter state.
- `EncounterView` (interface): interface EncounterView — Pooled per-frame readout of where the encounter stands.
- `EncounterWave` (interface): interface EncounterWave — One authored wave.
- `createEncounter` (function): function createEncounter(config: EncounterConfig): Encounter — Create a live encounter over an authored definition: open a wave, step its clock, take the orders whose time has come, and close the wave when the game says it is cleared.
- `expandWave` (function): function expandWave(config: EncounterConfig, waveIndex: number, pressure: EncounterPressure = {}): EncounterOrder[] — Expand one authored wave into the units it sends, at the times it sends them.

## @jgengine/core/ai/director/pressure

- `PressurePlan` (interface): interface PressurePlan — One bounded answer to "how hard now", plus the effects the encounter layer applies.
- `PressureReading` (interface): interface PressureReading — Encounter pressure: how hard a director leans on a player who is struggling, read from the player's own state, quantized to a tier, and bounded by the rule's cap. The plan is a value, not a callback, so a test can sweep it and a probe can print it.
- `PressureRule` (interface): interface PressureRule — The weights and window that turn a reading into an index, plus the hard cap.
- `evaluatePressure` (function): function evaluatePressure(reading: PressureReading, rule: PressureRule = {}): PressurePlan — Turn one reading into a bounded pressure plan.

## @jgengine/core/ai/director/roles

- `FightIntent` (type): type FightIntent = "retreat" | "hold" | "flank" | "cover" | "assault" — The five duties a fighter can be given in a fight. A duty is *who does what*; the squad role a game dials (range, angles, fire discipline) is *how that duty fights* and stays content.
- `FightOrders` (interface): interface FightOrders — What the director decided, per fighter, and why.
- `FightSituation` (interface): interface FightSituation — The squad as it stands and the enemy it is facing, or no enemy at all.
- `FighterState` (interface): interface FighterState — One fighter the director can order, with the state the decision reads.
- `assignFightIntents` (function): function assignFightIntents(situation: FightSituation): FightOrders — Assign each fighter a duty from the squad's own state — who is hurt, who is under fire, and who already stands on the outside of the formation — never from an authored order or a spawn index.
- `compositionForIntents` (function): function compositionForIntents(order: readonly string[], intents: ReadonlyMap<string, FightIntent>, roleFor: (intent: FightIntent) => SquadRole): SquadComposition — Turn duties into a squad composition `createSquadCombat` accepts: one slot per fighter, in the order the game gives its members, each mapped to the role that game dials for the duty. Build it through `composition` so squad combat executes the director's assignment instead of its own static list.

## @jgengine/core/ai/director/sound

- `Investigation` (interface): interface Investigation — A hunter still working a noise, as the squad layer reads it this tick.
- `NoiseEvent` (interface): interface NoiseEvent — One noise in the world, as the game produces it.
- `SoundHunt` (interface): interface SoundHunt — Sound hunting: raise a noise, get the bounded set of enemies that go and look.
- `SoundHuntConfig` (interface): interface SoundHuntConfig — Everything the hunt reads and its bounds.
- `SoundHuntEntry` (interface): interface SoundHuntEntry — One noise and the hunters sent to it. Serializable, so a hunt survives a save.
- `SoundHuntSnapshot` (interface): interface SoundHuntSnapshot — Serializable book-keeping: which noises are still being worked, and by whom.
- `SoundHunter` (interface): interface SoundHunter — A unit that could hear a noise: its id and where it stands when the noise lands.
- `createSoundHunt` (function): function createSoundHunt(config: SoundHuntConfig): SoundHunt — Make enemies investigate a noise, reusing the hearing owner.

## @jgengine/core/ai/driver

- `DrivePathPoint` (type): type DrivePathPoint = readonly [number, number] — A 2D polyline point (`[x, z]`), structurally compatible with authored road path centerlines.
- `DriverGoal` (interface): interface DriverGoal — Where the driver is trying to go this step.
- `DriverPose` (interface): interface DriverPose — A difficulty-aware driver brain: pose + goal in, the shared {@link AxisInput} (`throttle`/`brake`/`steer`/`handbrake`) out, ready for `tickDrivableVehicle` — the chase/traffic steering loop every game with AI cars hand-rolls as `steer = error * k, throttle = 1`. A {@link DifficultyProfile} decides how *well* it drives: reaction time trails the target, corners shed speed instead of orbiting at full throttle, obstacles are noticed late on low tiers, the wheel wobbles by `executionJitter`, and a stuck car backs out with counter-steer after grinding for a tier-scaled while. State is one small serializable object; randomness is injected; every step is allocation-light scalar math. The caller owns the sim, collision, and all spatial queries — this module never scans the world.
- `DriverState` (interface): interface DriverState — Serializable per-driver state advanced in place by {@link driveStep}.
- `DriverStep` (interface): interface DriverStep extends AxisInput — {@link driveStep}'s result: the axis sample to feed the vehicle sim, plus arrival.
- `DriverTuning` (interface): interface DriverTuning — Vehicle-feel numbers the game supplies; everything has a sensible default except `maxSpeed`.
- `createDriverState` (function): function createDriverState(targetX = 0, targetZ = 0): DriverState — Fresh driver state committed to an initial target (usually the spawn-time goal or the spawn position itself).
- `driveStep` (function): function driveStep(state: DriverState, dt: number, pose: DriverPose, goal: DriverGoal, profile: DifficultyProfile, tuning: DriverTuning, rng: () => number, obstacleAhead: number | null = null): DriverStep — Advance one driving step, mutating `state`, and return the {@link AxisInput} to feed the vehicle sim. `obstacleAhead` is the caller-measured distance to the nearest blocker in the driving corridor this step (`null`/omitted when clear) — the driver perceives it late by `speed * reactionSeconds`, so easy tiers brake at the last moment and expert tiers with proper margin. The steering target is a delay-line over the goal — resampled every `reactionSeconds`, so it trails a moving goal by up to that long, which is what makes an easy chaser visibly cut toward where the target *was*. When throttle produces no motion for a tier-scaled while the driver reverses out with counter-steer (brake past standstill — the shared sim's reverse).
- `pathTargetAhead` (function): function pathTargetAhead(path: readonly DrivePathPoint[], x: number, z: number, lookahead: number, loop = false): DrivePathPoint | null — The pure-pursuit target for street/route following: the point `lookahead` meters further along the polyline from wherever the vehicle currently projects onto it. Feed the result to {@link driveStep} as the goal each tick and the driver follows the road; `loop` wraps a circuit (traffic block, race lap) instead of pinning at the final point. Returns `null` for a degenerate path. Give sharper tiers a longer `lookahead` to cut corners cleanly and duller tiers a short one so they steer segment-to-segment.

## @jgengine/core/ai/flock

- `FlockAgent` (interface): interface FlockAgent { position: FlockVec3; velocity: FlockVec3 } — ⚠ undocumented
- `FlockConfig` (interface): interface FlockConfig { maxSpeed: number; accel?: number; separationRadius: number; separationWeight?: number; neighborRadius: number; cohesionWeight?: number; alignmentWeight?: number; seekWeight?: number; stragglerRadius?: number; stragglerBoost?: number } — ⚠ undocumented
- `FlockStepAgent` (interface): interface FlockStepAgent { position: FlockVec3; velocity: FlockVec3 } — ⚠ undocumented
- `FlockVec3` (type): type FlockVec3 = readonly [number, number, number] — ⚠ undocumented

## @jgengine/core/ai/groupAssist

- `AssistMember` (interface): interface AssistMember { id: string; groupId: string; table: ThreatTable } — ⚠ undocumented
- `AssistNetwork` (interface): interface AssistNetwork { register(member: AssistMember): void; remove(memberId: string): void; memberIds(groupId?: string): string[]; assistersOf(memberId: string): string[]; addThreat(memberId: string, sourceId: string, amount: number): string[]; snapshot(): Ass… — ⚠ undocumented
- `AssistNetworkConfig` (interface): interface AssistNetworkConfig { radius?: number; shareFraction?: number; distanceBetween?: (a: string, b: string) => number } — ⚠ undocumented
- `AssistNetworkState` (interface): interface AssistNetworkState — Plain JSON membership of an {@link AssistNetwork}, in registration order; threat lives in each member's own table.

## @jgengine/core/ai/heatSystem

- `HeatConfig` (interface): interface HeatConfig — Tuning for {@link createHeatState}/{@link advanceHeat} — levels, decay, and pursuit-spawn ring.
- `HeatGain` (interface): interface HeatGain — One crime tick's contribution — only `witnessed` gains raise heat (unseen crimes are free, GTA-style).
- `HeatLevelDef` (interface): interface HeatLevelDef — One escalation tier — the heat threshold it begins at and the pursuer count it wants active.
- `HeatPoint` (type): type HeatPoint = readonly [number, number] — A world-space `[x, z]` used for the heat system's spawn ring and witness proximity checks.
- `HeatState` (interface): interface HeatState — Serializable heat-system state — round-trips through `createHeatState`/`advanceHeat` each tick.
- `HeatStep` (interface): interface HeatStep — One `advanceHeat` tick's result — updated state plus what the caller should spawn/despawn.
- `HeatTickContext` (interface): interface HeatTickContext — Per-tick world facts {@link advanceHeat} needs but can't derive itself — witness proximity, pursuer count, origin.

## @jgengine/core/ai/interestScheduler

- `InterestCensus` (interface): interface InterestCensus — Aggregate counts of active vs dormant gates — the metric the issue asks a scheduler to expose.
- `InterestCensusAccumulator` (interface): interface InterestCensusAccumulator — A running census accumulator; call `record` inside the caller's existing tick loop (no extra pass).
- `InterestGateInput` (interface): interface InterestGateInput — Per-tick input the caller supplies to a gate.
- `InterestGateState` (interface): interface InterestGateState — Per-agent serializable gate state. Round-trip the whole object; never read fields to drive logic.
- `InterestGateStep` (interface): interface InterestGateStep — Per-tick output that tells the caller whether to run expensive work.
- `InterestSchedulerConfig` (interface): interface InterestSchedulerConfig — Static configuration shared by every gate of one behavior class.
- `InterestState` (type): type InterestState = "active" | "dormant" — Interest scheduling: the scale primitive that lets far-away agents sleep instead of running acquisition and pathing every frame. A per-agent gate decides — from proximity to the nearest interest source plus explicit wake signals — whether this tick does expensive work, at what cadence, with hysteresis so it never thrashes at the boundary and deterministic staggering so a thousand siblings do not all wake on the same frame. State is a plain serializable object; the caller drives it from a bounded spatial query, never a full-world scan.
- `InterestTier` (interface): interface InterestTier — A distance-keyed cadence tier: nearer agents tick faster, farther-but-awake agents tick slower.
- `advanceInterestGate` (function): function advanceInterestGate(state: InterestGateState, config: InterestSchedulerConfig, dt: number, input: InterestGateInput = {}): InterestGateStep — Advance one gate by `dt` seconds against this tick's `input`, mutating `state` in place and returning what the caller should do. Sleeping skips the expensive work (`active: false`) while the gate's timers keep advancing, so state is preserved; a `wake` signal or crossing `wakeRadius` flips it back to active and fires an immediate tick.
- `createInterestCensus` (function): function createInterestCensus(): InterestCensusAccumulator — Create a census accumulator so the caller can tally active/dormant gates during the loop it already runs, avoiding any separate full-world scan just to report scheduler metrics.
- `createInterestGateState` (function): function createInterestGateState(config: InterestSchedulerConfig, phase = 0): InterestGateState — Create a dormant gate state, staggered by `phase` (`[0,1)`, typically {@link interestPhase} of the agent id) so siblings created together do not all fire their first active tick on the same frame.
- `interestPhase` (function): function interestPhase(seed: string | number): number — A deterministic `[0,1)` cadence phase derived from a stable id, for staggering sibling gates so a batch of agents spawned together does not fire their first active tick on the same frame. Pass the result as the `phase` argument to {@link createInterestGateState}.

## @jgengine/core/ai/jobBoard

- `Job` (interface): interface Job { id: string; station: NavPoint; work: number; priority: number; arriveRadius: number; repeat: boolean; worker: string | null } — ⚠ undocumented · used by `activeJobs` (@jgengine/core/gameplay): Jobs currently progressing.
- `JobBoard` (interface): interface JobBoard { post(job: JobDef): string; cancel(jobId: string): boolean; assign(workerId: string, jobId: string): boolean; claim(workerId: string): string | null; release(workerId: string): void; advance(workerId: string, dt: number, ctx: JobTickContex… — ⚠ undocumented
- `JobDef` (interface): interface JobDef { id?: string; station: NavPoint; work: number; priority?: number; arriveRadius?: number; repeat?: boolean } — ⚠ undocumented
- `JobPhase` (type): type JobPhase = "idle" | "travelling" | "working" | "done" — ⚠ undocumented
- `JobReport` (interface): interface JobReport { jobId: string; workerId: string; cycle: number } — ⚠ undocumented
- `JobTickContext` (interface): interface JobTickContext { distanceToStation: number } — ⚠ undocumented
- `WorkerState` (interface): interface WorkerState { jobId: string | null; phase: JobPhase; worked: number; cycles: number } — ⚠ undocumented

## @jgengine/core/ai/laneSelect

- `LaneCandidate` (interface): interface LaneCandidate<TId extends string = string> { id: TId; cost: number } — ⚠ undocumented
- `PickLaneOptions` (interface): interface PickLaneOptions<TId extends string = string> { current?: TId | null; stickiness?: number; tieEpsilon?: number; rng?: () => number } — ⚠ undocumented

## @jgengine/core/ai/mobBrain

- `MobBrain` (interface): interface MobBrain — The wander → aggro → chase → engage → leash-evade loop every MMO-shaped game hand-rolls, composed over `ai/threat`. The brain decides intent; the game executes it (`moveToward`, ground-snap, facing, swings) and routes damage into `addThreat`. Pack aggro is game-side: call `addThreat` on nearby packmates' brains when one aggros.
- `MobBrainConfig` (interface): interface MobBrainConfig { aggroRadius: number; attackRange: number; leashDistance: number; wander?: MobWanderConfig | false; evadeSpeedScale?: number; stickiness?: number; homeArriveRadius?: number; threat?: ThreatTableConfig } — ⚠ undocumented
- `MobBrainDeps` (interface): interface MobBrainDeps { home: MobVec3; position(): MobVec3 | null; targetPosition(targetId: string): MobVec3 | null; candidates(): readonly string[]; rng?: () => number } — ⚠ undocumented
- `MobBrainMode` (type): type MobBrainMode = "idle" | "wander" | "chase" | "engage" | "evade" — ⚠ undocumented
- `MobBrainStep` (interface): interface MobBrainStep { mode: MobBrainMode; targetId: string | null; moveTo: MobVec3 | null; speedScale: number; inAttackRange: boolean; arrivedHome: boolean } — ⚠ undocumented
- `MobVec3` (type): type MobVec3 = readonly [number, number, number] — ⚠ undocumented
- `MobWanderConfig` (interface): interface MobWanderConfig { radius: number; intervalSeconds?: number; speedScale?: number; arriveRadius?: number } — ⚠ undocumented

## @jgengine/core/ai/mobBrainGraph

- `mobBrainGraph` (const): const mobBrainGraph: DecisionGraph — Graph-shaped description of the mob brain's idle, wander, chase, engage, and evade decisions.

## @jgengine/core/ai/policeResponse

- `DEFAULT_POLICE_TIERS` (const): const DEFAULT_POLICE_TIERS: readonly PoliceTier[] — The starting tier table: patrol until heat arrives, then investigate, pursue and finally cordon.
- `DEFAULT_POLICE_TUNING` (const): const DEFAULT_POLICE_TUNING: PoliceTuning — The starting policy: linear decay, a six-second escape and a search area that grows at 2 m/s.
- `PoliceLaneHit` (interface): interface PoliceLaneHit — A lane near a world point: its id, the arc of the nearest point on it, and how far away that is.
- `PoliceResponse` (interface): interface PoliceResponse — Stateful wanted/pursuit API with retuning and save/restore support.
- `PoliceResponseConfig` (interface): interface PoliceResponseConfig extends Partial<PoliceTuning> — Everything {@link createPoliceResponse} needs: the witness seam, the roster and the caller's policy.
- `PoliceResponseKind` (type): type PoliceResponseKind = "patrol" | "investigate" | "pursue" | "roadblock" — How police answer the current heat tier — watching the streets up to cordoning them.
- `PoliceResponseState` (interface): interface PoliceResponseState — Serializable response state — the heat curve, the sight timer, the anchor and the counters.
- `PoliceRoadblockSite` (interface): interface PoliceRoadblockSite — A roadblock site on a lane, resolved from authored road data.
- `PoliceRoads` (interface): interface PoliceRoads — Road data the response reads: nearby lanes for the search area, authored sites for roadblocks.
- `PoliceRoadsOptions` (interface): interface PoliceRoadsOptions — How the document reader recognizes authored road content.
- `PoliceSearchArea` (interface): interface PoliceSearchArea — Where the search is, as the last sighting places it.
- `PoliceSighting` (interface): interface PoliceSighting — One remembered sighting of the suspect, as the perception service reports it — `PerceptionMemory` from `sensor/perception` satisfies this shape.
- `PoliceStats` (interface): interface PoliceStats — Counters a devtools probe, a HUD or a test reads.
- `PoliceStep` (interface): interface PoliceStep — One tick's answer: the heat, the tier, the search area, the cordon and the escape.
- `PoliceTickContext` (interface): interface PoliceTickContext — Per-tick world facts {@link PoliceResponse.tick} needs but cannot derive itself.
- `PoliceTier` (interface): interface PoliceTier — One response tier: the heat it begins at, what it puts on the street, and how wide it searches.
- `PoliceTuning` (interface): interface PoliceTuning — The serializable policy of a response: the tier table, the heat curve and the search shape.
- `PoliceWitness` (interface): interface PoliceWitness — The witness seam: perception memory, queried by observer id. Pass `createPerception` (`sensor/perception`) straight in — a crime is witnessed when an observer still holds the suspect in view, so there is no second sight path to keep in step.
- `createPoliceResponse` (function): function createPoliceResponse(config: PoliceResponseConfig): PoliceResponse — The wanted level a crime sandbox needs, over the shared heat curve: a crime raises heat only while a witness holds the suspect in view, the heat bleeds on a stated linear curve once the suspect has been out of every witness's sight for `escapeSeconds`, the tier table decides what police do (patrol → investigate → pursue → roadblock), the search area sits where the suspect was last seen and grows while the trail is cold, and a roadblock tier cordons it with authored sites off the lane graph. Heat, tiers and curves are caller policy; witness facts come from `sensor/perception` memory (`sourceId`/`sourceTick` kept), so there is no second sight path.
- `policeRoadsFromLaneGraph` (function): function policeRoadsFromLaneGraph(graph: LaneGraph, markers: readonly EditorMarker[] = [], options: PoliceRoadsOptions = {}): PoliceRoads — Read the police road data out of an authored lane graph: `traffic_roadblock` markers become cordon sites projected onto the lane they block, and lanes are indexed so `lanesNear` answers from the local cells rather than a scan of every lane. With no roadblock markers authored, the graph's intersections are the sites, so a cordon still sits where streets meet. Built once; the index is rebuildable from the document, so it is never serialized.

## @jgengine/core/ai/populationDirector

- `PopulationCensus` (type): type PopulationCensus = Record<string, Record<string, number>> — Live census of alive counts keyed `region -> species -> count`, used to reconcile the director to reality.
- `PopulationDirector` (interface): interface PopulationDirector — Stateful ambient population manager for one world; drive it with `tick` and lifecycle notifications.
- `PopulationDirectorConfig` (interface): interface PopulationDirectorConfig — Full ambient-population configuration: per-region species budgets plus global refill limits and PRNG seed.
- `PopulationDirectorState` (interface): interface PopulationDirectorState — Opaque, JSON-serializable persistence for a {@link PopulationDirector}. Round-trip it through `snapshot`/`hydrate`; never read or mutate the fields directly.
- `PopulationRegionConfig` (interface): interface PopulationRegionConfig — Ambient population budget for a single region: its species ceilings, refill timing, and spawn geometry.
- `PopulationSpawnRequest` (interface): interface PopulationSpawnRequest — A single ambient spawn the game should realise, refilling a region toward its species caps.
- `PopulationSpeciesEntry` (interface): interface PopulationSpeciesEntry — One species that ambiently populates a region: how heavily it is favoured and its alive ceiling.
- `PopulationTickContext` (interface): interface PopulationTickContext — Per-call spawn-point selection hook, letting a game apply bias (distance from players, etc.) at tick time.
- `createPopulationDirector` (function): function createPopulationDirector(config: PopulationDirectorConfig): PopulationDirector — Ambient open-world population director. Holds a target creature population per region and refills it over time, distinct from wave/horde spawning: instead of a budget draining down a wave, each region has per-species caps and a timed respawn queue. Removing a creature frees a slot; after a respawn delay `tick` emits weighted spawn requests (bounded per tick) that refill toward the caps without ever exceeding them. Species are chosen through a persisted, serializable {@link RandomSeed} cursor, so the same seed and the same lifecycle events always yield the same requests. Regions are independent, spawn points are optional, and the whole state round-trips through `snapshot`/`hydrate`.

## @jgengine/core/ai/pursuit

- `CooldownMode` (type): type CooldownMode = "always" | "inRange" — When the attack cooldown ticks down. - `"always"` (default): every step, like a wall-clock weapon timer that keeps counting during the chase, so the entity can swing the instant it reaches its target. - `"inRange"`: only while within `stopDistance`, so the timer freezes during the chase and the full interval is paid out after each contact.
- `PursuitAction` (type): type PursuitAction = | "leash" /** Out of range — advance toward the target. */ | "pursue" /** In range and the cooldown is ready — perform the attack, then {@link armPursuit}. */ | "attack" /** In range but the cooldown has not elapsed — hold (face the target, idle, etc.). */ | "wait" /** No engage… — Composable pursuit/aggro step: the "I have a target — now chase it, stop at reach, hit it on a cooldown, and break off if led too far from home" loop that melee mobs, RTS units, and stationary turrets all re-implement by hand. This owns exactly that state machine and the per-entity attack cooldown; target *selection* stays separate (see {@link ./targetAcquisition}), and every side effect — move, attack, break off — is performed by the caller in response to the returned action.
- `PursuitState` (interface): interface PursuitState — Per-entity cooldown state owned by the primitive. One serializable number; no methods.
- `advancePursuit` (function): function advancePursuit(state: PursuitState, dt: number, targetDistance: number | null, stopDistance: number, cooldownMode: CooldownMode = "always", homeDistance = Number.NEGATIVE_INFINITY, leashRange = Number.POSITIVE_INFINITY): PursuitAction — Advance one pursuit step for a single entity, mutating `state.attackCooldown`, and return the action the caller should perform. All spatial input is scalar and measured this frame:
- `armPursuit` (function): function armPursuit(state: PursuitState, intervalSeconds: number): void — Set the cooldown after an attack fires (clamped at `0`). Call on the step that returned `"attack"`.
- `createPursuitState` (function): function createPursuitState(attackCooldown = 0): PursuitState — A fresh pursuit state, ready to attack immediately (`attackCooldown` at `0`).

## @jgengine/core/ai/rvo

- `RvoAgentSpec` (interface): interface RvoAgentSpec — One agent's circular footprint and top speed; positions and velocities live in the crowd.
- `RvoAgentView` (interface): interface RvoAgentView — One agent's live kinematics, as the crowd exposes them.
- `RvoCrowd` (interface): interface RvoCrowd — Many circular agents steering around each other. `setPreferredVelocity` states where each agent wants to go; `step` turns that into reciprocal collision-free velocities and integrates them. Deterministic: agents are visited in slot order, neighbours in grid and slot order, and head-on ties break on slot index rather than chance.
- `RvoCrowdOptions` (interface): interface RvoCrowdOptions extends Partial<RvoTunables> — Options for {@link createRvoCrowd}.
- `RvoSnapshot` (interface): interface RvoSnapshot — Serializable crowd state: tuning plus every agent's position, velocity and footprint.
- `RvoTunables` (interface): interface RvoTunables — Serializable avoidance tuning, retunable in play through {@link RvoCrowd.retune}.
- `createRvoCrowd` (function): function createRvoCrowd(options: RvoCrowdOptions = {}): RvoCrowd — Reciprocal velocity obstacle avoidance over circular agents. Each nearby pair contributes one or two half-plane constraints on the agent's velocity, and a small linear program picks the velocity closest to the preferred one that satisfies them all. The neighbour search is a uniform grid capped at `maxNeighbors`, so a tick costs the same for 50 agents and 5,000.

## @jgengine/core/ai/spawnDirector

- `DirectorContext` (interface): interface DirectorContext { alive: number; players?: number; playerPositions?: readonly NavPoint[] } — ⚠ undocumented
- `DirectorStep` (interface): interface DirectorStep { state: SpawnDirectorState; spawns: SpawnRequest[] } — ⚠ undocumented
- `SpawnDirectorConfig` (interface): interface SpawnDirectorConfig { waves: readonly WaveManifest[]; maxAlive?: number; escalationPerSecond?: number; alertBudgetPerSecond?: number; alertDecayPerSecond?: number; playerBudgetPerSecond?: number; maxSpawnsPerTick?: number; loop?: boolean; seed?: number; spawnP… — ⚠ undocumented
- `SpawnDirectorState` (interface): interface SpawnDirectorState { wave: number; elapsed: number; waveElapsed: number; budget: number; alert: number; spawnedThisWave: number; spawnedTotal: number; rng: RandomSeed; done: boolean } — ⚠ undocumented
- `SpawnEntry` (interface): interface SpawnEntry { id: string; cost: number; weight?: number; minWave?: number } — ⚠ undocumented
- `SpawnPointBiasStrength` (type): type SpawnPointBiasStrength = "subtle" | "moderate" | "strong" — How strongly `distanceBias` weights candidates by distance from `avoid` — a named intent, not a weighting exponent.
- `SpawnPointDistanceBias` (type): type SpawnPointDistanceBias = "near" | "far" | "none" — Preference for picking a spawn point relative to `avoid` positions: closer, farther, or unweighted.
- `SpawnPointSelectionOptions` (interface): interface SpawnPointSelectionOptions — Semantic options for selecting a spawn point without exposing weighting internals.
- `SpawnRequest` (interface): interface SpawnRequest { entryId: string; cost: number; wave: number; point?: NavPoint; laneId?: number } — ⚠ undocumented
- `WaveManifest` (interface): interface WaveManifest { budget: number; entries: readonly SpawnEntry[]; duration?: number; budgetPerSecond?: number } — ⚠ undocumented
- `advanceSpawnDirector` (function): function advanceSpawnDirector(config: SpawnDirectorConfig, state: SpawnDirectorState, dt: number, ctx: DirectorContext): DirectorStep — ⚠ undocumented
- `advanceWave` (function): function advanceWave(config: SpawnDirectorConfig, state: SpawnDirectorState): SpawnDirectorState — ⚠ undocumented
- `createSpawnDirectorState` (function): function createSpawnDirectorState(config: SpawnDirectorConfig): SpawnDirectorState — ⚠ undocumented
- `pickSpawnPoint` (function): function pickSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null — Selects a candidate spawn point using a semantic distance preference and caller-supplied randomness.
- `raiseAlert` (function): function raiseAlert(state: SpawnDirectorState, amount: number): SpawnDirectorState — ⚠ undocumented

## @jgengine/core/ai/spawnPoint

- `SpawnPointDistanceBias` (type): type SpawnPointDistanceBias = "near" | "far" | "none" — Preference for picking a spawn point relative to `avoid` positions: closer, farther, or unweighted.
- `SpawnPointSelectionOptions` (interface): interface SpawnPointSelectionOptions — Semantic options for selecting a spawn point without exposing weighting internals.

## @jgengine/core/ai/tacticalQueries

- `ScoredPosition` (interface): interface ScoredPosition — A candidate position with its deterministic weighted tactical score.
- `TacticalPositionEvaluators` (interface): interface TacticalPositionEvaluators — Functions that score one candidate position; higher values are preferred.
- `TacticalPositionWeights` (interface): interface TacticalPositionWeights — Weights and a hard bound for tactical candidate scoring.
- `coverPoints` (function): function coverPoints(mesh: NavMeshData, threatPos: Vec3, losBlocked: (a: Vec3, b: Vec3) => boolean): Vec3[] — Returns boundary locations that are hidden from a threat.
- `scorePositions` (function): function scorePositions(points: readonly Vec3[], evaluators: TacticalPositionEvaluators, weights: TacticalPositionWeights = {}): ScoredPosition[] — Score positions and retain at most `maxCandidates`, ordered highest score first.

## @jgengine/core/ai/targetAcquisition

- `AcquisitionEnvelope` (type): type AcquisitionEnvelope = number | ((selfId: string, candidateId: string) => number) — Composable target acquisition: the "which enemy do I lock onto?" decision split into the independent concerns every aggro system tangles together — a bounded candidate provider, an eligibility filter, a per-pair acquisition envelope (dynamic range), a perception/LOS gate, scoring, deterministic tie-break, and retention hysteresis. This owns *policy*; threat, brains, and movement stay separate. Feed `candidates` a spatial-index query, never a full-world scan.
- `AcquisitionPolicy` (interface): interface AcquisitionPolicy — A fully composed acquisition policy. Every concern is an independent, injectable seam; the only required pieces are the bounded `candidates` provider and the `distance` metric. Omit the rest to fall back to the thin default — a static/unbounded range, everything eligible and perceptible, nearest-wins scoring, id tie-break, no hysteresis — which matches a plain proximity aggro radius.
- `AcquisitionResult` (interface): interface AcquisitionResult — Outcome of one acquisition pass.
- `AcquisitionRetention` (interface): interface AcquisitionRetention — Retention hysteresis that keeps an already-held target from flickering under churn.
- `TargetAcquirer` (interface): interface TargetAcquirer — A stateful acquirer that holds the current target across passes — sugar over {@link acquireTarget}.
- `acquireTarget` (function): function acquireTarget(policy: AcquisitionPolicy, selfId: string, held: string | null = null): AcquisitionResult — Run one acquisition pass and pick the best target under `policy`. Pass the currently `held` target so retention hysteresis (`switchMargin`, `dropRangeScale`) can keep the lock stable; pass `null` for a cold acquire. Pure and allocation-light — the caller owns the held-target state.
- `createTargetAcquirer` (function): function createTargetAcquirer(policy: AcquisitionPolicy): TargetAcquirer — Wrap an {@link AcquisitionPolicy} in a small object that remembers the held target between passes, so callers get retention hysteresis for free without threading the previous target by hand. The only state is the held id (a string) — trivially serializable; round-trip it with {@link TargetAcquirer.hold}.

## @jgengine/core/ai/threat

- `HighestThreatOptions` (interface): interface HighestThreatOptions { current?: string | null; stickiness?: number } — ⚠ undocumented
- `ThreatEntry` (interface): interface ThreatEntry { sourceId: string; threat: number } — ⚠ undocumented
- `ThreatTable` (interface): interface ThreatTable { add(sourceId: string, amount: number): number; set(sourceId: string, amount: number): void; threatOf(sourceId: string): number; decay(dt: number): void; highest(options?: HighestThreatOptions): string | null; ranked(): ThreatEntry[]; taun… — ⚠ undocumented
- `ThreatTableConfig` (interface): interface ThreatTableConfig { decayPerSecond?: number; max?: number; forgetBelow?: number } — ⚠ undocumented
- `ThreatTableState` (interface): interface ThreatTableState — Plain JSON state of a {@link ThreatTable}; `entries` keeps insertion order, which breaks ties in `highest`.
- `createThreatTable` (function): function createThreatTable(config: ThreatTableConfig = {}): ThreatTable — ⚠ undocumented

## @jgengine/core/ai/utilityBrain

- `ResponseCurve` (type): type ResponseCurve = | { readonly kind: "linear"; readonly from: number; readonly to: number } /** Same shape as `linear`, raised to `exponent` (default `2`), so appeal stays flat until it matters. */ | { readonly kind: "quadratic"; readonly from: number; readonly to: number; readonly exponent?: num… — How one need's satisfaction maps to an option's appeal: `1` at `from`, `0` at `to`, clamped outside. Read satisfaction `1` as a full meter; pair with {@link UtilityTerm.invert} when a full meter is what makes the option attractive.
- `UtilityBrain` (interface): interface UtilityBrain — Utility-scored action selection over decaying needs: score every option's appeal through response curves, pick the best reachable candidate minus its cost, and hold that pick until a rival clears the hysteresis margin — unless a declared interrupt fires.
- `UtilityBrainConfig` (interface): interface UtilityBrainConfig extends UtilityTunables — Everything a utility brain needs: the shared need set, its scored options, and selection policy.
- `UtilityBrainSnapshot` (interface): interface UtilityBrainSnapshot — Serializable brain state: the held pick plus any in-play retuning. Needs save separately.
- `UtilityCandidate` (interface): interface UtilityCandidate — One reachable instance of an option this tick; `cost` is the caller's own effort number.
- `UtilityDebugSnapshot` (interface): interface UtilityDebugSnapshot — JSON-safe view of a brain for the devtools overlay and bug reports.
- `UtilityDecision` (interface): interface UtilityDecision — The outcome of one {@link UtilityBrain.decide}. Valid until the next `decide` call.
- `UtilityInterrupt` (interface): interface UtilityInterrupt — A need level that overrides the sticky pick the moment it is crossed.
- `UtilityOption` (interface): interface UtilityOption — A thing an agent can decide to do, scored against its needs.
- `UtilityScore` (interface): interface UtilityScore — One option's need-driven score, ignoring candidate cost.
- `UtilitySwitchReason` (type): type UtilitySwitchReason = "initial" | "score" | "interrupt" | "unavailable" — Why the brain's pick changed on the tick it changed.
- `UtilityTerm` (interface): interface UtilityTerm — One need's contribution to an option's appeal.
- `UtilityTunables` (interface): interface UtilityTunables — In-play dials that stay reachable through {@link UtilityBrain.retune}.
- `createUtilityBrain` (function): function createUtilityBrain(config: UtilityBrainConfig): UtilityBrain — Create a utility brain over an existing {@link NeedSet}. The need set is injected, not owned, so the game shows the same hunger the brain scores and persists one copy.
- `sampleResponseCurve` (function): function sampleResponseCurve(curve: ResponseCurve, satisfaction: number): number — Sample a response curve at a `0..1` satisfaction. Deterministic, allocation-free.

## @jgengine/core/ai/waveRunner

- `WaveRunner` (interface): interface WaveRunner — A live, observable, serializable wave/spawn runner over a seeded spawn director.
- `WaveRunnerConfig` (interface): interface WaveRunnerConfig extends SpawnDirectorConfig — Configuration for {@link createWaveRunner}: the full {@link SpawnDirectorConfig} (escalating waves, budgets, seed, spawn points) plus an optional {@link WaveSpawnSink}. The runner owns the director state — you never pass a `SpawnDirectorState` here.
- `WaveSpawnSink` (type): type WaveSpawnSink = (request: SpawnRequest) => void — A callback the wave runner hands each {@link SpawnRequest} the underlying spawn director emits. The runner never instantiates entities itself — it forwards the request (a free-string `entryId` "kind", cost, wave, optional point/lane) to the game, which decides what to build. Keeps the runner genre-agnostic.
- `WaveView` (interface): interface WaveView — A pooled, per-frame readout of the current wave — the "brain behind WAVE 3". Reused across {@link WaveRunner.view} calls (never per-frame allocated), so read it and render it, don't retain it.
- `createWaveRunner` (function): function createWaveRunner(config: WaveRunnerConfig): WaveRunner — A thin, stateful, observable wrapper around the seeded {@link createSpawnDirectorState} / {@link advanceSpawnDirector} model. It OWNS a {@link SpawnDirectorState}, ticks it from `update(dt, ctx?)`, keeps the new state, and forwards each emitted {@link SpawnRequest} to an optional `onSpawn` sink so the model never instantiates entities. `view()` returns a pooled per-frame readout — the "brain behind WAVE 3": the 1-based wave number, wave progress `0..1`, banked budget, per-wave and total spawn counts, alert, and done flag. `forceNextWave` / `raiseAlert` drive it, `subscribe` observes it, and `snapshot`/`restore` round-trip the plain serializable state object through a save. Nothing here is genre-specific: spawn-entry `kind`s (the director's `entryId`s) stay free strings the runner never interprets.

## @jgengine/core/anim/actionLayer

- `ACTION_REST_STATE` (const): const ACTION_REST_STATE: "rest" — State id of an action layer's resting state.
- `ActionLayerInput` (interface): interface ActionLayerInput — A masked, optionally additive overlay layer: a resting clip plus one one-shot state per action.
- `actionLayer` (function): function actionLayer(input: ActionLayerInput): AnimLayer — One overlay layer from plain data: a resting state plus a one-shot state per action, each joined to the rest by a consumed-trigger transition and returning on `exitTime`. Aim, reload, wave and hit reactions are the same shape, so they are one builder instead of a hand-written state machine per game. The layer is masked by bone prefix, and `additive: true` makes it a recoil/breathing overlay on top of the base pose rather than a replacement.
- `withActionLayers` (function): function withActionLayers(graph: AnimGraph, layers: readonly ActionLayerInput[]): AnimGraph — A graph plus overlay layers: the base layers keep their ids and order, and each overlay is appended. Duplicate layer ids are rejected rather than silently shadowing, because the shell keys its mixer actions by layer id.

## @jgengine/core/anim/animGraph

- `ANIM_PARAMS_KEY` (const): const ANIM_PARAMS_KEY: "anim.params" — Entity blackboard key the shell reads extra graph parameters from: `ctx.scene.entity.blackboard.set(id, ANIM_PARAMS_KEY, { aiming: true })`.
- `AnimClipOutput` (interface): interface AnimClipOutput — One clip's contribution: weight 0..1 and the time to seek it to.
- `AnimCompare` (type): type AnimCompare = ">" | "<" | ">=" | "<=" | "==" | "!=" — Comparison operators an {@link AnimCondition} supports.
- `AnimCondition` (interface): interface AnimCondition — A parameter comparison; every condition on a transition must hold.
- `AnimEvent` (interface): interface AnimEvent — A named moment inside a clip (foot plant, hit frame, reload point).
- `AnimGraph` (interface): interface AnimGraph — Serializable animation graph. Clip durations come from the rig at runtime (see {@link AnimGraphClipInfo}).
- `AnimGraphClipInfo` (type): type AnimGraphClipInfo = Readonly<Record<string, number | { duration: number; rootTrack?: { times: Float32Array; values: Float32Array } }>> — Per-clip duration in seconds, read from the loaded rig.
- `AnimGraphDiagnostic` (interface): interface AnimGraphDiagnostic — A located, repairable error in an authored animation graph; paths are relative to the graph value.
- `AnimGraphOutput` (interface): interface AnimGraphOutput — What one advance asks the rig to show.
- `AnimGraphRuntime` (interface): interface AnimGraphRuntime — The evaluator handle: arm triggers, advance, inspect, snapshot and restore.
- `AnimGraphRuntimeOptions` (interface): interface AnimGraphRuntimeOptions — Randomness used only when entering a clip state with variants. Omit to choose the first variant.
- `AnimGraphState` (interface): interface AnimGraphState — Serializable evaluator state.
- `AnimGraphValidation` (interface): interface AnimGraphValidation — The whole authored graph is retained unchanged only when every supported field is valid.
- `AnimLayer` (interface): interface AnimLayer — A blend layer with its own state machine. Masked layers apply only to bones whose track names start with a prefix.
- `AnimParamValue` (type): type AnimParamValue = number | boolean — Parameter value a graph reads: floats for blends and comparisons, booleans for gates.
- `AnimParams` (type): type AnimParams = Readonly<Record<string, AnimParamValue>> — The parameter set a graph evaluates against each advance.
- `AnimState` (type): type AnimState = | { kind: "clip"; clip: string; variants?: readonly string[]; speed?: number; loop?: boolean; rootMotion?: boolean } | { kind: "blend1D"; param: string; points: readonly { at: number; clip: string }[]; speed?: number; loop?: boolean; rootMotion?: boolean } | { kind: "blend2D"; param… — A state plays one clip, or blends clips by one or two parameters.
- `AnimTransition` (interface): interface AnimTransition — Edge between states. `from: "*"` matches any state except `to`.
- `createAnimGraphRuntime` (function): function createAnimGraphRuntime(initial: AnimGraph, options: AnimGraphRuntimeOptions = {}): AnimGraphRuntime — Headless animation state machine and blend evaluator. It owns every clip's playback time and weight, so the renderer only seeks and weights actions on a mixer, and headless hosts, replays, and tests advance the same graph without three.js. Transitions are data (parameter comparisons and consumed triggers), layers can be masked or additive, and events fire by clip time, including across loop wraps.
- `parseAnimGraph` (function): function parseAnimGraph(value: unknown): AnimGraph | undefined — Validates untrusted JSON (a saved scene document, a network payload) as an {@link AnimGraph}. Malformed states, transitions to unknown states, and bad conditions are dropped; a layer whose entry state is missing is dropped; the result is `undefined` when no layer survives.
- `stateClipWeights` (function): function stateClipWeights(state: AnimState, params: AnimParams): Record<string, number> — Static clip weights of a state at `params`, before any crossfade.
- `validateAnimGraph` (function): function validateAnimGraph(value: unknown): AnimGraphValidation — Validate an authored graph without dropping broken combat states or weakening transition conditions. Known malformed fields and dangling references reject the whole graph with relative repair locations; valid data, including authored object/array order, is returned unchanged. Unknown extension fields are retained. Clip availability belongs to the imported-rig diagnostics. Use {@link parseAnimGraph} when permissive repair is intentional.

## @jgengine/core/anim/boneTexture

- `BoneTextureClip` (interface): interface BoneTextureClip — One baked clip's rows in a {@link BoneTextureLayout}.
- `BoneTextureClipInput` (interface): interface BoneTextureClipInput — A clip to bake: its name and length in seconds.
- `BoneTextureInput` (interface): interface BoneTextureInput — Inputs for {@link planBoneTexture}.
- `BoneTextureLayout` (interface): interface BoneTextureLayout — Where every bone matrix of every baked frame lives in a vertex-animation texture: one row per frame, four RGBA texels (matrix columns) per bone. Plain data, so a baked crowd can be cached, shipped or checked in a test without a renderer.
- `BoneTextureSample` (interface): interface BoneTextureSample — Two texture rows around a playback time and the blend between them.
- `planBoneTexture` (function): function planBoneTexture(input: BoneTextureInput): BoneTextureLayout — Plans a bone-matrix texture for a rig's clips. Throws when the rig or the clip set does not fit `maxTextureSize`; lower `fps` or bake fewer clips.
- `sampleBoneTexture` (function): function sampleBoneTexture(clip: BoneTextureClip, fps: number, time: number, loop: boolean, out?: BoneTextureSample): BoneTextureSample — Finds the baked rows around `time` in a clip, wrapping when `loop` and holding the last pose otherwise. This is the CPU mirror of the crowd shader's lookup.

## @jgengine/core/anim/easing

- `Easing` (type): type Easing = (t: number) => number — ⚠ undocumented

## @jgengine/core/anim/footPlacement

- `FootGroundSample` (interface): interface FootGroundSample — One foot's animated ankle height and the ground found under it, both in world units.
- `FootPlacement` (interface): interface FootPlacement — Result of {@link placeFeet}: where each ankle should go and how far the pelvis drops.
- `FootPlacementInput` (interface): interface FootPlacementInput — Inputs for {@link placeFeet}. All heights are world units.
- `LegChain` (interface): interface LegChain — Thigh → shin → foot bone names for one leg.
- `RigBone` (interface): interface RigBone — A bone as {@link inferLegChains} sees it: its name and its parent's name.
- `inferLegChains` (function): function inferLegChains(bones: readonly RigBone[]): LegChain[] — Finds leg chains on a humanoid rig by bone name: a thigh-like bone (`UpLeg`, `UpperLeg`, `Thigh`) with its first child and grandchild as shin and foot. Control, IK-target and twist bones are skipped. Returns chains in rig order; an empty array means the rig has no recognizable legs.
- `placeFeet` (function): function placeFeet(input: FootPlacementInput, out?: FootPlacement): FootPlacement — Resolves foot placement for a rig whose clips were authored on flat ground at its origin. Each foot keeps its animated lift and moves by its ground's height above or below the origin, the sole is never left under the ground, and the pelvis drops by the deepest reach so both legs stay within length. Pure and allocation-light; the renderer applies the targets with {@link solveTwoBone}.

## @jgengine/core/anim/ikSolver

- `FabrikOptions` (interface): interface FabrikOptions — Iteration budget and convergence threshold for {@link solveFabrik}.
- `LookAtInput` (interface): interface LookAtInput — Inputs for {@link lookAt}. Angles are in radians.
- `MutableVec3` (type): type MutableVec3 = [number, number, number] — A mutable three-dimensional tuple used by allocation-aware solver outputs.
- `Quat` (type): type Quat = readonly [number, number, number, number] — A quaternion in `(x, y, z, w)` order.
- `TwoBoneInput` (interface): interface TwoBoneInput — Inputs for {@link solveTwoBone}.
- `TwoBoneOutput` (interface): interface TwoBoneOutput — Reused output buffers filled by {@link solveTwoBone}.
- `Vec3` (type): type Vec3 = readonly [number, number, number] — A three-dimensional point or direction represented without a renderer dependency.
- `lookAt` (function): function lookAt(input: LookAtInput): Quat — Returns a quaternion that points a +Z bone from `from` toward `target`, with optional yaw and pitch limits.
- `multiplyQuaternions` (function): function multiplyQuaternions(a: Quat, b: Quat): Quat — The product of two quaternions (`a` applied after `b`), both as `[x, y, z, w]`.
- `quaternionFromUnitVectors` (function): function quaternionFromUnitVectors(from: Vec3, to: Vec3): Quat — The shortest rotation taking one unit direction to another, as a quaternion. Parallel directions give the identity; opposite directions give a half turn about a perpendicular axis. Returns the identity for a zero-length input.
- `solveFabrik` (function): function solveFabrik(chain: readonly Vec3[], target: Vec3, options: FabrikOptions = {}): MutableVec3[] — Solves a chain with the FABRIK forward-and-backward reaching algorithm. Returned tuples are new values; the input chain is not modified.
- `solveTwoBone` (function): function solveTwoBone(input: TwoBoneInput, out: TwoBoneOutput): TwoBoneOutput — Solves a two-segment chain analytically, placing the middle and tip joints toward `target` and `pole`. The root remains fixed, and unreachable targets are clamped to the chain's maximum reach.

## @jgengine/core/anim/locomotionGraph

- `LOCOMOTION_BACKWARD_STATE` (const): const LOCOMOTION_BACKWARD_STATE: "backward" — State id of the backwards blend.
- `LOCOMOTION_CROUCHED_PARAM` (const): const LOCOMOTION_CROUCHED_PARAM: "crouched" — Physically resolved crouch stance from the shared player motor.
- `LOCOMOTION_DIRECTION_PARAM` (const): const LOCOMOTION_DIRECTION_PARAM: "direction" — Signed lateral share of the character's motion: `-1` fully to its left, `+1` fully to its right, `0` straight ahead or straight back. A custom mover feeds it under `ANIM_PARAMS_KEY`.
- `LOCOMOTION_FACING_PARAM` (const): const LOCOMOTION_FACING_PARAM: "facing" — Dot of the character's facing with its motion direction: `1` running forward, `-1` running backwards. A custom mover feeds it under `ANIM_PARAMS_KEY`.
- `LOCOMOTION_GROUNDED_PARAM` (const): const LOCOMOTION_GROUNDED_PARAM: "grounded" — Ground contact reported by the shared player motor; absent for custom movers without authored parameters.
- `LOCOMOTION_LAYER` (const): const LOCOMOTION_LAYER: "base" — Layer id the locomotion graph uses; query `runtime.stateOf(LOCOMOTION_LAYER)`.
- `LOCOMOTION_SPEED_PARAM` (const): const LOCOMOTION_SPEED_PARAM: "speed" — The parameter name the shell feeds with the entity's smoothed ground speed.
- `LOCOMOTION_STATE` (const): const LOCOMOTION_STATE: "locomotion" — State id of the forward idle/walk/run blend.
- `LOCOMOTION_STRAFE_STATE` (const): const LOCOMOTION_STRAFE_STATE: "strafe" — State id of the lateral strafe blend.
- `LOCOMOTION_TURN_RATE_PARAM` (const): const LOCOMOTION_TURN_RATE_PARAM: "turnRate" — Signed yaw rate in radians/sec; a custom mover feeds it under `ANIM_PARAMS_KEY`.
- `LOCOMOTION_TURN_STATE` (const): const LOCOMOTION_TURN_STATE: "turn" — State id of the on-the-spot turn blend.
- `LOCOMOTION_VERTICAL_SPEED_PARAM` (const): const LOCOMOTION_VERTICAL_SPEED_PARAM: "verticalSpeed" — Resolved vertical velocity from the shared player motor, in world units/sec.
- `LocomotionGraphInput` (interface): interface LocomotionGraphInput — Inputs for {@link locomotionGraph}: the locomotion clip names and the one-shot table a rig config already carries.
- `animGraphFromConfig` (function): function animGraphFromConfig(config: ModelAnimationConfig): AnimGraph | undefined — The graph a model animation config plays: its `graph`, or the {@link locomotionGraph} its `states` and `oneShots` describe, retaining every one-shot variant. `undefined` for a single-clip config or incomplete locomotion roles. Idle must name a clip; an absent or blank walk role holds that idle clip at walking speeds until configured. The shell plays this and the editor inspects it, so both see the same graph.
- `locomotionGraph` (function): function locomotionGraph(input: LocomotionGraphInput): AnimGraph — The engine's default locomotion as an authored graph: a speed-driven blend between idle, walk and run, plus a state per one-shot that plays once and returns (or clamps for `death`). What `useModelAnimation` used to hardcode.

## @jgengine/core/anim/ragdollRig

- `HUMANOID_RAGDOLL_BODIES` (const): const HUMANOID_RAGDOLL_BODIES: Readonly<Partial<Record<SkeletonSlot, RagdollBodyShape>>> — Humanoid body shapes for the standard slots, sized for a roughly 1.8 m character standing on the ground. A rig of another scale multiplies them (see {@link RagdollRigOptions.scale}).
- `RagdollBodyShape` (interface): interface RagdollBodyShape — Half-extents and mass of one standard slot's physics body, in the rig's own world units.
- `RagdollPose` (interface): interface RagdollPose — One standard slot's world pose, sampled at the moment a character is killed. The orientation is the reference the ragdoll's aim rotates from, so every bone keeps the roll it died with.
- `RagdollRigOptions` (interface): interface RagdollRigOptions — Tuning for {@link ragdollConfigFromPoses}.
- `ragdollBoneOrientations` (function): function ragdollBoneOrientations(rest: readonly RagdollPose[], positions: Readonly<Partial<Record<SkeletonSlot, readonly [number, number, number]>>>): Partial<Record<SkeletonSlot, [number, number, number, number]>> — World orientations for a ragdoll's bones from its bodies' current positions: each bone rotates from its rest direction-to-child onto the current one, so the aim follows the joints while every bone keeps the roll it had in the death pose. A bone with no posed child keeps its rest orientation. The physics bodies carry translation only, so this is what gives the ragdoll a skeleton instead of a pile of boxes.
- `ragdollConfigFromPoses` (function): function ragdollConfigFromPoses(map: SkeletonMap, poses: readonly RagdollPose[], options: RagdollRigOptions = {}): RagdollConfig — A jointed ragdoll for a mapped rig from its bones' world poses at the moment of death: one box body per standard slot that has a shape, sized to the character, and one distance link per slot that has its parent present, holding the bones' own separation. The bodies start where the character actually was, so the collapse continues the death pose instead of snapping to a preset.

## @jgengine/core/anim/skeletonStandard

- `KAYKIT_SCHEME` (const): const KAYKIT_SCHEME: RigScheme — The standard itself, as a scheme: a KayKit rig already is the standard, so its own names are the candidates. Both authored (`upperleg.l`) and runtime (`upperlegl`) spellings are accepted.
- `LOWER_BODY_MASK` (const): const LOWER_BODY_MASK: readonly string[] — Layer mask for a lower-body layer on a standard rig.
- `LOWER_BODY_SLOTS` (const): const LOWER_BODY_SLOTS: readonly SkeletonSlot[] — Standard slots a lower-body layer drives: hips, both legs and both feet.
- `MIXAMO_SCHEME` (const): const MIXAMO_SCHEME: RigScheme — Mixamo exports (`mixamorig*` names, or the same names without the prefix). Mixamo has a neck and a shoulder per side, which the standard folds into `chest` and `upperArm`; its toe is `ToeBase`, which is the standard's `toes`. Mixamo's topmost bone is `Hips`, so `root` and `hips` both resolve to it — a rig on this scheme has no bone above the pelvis.
- `QUATERNIUS_ALIEN_SCHEME` (const): const QUATERNIUS_ALIEN_SCHEME: RigScheme — Quaternius sci-fi aliens: a `Root` plus a `Spine_1..Spine_6` chain, a `Neck` and a `Head`. The pack ships no arms and no legs, so those slots stay empty and the alien can only be driven on its spine and head. That is the honest mapping: the pack's own clip set is `Alien_Idle` alone.
- `RIG_SCHEMES` (const): const RIG_SCHEMES: Readonly<Record<string, RigScheme>> — Every scheme the engine ships a mapping for, keyed by {@link RigScheme.id}.
- `RigScheme` (interface): interface RigScheme — A source naming scheme and the bone names on it that fill each standard slot. A slot lists every accepted spelling; matching is case- and punctuation-insensitive, so `mixamorigLeftUpLeg` and `LeftUpLeg` are the same candidate.
- `SKELETON_PARENT` (const): const SKELETON_PARENT: Readonly<Partial<Record<SkeletonSlot, SkeletonSlot>>> — The parent slot of each slot that has one; `root` has none.
- `SKELETON_SLOTS` (const): const SKELETON_SLOTS: readonly SkeletonSlot[] — Every standard slot, in parent-before-child order.
- `SKELETON_STANDARD` (const): const SKELETON_STANDARD: SkeletonStandard — The one humanoid skeleton standard. Bone names are the authored KayKit names; the loaded hierarchy spells them without `.` and `resolveRigNode` accepts either.
- `SkeletonMap` (interface): interface SkeletonMap — The result of mapping a rig's bones onto {@link SKELETON_STANDARD}.
- `SkeletonSlot` (type): type SkeletonSlot = | "root" | "hips" | "spine" | "chest" | "head" | "upperArm.l" | "upperArm.r" | "lowerArm.l" | "lowerArm.r" | "hand.l" | "hand.r" | "handSlot.l" | "handSlot.r" | "upperLeg.l" | "upperLeg.r" | "lowerLeg.l" | "lowerLeg.r" | "foot.l" | "foot.r" | "toes.l" | "toes.r" — The engine's one humanoid skeleton standard, and the path any other CC0 rig takes onto it.
- `SkeletonStandard` (interface): interface SkeletonStandard — A named skeleton standard: its id and the authored bone name for each slot it defines.
- `SlotLength` (interface): interface SlotLength — A standard slot and the rest-pose length of the bone chain that reaches it.
- `UPPER_BODY_MASK` (const): const UPPER_BODY_MASK: readonly string[] — Layer mask for an upper-body action layer (aim, reload, hit reaction) on a standard rig.
- `UPPER_BODY_SLOTS` (const): const UPPER_BODY_SLOTS: readonly SkeletonSlot[] — Standard slots an upper-body action layer drives: spine, chest, head and both arms.
- `mapRigToStandard` (function): function mapRigToStandard(bones: readonly string[], scheme: RigScheme | string = KAYKIT_SCHEME): SkeletonMap — Maps a rig's bone names onto {@link SKELETON_STANDARD} through one {@link RigScheme}. Each slot takes the first candidate that resolves; a candidate list is tried in order, so a scheme can name a preferred bone and fall back. Bones that fill no slot come back in `unmapped`, and slots the rig cannot fill in `missing` — the caller decides whether a partial map is usable.
- `retargetBoneScales` (function): function retargetBoneScales(source: readonly SlotLength[], target: readonly SlotLength[]): Partial<Record<SkeletonSlot, number>> — Per-slot length ratios that stretch a source rig's bone chain onto the standard's proportions, so a retargeted clip moves both rigs the same distance rather than the same angle. Slots with no counterpart on either side are omitted; a source length of zero is skipped instead of dividing.
- `retargetTracks` (function): function retargetTracks(tracks: readonly string[], map: SkeletonMap): (string | null)[] — Renames a clip's tracks from a rig's own bone names onto the standard's, so one authored clip plays on a mapped rig. The emitted node is the **runtime** bone name (see {@link runtimeBoneName}), which is what both the loaded scene graph and the loaded clips spell. A track whose node fills no slot is dropped (`null` in the result) rather than left pointing at a bone the rig does not have; a track whose property is not one of the four three writes is dropped too, since renaming it would not make it resolvable.
- `runtimeBoneName` (function): function runtimeBoneName(authored: string): string — The runtime name GLTFLoader gives an authored bone name: three's `PropertyBinding.sanitizeNodeName` strips `[ ] . : /`, so the authored `upperleg.l` loads as `upperlegl`.
- `standardBoneMask` (function): function standardBoneMask(slots: readonly SkeletonSlot[]): string[] — Bone-name prefixes for a set of standard slots, for an {@link AnimLayer.mask}. A slot on one side contributes its side-less prefix (`upperLeg.l` → `upperleg`), which matches both sides' tracks; an unsided slot contributes its own runtime name. Masking by slot means a rig mapped onto the standard is masked without hand-typing its bone names.

## @jgengine/core/area/areaEffectField

- `AreaEffectEvent` (interface): interface AreaEffectEvent<P> — One membership edge emitted by `step`, `removeSource`, or `clear`.
- `AreaEffectField` (interface): interface AreaEffectField<P> — Runtime handle tracking continuous area membership across ticks.
- `AreaEventKind` (type): type AreaEventKind = "enter" | "refresh" | "leave" — The three membership edges a step can emit.
- `AreaFieldState` (interface): interface AreaFieldState<P> — Serialized field state: source descriptors (minus their transient shape) and per-member refresh phase.
- `AreaLeaveReason` (type): type AreaLeaveReason = "exit" | "source-removed" | "disabled" | "cleared" — Why a `leave` edge fired.
- `AreaMembership` (interface): interface AreaMembership<P> — One active (source, receiver) membership — feed a receiver's list to a stacking policy.
- `AreaShape` (type): type AreaShape = | { readonly kind: "sphere"; readonly center: EntityPosition; readonly radius: number } | { readonly kind: "custom"; /** Bounding-sphere center the caller's broad-phase `candidates` query is built from. */ readonly center: EntityPosition; /** Bounding-sphere radius the caller's broa… — The area a source occupies this tick. `sphere` is first-class; `custom` leaves a seam for authored volumes and other shapes while still exposing a bounding sphere (`center`/`radius`) for the caller's broad-phase candidate query.
- `AreaSourceSpec` (interface): interface AreaSourceSpec<P> — Descriptor for one continuous area source; re-supplied each tick so its shape follows the emitter.
- `AreaStepInput` (interface): interface AreaStepInput — Per-tick inputs the field needs to reconcile membership without scanning the world.
- `createAreaEffectField` (function): function createAreaEffectField<P = unknown>(state?: AreaFieldState<P>): AreaEffectField<P> — Build a continuous area-effect field. Drive it with `setSource` (once per live source per tick, so shapes follow their emitters) and `step` (to reconcile membership and drain enter/refresh/leave edges). Optionally restore prior membership by passing a `serialize()` snapshot; re-`setSource` live shapes before the first `step` after restore, since shapes are transient.

## @jgengine/core/area/stackPolicy

- `AreaStackPolicy` (type): type AreaStackPolicy<P> = (memberships: readonly AreaMembership<P>[]) => AreaMembership<P>[] — Reduce one receiver's overlapping memberships to the subset that applies under a stacking rule.
- `MagnitudeOf` (type): type MagnitudeOf<P> = (membership: AreaMembership<P>) => number — Read a comparable magnitude from a membership (e.g. buff strength, damage per tick).
- `cappedStacks` (function): function cappedStacks<P>(limit: number, magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P> — Keep at most `limit` memberships per `stackKey` (the highest-magnitude ones when `magnitudeOf` is given, else the first-seen). Models capped stacks — e.g. a poison that stacks up to 5 times.
- `extremumStack` (function): function extremumStack<P>(magnitudeOf: MagnitudeOf<P>, weakest = false): AreaStackPolicy<P> — Reduce to the single strongest membership overall (`weakest = false` picks the weakest); ties broken by `sourceId`. Use when only the best or worst overlapping source should apply.
- `independentStacks` (function): function independentStacks<P>(): AreaStackPolicy<P> — Every overlapping membership applies independently (no deduplication) — the default for hazards, fields, and lights where two sources genuinely stack.
- `sumMagnitude` (function): function sumMagnitude<P>(memberships: readonly AreaMembership<P>[], magnitudeOf: MagnitudeOf<P>): number — Sum a numeric magnitude across memberships — additive aggregation for a total field strength (total damage per tick, total slow). A terminal reducer, not a filter, so it returns the number.
- `uniqueByStackKey` (function): function uniqueByStackKey<P>(magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P> — Keep at most one membership per `stackKey`. With `magnitudeOf` the strongest per key wins (ties broken by `sourceId` for determinism); without it the first-seen per key wins. Use for unique-by-key buffs where reapplying the same aura should not stack.

## @jgengine/core/audio/audioFalloff

- `AudioBusDef` (interface): interface AudioBusDef { id: AudioBusId; gain?: number } — ⚠ undocumented · used by `withFeedbackCueSounds` (@jgengine/core/audio/feedbackCues): Merge the default feedback reactions into a game's sound catalog.
- `AudioBusId` (type): type AudioBusId = string — ⚠ undocumented
- `AudioFalloffConfig` (interface): interface AudioFalloffConfig { minDistance?: number; maxDistance?: number; curve?: FalloffCurve } — ⚠ undocumented
- `FalloffCurve` (type): type FalloffCurve = "linear" | "inverse" | "none" — ⚠ undocumented
- `SoundDef` (interface): interface SoundDef { id: string; url?: string; synth?: SynthPatch; bus: AudioBusId; gain?: number; loop?: boolean; maxVoices?: number; priority?: number; positional?: boolean; falloff?: AudioFalloffConfig; doppler?: number; spatial?: {panning: "hrtf" | "equal… — ⚠ undocumented · used by `DEFAULT_FEEDBACK_CUE_SOUNDS` (@jgengine/core/audio/feedbackCues): Short procedural reactions - no samples to load, so every game has impact feedback without authoring audio.
- `computeFalloffGain` (function): function computeFalloffGain(distance: number, config: AudioFalloffConfig = {}): number — ⚠ undocumented
- `distance3` (function): function distance3(a: { x: number; y: number; z: number }, b: { x: number; y: number; z: number }): number — ⚠ undocumented
- `resolveEmitterGain` (function): function resolveEmitterGain(distance: number, sound: Pick<SoundDef, "gain" | "positional" | "falloff">, busGain: number): number — ⚠ undocumented

## @jgengine/core/audio/doppler

- `DopplerOptions` (interface): interface DopplerOptions — Options for {@link dopplerRate}.
- `SPEED_OF_SOUND` (const): const SPEED_OF_SOUND: 343 — Speed of sound in air at 20 °C, metres per second — the default for {@link dopplerRate}.
- `dopplerRate` (function): function dopplerRate(listenerPosition: Vec3Tuple, listenerVelocity: Vec3Tuple, emitterPosition: Vec3Tuple, emitterVelocity: Vec3Tuple, options: DopplerOptions = {}): number — Doppler pitch multiplier for an emitter heard by a listener: `(c + vListener) / (c - vEmitter)`, where each speed is the component along the line between them, positive when closing. Multiply a loop's playback rate by it. Pure and allocation-free.

## @jgengine/core/audio/engineLayers

- `EngineLayer` (interface): interface EngineLayer — One recorded engine sample, keyed by the rpm it was recorded at.
- `EngineLayerMix` (interface): interface EngineLayerMix — One layer's live mix.
- `EngineLayers` (interface): interface EngineLayers — A layered engine loop: N rpm-keyed samples crossfaded by rpm, with on- and off-load sets picked by engine load.
- `EngineLayersAudio` (interface): interface EngineLayersAudio — The part of `ctx.game.audio` {@link EngineLayers} drives.
- `EngineLayersConfig` (interface): interface EngineLayersConfig — Config for {@link createEngineLayers}.
- `EngineLayersPlayOptions` (interface): interface EngineLayersPlayOptions — Per-tick parameters {@link EngineLayers.play} forwards to every layer's loop.
- `EngineLayersState` (interface): interface EngineLayersState — Serializable {@link EngineLayers} state.
- `createEngineLayers` (function): function createEngineLayers(initial: EngineLayersConfig): EngineLayers — Layered engine sound: each set of rpm-keyed samples is equal-power crossfaded between the two samples bracketing the current rpm and pitched by `rpm / layer.rpm`; the on- and off-load sets are equal-power crossfaded by smoothed `engineLoad`. A config with only one load set plays it at every load. `play` drives `ctx.game.audio` directly, so a game needs no per-layer glue.

## @jgengine/core/audio/feedbackCues

- `DEFAULT_FEEDBACK_CUE_SOUNDS` (const): const DEFAULT_FEEDBACK_CUE_SOUNDS: Readonly<Record<FeedbackCue, SoundDef>> — Short procedural reactions - no samples to load, so every game has impact feedback without authoring audio. Loud enough to read, quiet enough to sit under a weapon's own sound.
- `FEEDBACK_CUES` (const): const FEEDBACK_CUES: readonly FeedbackCue[] — Every {@link FeedbackCue}, in a stable order.
- `FEEDBACK_CUE_BUS` (const): const FEEDBACK_CUE_BUS: "sfx" — Bus the default feedback cues mix through; the settings menu shows its volume and mute.
- `FeedbackCue` (type): type FeedbackCue = "hit" | "hurt" | "kill" | "pickup" | "objective" | "wave" | "deny" — A gameplay moment the engine reacts to: taking or dealing a hit, a kill, a pickup, an objective, a wave starting, or a refused action. The game names the moment; the engine owns the reaction.
- `FeedbackCueOverrides` (type): type FeedbackCueOverrides = false | Partial<Record<FeedbackCue, SoundDef | false>> — Per-cue override: a replacement sound, or `false` to silence that cue. `false` for the whole map silences all.
- `feedbackCueSoundId` (function): function feedbackCueSoundId(cue: FeedbackCue): string — Catalog id a cue plays under: `feel.hit`, `feel.kill`, ... A game sound with that id replaces the default.
- `withFeedbackCueSounds` (function): function withFeedbackCueSounds(sounds: Readonly<Record<string, SoundDef>> | undefined, buses: Readonly<Record<string, AudioBusDef>> | undefined, overrides?: FeedbackCueOverrides): { sounds: Record<string, SoundDef>; buses: Record<string, AudioBusDef> | undefined } — Merge the default feedback reactions into a game's sound catalog. A game sound already named `feel.<cue>` wins, then `overrides`, then the default. Adds the `sfx` bus (gain 0.9) when the game did not declare one, so the impact layer has its own volume and mute row.

## @jgengine/core/audio/music

- `MusicInstrument` (type): type MusicInstrument = | "strings" | "flute" | "harp" | "horn" | "choir" | "bell" | "timpani" | "bass" | "stacc" | "pad" | "lute" | "dulcimer" | "frameDrum" | "warDrum" | "reed" | "pipe" | "squareLead" | "woodBlock" | "tinyBell" | "piano" | "shaker" | "brassStab" | "cymSwell" | "oboe" — Named synthesised instrument. Each maps to a voice in the shell's instrument library (`@jgengine/shell/audio/musicVoices`); an unknown name falls back to a plain sine voice so a theme is never silent.
- `MusicTheme` (interface): interface MusicTheme — A through-composed, looping music track. `events` need not be sorted; the director schedules them ahead against a fixed anchor so loops are seamless.
- `NoteEvent` (interface): interface NoteEvent — One scheduled note in a theme, positioned on the loop's quarter-note grid.
- `ScheduledNote` (interface): interface ScheduledNote — A resolved note occurrence: the source note plus its absolute onset in seconds.
- `mtof` (function): function mtof(midi: number): number — Standard equal-temperament MIDI-to-frequency (A4 = 440 Hz at MIDI 69).
- `notesInWindow` (function): function notesInWindow(theme: MusicTheme, anchorSec: number, fromSec: number, toSec: number): ScheduledNote[] — Pure lookahead scheduler: every note occurrence of `theme` whose onset falls in the half-open window `(fromSec, toSec]`, given the theme's loop-zero at `anchorSec`. Handles any number of loop wraps, so a director calls it once per tick with a non-overlapping window and never double-schedules a note.
- `themeLoopSeconds` (function): function themeLoopSeconds(theme: MusicTheme): number — Loop length of a theme in seconds.

## @jgengine/core/audio/musicState

- `MusicStateConfig` (interface): interface MusicStateConfig — The tier ladder plus the release margin that keeps a hovering intensity from flapping between tiers.
- `MusicStateInput` (interface): interface MusicStateInput — The current intensity signal and clock reading for one resolve.
- `MusicStateResult` (interface): interface MusicStateResult — Next state, the theme that should be playing, and whether this advance is the one that changed it.
- `MusicStateSnapshot` (interface): interface MusicStateSnapshot — Which tier is playing and when it was entered, on the caller's clock. Serialisable.
- `MusicTier` (interface): interface MusicTier — Hysteretic music-state selector: turns a continuous intensity signal (nearby threat, alert count, chase proximity) into a stable theme id. The engine can already crossfade a soundtrack; this decides *when*, without the flapping a bare threshold produces when one enemy walks in and out of range.
- `createMusicState` (function): function createMusicState(): MusicStateSnapshot — Fresh state with no tier entered, so the first resolve always settles and reports `changed`.
- `resolveMusicState` (function): function resolveMusicState(state: MusicStateSnapshot, input: MusicStateInput, config: MusicStateConfig): MusicStateResult — Pick the theme for the current intensity. Escalation is immediate; de-escalation waits for the tier's `holdMs` and needs the intensity to fall a `release` margin below the tier it is leaving.

## @jgengine/core/audio/stepCadence

- `StepCadenceConfig` (interface): interface StepCadenceConfig — Distance-driven footstep cadence. Pure state-in/state-out: feed it how far a mover travelled this frame and it tells you how many steps landed, so foley stays locked to ground distance instead of a wall-clock timer that desyncs when speed changes.
- `StepCadenceInput` (interface): interface StepCadenceInput — What the mover did this advance: ground distance covered, whether feet are planting, and the stride multiplier.
- `StepCadenceResult` (interface): interface StepCadenceResult — Outcome of one advance: the next state plus how many steps landed and which foot led.
- `StepCadenceState` (interface): interface StepCadenceState — Cadence bookkeeping between advances — banked distance, last moving state, and the step count whose parity is the foot.
- `advanceStepCadence` (function): function advanceStepCadence(state: StepCadenceState, input: StepCadenceInput, config: StepCadenceConfig): StepCadenceResult — Bank this advance's distance and report the steps it completed. Pure — same state and input always give the same result, so footstep timing is testable headless and replays identically.
- `createStepCadenceState` (function): function createStepCadenceState(): StepCadenceState — Fresh cadence state for a mover that is standing still.

## @jgengine/core/audio/synth

- `NoiseVoice` (interface): interface NoiseVoice — A filtered white-noise burst — impacts, whooshes, breath, crackle. Realised from a shared 1s noise buffer at a randomised playback rate and start offset, decaying exponentially to silence at `duration * decay`.
- `SynthFilter` (type): type SynthFilter = "lowpass" | "highpass" | "bandpass" — Biquad filter shape a noise voice is coloured through.
- `SynthPatch` (interface): interface SynthPatch — A procedural sound cue: a set of voices triggered together, each with its own `delay`, summed into one one-shot. Pure serialisable data — the shell realises it on Web Audio, so the same catalog runs headless in tests with no `AudioContext`.
- `SynthVoice` (type): type SynthVoice = ToneVoice | NoiseVoice — One layered voice of a synth cue.
- `SynthWave` (type): type SynthWave = "sine" | "square" | "sawtooth" | "triangle" — Oscillator waveform available to a pitched synth voice.
- `ToneVoice` (interface): interface ToneVoice — A pitched oscillator voice: a 12ms linear attack to `gain`, then an exponential decay to silence across `duration`, with an optional exponential pitch slide from `freq` to `slideTo`.
- `patchDuration` (function): function patchDuration(patch: SynthPatch): number — Total wall-clock length of a patch in seconds — the latest voice end across all voices.

## @jgengine/core/audio/uiCues

- `DEFAULT_UI_CUE_SOUNDS` (const): const DEFAULT_UI_CUE_SOUNDS: Readonly<Record<UiCue, SoundDef>> — Short, soft procedural patches: no samples to load, quiet enough to sit under game audio.
- `NOTICE_TONE_CUES` (const): const NOTICE_TONE_CUES: Readonly<Record<NoticeTone, UiCue>> — The cue a notice of each tone plays when it appears.
- `UI_CUES` (const): const UI_CUES: readonly UiCue[] — Every {@link UiCue}, in a stable order.
- `UI_CUE_BUS` (const): const UI_CUE_BUS: "ui" — Bus the default UI cues mix through; the settings menu shows its volume.
- `UiCue` (type): type UiCue = "click" | "hover" | "open" | "close" | "confirm" | "deny" | "notify" — Interface sound cues every game gets: press, hover, panel open/close, confirm, refusal, notification.
- `UiCueOverrides` (type): type UiCueOverrides = false | Partial<Record<UiCue, SoundDef | false>> — Per-cue override: a replacement sound, or `false` to silence that cue. `false` for the whole map silences all.
- `uiCueSoundId` (function): function uiCueSoundId(cue: UiCue): string — Catalog id a cue plays under: `ui.click`, `ui.deny`, ... A game sound with that id replaces the default.
- `withUiCueSounds` (function): function withUiCueSounds(sounds: Readonly<Record<string, SoundDef>> | undefined, buses: Readonly<Record<string, AudioBusDef>> | undefined, overrides?: UiCueOverrides): { sounds: Record<string, SoundDef>; buses: Record<string, AudioBusDef> | undefined } — Merge the default UI cue patches into a game's sound catalog. A game sound already named `ui.<cue>` wins, then `overrides`, then the default. Adds the `ui` bus (gain 0.8) when the game did not declare one.

## @jgengine/core/audio/voiceAllocator

- `AudioVoice` (interface): interface AudioVoice — One reserved playback slot, including sources still loading.
- `VoiceAllocation` (type): type VoiceAllocation = { ok: false } | { ok: true; voiceId: number; stolen: number[] } — Admission result; stop every stolen source before starting the admitted voice.
- `VoiceAllocator` (interface): interface VoiceAllocator — Bounded reservations with higher-priority protection and oldest-first ties.
- `VoiceAllocatorConfig` (interface): interface VoiceAllocatorConfig — Playback budget. Zero disables playback; default 64.
- `VoiceAllocatorSnapshot` (interface): interface VoiceAllocatorSnapshot — Detached allocator state; ids increase monotonically for deterministic oldest-first ties.
- `VoiceAllocatorStorage` (interface): interface VoiceAllocatorStorage — Caller-owned reservation storage. Reads and writes use detached state.
- `createVoiceAllocator` (function): function createVoiceAllocator(config: VoiceAllocatorConfig = {}): VoiceAllocator — Reserve bounded sound playback before fetching or constructing a graph. Equal priorities steal the oldest reservation; lower priorities cannot interrupt higher priorities. Policy is retunable.

## @jgengine/core/faction/factions

- `FactionDef` (interface): interface FactionDef { id: string; relations?: Readonly<Record<string, FactionRelation>>; towardSelf?: FactionRelation; towardOthers?: FactionRelation } — ⚠ undocumented
- `FactionGraph` (interface): interface FactionGraph { relationBetween(observer: string | null | undefined, other: string | null | undefined): FactionRelation; isHostile(observer: string | null | undefined, other: string | null | undefined): boolean; isFriendly(observer: string | null | undef… — ⚠ undocumented
- `FactionGraphConfig` (interface): interface FactionGraphConfig { factions: readonly FactionDef[]; symmetric?: boolean; unaligned?: FactionRelation } — ⚠ undocumented
- `FactionRelation` (type): type FactionRelation = "hostile" | "neutral" | "friendly" — ⚠ undocumented
- `FactionRoster` (interface): interface FactionRoster { assign(entityId: string, factionId: string | null): void; factionOf(entityId: string): string | null; relationBetweenEntities(observer: string, other: string): FactionRelation; isHostile(observer: string, other: string): boolean; isFriend… — ⚠ undocumented
- `createFactionGraph` (function): function createFactionGraph(config: FactionGraphConfig): FactionGraph — ⚠ undocumented
- `createFactionRoster` (function): function createFactionRoster(graph: FactionGraph): FactionRoster — ⚠ undocumented

## @jgengine/core/faction/reputation

- `DEFAULT_REPUTATION_TIERS` (const): const DEFAULT_REPUTATION_TIERS: readonly ReputationTier[] — ⚠ undocumented
- `EffectiveRelationInput` (interface): interface EffectiveRelationInput { base: FactionRelation; ledger: ReputationLedger; actorId: string; factionId: string } — ⚠ undocumented
- `ReputationLedger` (interface): interface ReputationLedger { standing(actorId: string, factionId: string): number; hasStanding(actorId: string, factionId: string): boolean; gain(actorId: string, factionId: string, amount: number): number; set(actorId: string, factionId: string, standing: number): n… — ⚠ undocumented
- `ReputationLedgerConfig` (interface): interface ReputationLedgerConfig { tiers?: readonly ReputationTier[]; initial?: Readonly<Record<string, number>>; min?: number; max?: number } — ⚠ undocumented
- `ReputationLedgerState` (interface): interface ReputationLedgerState — Plain JSON standings of a {@link ReputationLedger}: stored values only, `initial` stays config.
- `ReputationTier` (interface): interface ReputationTier { id: string; min: number; relation: FactionRelation } — ⚠ undocumented · used by `tierForStanding`: Map a faction standing value to its named reputation tier.
- `createReputationLedger` (function): function createReputationLedger(config: ReputationLedgerConfig = {}): ReputationLedger — ⚠ undocumented
- `effectiveRelation` (function): function effectiveRelation(input: EffectiveRelationInput): FactionRelation — ⚠ undocumented
- `tierForStanding` (function): function tierForStanding(tiers: readonly ReputationTier[], standing: number): ReputationTier — Map a faction standing value to its named reputation tier.

## @jgengine/core/input/actionBindings

- `ActionBinding` (interface): interface ActionBinding<TCode extends string = string> — Action-binding model: games bind semantic actions ("jump", "interact") to physical control codes; capture layers resolve raw events through this map so gameplay code never sees keycodes. Control codes are plain strings, so the same model serves keyboard codes, mouse buttons, touch controls, or gamepad inputs.
- `ActionBindingConfig` (type): type ActionBindingConfig<TCode extends string = string> = ActionBinding<TCode>[] | ActionBindingModes<TCode> — ⚠ undocumented
- `ActionBindingMap` (type): type ActionBindingMap<TAction extends string, TCode extends string = string> = Record< TAction, ActionBinding<TCode> > — ⚠ undocumented
- `ActionBindingModes` (interface): interface ActionBindingModes<TCode extends string = string> { hold?: ActionBinding<TCode>[]; toggle?: ActionBinding<TCode>[] } — ⚠ undocumented
- `ActionCodes` (type): type ActionCodes<TCode extends string = string> = | readonly TCode[] | { hold?: readonly TCode[]; toggle?: readonly TCode[]; repeatMs?: number } — ⚠ undocumented
- `ActionCodesMap` (type): type ActionCodesMap<TAction extends string = string, TCode extends string = string> = Record< TAction, ActionCodes<TCode> > — Maps each game action name to the input codes (hold/toggle keys, repeat rate) that trigger it. In a `defineGame({ input })`, pressing an action runs the same-named command with `{ yaw, pitch, aim }`; `repeatMs` re-fires it while held (automatic weapons).
- `ActionStateBindingMap` (type): type ActionStateBindingMap<TAction extends string, TCode extends string = string> = Record< TAction, ActionBindingConfig<TCode> > — ⚠ undocumented
- `ActionStateTracker` (interface): interface ActionStateTracker<TAction extends string> { handleDown(code: string): TAction | null; handleUp(code: string): TAction | null; isDown(action: TAction): boolean; wasPressed(action: TAction): boolean; endFrame(): void; reset(): void; rebind(map: ActionStateBindingMap<TAction, string>)… — ⚠ undocumented · used by `rebindGamepadPoll` (@jgengine/shell/input/gamepadPoll): Swap the pad bindings mid-game (a context push) without touching keyboard state: release the codes of pad-held actions whose pad codes chang…
- `ShouldDispatchActionInput` (interface): interface ShouldDispatchActionInput { pressed: boolean; down: boolean; repeatMs: number | undefined; lastFiredAt: number | null; now: number } — ⚠ undocumented

## @jgengine/core/input/actionContexts

- `ActionContext` (interface): interface ActionContext — Named action-binding layer that may optionally expose lower layers.
- `ActionContextAxisShape` (type): type ActionContextAxisShape = Omit<AxisShapeConfig, "scale"> — Serializable axis shaping a context may carry: {@link AxisShapeConfig} without the `scale` callback.
- `ActionContextStack` (interface): interface ActionContextStack — Mutable layered action-map stack with snapshot and restore support.
- `ActionContextStackSnapshot` (interface): interface ActionContextStackSnapshot — Serializable state for an action-context stack.
- `ActiveContextAxes` (interface): interface ActiveContextAxes — Axis bindings and shaping merged across the active contexts.
- `createActionContextStack` (function): function createActionContextStack(): ActionContextStack — Creates a serializable stack of layered action maps for menus and gameplay modes.

## @jgengine/core/input/axisInput

- `AXIS_RANGE` (const): const AXIS_RANGE: Record<AxisName, AxisRange> — ⚠ undocumented
- `AxisBinding` (interface): interface AxisBinding { positive: readonly string[]; negative?: readonly string[]; pointer?: PointerAxisBinding } — ⚠ undocumented · used by `analogAxes` (@jgengine/core/input/axisShaper): Which axes an analog source is driving this frame: an axis counts as analog when any action bound to it has a published analog magnitude (`c…
- `AxisBindingMap` (type): type AxisBindingMap = Record<AxisName, AxisBinding> — ⚠ undocumented · used by `DRIVE_AXIS_BINDINGS`: Car axes bound to raw key codes, for an {@link AxisChannel} sampled with a key-code `isDown`.
- `AxisChannelConfig` (interface): interface AxisChannelConfig { bindings: AxisBindingMap; smoothing?: number } — ⚠ undocumented · used by `useAxisChannel` (@jgengine/react): Wires useHeldKeys into a fresh AxisChannel, ready for a per-frame `channel.sample(dt, isDown)`.
- `AxisInput` (interface): interface AxisInput { throttle: number; brake: number; steer: number; handbrake: number } — ⚠ undocumented · used by `tickDrivableVehicle` (@jgengine/core/physics/drivableVehicle): Connects an `AxisInput` sample straight through a ground-vehicle sim (`KinematicVehicle` or `VehicleDynamics`) to a scene entity's pose for …
- `AxisName` (type): type AxisName = keyof AxisInput — ⚠ undocumented
- `AxisRange` (interface): interface AxisRange { min: number; max: number } — ⚠ undocumented
- `DRIVE_AXIS_BINDINGS` (const): const DRIVE_AXIS_BINDINGS: AxisBindingMap — Car axes bound to raw key codes, for an {@link AxisChannel} sampled with a key-code `isDown`. `ctx.input.axis` samples action names instead, so bind it to the game's input actions (e.g. `moveForward`), not this map.
- `GenericAxisChannel` (interface): interface GenericAxisChannel<TAxes extends string> — The held-key-ramping analog channel for any axis schema (#282.7) — drones (pitch/roll/strafe), boats, mechs — not just the four car axes `AxisChannel` hardcodes. Same semantics: keys ramp, `setAnalog` overrides, a binding's `pointer` source takes over while a pointer is active.
- `GenericAxisConfig` (interface): interface GenericAxisConfig<TAxes extends string> { bindings: Record<TAxes, AxisBinding>; ranges?: Partial<Record<TAxes, AxisRange>>; smoothing?: number } — ⚠ undocumented
- `NEUTRAL_AXIS` (const): const NEUTRAL_AXIS: AxisInput — ⚠ undocumented

## @jgengine/core/input/axisShaper

- `AxisShapeConfig` (interface): interface AxisShapeConfig — Shaping for one named axis.
- `AxisShapeProfile` (interface): interface AxisShapeProfile — How one axis responds to one kind of source. Keys want ramps (a held key should feel like a pedal being pressed, not a switch); sticks want deadzone and curve but no lag.
- `AxisShapeSample` (interface): interface AxisShapeSample<TAxes extends string> — Per-sample options for {@link AxisShaper.shape}.
- `AxisShaper` (interface): interface AxisShaper<TAxes extends string> — Stateful per-axis response shaping between raw input and a sim.
- `AxisShaperConfig` (interface): interface AxisShaperConfig<TAxes extends string> — Config for {@link createAxisShaper}: one entry per axis.
- `AxisValues` (type): type AxisValues<TAxes extends string> = Record<TAxes, number> — Shaped axis output, one number per axis.
- `analogAxes` (function): function analogAxes<TAxes extends string>(bindings: Readonly<Record<TAxes, AxisBinding>>, analog: Readonly<Record<string, number>> | null): Set<TAxes> — Which axes an analog source is driving this frame: an axis counts as analog when any action bound to it has a published analog magnitude (`ctx.input.analog()`). Feed the result to {@link AxisShaper.shape}.
- `createAxisShaper` (function): function createAxisShaper<TAxes extends string>(initial: AxisShaperConfig<TAxes>): AxisShaper<TAxes> — Creates an {@link AxisShaper}: deadzone, curve and ramp rates per axis, chosen per frame by whether the source was a key or a stick. It sits between `ctx.input.axis(...)` and any sim (a vehicle, an aircraft, aim), so a held key eases in and self-centres while a stick stays direct. Deterministic and serializable.
- `shapeAxisValue` (function): function shapeAxisValue(raw: number, profile: AxisShapeProfile | undefined): number — Deadzone, saturation and curve applied to one raw value; sign is preserved.

## @jgengine/core/input/bindingOverrides

- `BINDING_OVERRIDES_STORAGE_PREFIX` (const): const BINDING_OVERRIDES_STORAGE_PREFIX: "jgengine:keybinds:" — ⚠ undocumented
- `BindingOverrides` (type): type BindingOverrides = Record<string, ActionCodes> — Player-rebound keys, keyed by action name. Values mirror an `ActionCodes` entry so hold/toggle/repeat semantics survive a rebind — the settings menu only swaps which physical codes drive the action.
- `applyBindingOverrides` (function): function applyBindingOverrides<TAction extends string, TCode extends string>(input: ActionCodesMap<TAction, TCode>, overrides: BindingOverrides): ActionCodesMap<TAction, TCode> — Merge player rebinds over a game's authored `input` map. Only actions the game already declares can be overridden; unknown override keys are ignored so a stale localStorage entry can't inject phantom actions.
- `bindingOverridesStorageKey` (function): function bindingOverridesStorageKey(gameId: string): string — ⚠ undocumented
- `clearAllBindingOverrides` (function): function clearAllBindingOverrides(gameId: string, storage: Pick<WebStorageLike, "removeItem"> | null | undefined = defaultStorage()): void — ⚠ undocumented
- `clearBindingOverride` (function): function clearBindingOverride(gameId: string, action: string, storage: Pick<WebStorageLike, "getItem" | "setItem" | "removeItem"> | null | undefined = defaultStorage()): BindingOverrides — ⚠ undocumented
- `loadBindingOverrides` (function): function loadBindingOverrides(gameId: string, storage: Pick<WebStorageLike, "getItem"> | null | undefined = defaultStorage()): BindingOverrides — ⚠ undocumented
- `saveBindingOverride` (function): function saveBindingOverride(gameId: string, action: string, codes: ActionCodes, storage: Pick<WebStorageLike, "getItem" | "setItem" | "removeItem"> | null | undefined = defaultStorage()): BindingOverrides — ⚠ undocumented

## @jgengine/core/input/controlGroups

- `ControlGroupInput` (interface): interface ControlGroupInput — A decoded control-group key press plus the memory needed to detect a double-tap.
- `ControlGroupIntent` (type): type ControlGroupIntent = | { kind: "bind"; key: string } /** Digit: recall the set saved under `key` into the active selection. */ | { kind: "recall"; key: string } /** Second digit tap within the double-tap window: recall and focus the camera on `key`. */ | { kind: "focus"; key: string } — Optional RTS binding composition over the genre-agnostic selection-bookmark store (`@jgengine/core/scene/selectionBookmarks`). It maps the classic control- group idiom — Ctrl+digit binds, digit recalls, a second digit tap within a window focuses — onto opaque bookmark keys, without pulling input mapping into the store. Games that want a different scheme (named bookmarks, gamepad, touch) skip this and call the store directly.
- `ControlGroupOptions` (interface): interface ControlGroupOptions — Tuning for the control-group idiom: the double-tap focus window and the bookmark-key namespace.
- `controlGroupKey` (function): function controlGroupKey(digit: number, options: ControlGroupOptions = {}): string — The stable bookmark key for a control-group `digit` under `options.keyPrefix` — the key a caller passes to `SelectionBookmarks.bind`/`recall` to store a group without going through {@link resolveControlGroupIntent}.
- `resolveControlGroupIntent` (function): function resolveControlGroupIntent(input: ControlGroupInput, options: ControlGroupOptions = {}): ControlGroupIntent — Resolve a control-group key press into a {@link ControlGroupIntent}: Ctrl+digit binds, a bare digit recalls, and a second recall of the same group within `doubleTapMs` focuses. Pure — the caller applies the intent against the store and its own focus hook, and records the returned recall for the next call.

## @jgengine/core/input/gamepadModel

- `DEFAULT_GAMEPAD_DEADZONE` (const): const DEFAULT_GAMEPAD_DEADZONE: GamepadDeadzone — Shell default stick deadzone.
- `GAMEPAD_GLYPH_SETS` (const): const GAMEPAD_GLYPH_SETS: Record<GamepadGlyphName, GamepadGlyphSet> — Built-in short labels for the common controller families.
- `GamepadBindings` (type): type GamepadBindings<TAction extends string = string> = ActionCodesMap<TAction, GamepadCode> — Action bindings whose codes identify gamepad buttons or axes.
- `GamepadCode` (type): type GamepadCode = `pad:${number}` | `padaxis:${number}${"+" | "-"}` — A gamepad button or signed axis binding code.
- `GamepadDeadzone` (interface): interface GamepadDeadzone — Deadzone policy applied to gamepad axes.
- `GamepadFeelConfig` (interface): interface GamepadFeelConfig — Game-level pad feel read by the shell's gamepad poll. A number `deadzone` is the axial inner deadzone with a `0.95` outer edge.
- `GamepadFrame` (interface): interface GamepadFrame — The digital and analog action state produced by a gamepad frame.
- `GamepadGlyphName` (type): type GamepadGlyphName = "xbox" | "playstation" | "nintendo" | "generic" — Names of the built-in controller glyph sets.
- `GamepadGlyphSet` (interface): interface GamepadGlyphSet — Button labels used by one controller family.
- `GamepadSample` (interface): interface GamepadSample — Read-only view of one sampled gamepad. The browser `Gamepad` satisfies it structurally, so a poll loop can resolve `navigator.getGamepads()` entries without copying them.
- `GamepadSnapshot` (interface): interface GamepadSnapshot — A serializable gamepad state sampled from the platform input API.
- `ResolveGamepadFrameOptions` (interface): interface ResolveGamepadFrameOptions — Options for resolving one gamepad snapshot into action state.
- `gamepadFeelOptions` (function): function gamepadFeelOptions(config: GamepadFeelConfig | undefined): ResolveGamepadFrameOptions — Resolve a {@link GamepadFeelConfig} into the options {@link resolveGamepadFrame} takes.
- `gamepadGlyphSets` (const): const gamepadGlyphSets: Record<GamepadGlyphName, GamepadGlyphSet> — Lowercase alias for consumers that prefer data-oriented naming.
- `resolveGamepadFrame` (function): function resolveGamepadFrame(snapshot: GamepadSample, bindings: GamepadBindings, options: ResolveGamepadFrameOptions, out: GamepadFrame = { held: [], analog: {} }): GamepadFrame — Resolve one sampled gamepad into held actions and shaped analog action values. Sticks go through the deadzone and curve; analog buttons (triggers) through `triggerDeadzone` and the same curve. Pass `out` to reuse a frame across polls; it is cleared and returned.

## @jgengine/core/input/gestureSurface

- `DEFAULT_GESTURE_TUNING` (const): const DEFAULT_GESTURE_TUNING: GestureSurfaceTuning — ⚠ undocumented
- `GestureSurfaceTracker` (interface): interface GestureSurfaceTracker { begin(x: number, y: number, nowMs: number): void; move(x: number, y: number): readonly string[]; end(x: number, y: number, nowMs: number): readonly string[]; cancel(): void; isActive(): boolean } — ⚠ undocumented
- `GestureSurfaceTuning` (interface): interface GestureSurfaceTuning { tapMoveThresholdPx: number; tapMaxMs: number; swipeMinPx: number; swipeMinVelocity: number; dragStepPx: number } — ⚠ undocumented
- `createGestureSurfaceTracker` (function): function createGestureSurfaceTracker(bindings: TouchGestureBindings, tuning: GestureSurfaceTuning = DEFAULT_GESTURE_TUNING): GestureSurfaceTracker — ⚠ undocumented

## @jgengine/core/input/haptics

- `HapticChannels` (interface): interface HapticChannels — Named continuous rumble channels for one player, mixed by priority each frame. Game code sets levels from its own telemetry (engine rpm, road surface, impacts); the shell mixes and drives the pad.
- `HapticChannelsOptions` (interface): interface HapticChannelsOptions — Options for {@link createHapticChannels}.
- `HapticChannelsSnapshot` (interface): interface HapticChannelsSnapshot — Serializable channel state.
- `HapticLevel` (interface): interface HapticLevel — Motor intensities, each `0..1`: `strong` is the low-frequency motor, `weak` the high-frequency one.
- `HapticPulse` (interface): interface HapticPulse extends HapticLevel — A decaying one-shot on a channel: starts at `strong`/`weak` and fades to zero over `ms`.
- `createHapticChannels` (function): function createHapticChannels(options: HapticChannelsOptions = {}): HapticChannels — Per-player haptic channels mixed by priority.

## @jgengine/core/input/inputBuffer

- `BufferedAction` (interface): interface BufferedAction — One action's press history inside an {@link InputBuffer}.
- `InputBuffer` (interface): interface InputBuffer — Remembers recent action presses so a press slightly early (a jump before landing) still counts. Times are caller-supplied ms, so it runs the same on a client, a host or in a replay.
- `InputBufferSnapshot` (interface): interface InputBufferSnapshot — Serializable state for an {@link InputBuffer}.
- `createInputBuffer` (function): function createInputBuffer(options: { windowMs: number }): InputBuffer — Creates an input buffer for jump buffering, coyote time, hold duration and double taps.

## @jgengine/core/input/lookChannel

- `LookChannel` (interface): interface LookChannel { accumulate(dx: number, dy: number): void; consume(): LookDeltas; setYaw(yaw: number): void; readYaw(): number; setPitch(pitch: number): void; readPitch(): number; setVerticalOffset(offset: number): void; readVerticalOffset(): number; snap… — ⚠ undocumented
- `LookChannelOptions` (interface): interface LookChannelOptions { sensitivity: number; maxVerticalOffset?: number } — ⚠ undocumented
- `LookChannelState` (interface): interface LookChannelState — Plain JSON state of a {@link LookChannel}: the pending pixel deltas and the committed pose.
- `LookDeltas` (interface): interface LookDeltas — Per-frame look channel shared between an event-driven capture layer (writer of raw pointer deltas) and a frame-driven controller (consumer), plus the latest committed pose for same-frame readers such as presence sync. Kept as plain mutable state on purpose: routing per-frame deltas through a reactive store would notify subscribers every frame for state no UI reads.
- `createLookChannel` (function): function createLookChannel({ sensitivity, maxVerticalOffset = Infinity }: LookChannelOptions): LookChannel — ⚠ undocumented

## @jgengine/core/input/pointer

- `DragCapture` (interface): interface DragCapture — Renderer-agnostic drag-capture / pull-vector state machine for slingshot-style aiming, drawback abilities, and similar gestures.
- `DragCaptureConfig` (interface): interface DragCaptureConfig { maxPull?: number; grabRadius?: number } — ⚠ undocumented
- `DragResult` (type): type DragResult = DragState — ⚠ undocumented
- `DragState` (interface): interface DragState — Snapshot of an in-progress or just-released drag: origin/current cursor points plus the clamped pull vector.
- `PointerButton` (type): type PointerButton = "primary" | "secondary" | "middle" — ⚠ undocumented
- `PointerHit` (interface): interface PointerHit — Renderer-free result of a screen→world raycast. The shell's pointer service produces this from the cursor; core-side gameplay (item.use aim, click-to-move, ground-target abilities, pings) consumes it without touching three.js.
- `PointerVec3` (type): type PointerVec3 = readonly [number, number, number] — ⚠ undocumented · used by `aimToPoint`: Build an `origin → point` aim for `item.use` / projectiles, firing toward the cursor.
- `aimToPoint` (function): function aimToPoint(origin: PointerVec3, point: PointerVec3): Aim — Build an `origin → point` aim for `item.use` / projectiles, firing toward the cursor.
- `createDragCapture` (function): function createDragCapture(config: DragCaptureConfig = {}): DragCapture — ⚠ undocumented
- `groundOf` (function): function groundOf(hit: PointerHit): readonly [number, number] — Project a pointer hit onto the XZ plane for navmesh routing (`findPath` takes `[x, z]`).
- `moveTargetFromHit` (function): function moveTargetFromHit(hit: PointerHit): PointerVec3 — The move-to target of a pointer hit — sugar over `hit.point`.

## @jgengine/core/input/pointerAxis

- `PointerAxisBinding` (interface): interface PointerAxisBinding — Maps one pointer axis onto an analog axis target — the pointer-backed counterpart of an `AxisBinding`'s key lists.
- `PointerAxisState` (interface): interface PointerAxisState { x: number; y: number; active: boolean } — ⚠ undocumented · used by `normalizePointerToAxis`: Normalize client coordinates against a surface rect into a `PointerAxisState`, clamped to `[-1, 1]` per axis.
- `PointerSurfaceRect` (interface): interface PointerSurfaceRect { left: number; top: number; width: number; height: number } — ⚠ undocumented · used by `normalizePointerToAxis`: Normalize client coordinates against a surface rect into a `PointerAxisState`, clamped to `[-1, 1]` per axis.
- `normalizePointerToAxis` (function): function normalizePointerToAxis(clientX: number, clientY: number, rect: PointerSurfaceRect): PointerAxisState — Normalize client coordinates against a surface rect into a `PointerAxisState`, clamped to `[-1, 1]` per axis.
- `pointerAxisValue` (function): function pointerAxisValue(binding: PointerAxisBinding, state: PointerAxisState | null | undefined): number | null — Resolve a pointer binding against the current pointer state: `null` when no pointer is active (callers fall back to their digital target), otherwise the deadzone/curve-shaped value in `[-1, 1]`.

## @jgengine/core/input/rebindSession

- `RebindActionConfig` (interface): interface RebindActionConfig — One rebindable action as declared to {@link createRebindSession}. The `id` and `label` are FREE strings the session never interprets — the game owns their meaning and display text. `defaultCodes` is the authored binding the session resets back to.
- `RebindConflict` (interface): interface RebindConflict — A group of actions bound to the same normalized code — the conflict this session detects.
- `RebindRow` (interface): interface RebindRow — One controls-list row: an action, its effective binding, and any conflicts.
- `RebindSession` (interface): interface RebindSession — A live, observable, conflict-aware key-remap editor over the action-binding model.
- `RebindSessionActionsConfig` (interface): interface RebindSessionActionsConfig extends RebindSessionCommon — Declare actions explicitly, in list order.
- `RebindSessionConfig` (type): type RebindSessionConfig = RebindSessionActionsConfig | RebindSessionMapConfig — Config for {@link createRebindSession}: an explicit action list, or an {@link ActionCodesMap} + labels.
- `RebindSessionMapConfig` (interface): interface RebindSessionMapConfig extends RebindSessionCommon — Declare actions from an authored {@link ActionCodesMap}, labelled by `labels` (falling back to the id).
- `RebindSessionSnapshot` (interface): interface RebindSessionSnapshot — Serializable session state for save/restore.
- `createRebindSession` (function): function createRebindSession(config: RebindSessionConfig): RebindSession — A conflict-aware key-remap session over the action-binding model — the missing editor behind a controls-settings menu. It takes the game's authored actions ({@link RebindActionConfig}s, or an {@link ActionCodesMap} + labels) plus the player's saved {@link BindingOverrides}, and tracks the *effective* binding per action (default merged with the override via `applyBindingOverrides`). `rows()` exposes each action's label, current key glyph (via `bindingLabel`), whether it is still the default, and which other actions it collides with; `conflicts()` groups every action pair sharing a normalized code (the value-add a raw override map can't give you). `beginCapture`/`capture`/`cancelCapture` drive a "press a key" rebind (codes normalized via `normalizeKeyCode`), `reset`/ `resetAll` return to defaults, and `overrides()`/`apply()` hand the caller the `BindingOverrides` to persist. Nothing here is genre-specific: action ids and labels are free strings the session never interprets, and hold/toggle/repeat binding shapes survive a rebind. `snapshot`/`restore` round-trips the editor (including the in-flight capture) through a save.

## @jgengine/core/input/touchControlsMode

- `activeTouchControlsMode` (function): function activeTouchControlsMode(ctx: GameContext): string | null — The active touch control mode, `null` when the base config applies.
- `setTouchControlsMode` (function): function setTouchControlsMode(ctx: GameContext, mode: string | null): void — Activate a named touch control mode, or `null` to return to the base config.

## @jgengine/core/input/touchGestures

- `TouchGestureEnd` (type): type TouchGestureEnd = "tap" | "hold-end" | null — ⚠ undocumented
- `TouchGestureTracker` (interface): interface TouchGestureTracker { begin(x: number, y: number, nowMs: number): void; move(x: number, y: number): {dx: number; dy: number} | null; beginHold(): boolean; end(nowMs: number): TouchGestureEnd; cancel(): TouchGestureEnd; isActive(): boolean; isHolding(): boolean… — ⚠ undocumented
- `TouchGestureTuning` (interface): interface TouchGestureTuning — Single-finger gesture disambiguation for touch look controls: one touch stream drives look-drag, tap, and long-press-hold without fighting. Movement past the tap threshold commits the gesture to "look" and cancels tap/hold; a still finger that lifts quickly is a tap; a still finger held past the long-press delay is a hold. Timestamps are injected so the state machine stays pure; the capture layer owns timers and touch identifiers.
- `createTouchGestureTracker` (function): function createTouchGestureTracker(tuning: TouchGestureTuning): TouchGestureTracker — ⚠ undocumented

## @jgengine/core/input/touchScheme

- `DEFAULT_TOUCH_JOYSTICK_VARIANT` (const): const DEFAULT_TOUCH_JOYSTICK_VARIANT: TouchJoystickVariant — Variant used when the player has not picked one.
- `DEFAULT_TOUCH_STYLE` (const): const DEFAULT_TOUCH_STYLE: TouchStyle — Skin used when neither the game nor the player picks one.
- `DeriveTouchSchemeOptions` (interface): interface DeriveTouchSchemeOptions { reserved: ReadonlySet<string>; firstPerson: boolean; config?: TouchControlsConfig | false; mode?: string | null } — ⚠ undocumented · used by `deriveTouchScheme`: Null means "render no touch controls" — either the game opted out or there is nothing to synthesize.
- `ResolvedTouchLayout` (interface): interface ResolvedTouchLayout — The dock zone each cluster resolved to, after applying game config over the bottom-layout defaults.
- `TOUCH_CODE_PREFIX` (const): const TOUCH_CODE_PREFIX: "touch:" — ⚠ undocumented
- `TOUCH_JOYSTICK_VARIANTS` (const): const TOUCH_JOYSTICK_VARIANTS: readonly TouchJoystickVariant[] — Every joystick variant id, in menu order.
- `TOUCH_JOYSTICK_VARIANT_OPTIONS` (const): const TOUCH_JOYSTICK_VARIANT_OPTIONS: readonly { value: TouchJoystickVariant; label: string }[] — Joystick variants as `{ value, label }` rows for the Settings → Controls selector.
- `TOUCH_STYLES` (const): const TOUCH_STYLES: readonly TouchStyle[] — Every touch skin id, in menu order.
- `TOUCH_STYLE_OPTIONS` (const): const TOUCH_STYLE_OPTIONS: readonly { value: TouchStyle; label: string }[] — Touch skins as `{ value, label }` rows for the Settings → Controls selector.
- `TouchAnchor` (type): type TouchAnchor = | "bottom-left" | "bottom-center" | "bottom-right" | "left" | "right" | "top-left" | "top-center" | "top-right" — Screen zone a touch cluster or button docks to. The four corners plus the mid `left`/`right` rails (vertical stacks, MMO-style hotbars) and the `bottom-center` / `top-center` strips let controls use the whole viewport instead of piling into one bottom bar.
- `TouchButton` (interface): interface TouchButton { action: string; label: string; icon: string | false | null; kind: TouchButtonKind; shape: TouchButtonShape; anchor: TouchAnchor | null; image: string | null } — ⚠ undocumented
- `TouchButtonKind` (type): type TouchButtonKind = "primary" | "utility" — ⚠ undocumented
- `TouchButtonShape` (type): type TouchButtonShape = "circle" | "square" | "pedal" | "lever" | "trigger" | "wheel" | "tab" — Physical silhouette a touch button wears. The capture layer draws each as its own shape — a `pedal` reads as a foot pedal, a `lever` as a pull handle, a `trigger` as a firing paddle — so a control looks like the thing it does instead of a labelled circle. `circle`/`square` are the neutral fallbacks.
- `TouchButtonSpec` (interface): interface TouchButtonSpec { action: string; label?: string; icon?: string | false; kind?: TouchButtonKind; shape?: TouchButtonShape; anchor?: TouchAnchor; image?: string } — ⚠ undocumented
- `TouchControlsConfig` (interface): interface TouchControlsConfig — Game-authored refinement of the derived touch scheme on `defineGame({ touch })` — gestures, curated buttons, hidden actions, cluster layout, skin, and per-context `modes`.
- `TouchControlsModeConfig` (type): type TouchControlsModeConfig = Omit<TouchControlsConfig, "modes"> — One named control context's touch config — the same shape as the base config, minus nested modes.
- `TouchDragBinding` (interface): interface TouchDragBinding { left?: string; right?: string; up?: string; down?: string; stepPx?: number } — ⚠ undocumented
- `TouchGestureBindings` (interface): interface TouchGestureBindings { tap?: string; swipeUp?: string; swipeDown?: string; swipeLeft?: string; swipeRight?: string; drag?: TouchDragBinding } — ⚠ undocumented
- `TouchJoystick` (interface): interface TouchJoystick { up: string | null; down: string | null; left: string | null; right: string | null } — ⚠ undocumented
- `TouchJoystickVariant` (type): type TouchJoystickVariant = "fixed" | "floating" — How the movement joystick behaves — the two shipped variants, player-selectable in Settings → Controls. `fixed` is the classic always-visible stick in its dock corner; `floating` keeps the corner as an empty capture zone and spawns the stick centered under wherever the thumb lands, so the hand never has to find a fixed target mid-play.
- `TouchLayoutConfig` (interface): interface TouchLayoutConfig — Where each touch cluster docks; unset falls back to the classic bottom layout.
- `TouchMovementConfig` (interface): interface TouchMovementConfig — Restricts the virtual joystick to one axis — a `horizontal` zone reads as a steering control, freeing throttle/brake to become pedal buttons.
- `TouchScheme` (interface): interface TouchScheme { joystick: TouchJoystick | null; buttons: readonly TouchButton[]; gestures: TouchGestureBindings | null; look: boolean; lookSensitivity: number; layout: ResolvedTouchLayout; style: TouchStyle } — ⚠ undocumented · used by `deriveTouchScheme`: Null means "render no touch controls" — either the game opted out or there is nothing to synthesize.
- `TouchStyle` (type): type TouchStyle = "glass" | "arcade" | "mechanical" | "minimal" — Player-selectable skin for the whole touch layer. A style is a material + geometry preset (not just colours), chosen in Settings → Controls and persisted; `glass` is the translucent default, the rest are opt-in looks.
- `deriveTouchScheme` (function): function deriveTouchScheme(input: ActionCodesMap | undefined, { reserved, firstPerson, config: rawConfig, mode }: DeriveTouchSchemeOptions): TouchScheme | null — Null means "render no touch controls" — either the game opted out or there is nothing to synthesize.
- `touchActionLabel` (function): function touchActionLabel(action: string): string — ⚠ undocumented
- `touchButtonKind` (function): function touchButtonKind(action: string): TouchButtonKind — ⚠ undocumented
- `touchButtonShape` (function): function touchButtonShape(action: string): TouchButtonShape — Default silhouette for an action; `circle` when nothing more specific fits.
- `touchCode` (function): function touchCode(action: string): string — ⚠ undocumented
- `withTouchCodes` (function): function withTouchCodes(map: ActionCodesMap | undefined): ActionCodesMap — Every action gains a synthetic touch code alongside its physical codes.

## @jgengine/core/interaction/contextMenu

- `BuildContextMenuInput` (interface): interface BuildContextMenuInput { kind: ContextTargetKind; targetId: string; verbs: readonly ContextVerb[] | undefined; point?: readonly [number, number, number] } — ⚠ undocumented · used by `buildContextMenu`: Assemble a menu from a target's catalog verbs; null when the target lists none.
- `ContextMenu` (interface): interface ContextMenu { kind: ContextTargetKind; targetId: string; point?: readonly [number, number, number]; verbs: readonly ContextVerb[] } — ⚠ undocumented · used by `buildContextMenu`: Assemble a menu from a target's catalog verbs; null when the target lists none.
- `ContextTargetKind` (type): type ContextTargetKind = "entity" | "object" — ⚠ undocumented
- `ContextVerb` (interface): interface ContextVerb — One right-click verb: a label plus the command it dispatches (walk-then-act supported by args).
- `buildContextMenu` (function): function buildContextMenu(input: BuildContextMenuInput): ContextMenu | null — Assemble a menu from a target's catalog verbs; null when the target lists none.
- `contextVerb` (function): function contextVerb(label: string, command: string, args?: Record<string, unknown>): ContextVerb — Builds a {@link ContextVerb} for a right-click menu entry.
- `contextVerbInput` (function): function contextVerbInput(menu: ContextMenu, verb: ContextVerb): Record<string, unknown> — Command input a chosen verb dispatches: the verb's own args, plus the target id and the world point, so a single handler can walk the actor to the target then perform it.

## @jgengine/core/interaction/lockpick

- `LOCK_ACTIONS` (const): const LOCK_ACTIONS: readonly LockAction[] — The five pick actions, in display order (shallow → deep).
- `LOCK_ACTION_DELTA` (const): const LOCK_ACTION_DELTA: Readonly<Record<LockAction, number>> — Vertical row delta applied to the pick for each action. Row 0 is the shallow/top row.
- `LockAction` (type): type LockAction = "hardSet" | "set" | "steady" | "ease" | "drop" — One discrete pick move: how far the pick drives into the lock this step.
- `LockCell` (interface): interface LockCell — One cell inside the fogged {@link visibleCells} window: its board position and kind.
- `LockCellKind` (type): type LockCellKind = "open" | "gate" | "seat" | "trap" — What a revealed cell renders as: a plain open notch, an exact tumbler gate, the bolt seat (win condition), or a ward-trap that looks open but jams on contact.
- `LockSpec` (interface): interface LockSpec — A generated lock board. `open[col]` holds every enterable row in that column.
- `LockStepResult` (type): type LockStepResult = "advanced" | "slip" | "bind" | "trap" | "success" — Outcome of one {@link stepLock} call: `advanced`/`success` move the pick, `slip`/`bind`/`trap` do not and should cost a life.
- `LockTierSpec` (interface): interface LockTierSpec — Difficulty dials for one lock: board size, forgiveness band, gates, fog window, traps.
- `generateLock` (function): function generateLock(seed: string | number, tier: LockTierSpec): LockSpec — Generate a solvable depth-puzzle lock: a "Tumbler's Path" board with a guaranteed solution path carved first, an open-row forgiveness band wrapped around it, tumbler gate columns that pinch to a single exact row, and optional ward-traps that look open but jam on contact. Deterministic: the same (seed, tier) always yields the same board.
- `solveLock` (function): function solveLock(spec: LockSpec): boolean — Whether the board has a path from the start row to the bolt seat at all.
- `solveLockPath` (function): function solveLockPath(spec: LockSpec): number[] | null — Return a concrete row-per-column solution, or null if the board is unsolvable.
- `stepLock` (function): function stepLock(spec: LockSpec, col: number, row: number, action: LockAction): { result: LockStepResult; col: number; row: number } — Authoritative single step. The caller owns the lives economy: a slip/bind/trap does not advance the pick and should cost a life; advanced/success move the pick.
- `visibleCells` (function): function visibleCells(spec: LockSpec, col: number, window: number): LockCell[] — The render-safe slice: every open cell in columns [0, col + window]. The single source of truth for fog and the anti-cheat boundary — never serialize the full spec to a client.

## @jgengine/core/interaction/promptRegistry

- `PositionedPromptPatch` (type): type PositionedPromptPatch = Partial<Omit<PositionedPrompt, "id">> — A partial edit applied to an already-registered {@link PositionedPrompt} by {@link PromptRegistry.update}. Any subset of the mutable fields — everything but the stable `id` — may be supplied; omitted fields keep their prior value.
- `PromptRegistry` (interface): interface PromptRegistry — A live, observable set of interaction prompts that OWNS the registered {@link PositionedPrompt}s and tracks which one is active for a player. It is a thin stateful layer over {@link resolveActivePrompt}: registration/order lives here, the nearest-within-radius / higher-priority selection stays in the pure resolver. {@link resolve} is the per-frame hot path — call it as the player moves; subscribers fire only when the active prompt actually CHANGES.
- `PromptRegistrySnapshot` (interface): interface PromptRegistrySnapshot — The serializable shape {@link PromptRegistry.snapshot} returns and {@link PromptRegistry.restore} consumes: the full set of positioned prompts (in registration order) plus the id of the prompt that was active when the snapshot was taken. Prompt display/command payloads are free strings and ids — keep them serializable and this round-trips through a save cleanly.
- `createPromptRegistry` (function): function createPromptRegistry(): PromptRegistry — Create a live, observable interaction-prompt registry over the pure {@link resolveActivePrompt} resolver. Register positioned "press E" prompts, `resolve(playerPosition)` each frame as the hero moves, and read `active()` — the nearest strictly-in-range prompt (higher `priority` beats closer). The set is owned here (register/update/unregister/clear/all); selection stays pure. Subscribers are notified only when the active prompt *changes*, so a HUD does not thrash per frame, and `snapshot`/`restore` round-trip the prompts plus the active id through a save (display payloads are free strings/ids the game owns — the registry never branches on their meaning). Allocation-aware: `all()` and `resolve()` reuse a cached array instead of rebuilding per call.

## @jgengine/core/interaction/proximityPrompt

- `GaugePromptDisplay` (interface): interface GaugePromptDisplay { kind: "gauge"; gaugeId: string } — ⚠ undocumented
- `KeybindPromptDisplay` (interface): interface KeybindPromptDisplay { kind: "keybind"; actionId: string; label?: string } — ⚠ undocumented
- `LabelPromptDisplay` (interface): interface LabelPromptDisplay { kind: "label"; text: string } — ⚠ undocumented
- `PositionedPrompt` (interface): interface PositionedPrompt { id: string; position: PromptPoint; priority?: number; prompt: ProximityPrompt } — ⚠ undocumented · used by `resolveActivePrompt`: Nearest prompt strictly within its radius wins; a higher-priority prompt in range beats any lower-priority one regardless of distance; equal…
- `PromptCommand` (interface): interface PromptCommand { name: string; input: unknown } — ⚠ undocumented
- `PromptPoint` (interface): interface PromptPoint { x: number; z: number } — ⚠ undocumented · used by `resolveActivePrompt`: Nearest prompt strictly within its radius wins; a higher-priority prompt in range beats any lower-priority one regardless of distance; equal…
- `ProximityPrompt` (interface): interface ProximityPrompt { radius: number; display: ProximityPromptDisplay; invoke: PromptCommand | null } — ⚠ undocumented
- `ProximityPromptConfig` (interface): interface ProximityPromptConfig { radius: number; display: ProximityPromptDisplay; invoke?: PromptCommand | null } — ⚠ undocumented
- `ProximityPromptDisplay` (type): type ProximityPromptDisplay = KeybindPromptDisplay | GaugePromptDisplay | LabelPromptDisplay — ⚠ undocumented
- `command` (function): function command(name: string, input?: unknown): PromptCommand — ⚠ undocumented
- `gauge` (function): function gauge(gaugeId: string): GaugePromptDisplay — ⚠ undocumented
- `keybind` (function): function keybind(actionId: string, label?: string): KeybindPromptDisplay — ⚠ undocumented
- `label` (function): function label(text: string): LabelPromptDisplay — ⚠ undocumented
- `positionedPromptsEqual` (function): function positionedPromptsEqual(a: PositionedPrompt, b: PositionedPrompt): boolean — ⚠ undocumented
- `promptCommandsEqual` (function): function promptCommandsEqual(a: PromptCommand | null, b: PromptCommand | null): boolean — ⚠ undocumented
- `promptDisplaysEqual` (function): function promptDisplaysEqual(a: ProximityPromptDisplay, b: ProximityPromptDisplay): boolean — ⚠ undocumented
- `proximityPrompt` (function): function proximityPrompt({ radius, display, invoke = null }: ProximityPromptConfig): ProximityPrompt — ⚠ undocumented
- `resolveActivePrompt` (function): function resolveActivePrompt<T extends PositionedPrompt>(playerPosition: PromptPoint, prompts: readonly T[]): T | null — Nearest prompt strictly within its radius wins; a higher-priority prompt in range beats any lower-priority one regardless of distance; equal priority and distance keep the earliest prompt in the list.

## @jgengine/core/interaction/qte

- `QteInputEvent` (interface): interface QteInputEvent { action: string; at: number } — ⚠ undocumented · used by `evaluateQteSequence`: Evaluate a quick-time-event input sequence against timed hit windows.
- `QteOutcome` (type): type QteOutcome = | { status: "success" } | { status: "fail"; atStep: string; reason: "missed-window" | "wrong-action" | "too-early" } — ⚠ undocumented · used by `evaluateQteSequence`: Evaluate a quick-time-event input sequence against timed hit windows.
- `QteStep` (interface): interface QteStep { id: string; action: string; windowStart: number; windowEnd: number } — ⚠ undocumented · used by `evaluateQteSequence`: Evaluate a quick-time-event input sequence against timed hit windows.
- `evaluateQteSequence` (function): function evaluateQteSequence(steps: readonly QteStep[], inputs: readonly QteInputEvent[]): QteOutcome — Evaluate a quick-time-event input sequence against timed hit windows.
- `pendingQteStep` (function): function pendingQteStep(steps: readonly QteStep[], elapsedSeconds: number): QteStep | null — ⚠ undocumented
- `qteProgress` (function): function qteProgress(steps: readonly QteStep[], elapsedSeconds: number): number — ⚠ undocumented

## @jgengine/core/interaction/skillCheck

- `SkillCheckConfig` (interface): interface SkillCheckConfig { trackWidth: number; zone: SkillCheckZone; markerPeriod: number; window: number; zoneDriftPerSecond?: number } — ⚠ undocumented · used by `skillCheckZoneAt`: A timing-bar skill check that succeeds when the moving marker is released inside the target zone.
- `SkillCheckResult` (interface): interface SkillCheckResult { success: boolean; timedOut: boolean; markerPosition: number; zone: SkillCheckZone } — ⚠ undocumented
- `SkillCheckZone` (interface): interface SkillCheckZone { start: number; end: number } — ⚠ undocumented · used by `skillCheckZoneAt`: A timing-bar skill check that succeeds when the moving marker is released inside the target zone.
- `evaluateSkillCheck` (function): function evaluateSkillCheck(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckResult — ⚠ undocumented
- `skillCheckMarkerPosition` (function): function skillCheckMarkerPosition(config: SkillCheckConfig, elapsedSeconds: number): number — ⚠ undocumented
- `skillCheckZoneAt` (function): function skillCheckZoneAt(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckZone — A timing-bar skill check that succeeds when the moving marker is released inside the target zone.

## @jgengine/core/material/appearanceSignals

- `MaterialAppearanceBaseline` (interface): interface MaterialAppearanceBaseline — Resolved dry values from one assigned surface, after imported and instance edits. RGB is linear.
- `MaterialAppearancePolicy` (interface): interface MaterialAppearancePolicy — Local appearance only. Wind is a separate geometry/simulation input, and no field creates motion.
- `MaterialAppearanceResponse` (interface): interface MaterialAppearanceResponse — Sparse edits for one sample. Unrequested imported parameters, textures, coverage and transmission stay intact.
- `MaterialAppearanceTarget` (interface): interface MaterialAppearanceTarget — Explicit sample position; callers schedule a bounded set of visible or relevant targets.
- `MaterialWetnessPolicy` (interface): interface MaterialWetnessPolicy — Opt-in wet endpoints. Color retention multiplies linear albedo; it never replaces the authored hue.
- `resolveMaterialAppearance` (function): function resolveMaterialAppearance(sample: EnvironmentSample, baseline: MaterialAppearanceBaseline, policy: MaterialAppearancePolicy = {}): MaterialAppearanceResponse — Resolve one surface from an immutable dry baseline, avoiding cumulative drift. Wetness already includes field shelter; neither exposure nor sheltered is multiplied into it again. No accumulation or drying simulation.
- `sampleMaterialAppearance` (function): function sampleMaterialAppearance(field: Pick<EnvironmentField, "sample">, target: MaterialAppearanceTarget, baseline: MaterialAppearanceBaseline, policy: MaterialAppearancePolicy = {}): MaterialAppearanceResponse — Exactly one field sample per target; no traversal, subscription, hidden tick, or full-world scan.

## @jgengine/core/movement/avatarGait

- `DEFAULT_GAIT_TUNING` (const): const DEFAULT_GAIT_TUNING: GaitTuning — ⚠ undocumented
- `GaitTuning` (interface): interface GaitTuning { stridesPerUnit: number; bobAmplitude: number; swayAmplitude: number; fullIntensitySpeed: number } — ⚠ undocumented · used by `gaitBobOffset`: Vertical hop per footfall — two peaks per stride cycle.
- `advanceGaitPhase` (function): function advanceGaitPhase(phase: number, speedUnitsPerSec: number, dtSec: number, tuning: GaitTuning = DEFAULT_GAIT_TUNING): number — ⚠ undocumented
- `gaitBobOffset` (function): function gaitBobOffset(phase: number, speedUnitsPerSec: number, tuning: GaitTuning = DEFAULT_GAIT_TUNING): number — Vertical hop per footfall — two peaks per stride cycle.
- `gaitSwayAngle` (function): function gaitSwayAngle(phase: number, speedUnitsPerSec: number, tuning: GaitTuning = DEFAULT_GAIT_TUNING): number — Signed side-to-side lean alternating with each footfall.

## @jgengine/core/movement/avoidance

- `AvoidanceAgent` (interface): interface AvoidanceAgent — A circular agent that avoidance may push on the XZ plane.
- `LocalAvoidanceOptions` (interface): interface LocalAvoidanceOptions — Tuning for {@link resolveLocalAvoidance}.
- `resolveLocalAvoidance` (function): function resolveLocalAvoidance(agents: AvoidanceAgent[], options: LocalAvoidanceOptions = {}): number — Resolve overlaps in `agents` in place and return how many overlapping pairs remained on the final pass (`0` = fully separated). Uses a bounded uniform hash grid sized to the largest agent, so only nearby agents are ever compared. Deterministic: corrections are accumulated then applied per pass, independent of agent order. Pass `weights` to pin or differentially push agents.

## @jgengine/core/movement/cameraRig

- `CAMERA_PITCH_LIMIT` (const): const CAMERA_PITCH_LIMIT: 1.45 — ⚠ undocumented

## @jgengine/core/movement/characterController

- `CharacterController` (interface): interface CharacterController — The controller handle: config, state, and the per-step move.
- `CharacterControllerConfig` (interface): interface CharacterControllerConfig — Capsule dimensions and the walk rules a controller applies; every field is retunable during play.
- `CharacterControllerState` (interface): interface CharacterControllerState — The controller's serializable state. `position` is the feet point; the capsule stands above it.
- `CharacterMoveInput` (interface): interface CharacterMoveInput — One step of intent for {@link CharacterController.move}.
- `CharacterMoveResult` (interface): interface CharacterMoveResult — What one move did.
- `createCharacterController` (function): function createCharacterController(initial: CharacterControllerConfig): CharacterController — Collide-and-slide capsule controller over any {@link PhysicsBackend}: horizontal slide along walls, step-up over ledges, slope limit, ceiling test, crouch with headroom check, ground snapping, and moving-platform carry read from the ground body's velocity. Pure over the backend's `shapecast`/`overlap`; the caller owns input and gravity policy. Invalid dimensions or control ranges throw before configuration changes.

## @jgengine/core/movement/dash

- `DashBurst` (interface): interface DashBurst { direction: DashDirection; durationMs: number; distance: number } — ⚠ undocumented
- `DashConfig` (interface): interface DashConfig { distance: number; durationMs: number; iframes: {fromMs: number; toMs: number}; staminaCost: number; staminaMax: number; staminaRegenPerSecond: number; cooldownMs: number } — ⚠ undocumented
- `DashDirection` (interface): interface DashDirection { x: number; z: number } — ⚠ undocumented
- `DashRejection` (type): type DashRejection = { reason: "no-stamina" | "cooldown" | "dashing" } — ⚠ undocumented
- `DashState` (interface): interface DashState { tryDash(direction: DashDirection, nowMs: number): DashRejection | DashBurst; tick(dtSeconds: number, nowMs: number): void; stamina(): number; staminaFraction(): number; isDashing(nowMs: number): boolean; isInvulnerable(nowMs: number): boo… — ⚠ undocumented

## @jgengine/core/movement/formation

- `BoxFormationOptions` (interface): interface BoxFormationOptions — Options for {@link boxFormation}.
- `CircleFormationOptions` (interface): interface CircleFormationOptions — Options for {@link circleFormation}.
- `FormationSlotGenerator` (type): type FormationSlotGenerator = (count: number) => Vec2[] — Produces `count` slot offsets in the group's local frame — `[right, forward]` where `+forward` points where the group faces. Index order is the slot order; a generator must be pure (same `count` → same offsets) so placement stays deterministic. Sample generators below cover common shapes; games pass their own for anything else (crowds, convoys, sports positions) with no engine edit.
- `LineFormationOptions` (interface): interface LineFormationOptions — Options for {@link lineFormation}.
- `SlotAssignmentOptions` (interface): interface SlotAssignmentOptions — Tuning for {@link assignFormationSlots}' stable, low-churn matching.
- `Vec2` (type): type Vec2 = readonly [number, number] — A point or offset on the XZ ground plane: `[x, z]`.
- `WedgeFormationOptions` (interface): interface WedgeFormationOptions — Options for {@link wedgeFormation}.
- `assignFormationSlots` (function): function assignFormationSlots(members: readonly Vec2[], slots: readonly Vec2[], options: SlotAssignmentOptions = {}): number[] — Match `members` to `slots` by a deterministic greedy nearest assignment: every (member, slot) pair is ranked by squared travel distance (minus a stickiness bonus for a member's previous slot) and assigned in order while both ends are free. Returns `assignment[member] = slot`, or `-1` for members left unmatched when there are fewer slots than members. Ties break by member then slot index, so the result is stable across runs and independent of input ordering — the property replay and lockstep multiplayer rely on. Groups are bounded, so the `O(members·slots·log)` sort is fine; this is not a per-frame whole-world pass.
- `boxFormation` (function): function boxFormation(options: BoxFormationOptions): FormationSlotGenerator — A rectangular grid centered on the destination, front row toward `+forward` — a marching block or a phalanx. Rows fill front-to-back, left-to-right.
- `circleFormation` (function): function circleFormation(options: CircleFormationOptions): FormationSlotGenerator — An evenly spaced ring around the destination — a guard cordon, a huddle, or a surround. Slot 0 sits `startAngle` from forward; slots advance evenly around the circle.
- `facingYaw` (function): function facingYaw(from: Vec2, to: Vec2): number — Engine yaw (`rotationY`, radians) that faces from `from` toward `to` on the XZ plane, matching the `forward = (sin yaw, cos yaw)` convention. Feed the result as the `facing` of {@link placeFormation} to orient a formation along its travel direction. Returns `0` when the points coincide.
- `lineFormation` (function): function lineFormation(options: LineFormationOptions): FormationSlotGenerator — A single rank abreast, centered on the destination and facing forward — a skirmish line or a chorus row. Slots run left→right along the group's right axis.
- `placeFormation` (function): function placeFormation(destination: Vec2, facing: number, count: number, generator: FormationSlotGenerator): Vec2[] — Transform a generator's local slot offsets into world XZ positions around a `destination`, rotated by `facing` (engine yaw). Slot `i` in the returned array is `generator(count)[i]` mapped through the group frame, so it stays aligned with {@link assignFormationSlots}' slot indices. Pure and allocation- light: one array of `count` points, no per-call closures retained.
- `wedgeFormation` (function): function wedgeFormation(options: WedgeFormationOptions): FormationSlotGenerator — A "V"/arrowhead with the apex at the destination and arms trailing back — a flying-wedge charge or a goose skein. Slot 0 is the tip; later slots alternate right then left, each rank stepping one `spacing` outward and backward.

## @jgengine/core/movement/freeFlight

- `CREATIVE_FLIGHT_TUNING` (const): const CREATIVE_FLIGHT_TUNING: FreeFlightTuning — Preset for Minecraft-like creative flight — weightless, collides, yaw-relative strafe.
- `FreeFlightBindings` (interface): interface FreeFlightBindings — Per-axis bindings for free-flight — which actions drive each flight axis. Positive is forward/right/up.
- `FreeFlightController` (interface): interface FreeFlightController — Stateful handle for any free-flight actor with snapshot/restore/retune.
- `FreeFlightIntent` (interface): interface FreeFlightIntent — Intent for one free-flight tick — forward/right from WASD/analog, vertical from jump/crouch.
- `FreeFlightMode` (type): type FreeFlightMode = "creative" | "spectator" | "noclip" | "hover" — Free-flight families — character-scale 6DOF movement, distinct from vehicle aerodynamics.
- `FreeFlightState` (interface): interface FreeFlightState — Velocity state for a free-flight actor — serializable and ownable by the caller.
- `FreeFlightStep` (interface): interface FreeFlightStep — World displacement produced by one free-flight tick.
- `FreeFlightTuning` (interface): interface FreeFlightTuning — Data-first tuning for one free-flight profile.
- `HOVER_FLIGHT_TUNING` (const): const HOVER_FLIGHT_TUNING: FreeFlightTuning — Preset for hover/jetpack — gravity + thrust, useful for short bursts.
- `NOCLIP_FLIGHT_TUNING` (const): const NOCLIP_FLIGHT_TUNING: FreeFlightTuning — Preset for noclip — weightless, noclips, yaw-relative with independent vertical.
- `SPECTATOR_FLIGHT_TUNING` (const): const SPECTATOR_FLIGHT_TUNING: FreeFlightTuning — Preset for spectator — weightless, noclips, flies where the camera looks.
- `advanceFreeFlight` (function): function advanceFreeFlight(state: FreeFlightState, intent: FreeFlightIntent, yaw: number, pitch: number | undefined, dt: number, tuning: FreeFlightTuning, options?: Pick<MotionFrameOptions, "authoritativeStep">): FreeFlightStep — Advance one frame of free-flight kinematics. Horizontal uses yaw-relative strafe (A = left, D = right) — never roll/bank. Vertical is independent of pitch unless `alignWithLook` is true (spectator).
- `createFreeFlightController` (function): function createFreeFlightController(initialTuning: FreeFlightTuning, options: { yaw?: number; pitch?: number; state?: FreeFlightState } = {}): FreeFlightController — Totally free flight for any actor — character, camera, drone, or debug rig. Horizontal is always yaw-relative strafe; vertical is jump/crouch. Use `alignWithLook` for a 6DOF spectator that flies where the camera looks.
- `createFreeFlightState` (function): function createFreeFlightState(): FreeFlightState — Create an empty flight velocity state.
- `resolveFlightStep` (function): function resolveFlightStep(position: readonly [number, number, number], stepX: number, stepY: number, stepZ: number, obstacles: readonly CollisionObstacle[], radius: number = DEFAULT_OBSTACLE_PLAYER_RADIUS): { stepX: number; stepY: number; stepZ: number } — Resolve a flight step against world solids (XZ slide + Y clamp).
- `resolveFreeFlightIntent` (function): function resolveFreeFlightIntent(keys: MovementKeysState, analog: AnalogMoveIntent | null | undefined): FreeFlightIntent — Translate held keys + analog into a free-flight intent. Vertical is `space - (control|c)` so jump ascends and crouch descends — the same keys that walk/jump/crouch use, re-mapped for flight without re-binding.
- `resolveFreeFlightIntentFromInput` (function): function resolveFreeFlightIntentFromInput(isDown: (action: string) => boolean, value: (action: string) => number, pointer: PointerAxisState | null, bindings?: FreeFlightBindings): FreeFlightIntent — Translate live input (held actions + analog + pointer) into a flight intent using per-profile axis bindings. Unlisted bindings fall back to the defaults above so existing games keep WASD/Space/Ctrl/Shift without declaring anything.

## @jgengine/core/movement/glideModel

- `GlideInput` (interface): interface GlideInput { yaw?: number; throttle?: number; control?: number } — ⚠ undocumented
- `GlideModel` (interface): interface GlideModel — A kinematic glider (#282.6) — the walk-controller-compatible sibling of `physics/traversal`'s rigid-body `Glide`, with the yaw and powered-climb authority that one lacks. External flows — `physics/flowTube` corridors, `world/windZones` schedules — compose per tick through `externalVelocity`, and turbulence degrades control through the `control` scalar.
- `GlideModelConfig` (interface): interface GlideModelConfig { gravityScale?: number; gravity?: number; thrustAccel?: number; forwardSpeed?: number; yawRate?: number; climbAccel?: number; maxFallSpeed?: number; control?: number } — ⚠ undocumented · used by `createGlideModel`: Gliding/wingsuit descent control — lift, drag, and steering from a launch.
- `GlideStep` (interface): interface GlideStep { position: GlideVec3; velocity: GlideVec3; heading: number } — ⚠ undocumented
- `GlideVec3` (type): type GlideVec3 = readonly [number, number, number] — ⚠ undocumented
- `createGlideModel` (function): function createGlideModel(config: GlideModelConfig = {}): GlideModel — Gliding/wingsuit descent control — lift, drag, and steering from a launch.

## @jgengine/core/movement/grappleSwing

- `GrappleSwing` (interface): interface GrappleSwing — A rope-swing constraint for kinematic controllers (#282.5) — the walk-controller-compatible sibling of `physics/traversal`'s rigid-body `Grapple`. Fire at an anchor, feed each frame's integrated position/velocity through `step`, and commit what comes back (via `beforeCommit` or `setPose`): positions beyond the rope clamp to its sphere and velocity loses its outward radial component, which is exactly a pendulum swing.
- `GrappleSwingConfig` (interface): interface GrappleSwingConfig { reelSpeed?: number; minLength?: number; stiffness?: number; damping?: number } — ⚠ undocumented · used by `createGrappleSwing`: Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.
- `GrappleSwingState` (interface): interface GrappleSwingState { attached: boolean; anchor: SwingVec3 | null; ropeLength: number } — ⚠ undocumented
- `GrappleSwingStep` (interface): interface GrappleSwingStep { position: SwingVec3; velocity: SwingVec3 } — ⚠ undocumented
- `SwingVec3` (type): type SwingVec3 = readonly [number, number, number] — ⚠ undocumented
- `createGrappleSwing` (function): function createGrappleSwing(config: GrappleSwingConfig = {}): GrappleSwing — Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.

## @jgengine/core/movement/leaderTrail

- `LeaderTrail` (interface): interface LeaderTrail — A live breadcrumb trail recorded from a moving leader, with followers placed by arc-length behind the head — conga lines, convoys, duckling chains, snake bodies. Call `record` with the leader's position every tick; read `followerAt(i)` for the pose `spacing * (i + 1)` behind.
- `LeaderTrailConfig` (interface): interface LeaderTrailConfig { spacing: number; maxFollowers?: number; sampleDistance?: number } — ⚠ undocumented · used by `createLeaderTrail`: A trailing follower formation that chases a leader along its past path — snake/convoy trails.
- `TrailPoint` (type): type TrailPoint = readonly [number, number, number] — ⚠ undocumented
- `TrailPose` (interface): interface TrailPose { position: TrailPoint; heading: number } — ⚠ undocumented
- `createLeaderTrail` (function): function createLeaderTrail(config: LeaderTrailConfig): LeaderTrail — A trailing follower formation that chases a leader along its past path — snake/convoy trails.

## @jgengine/core/movement/movementModel

- `AnalogMoveIntent` (interface): interface AnalogMoveIntent — Analog movement vector (camera-relative, each axis in [-1, 1]) from a continuous source — a virtual joystick or gamepad stick. When present it replaces the digital WASD axes so a slight tilt walks slightly instead of slamming a full strafe.
- `CollisionObstacle` (interface): interface CollisionObstacle — A placed scene object the walking player collides against as a circle-vs-AABB obstacle.
- `MAX_JUMP_OFFSET` (const): const MAX_JUMP_OFFSET: 1.15 — Peak jump height from MOVEMENT_TUNING.jumpVelocity + gravity, with small buffer.
- `MOVEMENT_TUNING` (const): const MOVEMENT_TUNING: { readonly standEyeHeight: 1.7; readonly crouchEyeHeight: 1.15; readonly walkSpeedMultiplier: 1.75; readonly runSpeedMultiplier: 2.25; readonly crouchSpeedMultiplier: 0.45; readonly backpedalSpeedMultiplier: 0.65; readonly groundAcceleration: 26; readonly airAcceleration: 12; … — Kinematics + feel tuning for the first-person controller. Centralised here so movement feel lives in one place rather than scattered through the renderer.
- `MotionFrameOptions` (interface): interface MotionFrameOptions — Per-frame dynamic modifiers for {@link advancePlayerMotion} — state the caller recomputes each tick (unlike the static {@link MovementTuningOverrides}). Omitted fields leave the integrator at its default behavior.
- `MovementFrameStep` (interface): interface MovementFrameStep — Horizontal step (world units) the avatar should commit this frame.
- `MovementIntent` (interface): interface MovementIntent — Frame-independent description of what the player is asking the avatar to do. `forward`/`right` are in the range -1..1 in the avatar's local frame; the controller rotates them into world space against the camera each frame.
- `MovementKey` (type): type MovementKey = "w" | "a" | "s" | "d" | "shift" | "control" | "c" | "space" — Movement core (pure model).
- `MovementKeysState` (type): type MovementKeysState = Record<MovementKey, boolean> — ⚠ undocumented · used by `resolveFreeFlightIntent` (@jgengine/core/movement/freeFlight): Translate held keys + analog into a free-flight intent.
- `MovementTuningOverrides` (interface): interface MovementTuningOverrides — Per-game overrides for the gravity/jump feel, sourced from `GameDefinition.physics`. Omitted fields fall back to {@link MOVEMENT_TUNING}.
- `PlayerMotionState` (interface): interface PlayerMotionState — Mutable kinematic state carried between frames by the controller. Kept here so the velocity / jump / gravity integration is a pure function testable without a renderer — the controller just owns the ref.

## @jgengine/core/movement/movementProbe

- `MovementProbeOptions` (interface): interface MovementProbeOptions — Scenario settings for {@link measureMovement}; every field has a default.
- `MovementProbeSubject` (interface): interface MovementProbeSubject — The walk character {@link measureMovement} drives: the same fields a game passes to `defineGame`.
- `MovementReport` (interface): interface MovementReport — Deterministic walk-feel metrics. `Infinity` means the target was never reached.
- `measureMovement` (function): function measureMovement(subject: MovementProbeSubject = {}, options: MovementProbeOptions = {}): MovementReport — Drives a walk character through fixed scenarios (standing start, release to stop, reversal, a standing jump, a tapped jump, a strafed jump) on the same integrator `stepPlayerMovement` uses, and reports the feel metrics a test can assert. Deterministic: the same subject and options always produce the same report, so a feel change shows up as a number moving. Collision, terrain and swimming are out of scope; it measures flat ground.

## @jgengine/core/movement/playerMovement

- `PlayerMovementSnapshot` (interface): interface PlayerMovementSnapshot — One player's serializable movement state: heading, facing, velocities, jump latch and controller capsule. The entity pose lives in the entity store.
- `PlayerMovementTelemetry` (interface): interface PlayerMovementTelemetry — Last completed shared movement step for one entity; a live read-only view, not a save snapshot.
- `PlayerMovementTuning` (interface): interface PlayerMovementTuning — The resolved, per-world movement configuration {@link stepPlayerMovement} integrates against — the same inputs the shell FrameDriver used to read piecemeal, gathered into one struct so single-player and host movement run identical math.
- `forgetPlayerMovement` (function): function forgetPlayerMovement(ctx: GameContext, userId: string): void — Drop a player's retained movement state (heading + kinematic body) — call on leave so a rejoin starts fresh instead of resuming stale velocity.
- `playerMovementHeading` (function): function playerMovementHeading(ctx: GameContext, userId: string): number — One player's current heading (radians), integrated by {@link stepPlayerMovement} — the shell reads it back into its camera/aim yaw.
- `playerMovementTelemetry` (function): function playerMovementTelemetry(ctx: GameContext, entityId: string): Readonly<PlayerMovementTelemetry> | null — Read the entity's last shared movement result through indexed possession ownership. Returns `null` before a step, after movement restore/forget, when a commit policy replaces the motor proposal, or for an entity not currently driven by this motor. Reuses one live view; custom movers supply their own animation parameters. Flight never reports ground contact or a walking crouch.
- `resolvePhysicsTuning` (function): function resolvePhysicsTuning(physics: PhysicsConfig | undefined): MovementTuningOverrides | undefined — Maps a game's declared `physics` onto the movement controllers' tuning. `PhysicsConfig.gravity` is a signed world acceleration (negative points down), but the controllers integrate `velocityY -= gravityAcceleration * dt` and expect a positive downward magnitude — so gravity is negated here to keep down-pointing gravity pulling down.
- `resolvePlayerMovementTuning` (function): function resolvePlayerMovementTuning(opts: { collision?: VoxelCollisionConfig; movement?: PlayerMovementConfig; physics?: PhysicsConfig; world?: WorldFeature; }): PlayerMovementTuning — Gather a game's collision/movement/physics/world config into a {@link PlayerMovementTuning} — call once per world; both the shell and a host pass the result to {@link stepPlayerMovement}.
- `restorePlayerMovement` (function): function restorePlayerMovement(ctx: GameContext, userId: string, snapshot: PlayerMovementSnapshot): void — Put a player's movement state back to a {@link snapshotPlayerMovement} copy. Pending state survives until first spawn; a driven actor's despawn clears it.
- `snapshotPlayerMovement` (function): function snapshotPlayerMovement(ctx: GameContext, userId: string): PlayerMovementSnapshot | null — Copy one player's movement state for prediction, rollback or a save; `null` when the player has not moved yet.
- `stepPlayerMovement` (function): function stepPlayerMovement(ctx: GameContext, userId: string, input: InputFrame, dt: number, tuning: PlayerMovementTuning, heading?: number, pitch?: number): void — Integrate one player's movement for a tick from their held-input frame and commit the pose — the single genre-agnostic controller both the shell (its local player) and a host (each connected player in `onTick`) call, so single-player and server-authoritative movement are identical. Reads the player's controlled entity, terrain, scene solids, and pending motion impulses; writes the entity pose via `setPose`. Retains heading + kinematic body per `userId` on the `ctx`. Pass `heading` to override the internally-integrated yaw (the shell owns yaw for its camera); omit it and the controller turns from the frame's `turnLeft`/`turnRight` actions. Pass `pitch` for 6DOF spectator flight when `alignWithLook` is set.

## @jgengine/core/movement/poseState

- `AimMode` (type): type AimMode = "hip" | "ads" — ⚠ undocumented
- `MovementPose` (type): type MovementPose = "standing" | "crouch" | "prone" | "running" — ⚠ undocumented
- `POSE_HITBOX` (const): const POSE_HITBOX: Record<MovementPose, PoseHitbox> — ⚠ undocumented
- `PoseAllowedStates` (interface): interface PoseAllowedStates { poses?: readonly MovementPose[]; aim?: readonly AimMode[] } — ⚠ undocumented · used by `createPoseState`: Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.
- `PoseHitbox` (interface): interface PoseHitbox { height: number; eyeHeight: number; speedMultiplier: number } — ⚠ undocumented
- `PoseRejection` (interface): interface PoseRejection { reason: string } — ⚠ undocumented
- `PoseSnapshot` (interface): interface PoseSnapshot { poses: Record<string, MovementPose>; aims: Record<string, AimMode> } — ⚠ undocumented
- `PoseState` (interface): interface PoseState { getPose(instanceId: string): MovementPose; setPose(instanceId: string, pose: MovementPose): PoseRejection | null; getAim(instanceId: string): AimMode; setAim(instanceId: string, mode: AimMode): PoseRejection | null; clear(instanceId: stri… — ⚠ undocumented · used by `createPoseState`: Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.
- `createPoseState` (function): function createPoseState(resolveAllowed: (instanceId: string) => PoseAllowedStates | null | undefined): PoseState — Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.

## @jgengine/core/movement/serverStep

- `serverStep` (function): function serverStep(ctx: GameContext, userId: string, frame: InputFrame, dt: number, tuning?: PlayerMovementTuning): void — Advance one authoritative player's movement using the same controller as the shell.

## @jgengine/core/movement/solidObstacles

- `ObstacleReach` (interface): interface ObstacleReach — Largest blocking-collider extent in the scene, split so tower height cannot inflate the XZ query.
- `ObstacleReachCache` (interface): interface ObstacleReachCache — Mutable reach cache; one per source, invalidated by object count.
- `SolidObstacleSource` (interface): interface SolidObstacleSource — The slice of the scene's object store this query needs. Narrow on purpose: the scene context wires its own store here while it is still being constructed, `ctx.scene.object` satisfies it as-is, and a pure rules package with no `GameContext` to import can satisfy it from its own object list.
- `createObstacleReachCache` (function): function createObstacleReachCache(): ObstacleReachCache — A fresh {@link ObstacleReachCache} for a caller that owns its own source.
- `obstacleFromSolid` (function): function obstacleFromSolid(solid: WorldSolid): CollisionObstacle — A {@link WorldSolid} as a {@link CollisionObstacle}. Axis-aligned solids are one box; a yawed solid is cut into strips along its long axis, each fitted with an AABB, so a turned building does not block the street beside it the way a single enclosing box would.
- `resolveSourceWalkerStep` (function): function resolveSourceWalkerStep(source: SolidObstacleSource, cache: ObstacleReachCache, position: EntityPosition, stepX: number, stepZ: number, options: { radius?: number; stepUpHeight?: number } = {}): { stepX: number; stepZ: number } — {@link resolveWalkerStep} with no `GameContext`: gather plus slide against a bare {@link SolidObstacleSource} and a caller-owned {@link ObstacleReachCache}.
- `resolveWalkerStep` (function): function resolveWalkerStep(ctx: GameContext, position: EntityPosition, stepX: number, stepZ: number, options: { radius?: number; stepUpHeight?: number } = {}): { stepX: number; stepZ: number } — Slide a walker's horizontal step against the same solid geometry that stops the player, returning the X/Z it may actually take this tick. A step into a wall is cut on the blocked axis and preserved on the other, exactly as {@link stepPlayerMovement} resolves the player's.
- `slideStep` (function): function slideStep(position: EntityPosition, stepX: number, stepZ: number, obstacles: readonly CollisionObstacle[], radius = DEFAULT_OBSTACLE_PLAYER_RADIUS, stepUpHeight = 0): { stepX: number; stepZ: number } — {@link resolveWalkerStep} against an already-gathered obstacle set.
- `solidObstaclesNear` (function): function solidObstaclesNear(ctx: GameContext, position: EntityPosition, reachX: number, reachZ: number, height = WALKER_HEIGHT): CollisionObstacle[] — Every blocking physical obstacle overlapping the box `position` ± `reachX`/`reachZ`, read from the scene's resolved colliders and `ctx.world.solids`.
- `sourceObstacleReach` (function): function sourceObstacleReach(source: SolidObstacleSource, cache: ObstacleReachCache): ObstacleReach — {@link solidObstacleReach} against a bare source and caller-owned cache.
- `sourceObstaclesNear` (function): function sourceObstaclesNear(source: SolidObstacleSource, reach: ObstacleReach, position: EntityPosition, reachX: number, reachZ: number, height = WALKER_HEIGHT): CollisionObstacle[] — {@link solidObstaclesNear} against a bare source and an already-resolved reach.

## @jgengine/core/movement/steering

- `YawVectorXZ` (type): type YawVectorXZ = readonly [number, number] — Yaw-frame steering math. The engine's heading convention is `forward = (sin yaw, cos yaw)` on the XZ plane with +Y up, which makes a positive yaw increment rotate counterclockwise seen from above — a turn to the entity's LEFT on screen. Every hand-written `heading += steer * rate * dt` therefore turns the wrong way; integrate steering through `steerYaw` instead.
- `steerToward` (function): function steerToward(yaw: number, desiredYaw: number): number — Signed steer-right input that closes on `desiredYaw` when integrated through `steerYaw` — the seek half every AI driver and homing script needs. Magnitude is the wrapped radian error in (−π, π]; scale and clamp it into [-1, 1] at the call site.
- `steerYaw` (function): function steerYaw(yaw: number, steerRight: number, turnRatePerSecond: number, dt: number): number — Integrate one steering step. `steerRight` is the signed steer input (+1 = turn right, matching `DRIVE_AXIS_BINDINGS`' KeyD/ArrowRight), `turnRatePerSecond` is radians per second at full lock. Steering right decreases yaw in the engine frame; this helper owns that sign so game code never re-derives it.
- `yawForward` (function): function yawForward(yaw: number): YawVectorXZ — XZ forward direction of a yaw (`rotationY`): `(sin yaw, cos yaw)`.
- `yawRight` (function): function yawRight(yaw: number): YawVectorXZ — XZ screen-right of a yaw — `forward × up` with up = +Y: `(-cos yaw, sin yaw)`.

## @jgengine/core/movement/terrainGrade

- `resolveTerrainGradeStep` (function): function resolveTerrainGradeStep(sampler: { sampleHeight(x: number, z: number): number } | ((x: number, z: number) => number), position: readonly [number, number, number], stepX: number, stepZ: number, maxClimbGrade: number): { stepX: number; stepZ: number } — Constrain an uphill heightfield step by its sampled rise/run grade. Try the full step, then X-only, then Z-only, preserving downhill travel and sliding along a traversable axis. The sampler can represent a game's terrain policy independently of the ground used for feet. This endpoint test also applies while jumping; it is not continuous terrain collision.

## @jgengine/core/movement/voxelController

- `DEFAULT_VOXEL_DIMS` (const): const DEFAULT_VOXEL_DIMS: VoxelPlayerDims — ⚠ undocumented
- `GroundHeightQuery` (type): type GroundHeightQuery = (x: number, z: number) => number — Samples the terrain floor height at a point; unset means flat ground plays no part in support.
- `SolidQuery` (type): type SolidQuery = (x: number, y: number, z: number) => boolean — ⚠ undocumented · used by `advanceVoxelPlayer`: Advance one frame of voxel-collided player kinematics.
- `VoxelPlayerBody` (interface): interface VoxelPlayerBody — Mutable kinematic state carried between frames by the voxel controller.
- `VoxelPlayerDims` (interface): interface VoxelPlayerDims — Footprint + height of the player box, in world units.
- `advanceVoxelPlayer` (function): function advanceVoxelPlayer(body: VoxelPlayerBody, intent: MovementIntent, forwardX: number, forwardZ: number, baseSpeed: number, rawDeltaSeconds: number, isSolid: SolidQuery, dims: VoxelPlayerDims = DEFAULT_VOXEL_DIMS, tuning?: MovementTuningOverrides, groundHeight?: GroundHeightQuery, options?: Pi… — Advance one frame of voxel-collided player kinematics. Mutates `body` (position, velocity, grounded) in place.
- `createVoxelPlayerBody` (function): function createVoxelPlayerBody(x: number, y: number, z: number): VoxelPlayerBody — ⚠ undocumented

## @jgengine/core/nav/corridors

- `CorridorEdge` (interface): interface CorridorEdge { points: readonly CorridorPoint[]; width: number } — ⚠ undocumented
- `CorridorField` (interface): interface CorridorField — Organic corridor/path collision (#284.9): a distance-to-polyline width clamp over an edge graph — cave tunnels, river channels, winding roads. Grid/navmesh/voxel collision can't express a smooth ribbon; this can. Pure math over authored centerlines.
- `CorridorPoint` (type): type CorridorPoint = readonly [number, number] — ⚠ undocumented
- `CorridorSample` (interface): interface CorridorSample { distance: number; closest: CorridorPoint; edgeIndex: number } — ⚠ undocumented
- `createCorridorField` (function): function createCorridorField(edges: readonly CorridorEdge[]): CorridorField — ⚠ undocumented

## @jgengine/core/nav/laneGraph

- `LaneEdgeConfig` (interface): interface LaneEdgeConfig — One directed lane span to resolve into the graph.
- `LaneGraph` (interface): interface LaneGraph — Authored lane topology: junctions, directed spans with speed limits and arc lengths, crossings with their right-of-way, and parking spots. Positions come from the spans themselves, so a traffic runtime never re-derives geometry or runs a path search per vehicle.
- `LaneGraphConfig` (interface): interface LaneGraphConfig — The authored lane graph: junctions, directed spans, crossings and parking spots.
- `LaneGraphDocumentOptions` (interface): interface LaneGraphDocumentOptions — How the document reader recognizes authored lane content.
- `LaneIntersection` (interface): interface LaneIntersection — A resolved crossing: the lanes that feed it, the lanes that leave it, and its right-of-way.
- `LaneIntersectionConfig` (interface): interface LaneIntersectionConfig — Right-of-way and signal timing for one authored crossing.
- `LaneNode` (interface): interface LaneNode — A junction where lane spans meet.
- `LanePose` (interface): interface LanePose — World pose of a lane at an arc position.
- `LaneRightOfWay` (type): type LaneRightOfWay = "signal" | "priority" — How an intersection resolves which approach may enter next.
- `LaneSignalProgram` (interface): interface LaneSignalProgram — Signal timing for one intersection; phases list the in-lanes each green window serves.
- `LaneSpan` (interface): interface LaneSpan — A resolved lane span: centerline, arc lengths, limit and adjacency.
- `LaneSpot` (interface): interface LaneSpot — A parking spot projected onto one lane at an arc position.
- `createLaneGraph` (function): function createLaneGraph(config: LaneGraphConfig): LaneGraph — Read handle over the graph resolved once at construction. The build mutates its working set; this object never changes, so a save system rebuilds it from the scene document instead of serializing it.
- `laneGraphFromDocument` (function): function laneGraphFromDocument(doc: Pick<EditorDocument, "paths" | "markers">, options: LaneGraphDocumentOptions = {}): LaneGraph — Read a lane graph out of an authored scene document. `traffic_lane` paths are one directed lane each; `road` paths (the editor's street bake) become a lane per direction, offset onto their own side of the road; `traffic_intersection` markers carry a signal program and right-of-way in `meta`; `traffic_parking` markers place parking spots. Runtime positions come from the paths, so editing a road moves its traffic instead of leaving a duplicate lane behind.

## @jgengine/core/nav/navConstrain

- `NavConstrainEntity` (interface): interface NavConstrainEntity { position: EntityPosition } — ⚠ undocumented
- `NavConstrainOptions` (interface): interface NavConstrainOptions { y?: (point: NavPoint) => number } — ⚠ undocumented
- `NavConstrainProposed` (interface): interface NavConstrainProposed { position: EntityPosition; rotationY: number; grounded: boolean } — ⚠ undocumented
- `constrainToNavGrid` (function): function constrainToNavGrid(grid: NavGrid, options?: NavConstrainOptions): (proposed: NavConstrainProposed, entity: NavConstrainEntity) => NavConstrainProposed | null — ⚠ undocumented

## @jgengine/core/nav/navCrowd

- `NavCrowd` (interface): interface NavCrowd — Agents that cross an editor-baked nav mesh: each one plans a corridor with {@link NavRuntime}, walks the funnel-smoothed waypoints, and keeps its distance through reciprocal velocity obstacle avoidance. Goals, arrivals and replans are serializable; a mesh edit only re-plans the agents whose remaining route actually crossed the rebuilt region.
- `NavCrowdAgentSpec` (interface): interface NavCrowdAgentSpec — How one crowd agent was configured when it joined.
- `NavCrowdAgentView` (interface): interface NavCrowdAgentView — One crowd agent's live state, as a game or the devtools overlay reads it.
- `NavCrowdOptions` (interface): interface NavCrowdOptions — Tunables for {@link createNavCrowd}, every one retunable in play.
- `NavCrowdRevalidate` (interface): interface NavCrowdRevalidate — Result of telling the crowd the nav mesh changed.
- `NavCrowdSnapshot` (interface): interface NavCrowdSnapshot — Serializable crowd state: agents, their routes, and the avoidance tuning they run under.
- `NavCrowdStats` (interface): interface NavCrowdStats — Counters a devtools probe or test reads.
- `createNavCrowd` (function): function createNavCrowd(options: NavCrowdOptions & { nav: NavRuntime }): NavCrowd — Compose {@link createNavRuntime} and {@link createRvoCrowd} into a moving crowd: plan on the mesh, follow the smoothed corridor, avoid each other. Deterministic — agents advance in insertion order and the avoidance solve breaks ties by slot, not chance.

## @jgengine/core/nav/navFromEnvironment

- `NavObstacleGrid` (interface): interface NavObstacleGrid { blockAabb(aabb: Aabb): void } — ⚠ undocumented · used by `populateNavGridFromEnvironment`: Blocks the footprint of every solid building an environment feature's `structures` generate — the same set `ctx.world.solids` holds for it.
- `populateNavGridFromEnvironment` (function): function populateNavGridFromEnvironment(grid: NavObstacleGrid, world: EnvironmentWorldFeature): number — Blocks the footprint of every solid building an environment feature's `structures` generate — the same set `ctx.world.solids` holds for it. Returns the number of buildings blocked.
- `populateNavGridFromSolids` (function): function populateNavGridFromSolids(grid: NavObstacleGrid, solids: Pick<WorldSolids, "all">): number — Blocks the XZ footprint of every solid in `solids` (usually `ctx.world.solids`) on `grid`, so NPC paths avoid exactly what movement and physics collide with. Returns the number of solids blocked.

## @jgengine/core/nav/navGrid

- `FindPathOptions` (interface): interface FindPathOptions { smooth?: boolean; clearance?: number; stepCost?: (from: NavPoint, to: NavPoint) => number; canTraverse?: (from: NavPoint, to: NavPoint) => boolean; maxNodes?: number } — ⚠ undocumented · used by `findPath`: A* over the walkable grid.
- `FindPathResult` (type): type FindPathResult = | { status: "path"; points: NavPoint[]; visited: number } | { status: "no-path" | "budget"; visited: number } — Bounded grid search distinguishes exhausted work from a proven unreachable goal.
- `NavCell` (interface): interface NavCell { col: number; row: number } — ⚠ undocumented
- `NavGrid` (interface): interface NavGrid { readonly cols: number; readonly rows: number; readonly cellSize: number; readonly bounds: Aabb; readonly diagonal: boolean; isWalkable(col: number, row: number): boolean; setWalkable(col: number, row: number, walkable: boolean): void; blo… — ⚠ undocumented · used by `findPath`: A* over the walkable grid.
- `NavGridConfig` (interface): interface NavGridConfig { bounds: Aabb; cellSize: number; diagonal?: boolean } — ⚠ undocumented
- `NavPoint` (type): type NavPoint = readonly [number, number] — ⚠ undocumented · used by `findPath`: A* over the walkable grid.
- `createNavGrid` (function): function createNavGrid(config: NavGridConfig): NavGrid — ⚠ undocumented
- `findPath` (function): function findPath(grid: NavGrid, from: NavPoint, to: NavPoint, options: FindPathOptions = {}): NavPoint[] | null — A* over the walkable grid. Returns a polyline of world-space `[x, z]` waypoints from `from` to `to`, or `null` when no route exists. Blocked start/goal snap to the nearest walkable cell so a click on an obstacle still routes to its edge.
- `findPathResult` (function): function findPathResult(grid: NavGrid, from: NavPoint, to: NavPoint, options: FindPathOptions = {}): FindPathResult — Same endpoint snapping as {@link findPath}, with explicit search-budget exhaustion.
- `slopeStepCost` (function): function slopeStepCost(field: { sampleHeight(x: number, z: number): number }, weight = DEFAULT_SLOPE_STEP_WEIGHT): (from: NavPoint, to: NavPoint) => number — `FindPathOptions.stepCost` factory that penalizes steep terrain: cost is `1 + weight * |Δheight| / horizontalDistance`, so with the default weight a 45° slope roughly doubles the step cost.
- `smoothPath` (function): function smoothPath(grid: NavGrid, points: readonly NavPoint[], canTraverse?: (from: NavPoint, to: NavPoint) => boolean): NavPoint[] — Remove waypoints the mover can skip because it has clear line-of-sight past them.

## @jgengine/core/nav/navMesh

- `NavMeshAdjacency` (interface): interface NavMeshAdjacency — Neighbor relationship for one navigation polygon.
- `NavMeshData` (interface): interface NavMeshData — Serializable polygon navigation mesh data. Treat it as immutable once queried; queries cache derived geometry per object.
- `NavMeshLink` (interface): interface NavMeshLink — Explicit traversable connection between two navigation polygons.
- `NavMeshPath` (interface): interface NavMeshPath — Route points and polygons selected through a navigation mesh.
- `NavMeshQuery` (interface): interface NavMeshQuery — Cached, allocation-light queries over one {@link NavMeshData}.
- `NavMeshQueryOptions` (interface): interface NavMeshQueryOptions — Tunable pricing and bounds for a {@link NavMeshQuery}.
- `NavMeshQuerySnapshot` (interface): interface NavMeshQuerySnapshot — Serializable tuning of a {@link NavMeshQuery}.
- `buildNavAdjacency` (function): function buildNavAdjacency(mesh: NavMeshData): NavMeshAdjacency[] — Build polygon adjacency from shared edges and explicit off-mesh links.
- `closestPoint` (function): function closestPoint(mesh: NavMeshData, point: Vec3): Vec3 | null — Return the closest point on the mesh surface, or null for an empty mesh.
- `createNavMeshQuery` (function): function createNavMeshQuery(mesh: NavMeshData, options: NavMeshQueryOptions = {}): NavMeshQuery — Create a cached query over a nav mesh: height-aware polygon lookup through a uniform grid, binary-heap A* priced by area costs and bounded by `maxNodes`, portal-funnel path straightening, and edge-walking raycasts.
- `findPath` (function): function findPath(mesh: NavMeshData, from: Vec3, to: Vec3): NavMeshPath | null — A* over polygon portals with default area costs, straightened by a portal funnel. Use {@link createNavMeshQuery} to price areas.
- `raycastNav` (function): function raycastNav(mesh: NavMeshData, from: Vec3, to: Vec3): boolean — True when the segment remains over walkable polygons.

## @jgengine/core/nav/navRuntime

- `AuthoredNavLink` (interface): interface AuthoredNavLink — A connection the scene author places between two spots — a door through a wall, a ladder to a deck, a jump across a gap. Authored as world points, not polygon ids, so it survives a re-bake: {@link NavRuntime.applyMesh} resolves each end onto the nearest walkable polygon.
- `NavLinkKind` (type): type NavLinkKind = "door" | "ladder" | "jump" | "link" — What an authored off-mesh connection crosses; the runtime prices it by kind unless the author sets a cost.
- `NavRebuildStats` (interface): interface NavRebuildStats — How one {@link NavRuntime.applyMesh} exchange changed the mesh.
- `NavRegion` (interface): interface NavRegion — An XZ box naming the authored area a scene edit touched, so routing state elsewhere is left alone.
- `NavRuntime` (interface): interface NavRuntime — Runtime seam over a baked {@link NavMeshData}: route, price areas, resolve authored links, rebuild in place.
- `NavRuntimeOptions` (interface): interface NavRuntimeOptions extends NavMeshQueryOptions — Options for {@link createNavRuntime}.
- `NavRuntimeSnapshot` (interface): interface NavRuntimeSnapshot — Serializable tuning and authored links of a {@link NavRuntime}; the baked geometry is replaced by `applyMesh`.
- `SceneBake` (interface): interface SceneBake — A bake stored on an editor scene document, structurally compatible with `EditorBake`.
- `createNavRuntime` (function): function createNavRuntime(options: NavRuntimeOptions & { mesh: NavMeshData }): NavRuntime — Route agents over the nav mesh an editor baked. Wraps {@link createNavMeshQuery}, resolves authored off-mesh links (doors, ladders, jumps) onto the current surface, and exchanges the mesh one scene region at a time so untouched polygons keep their ids and the agents routing over them keep their paths.
- `navMeshFromBake` (function): function navMeshFromBake(bakes: readonly SceneBake[] | undefined, id = "main"): NavMeshData | null — Read the named navigation bake an editor wrote onto a scene document. Returns `null` when the document holds no such bake yet, and throws when the stored bake is not a valid nav mesh — a corrupt bake should fail at load, not as agents walking through walls.

## @jgengine/core/nav/pathFollow

- `HeightSampler` (interface): interface HeightSampler { sampleHeight(x: number, z: number): number } — ⚠ undocumented · used by `drapePolyline` (@jgengine/core/world): Drapes an XZ polyline onto the surface: subdivides each span to at most `spacing` and lifts every vertex to `sampleHeight + offset`, returni…
- `PathFollowConfig` (interface): interface PathFollowConfig { waypoints: readonly Waypoint[]; speed: number; loop?: boolean } — ⚠ undocumented · used by `advancePathFollow`: Advance a path-follower by `speed * dt` along its authored polyline.
- `PathFollowProgress` (interface): interface PathFollowProgress — Read-only progress readout for inspection/debug tooling, produced by {@link pathFollowProgress}.
- `PathFollowState` (interface): interface PathFollowState { position: Waypoint; target: number; heading: number; done: boolean; distanceTravelled: number } — ⚠ undocumented · used by `advancePathFollow`: Advance a path-follower by `speed * dt` along its authored polyline.
- `PathProgress` (type): type PathProgress = | { readonly kind: "normalized"; readonly value: number } /** World-distance travelled from the first waypoint (looping paths wrap; clamped otherwise). */ | { readonly kind: "distance"; readonly value: number } /** Segment `index` (0-based) plus `fraction` `0..1` along that segme… — Semantic seek target for {@link pathFollowSeek} — the caller-facing progress vocabulary a stateful path behavior restores from, so a follower can start at a distributed phase or resume a serialized route without knowing waypoint internals. `direction` (forward heading) falls out of the resulting {@link PathFollowState.heading}, so it is an output rather than a seek input.
- `Waypoint` (type): type Waypoint = readonly [number, number, number] — ⚠ undocumented · used by `planSolidRoute` (@jgengine/core/nav/solidRoute): Plan an exact-endpoint local route over indexed movement boxes using the shared nav grid.
- `advancePathFollow` (function): function advancePathFollow(config: PathFollowConfig, state: PathFollowState, dt: number): PathFollowState — Advance a path-follower by `speed * dt` along its authored polyline. Pure — returns the next state. Crosses multiple waypoints in one step, loops when configured, and reports `done` at the end of a non-looping path. No navmesh required (#52); feed it a navmesh route via `pathFromNav` for click-to-move (#51).
- `createPathFollow` (function): function createPathFollow(config: PathFollowConfig): PathFollowState — ⚠ undocumented
- `pathFollowProgress` (function): function pathFollowProgress(config: PathFollowConfig, state: PathFollowState): PathFollowProgress — Read a follower's current progress in every semantic form — the inverse of {@link pathFollowSeek}, for editor/debug inspection and progress HUDs. Pure and allocation-light.
- `pathFollowSeek` (function): function pathFollowSeek(config: PathFollowConfig, target: PathProgress): PathFollowState — Place a follower at a semantic {@link PathProgress} without simulating from the start — the seek adapter behavior lifecycles use to seed distributed phases and restore serialized routes. Pure; returns a fresh {@link PathFollowState} whose `heading` gives travel direction. Looping paths wrap the distance; non-looping paths clamp to `[0, pathLength]` and report `done` at the end.
- `pathFromNav` (function): function pathFromNav(points: readonly NavPoint[], elevation: number | HeightSampler = 0, offset = 0): Waypoint[] — ⚠ undocumented
- `pathLength` (function): function pathLength(config: PathFollowConfig): number — Total world-distance of a path — sum of every segment, including the wrap segment back to the first waypoint when `loop` is set. Zero for a degenerate (0- or 1-waypoint) path.

## @jgengine/core/nav/railGraph

- `RailEdge` (interface): interface RailEdge { id: string; from: string; to: string; via?: readonly Waypoint[] } — ⚠ undocumented
- `RailGraph` (interface): interface RailGraph — A directed graph of track segments with junction switch-throw semantics — the topological seam `nav/navGrid`'s walkable cells can't express. Each node with several out-edges is a switch whose thrown edge decides where traffic exits; riders (`createRailRider`) run along edge polylines and take the thrown edge at every junction.
- `RailGraphConfig` (interface): interface RailGraphConfig { nodes: readonly RailNode[]; edges: readonly RailEdge[] } — ⚠ undocumented
- `RailNode` (interface): interface RailNode { id: string; at: Waypoint } — ⚠ undocumented
- `RailRider` (interface): interface RailRider { advance(dt: number): RailRiderPose; pose(): RailRiderPose; setSpeed(speed: number): void; place(edgeId: string, s?: number): void } — ⚠ undocumented
- `RailRiderConfig` (interface): interface RailRiderConfig { edgeId: string; s?: number; speed: number } — ⚠ undocumented
- `RailRiderPose` (interface): interface RailRiderPose { position: Waypoint; heading: number; edgeId: string; s: number; atDeadEnd: boolean } — ⚠ undocumented
- `ResolvedRailEdge` (interface): interface ResolvedRailEdge { id: string; from: string; to: string; points: readonly Waypoint[]; length: number } — ⚠ undocumented
- `createRailGraph` (function): function createRailGraph(config: RailGraphConfig): RailGraph — ⚠ undocumented
- `createRailRider` (function): function createRailRider(graph: RailGraph, config: RailRiderConfig): RailRider — ⚠ undocumented

## @jgengine/core/nav/solidRoute

- `SolidRouteOptions` (interface): interface SolidRouteOptions — Caller-owned local collision query and terrain policy; no movement or perception state.
- `SolidRouteResult` (type): type SolidRouteResult = | { status: "path"; waypoints: Waypoint[]; work: SolidRouteWork } | { status: "no-path" | "budget"; work: SolidRouteWork } — Failures never carry a partial or snapped route.
- `SolidRouteWork` (interface): interface SolidRouteWork — Work counters exclude the caller's spatial-query implementation.
- `planSolidRoute` (function): function planSolidRoute(from: Waypoint, to: Waypoint, options: SolidRouteOptions): SolidRouteResult — Plan an exact-endpoint local route over indexed movement boxes using the shared nav grid. Every edge is swept at body width; bounded failure leaves retry/stop policy with the caller.

## @jgengine/core/nav/timetable

- `RouteTimetable` (interface): interface RouteTimetable — A deterministic mover over an authored route: position is a pure function of absolute time, so a forecast preview (`poseAt(t + 30)`) and the live mover can never disagree — the seam `nav/pathFollow`'s dt-incremental state can't offer. Trains, ferries, patrol shuttles, crushers: anything on a timetable.
- `RouteTimetableConfig` (interface): interface RouteTimetableConfig { waypoints: readonly (Waypoint | TimetableStop)[]; speed: number; loop?: boolean; dwellSeconds?: number; offsetSeconds?: number } — ⚠ undocumented
- `TimetablePose` (interface): interface TimetablePose { position: Waypoint; heading: number; segment: number; dwelling: boolean } — ⚠ undocumented
- `TimetableStop` (interface): interface TimetableStop { at: Waypoint; dwellSeconds?: number } — ⚠ undocumented
- `createRouteTimetable` (function): function createRouteTimetable(config: RouteTimetableConfig): RouteTimetable — ⚠ undocumented

## @jgengine/core/nav/traffic

- `Traffic` (interface): interface Traffic — Traffic on an authored lane graph: cars follow lane spans with IDM car-following, hold at stop lines, cross intersections under a signal phase or first-come right-of-way, change lanes, park in authored spots, and grow or shrink with the caller's `demand`. Deterministic — cars advance in insertion order, ties break on id, and the injected generator is the only source of variety. Bounded per tick: one pass over the cars, one sorted pass per occupied lane, no path search.
- `TrafficCarView` (interface): interface TrafficCarView — One car's live state, as a renderer, a game or the devtools overlay reads it.
- `TrafficOptions` (interface): interface TrafficOptions — Everything {@link createTraffic} needs: the graph, the injected generator and the caller's policies.
- `TrafficRoutePolicy` (type): type TrafficRoutePolicy = (context: { carId: string; laneId: string; nodeId: string; /** Outbound lanes that are not the lane the car arrived on, sorted by id. */ options: readonly string[]; }) => string | null — Caller-supplied exit choice at a junction: return one of `options`, or `null` to leave the graph.
- `TrafficSignalState` (interface): interface TrafficSignalState — An intersection's signal right now: which phase is green and for how long.
- `TrafficSnapshot` (interface): interface TrafficSnapshot — Serializable traffic state: the fleet, the parking occupancy, the signal clocks and the demand.
- `TrafficStats` (interface): interface TrafficStats — Counters a devtools probe, a HUD or a test reads.
- `TrafficTuning` (interface): interface TrafficTuning — Every per-car behaviour number, retunable in play.
- `createTraffic` (function): function createTraffic(options: TrafficOptions): Traffic — Traffic for an authored lane graph (see {@link createLaneGraph}).

## @jgengine/core/orders/orderKinds

- `AttackMoveOrderPayload` (interface): interface AttackMoveOrderPayload — Payload for an attack-move: advance toward `point`, engaging hostiles encountered en route.
- `EmptyOrderPayload` (type): type EmptyOrderPayload = Record<string, never> — Payload for stop/hold orders — no data; the verb is the intent.
- `EngagementKindConfig` (interface): interface EngagementKindConfig extends OrderKindConfig — Move + engagement config carrying the default radii the payload may override.
- `EngagementOrderState` (interface): interface EngagementOrderState — Live intent an attack-move/targeted order writes into `Order.state`; the game reads it to run the actual attack. Serializable.
- `MoveOrderPayload` (interface): interface MoveOrderPayload — Payload for a move order: go to a point and complete on arrival.
- `OrderKindConfig` (interface): interface OrderKindConfig — Shared factory config: override the verb key so a game can register the composition under its own name.
- `OrderMoveResult` (interface): interface OrderMoveResult — Result of one movement step, from the game's motion adapter.
- `OrderMover` (interface): interface OrderMover — Narrow motion adapter an order kind drives. The game implements it over its own controller/motor (`scene.moveToward`, a nav follower, physics) for one entity; the kind never touches the scene directly.
- `OrderTargeting` (interface): interface OrderTargeting — Narrow targeting adapter for engagement verbs. `acquire` returns the id of a hostile within `radius` (nearest, or whatever policy the game injects), and `positionOf` locates a known target. Actual damage/effects stay game-side.
- `PatrolOrderPayload` (interface): interface PatrolOrderPayload — Payload for a patrol: walk a waypoint route, optionally looping forever.
- `PatrolOrderState` (interface): interface PatrolOrderState — Serializable patrol progress.
- `TargetedOrderPayload` (interface): interface TargetedOrderPayload — Payload for a targeted action: pursue one target until in range, holding within a leash.
- `defineAttackMoveOrder` (function): function defineAttackMoveOrder<TCtx extends OrderMover & OrderTargeting>(config: EngagementKindConfig = {}): OrderKind<TCtx, AttackMoveOrderPayload> — Attack-move: advance toward a destination but break off to engage any hostile acquired within `aggroRadius`, pursuing it to `attackRange` and writing the engagement intent into `order.state` for the game to act on. Completes on reaching the destination with nothing to engage.
- `defineHoldOrder` (function): function defineHoldOrder<TCtx extends OrderMover>(config: OrderKindConfig = {}): OrderKind<TCtx, EmptyOrderPayload> — Hold position: stand ground indefinitely (never completes on its own) until preempted or canceled — the "guard here" verb.
- `defineMoveOrder` (function): function defineMoveOrder<TCtx extends OrderMover>(config: OrderKindConfig & { arriveRadius?: number } = {}): OrderKind<TCtx, MoveOrderPayload> — The plain "go here" verb: step toward a point each tick, complete on arrival, fail if the entity despawns. The completion predicate is arrival within `arriveRadius`.
- `definePatrolOrder` (function): function definePatrolOrder<TCtx extends OrderMover>(config: OrderKindConfig & { arriveRadius?: number } = {}): OrderKind<TCtx, PatrolOrderPayload> — Patrol: walk a waypoint route, advancing the serialized `index` as each point is reached. Loops forever by default, or completes at the last waypoint when `loop` is `false`.
- `defineStopOrder` (function): function defineStopOrder<TCtx extends OrderMover>(config: OrderKindConfig = {}): OrderKind<TCtx, EmptyOrderPayload> — Stop: halt immediately and complete the same tick — the interrupt that clears a unit's intent to standstill.
- `defineTargetedOrder` (function): function defineTargetedOrder<TCtx extends OrderMover & OrderTargeting>(config: EngagementKindConfig = {}): OrderKind<TCtx, TargetedOrderPayload> — Targeted action: pursue one specific target until within `range`, writing the engagement intent into `order.state`. Completes when the target is gone (despawned/dead), so the game's effect loop runs while `inRange` is true.

## @jgengine/core/orders/orderQueue

- `Order` (interface): interface Order<TPayload = unknown> — One issued order. Fully serializable: `kind` is a registry key (not a closure), `payload` is the caller's plain data, and `state` is the kind's own plain progress scratch (e.g. a patrol waypoint index) written during `start`/`update`. Never holds functions, so the whole queue round-trips through `JSON`/`structuredClone`.
- `OrderCancelReason` (type): type OrderCancelReason = "replaced" | "preempted" | "requested" | "invalid" | "failed" | "cleared" — Why an order left the queue without completing. `replaced`/`preempted` come from a newer order taking over; `requested` from explicit `cancelActive`; `invalid` when the kind's `start` rejects; `failed` when `update` reports failure; `cleared` from a full `clear`/`cancelAll`.
- `OrderEvent` (interface): interface OrderEvent — A lifecycle event emitted synchronously as orders move through the queue.
- `OrderIssueResult` (type): type OrderIssueResult<TPayload = unknown> = | { status: "accepted"; order: Order<TPayload> } | { status: "queued"; order: Order<TPayload> } | { status: "rejected"; reason: string } — Outcome of `issue`: `accepted` entered the queue, `queued` entered behind an uninterruptible/active order, `rejected` was refused (validation or `reject` policy).
- `OrderKind` (interface): interface OrderKind<TCtx, TPayload = unknown> — The composition seam for one order verb. `TCtx` is the game's world adapter (movement, targeting, effects) shared by every kind in a registry; `TPayload` is this verb's caller data. `start` seeds `order.state`, `update` advances it and reports lifecycle, and `finish` releases anything the kind held. Kinds are pure over their injected `ctx` -- no globals, no direct scene reach.
- `OrderOutcome` (interface): interface OrderOutcome — Terminal outcome handed to a kind's `finish` cleanup hook.
- `OrderPhase` (type): type OrderPhase = "queued" | "active" | "completed" | "canceled" — Lifecycle phase of a single order. `queued` waits behind the active order; `active` is ticking; `completed`/`canceled` are terminal.
- `OrderProgress` (type): type OrderProgress = { status: "running" } | { status: "completed" } | { status: "failed"; reason: string } — Result of a kind's `update` tick. `running` keeps the order active; the completion predicate lives in the kind (returns `completed`); `failed` cancels the order (reason `failed`) so the queue advances to the next one.
- `OrderQueue` (interface): interface OrderQueue<TCtx, TPayload = unknown> — A per-entity order queue: one commandable unit's lifecycle of intent. The game ticks it with its world adapter; it activates, advances, completes, and cancels orders and enforces preemption policy. State is serializable for save and host-authoritative replication.
- `OrderQueueOptions` (interface): interface OrderQueueOptions<TPayload = unknown> — Construction options for a queue.
- `OrderQueuePolicy` (type): type OrderQueuePolicy = "replace" | "append" | "front" | "reject" — How a newly issued order interacts with what's already queued. `replace` preempts the active order and clears pending; `append` queues it behind everything (shift-queue); `front` makes it the next to run without touching the active order; `reject` refuses it while anything is queued.
- `OrderQueueState` (interface): interface OrderQueueState<TPayload = unknown> — Serializable snapshot of a queue: the active order plus the pending list, in order.
- `OrderRegistry` (interface): interface OrderRegistry<TCtx> — Registry of order kinds keyed by verb string; the queue dispatches through it so engine code never switches on a verb.
- `OrderRejection` (interface): interface OrderRejection — A kind's refusal of a payload (from `validate`) — surfaced to the issuer as a rejection reason.
- `OrderRequest` (interface): interface OrderRequest<TPayload = unknown> — A request to issue an order; `policy` defaults to `replace`, `id` is generated when omitted.
- `OrderStartResult` (type): type OrderStartResult = { ok: true } | { ok: false; reason: string } — Result of a kind's `start`: `ok:false` skips the order and cancels it with reason `invalid`. The kind seeds `order.state` directly when `ok:true`.
- `OrderTickReport` (interface): interface OrderTickReport<TPayload = unknown> — What one `tick` did this frame, for tests and game reactions (play a bark on activation, flash on completion). Bounded per tick.
- `OrderVec3` (type): type OrderVec3 = readonly [number, number, number] — Composable entity orders: a serializable command queue with lifecycle, preemption, and pluggable order kinds (#912). Player- or AI-issued intent ("move here", "attack that", "patrol this route") becomes reusable data instead of a hard-coded RTS verb kit. The queue owns issue -> activate -> tick -> complete/cancel lifecycle and deterministic preemption policy; each order KIND owns what "running" means, composed over narrow world adapters. Engine code never branches on `move`, `attack`, or any game verb -- kinds are looked up by string in a registry, so a game adds a verb by registering data.
- `createOrderQueue` (function): function createOrderQueue<TCtx, TPayload = unknown>(registry: OrderRegistry<TCtx>, options: OrderQueueOptions<TPayload> = {}): OrderQueue<TCtx, TPayload> — Create a per-entity order queue over a shared kind registry. The queue owns the deterministic lifecycle and preemption policy; the kinds own behavior. Nothing here is random or unbounded: id generation is injected, activation is bounded by the pending count, and a single `tick` advances at most the active order plus one activation.
- `createOrderRegistry` (function): function createOrderRegistry<TCtx>(): OrderRegistry<TCtx> — Build an empty order-kind registry. Register the built-in compositions from `orders/orderKinds` or your own verbs, then hand it to `createOrderQueue`. One registry is shared by many per-entity queues.

## @jgengine/core/physics/aircraftDynamics

- `AircraftAssistCommand` (interface): interface AircraftAssistCommand — Control commands, `-1..1`, that drive the actuators after the assists.
- `AircraftAssistContext` (interface): interface AircraftAssistContext — What an assist sees each substep, derived from the integrator state so it replays deterministically.
- `AircraftAssistTuning` (interface): interface AircraftAssistTuning — Flight assists. Each one moves the same actuators the pilot does, so a stronger assist still flies within the airframe's authority. Strengths are `0..1`; an axis the pilot is deflecting gets less help the further the stick is pushed, so full stick is always the pilot's.
- `AircraftControlChannel` (interface): interface AircraftControlChannel — One control channel's actuator: how far the surfaces move and how fast.
- `AircraftEngineTuning` (interface): interface AircraftEngineTuning — A thrust source fixed to the body.
- `AircraftGearTuning` (interface): interface AircraftGearTuning — Wheels or skids: what the body rests on when it touches the ground.
- `AircraftMotorTuning` (interface): interface AircraftMotorTuning — A rocket motor: thrust follows a curve over burn time, propellant leaves at a mass flow so the body gets lighter and easier to turn, and the nozzle gimbals on the pitch and yaw channels. Stage by `retune`-ing to the next stage's mass and motor.
- `AircraftQuaternion` (type): type AircraftQuaternion = readonly [number, number, number, number] — Unit quaternion `[x, y, z, w]` taking body-frame vectors to world space.
- `AircraftRotorTuning` (interface): interface AircraftRotorTuning — A main rotor. Collective sets blade pitch, throttle sets rotor speed, and cyclic (the pitch and roll channels) tilts the disc. Its drag torque yaws the body the other way unless a tail rotor, a second rotor or a pedal input cancels it.
- `AircraftSurface` (interface): interface AircraftSurface — One lifting surface: a wing panel, a tailplane, a fin, a canard. Its lift acts at `at`, so the moments that pitch, roll and yaw the body come from where the surfaces sit, not from commanded rates.
- `AircraftVector` (type): type AircraftVector = readonly [number, number, number] — Body-frame or world-frame vector, m or N. The body frame is `[left, up, forward]` about the centre of mass.
- `RigidAircraft` (interface): interface RigidAircraft — A force-and-torque aircraft on the same tick/snapshot/retune contract as `VehicleDynamics`.
- `RigidAircraftInput` (interface): interface RigidAircraftInput — Pilot input for one tick.
- `RigidAircraftModifiers` (interface): interface RigidAircraftModifiers — Per-tick overrides layered over tuning: damage, icing, boost, gusts. Each scale defaults to `1`.
- `RigidAircraftOptions` (interface): interface RigidAircraftOptions — World hooks for one aircraft instance.
- `RigidAircraftState` (interface): interface RigidAircraftState — Serializable integrator state: everything `restore` needs to resume bit-for-bit.
- `RigidAircraftStep` (interface): interface RigidAircraftStep — One aircraft tick: pose plus the telemetry HUDs, camera, sound and probes read.
- `RigidAircraftTuning` (interface): interface RigidAircraftTuning — A rigid aircraft in physical units. There is no aircraft type: a jet, a glider and a paper plane differ only in these numbers. Rotation comes from surface forces acting on the inertia tensor, so loops, rolls, stalls and weathervaning are outcomes, not special cases.
- `aircraftAttitudeQuaternion` (function): function aircraftAttitudeQuaternion(heading: number, pitch: number, bank: number): AircraftQuaternion — Quaternion from heading, nose-up pitch and right bank, rad — the inverse of a step's `heading`/`pitch`/`bank`. Matches three.js `Euler(-pitch, heading, bank, "YXZ")`.
- `aircraftHeadingQuaternion` (function): function aircraftHeadingQuaternion(heading: number): AircraftQuaternion — Quaternion for a heading about world up, forward `[sin h, 0, cos h]`.
- `createRigidAircraft` (function): function createRigidAircraft(initial: RigidAircraftTuning, options: RigidAircraftOptions = {}): RigidAircraft — Creates a {@link RigidAircraft}: a quaternion rigid body with a diagonal inertia tensor, pushed by lifting surfaces, fuselage drag, an engine and gravity. Controls deflect surfaces through rate-limited actuators; nothing commands a rotation rate, so a jet loops when its tail can push the nose around and a glider stalls when it runs out of speed. Fixed internal substeps make it deterministic for a given `dt` sequence.

## @jgengine/core/physics/ballisticSweep

- `BallisticSweep` (type): type BallisticSweep = ( origin: readonly [number, number, number], velocity: readonly [number, number, number], gravity: number, maxTime: number, ) => BallisticSweepHit | null — ⚠ undocumented · used by `createBallisticSweep`: Sweeps each short chord of the closed-form arc through live body AABBs, including sleeping bodies.
- `BallisticSweepHit` (interface): interface BallisticSweepHit { point: [number, number, number]; time: number } — ⚠ undocumented
- `BallisticSweepOptions` (interface): interface BallisticSweepOptions { step?: number; radius?: number } — ⚠ undocumented · used by `createBallisticSweep`: Sweeps each short chord of the closed-form arc through live body AABBs, including sleeping bodies.
- `createBallisticSweep` (function): function createBallisticSweep(world: PhysicsWorld, options: BallisticSweepOptions = {}): BallisticSweep — Sweeps each short chord of the closed-form arc through live body AABBs, including sleeping bodies. Thin cover between samples blocks; `step` controls the approximation of the curved path.
- `sweepMovingBounds` (function): function sweepMovingBounds(from: readonly [number, number, number], to: readonly [number, number, number], targetFrom: readonly [number, number, number], targetTo: readonly [number, number, number], halfExtents: readonly [number, number, number]): number | null — Contact fraction for a point segment against a translating axis-aligned box; inflate extents for a projectile radius.
- `sweepMovingSphere` (function): function sweepMovingSphere(from: readonly [number, number, number], to: readonly [number, number, number], targetFrom: readonly [number, number, number], targetTo: readonly [number, number, number], radius: number): number | null — Contact fraction for a point segment against a translating sphere; add the projectile radius to `radius`.

## @jgengine/core/physics/boatDynamics

- `BoatDynamics` (interface): interface BoatDynamics — A force-based powered hull on the same tick/snapshot/retune contract as `VehicleDynamics`.
- `BoatOptions` (interface): interface BoatOptions — World hooks for a boat instance.
- `BoatState` (interface): interface BoatState — Serializable boat state.
- `BoatSteering` (type): type BoatSteering = | { kind: "rudder"; /** Rudder area, m². */ area: number; /** Largest rudder angle, rad (default `0.6`). */ maxAngle?: number; /** Share of prop thrust that washes over the rudder as flow, `0..1` (default `0.5`) — steering at low speed. */ propWash?: number; } | { kind: "outboard… — How the boat turns: a rudder needs water flowing past it; an outboard swings its own thrust.
- `BoatStep` (interface): interface BoatStep — One boat tick: pose plus the telemetry wake, spray and engine sound read.
- `BoatTuning` (interface): interface BoatTuning — A powered hull in physical units. Drag rises toward hull speed (`√(g·L)·1.34`) and then falls away once the hull planes, the keel resists sliding sideways, and the prop's thrust fades as the boat approaches the prop's speed.
- `createBoatDynamics` (function): function createBoatDynamics(initial: BoatTuning, options: BoatOptions = {}): BoatDynamics — Creates a {@link BoatDynamics}: throttle drives the prop, brake reverses it, steer swings the rudder or outboard. A rudder boat barely turns at rest unless the prop is washing over it; an outboard turns at rest because it swings the thrust itself. Deterministic for a given `dt` sequence.

## @jgengine/core/physics/buoyancy

- `BuoyantBody` (class): class BuoyantBody — Floats a {@link PhysicsWorld} body on a CPU {@link WaterSurface}: each hull sample point pushes the body up by its submerged depth (Archimedes, coarse), with vertical and horizontal water drag so the hull settles at the waterline and rides the Gerstner waves. Passing an {@link AxisInput} drives it as a boat — throttle thrusts along the heading, steer yaws, a keel bleeds sideways slip. Call `update(dt, time, input?)` before the shared `world.step(dt)`.
- `BuoyantBodyConfig` (interface): interface BuoyantBodyConfig { body: number; water: WaterSurface; heading?: number; hullPoints?: readonly (readonly [number, number])[]; hullDepth?: number; buoyancy?: number; verticalDrag?: number; linearDrag?: number; engineAccel?: number; reverseAccel?: number; topS… — ⚠ undocumented
- `createBuoyantBody` (function): function createBuoyantBody(world: PhysicsWorld, config: BuoyantBodyConfig): BuoyantBody — ⚠ undocumented

## @jgengine/core/physics/carryable

- `Carryable` (class): class Carryable — A grabbed physics object following a moving hold point through a spring constraint (the pick — a raycast — is the caller's/shell's job; core owns the constraint). Supports shared multi-owner carry (the follow point is the average of owners' hold points), an encumbrance read, and drop/throw. Reuses `PhysicsWorld.springJoint` to a world anchor moved each frame.
- `CarryableConfig` (interface): interface CarryableConfig { followStiffness?: number; followDamping?: number; maxForce?: number; carryCapacity?: number } — ⚠ undocumented
- `carrySpeedMultiplier` (function): function carrySpeedMultiplier(mass: number, carryCapacity: number, owners: number): number — Movement multiplier (1 = unhindered, →0 = crushed) for a body of `mass` carried by `owners`. Pure — the HUD/movement kit reads it to slow a laden hauler (Lethal Company) and to gate items that need 2+ people (R.E.P.O.).

## @jgengine/core/physics/damageZones

- `DamageModel` (class): class DamageModel — Coarse crash-damage model (issue #86 — stages, not soft-body). Each zone accumulates contact impulse fed from G3's `onCollision` `CollisionEvent`; crossing a threshold bumps the zone to the next discrete stage (the caller swaps the visual/collider), an optional `detachStage` ejects a part as debris once, and a total-impulse `disableAt` flips the whole body to a disabled state. `absorb` returns a transition only when something actually changed, so it doubles as the event source for HUD/feed.
- `DamageModelConfig` (interface): interface DamageModelConfig { zones: readonly DamageZoneDef[]; disableAt?: number; onStage?: (transition: DamageTransition) => void; onDetach?: (zoneId: string, accumulated: number) => void } — ⚠ undocumented
- `DamageTransition` (interface): interface DamageTransition { zone: string; stage: number; previousStage: number; detached: boolean; disabled: boolean; accumulated: number; total: number } — ⚠ undocumented
- `DamageZoneDef` (interface): interface DamageZoneDef { id: string; thresholds: readonly number[]; detachStage?: number } — ⚠ undocumented
- `DamageZoneState` (interface): interface DamageZoneState { id: string; accumulated: number; stage: number; detached: boolean } — ⚠ undocumented
- `createDamageModel` (function): function createDamageModel(config: DamageModelConfig): DamageModel — ⚠ undocumented

## @jgengine/core/physics/drivableVehicle

- `DrivableSim` (interface): interface DrivableSim<TModifiers, TStep extends DrivableSimStep> — Any ground-vehicle sim {@link tickDrivableVehicle} can drive: `KinematicVehicle` or `VehicleDynamics`.
- `DrivableSimStep` (interface): interface DrivableSimStep — The pose fields {@link tickDrivableVehicle} reads from a sim step; `KinematicVehicleStep` and `VehicleDynamicsStep` both carry them.
- `DrivableVehicleOptions` (interface): interface DrivableVehicleOptions<TModifiers = KinematicVehicleModifiers> — Options for {@link tickDrivableVehicle} — ground snapping and per-tick tuning modifiers.
- `DrivableVehiclePose` (interface): interface DrivableVehiclePose — A `setPose`-ready patch — spread straight into `entities.setPose(vehicleId, drive.pose)`.
- `DrivableVehiclePosition` (type): type DrivableVehiclePosition = readonly [number, number, number] — World-space `[x, y, z]` for a drivable vehicle's resolved pose.
- `DrivableVehicleStep` (interface): interface DrivableVehicleStep<TStep extends DrivableSimStep = KinematicVehicleStep> — {@link tickDrivableVehicle}'s result — the ready-to-apply pose patch plus the raw sim step for HUD/telemetry reads.
- `tickDrivableVehicle` (function): function tickDrivableVehicle<TStep extends DrivableSimStep = KinematicVehicleStep, TModifiers = KinematicVehicleModifiers>(vehicle: DrivableSim<TModifiers, TStep>, dt: number, axis: AxisInput, options: DrivableVehicleOptions<TModifiers> = {}): DrivableVehicleStep<TStep> — Connects an `AxisInput` sample straight through a ground-vehicle sim (`KinematicVehicle` or `VehicleDynamics`) to a scene entity's pose for one tick (#533.1) — the throttle/steer/handbrake → sim → `setPose` loop every drivable-vehicle game hand-rolled. Ground-snaps the result when `groundHeight` is given (terrain-following cars, not just flat racetracks). Pair with `scene/vehicleSeat` for who is allowed to drive and where the camera points; this function only steps the sim and shapes the pose patch, nothing else.

## @jgengine/core/physics/flightDynamics

- `AircraftAxis` (type): type AircraftAxis = "pitch" | "roll" | "yaw" | "throttle" | "collective" | "airbrake" | "afterburner" | "vectoring" — Axes an aircraft can bind — which actions drive each flight control.
- `AircraftDynamics` (interface): interface AircraftDynamics — Stateful six-degree-of-freedom aircraft simulation.
- `AircraftDynamicsState` (interface): interface AircraftDynamicsState — Serializable integrator state of an {@link AircraftDynamics}: what `restore` needs to resume bit-for-bit.
- `AircraftKind` (type): type AircraftKind = "fixedWing" | "rotorcraft" | "vtol" — Supported aerodynamic/propulsion families.
- `AircraftOptions` (interface): interface AircraftOptions — Spawn state and injectable world-field samplers for an aircraft instance.
- `AircraftStep` (interface): interface AircraftStep — Pose and aerodynamic telemetry returned after one flight tick.
- `AircraftTuning` (interface): interface AircraftTuning — Data-first physical tuning shared by all aircraft instances of one catalog type.
- `FlightControlInput` (interface): interface FlightControlInput — Normalized pilot inputs for one flight-simulation tick.
- `FlightControlRates` (interface): interface FlightControlRates — Angular authority, response, damping, and self-leveling configuration.
- `FlightVector` (type): type FlightVector = readonly [number, number, number] — Three-dimensional world-space vector used by the flight model.
- `createAircraftDynamics` (function): function createAircraftDynamics(initialTuning: AircraftTuning, options: AircraftOptions = {}): AircraftDynamics — Six-degree-of-freedom arcade flight model for fixed-wing, helicopter, and VTOL aircraft.

## @jgengine/core/physics/flowTube

- `FlowTube` (interface): interface FlowTube — An axial corridor of directional flow with radial core falloff and a spool scalar — fan tunnels, updraft shafts, river narrows, thruster wash. Pure math: sample `velocityAt(point, spool)` and add it to whatever integrator moves the body (walk controller drift, `BuoyantBody`, a custom sim).
- `FlowTubeConfig` (interface): interface FlowTubeConfig { from: FlowVec3; to: FlowVec3; radius: number; strength: number; falloff?: number; capFalloff?: number } — ⚠ undocumented
- `FlowVec3` (type): type FlowVec3 = readonly [number, number, number] — ⚠ undocumented · used by `combineFlowVelocity`: Sum several tubes' flow at one point — each entry carries its own spool.
- `combineFlowVelocity` (function): function combineFlowVelocity(tubes: readonly (FlowTube | { tube: FlowTube; spool: number })[], point: FlowVec3): FlowVec3 — Sum several tubes' flow at one point — each entry carries its own spool.
- `createFlowTube` (function): function createFlowTube(config: FlowTubeConfig): FlowTube — ⚠ undocumented

## @jgengine/core/physics/forceVolume

- `ForceFieldConfig` (interface): interface ForceFieldConfig — Renderer-free localized acceleration shared by physical actors and cosmetic particles.
- `ForceMode` (type): type ForceMode = "impulse" | "velocity" | "accelerate" — ⚠ undocumented · used by `applyVolumeForce`: One tick's force math for a body outside `PhysicsWorld` — apply the returned velocity in any custom integrator.
- `ForceVector` (type): type ForceVector = readonly [number, number, number] — World-space force position, axis or acceleration vector.
- `ForceVolume` (class): class ForceVolume — A trigger region that pushes bodies passing through it — boost pads (`impulse` + `once`), conveyors (`velocity`), fans/wind (`accelerate`). Call `apply` each tick; `once` mode fires only on entry by tracking membership between ticks.
- `ForceVolumeConfig` (interface): interface ForceVolumeConfig { bounds: PhysicsBounds; force: readonly [number, number, number]; mode?: ForceMode; once?: boolean } — ⚠ undocumented
- `PlatformCarry` (class): class PlatformCarry — Carries bodies standing on a moving platform by composing their transform with the platform's per-`step` delta — moving/rotating lifts and conveyor floors (Fall Guys, Gang Beasts). The platform is a body the game repositions each frame; riders are detected by overlap on its top face.
- `PlatformCarryConfig` (interface): interface PlatformCarryConfig { contactTolerance?: number } — ⚠ undocumented
- `VolumeTrigger` (interface): interface VolumeTrigger<TId> — The enter-once membership tracking from `ForceVolume`, freed from `PhysicsWorld`'s body indices (#286.8): feed any integrator's `{ id, position }` list each tick and act on the edges — apply `applyVolumeForce` on `entered` for a boost pad, on `inside` for a fan.
- `VolumeTriggerConfig` (interface): interface VolumeTriggerConfig { bounds: PhysicsBounds } — ⚠ undocumented
- `VolumeTriggerStep` (interface): interface VolumeTriggerStep<TId> { entered: readonly TId[]; inside: readonly TId[]; exited: readonly TId[] } — ⚠ undocumented
- `applyVolumeForce` (function): function applyVolumeForce(velocity: readonly [number, number, number], force: readonly [number, number, number], mode: ForceMode, dt: number): readonly [number, number, number] — One tick's force math for a body outside `PhysicsWorld` — apply the returned velocity in any custom integrator.
- `createVolumeTrigger` (function): function createVolumeTrigger<TId = string>(config: VolumeTriggerConfig): VolumeTrigger<TId> — ⚠ undocumented
- `sampleForceField` (function): function sampleForceField(config: ForceFieldConfig, position: ForceVector, targetMask = 0xffffffff, out: [number, number, number] = [0, 0, 0]): [number, number, number] — Sample localized acceleration; `out` permits allocation-free integration.
- `validateForceField` (function): function validateForceField(config: ForceFieldConfig): void — Validate force authoring once before sampling in a hot loop. Coordinates stay within the safe integer range; acceleration magnitudes stay within 1e12 units/s².

## @jgengine/core/physics/gravityField

- `GravityField` (interface): interface GravityField — Position-dependent gravity source used by movement and vehicle simulations.
- `GravityVector` (type): type GravityVector = readonly [number, number, number] — Three-dimensional acceleration vector sampled from a gravity field.
- `PointGravityOptions` (interface): interface PointGravityOptions — Center, strength, and falloff for radial gravity.
- `combineGravity` (function): function combineGravity(fields: readonly GravityField[]): GravityField — Adds several gravity sources into one field.
- `pointGravity` (function): function pointGravity(options: PointGravityOptions): GravityField — Radial gravity toward one center, with optional inverse-square falloff for planetary worlds.
- `uniformGravity` (function): function uniformGravity(vector: GravityVector = [0, -9.81, 0]): GravityField — Constant vector gravity for ordinary worlds, space stations, and sideways-gravity levels.

## @jgengine/core/physics/handlingProbe

- `AirReport` (interface): interface AirReport — Deterministic jump and air-control metrics.
- `AirSubject` (interface): interface AirSubject — The slice of a jumping vehicle sim {@link measureAir} drives; a `VehicleDynamics` with `suspension`, `jump` and `air` fits.
- `CourseProbeOptions` (interface): interface CourseProbeOptions — Settings for {@link measureCourse}; every field but `wheelbase` has a default.
- `CourseReport` (interface): interface CourseReport — Deterministic driven-course metrics.
- `CourseSubject` (interface): interface CourseSubject — A vehicle sim {@link measureCourse} can drive along a line: a {@link HandlingSubject} that also reports its pose and front-wheel angle.
- `FlightProbeOptions` (interface): interface FlightProbeOptions — Scenario settings for {@link measureFlight}.
- `FlightReport` (interface): interface FlightReport — Deterministic flight metrics. Fields that don't apply to the aircraft are `NaN`: turn and stall need wings, hover drift needs a rotor.
- `FlightSpawn` (interface): interface FlightSpawn — Where {@link measureFlight} spawns each fresh aircraft: level, heading `0` (forward `+z`).
- `HandlingProbeOptions` (interface): interface HandlingProbeOptions — Scenario settings for {@link measureHandling}; every field has a default.
- `HandlingReport` (interface): interface HandlingReport — Deterministic feel metrics, in the units drivers and reviewers use. `Infinity` means the target was never reached.
- `HandlingSubject` (interface): interface HandlingSubject — The slice of a vehicle sim {@link measureHandling} drives: `VehicleDynamics` and `KinematicVehicle` both fit.
- `LeanReport` (interface): interface LeanReport — Deterministic lean metrics for a motorcycle or bicycle.
- `LeanSubject` (interface): interface LeanSubject — The slice of a single-track sim {@link measureLean} drives; a `VehicleDynamics` with a `lean` block fits.
- `RideReport` (interface): interface RideReport — Deterministic ride metrics for a sprung vehicle.
- `RideSubject` (interface): interface RideSubject — The slice of a sprung vehicle sim {@link measureRide} drives; a `VehicleDynamics` with `suspension` fits.
- `measureAir` (function): function measureAir(create: () => AirSubject, options: { dt?: number } = {}): AirReport — Jumps a fresh vehicle from rest and holds full air input on each axis, reporting jump height and timing, double-jump height, and how fast the body rotates in the air.
- `measureCourse` (function): function measureCourse(create: () => CourseSubject, options: CourseProbeOptions): CourseReport — Drives a fresh vehicle from `create` through a steer ramp, a skidpad and a slalom with simple deterministic drivers, and reports understeer gradient, skidpad g and the fastest clean slalom.
- `measureFlight` (function): function measureFlight(create: (spawn: FlightSpawn) => RigidAircraft, options: FlightProbeOptions = {}): FlightReport — Flies fresh aircraft from `create` through fixed scenarios with simple deterministic autopilots: a full-aileron roll, banked turns at full throttle, an idle deceleration holding altitude, a full-throttle climb at cruise speed, a throttle step from idle, and a hands-off hover. `create` gets a spawn to pass straight into `createRigidAircraft`. Deterministic, so a tuning change shows up as a number moving.
- `measureHandling` (function): function measureHandling(create: () => HandlingSubject, options: HandlingProbeOptions = {}): HandlingReport — Drives fresh instances from `create` through fixed scenarios (launch, top speed, braking, a slow steer ramp, a step steer, a mid-corner lift-off, a handbrake pull, full throttle with full steer) and reports the feel metrics a test can assert. Deterministic: the same subject and options always produce the same report, so a tuning change shows up as a number moving, not an opinion.
- `measureLean` (function): function measureLean(create: () => LeanSubject, options: { dt?: number; speed?: number } = {}): LeanReport — Brings a fresh bike to `speed` and holds full steer, reporting how far and how fast it leans and how much it tips the other way first.
- `measureRide` (function): function measureRide(create: () => RideSubject, options: { dt?: number } = {}): RideReport — Drives fresh sprung vehicles from `create` through a vertical kick, a hard stop, a steady corner and a launch-and-land, and reports how the body moves: how fast it settles, how much it dives and rolls, and whether a landing bounces.

## @jgengine/core/physics/kinematicVehicle

- `DEFAULT_REVERSE_FORCE_SCALE` (const): const DEFAULT_REVERSE_FORCE_SCALE: 0.48 — Default reverse drive force as a fraction of forward `engineForce` / `engineAccel`.
- `KinematicChassisTuning` (interface): interface KinematicChassisTuning — Mass-and-force chassis layer (#1051); when present it supersedes `engineAccel`/`brakeAccel` with force/mass dynamics. Drive/brake become forces divided by `massKg`, a per-tick tire friction budget (`tireGrip` * grip curve * surface * downforce * m * g) is split lateral-first then longitudinal so hard slides and launches saturate, and `comHeight`/`trackWidth` set weight-transfer washout and body lean. Coasting decelerates from physical road load, not a per-vehicle constant: rolling resistance `μ_rr · m · g` always, plus engine braking `ENGINE_BRAKE_FRACTION · engineForce` routed through the current gear (so it strengthens as the car downshifts) whenever the throttle is lifted and a `powertrain` is configured. All fields are required; omit the whole block for the legacy model.
- `KinematicDynamicsTuning` (interface): interface KinematicDynamicsTuning — Aerodynamic and electronic-assist settings layered over tire grip.
- `KinematicPowertrainTuning` (interface): interface KinematicPowertrainTuning — Data-first gearbox and torque-curve tuning for a kinematic ground vehicle.
- `KinematicSteeringTuning` (interface): interface KinematicSteeringTuning — Bicycle-model steering settings; all angles are radians.
- `KinematicVehicle` (interface): interface KinematicVehicle — The pure-kinematic arcade car every racing game hand-rolled (#282.1): steer-yaw scaled by speed, throttle/brake acceleration, and a grip-curve lateral-slip bleed — no `PhysicsWorld`, no wheels, just the drift-friendly integration the three shipped racers proved out. Games keep their flavor (drift meters, boost, off-track rules) via `surfaceFriction`/`dragAt` hooks and the returned slip.
- `KinematicVehicleModifiers` (interface): interface KinematicVehicleModifiers — Per-tick multipliers layered over the base tuning — the transient overrides games apply for one frame without rebuilding the vehicle: nitro/boost, a braced-plow bonus, or entering a speed zone or slow field. Each defaults to `1` (no change), so passing nothing leaves the base tuning untouched.
- `KinematicVehicleOptions` (interface): interface KinematicVehicleOptions { position?: readonly [number, number, number]; heading?: number; surfaceFriction?: (x: number, z: number) => number; dragAt?: (x: number, z: number) => number; clampMove?: (from: readonly [number, number], to: readonly [number, number]) =>… — ⚠ undocumented · used by `createKinematicVehicle`: Arcade ground-vehicle sim (car, kart, bike) with throttle, brake, steer, drift and retunable handling.
- `KinematicVehicleState` (interface): interface KinematicVehicleState — Serializable integrator state of a {@link KinematicVehicle}: what `restore` needs to resume bit-for-bit.
- `KinematicVehicleStep` (interface): interface KinematicVehicleStep { position: readonly [number, number, number]; heading: number; forwardSpeed: number; lateralSpeed: number; slip: number; surface: number; weightTransfer: number; loadGrip: number; gear: number; rpm: number; steerAngle: number; yawRate: num… — ⚠ undocumented · used by `tickDrivableVehicle` (@jgengine/core/physics/drivableVehicle): Connects an `AxisInput` sample straight through a ground-vehicle sim (`KinematicVehicle` or `VehicleDynamics`) to a scene entity's pose for …
- `KinematicVehicleTuning` (interface): interface KinematicVehicleTuning { engineAccel: number; brakeAccel: number; topSpeed: number; reverseSpeed: number; turnRate: number; turnSpeedRef: number; grip?: GripCurve; gripStrength: number; handbrakeGrip: number; rollingResistance?: number; coastDeceleration?: number… — ⚠ undocumented · used by `createKinematicVehicle`: Arcade ground-vehicle sim (car, kart, bike) with throttle, brake, steer, drift and retunable handling.
- `KinematicWeightTransferTuning` (interface): interface KinematicWeightTransferTuning — Load-transfer handling for the arcade model. Weight moves under braking, traction and cornering; the tire that goes light loses more grip than the loaded one gains (load sensitivity), so the axle's combined grip falls. Every term is bounded by the geometry, and `sensitivity` caps the loss, so the transfer can never drive grip negative or diverge. For per-axle balance from tire forces, use `createVehicleDynamics` (`physics/vehicleDynamics`) instead.
- `createKinematicVehicle` (function): function createKinematicVehicle(initialTuning: KinematicVehicleTuning, options: KinematicVehicleOptions = {}): KinematicVehicle — Arcade ground-vehicle sim (car, kart, bike) with throttle, brake, steer, drift and retunable handling.

## @jgengine/core/physics/physicsBackend

- `BodyDesc` (interface): interface BodyDesc — Everything a backend needs to create a body. Rotation-free backends ignore `rotation` and `angularVelocity` and say so in {@link PhysicsCapabilities}.
- `BodyHandle` (type): type BodyHandle = number — Backend-issued body id; stable for the body's lifetime and across snapshot/restore.
- `BodyKind` (type): type BodyKind = "dynamic" | "kinematic" | "static" — `dynamic` integrates under forces, `kinematic` moves only through {@link PhysicsBackend.setKinematicTarget}, `static` never moves.
- `BodyShape` (type): type BodyShape = | { kind: "box"; halfExtents: PhysicsVec3 } | { kind: "sphere"; radius: number } | { kind: "capsule"; radius: number; halfHeight: number } | { kind: "convex"; points: readonly PhysicsVec3[] } | { kind: "trimesh"; vertices: ArrayLike<number>; indices: ArrayLike<number> } | { kind: "h… — Collision shape of a body or a cast. Capsules stand along +Y; a trimesh or heightfield is static-only on every backend.
- `BodyShapeKind` (type): type BodyShapeKind = BodyShape["kind"] — Shape discriminator, as listed in {@link PhysicsCapabilities.shapes}.
- `BodyState` (interface): interface BodyState — A body's live pose and motion. Rotation-free backends report identity rotation and zero angular velocity.
- `ContactEvent` (interface): interface ContactEvent — A contact reported during {@link PhysicsBackend.step}; the object is reused between calls, so copy what you keep.
- `IDENTITY_QUAT` (const): const IDENTITY_QUAT: PhysicsQuat — The identity rotation.
- `JointDesc` (interface): interface JointDesc — Joint between two bodies, or between `bodyA` and a world anchor when `bodyB` is omitted.
- `JointHandle` (type): type JointHandle = number — Backend-issued joint id.
- `OverlapDesc` (interface): interface OverlapDesc — Which bodies a shape placed at `position` intersects.
- `PhysicsBackend` (interface): interface PhysicsBackend — The seam every physics consumer talks to: the in-tree `PhysicsWorld` behind `createPhysicsWorldBackend`, or a native solver such as Rapier behind its own adapter. Handles are backend-issued and survive snapshot/restore, so gameplay state can store them.
- `PhysicsBackendConfig` (interface): interface PhysicsBackendConfig — Solver-wide knobs a backend accepts at creation and through `retune`.
- `PhysicsCapabilities` (interface): interface PhysicsCapabilities — What a backend can actually simulate, so a game or the conformance suite can adapt instead of guessing.
- `PhysicsQuat` (type): type PhysicsQuat = readonly [number, number, number, number] — Unit quaternion `[x, y, z, w]`; `[0, 0, 0, 1]` is identity.
- `PhysicsVec3` (type): type PhysicsVec3 = readonly [number, number, number] — `[x, y, z]`.
- `RayDesc` (interface): interface RayDesc — A ray query.
- `RayHit` (interface): interface RayHit — Nearest surface a ray reached.
- `ShapeCastDesc` (interface): interface ShapeCastDesc — Sweep `shape` from `position` along `motion` and report the first body it touches.
- `ShapeCastHit` (interface): interface ShapeCastHit — First contact of a shape sweep.
- `isIdentityQuat` (function): function isIdentityQuat(q: PhysicsQuat | undefined): boolean — True for an absent or identity rotation.
- `shapeHalfExtents` (function): function shapeHalfExtents(shape: BodyShape): [number, number, number] — Axis-aligned bounds of a shape at identity rotation, as half extents.

## @jgengine/core/physics/physicsBackendConformance

- `ConformanceHarness` (interface): interface ConformanceHarness — The slice of a test runner the conformance suite needs; `bun:test` satisfies it directly.
- `runPhysicsBackendConformance` (function): function runPhysicsBackendConformance(create: () => PhysicsBackend, harness: ConformanceHarness): void — Behavioral contract every {@link PhysicsBackend} must pass: bodies rest on floors, casts and rays report the first surface with an outward normal, kinematic targets produce velocity, masks filter, and snapshot/restore round-trips with stable handles. Backends declare what they cannot do through `capabilities`; the suite reads it. Expects `create()` to return a fresh backend whose world spans at least ±50 on every axis with a floor at y=0.

## @jgengine/core/physics/physicsWorld

- `AddBodyOptions` (type): type AddBodyOptions = BoxBodyOptions | SphereBodyOptions — ⚠ undocumented
- `BodyCommonOptions` (interface): interface BodyCommonOptions { position: readonly [number, number, number]; velocity?: readonly [number, number, number]; mass?: number; static?: boolean; asleep?: boolean } — ⚠ undocumented
- `BoxBodyOptions` (interface): interface BoxBodyOptions extends BodyCommonOptions { shape?: "box"; halfExtents: readonly [number, number, number] } — ⚠ undocumented
- `CollisionEvent` (interface): interface CollisionEvent — A contact reported to `onCollision`. The object is reused each call — read/copy, never retain.
- `JOINT_DISTANCE` (const): const JOINT_DISTANCE: 2 — ⚠ undocumented
- `JOINT_FIXED` (const): const JOINT_FIXED: 0 — ⚠ undocumented
- `JOINT_HINGE` (const): const JOINT_HINGE: 1 — ⚠ undocumented
- `JOINT_SPRING` (const): const JOINT_SPRING: 3 — ⚠ undocumented
- `JointKind` (type): type JointKind = "hinge" | "distance" | "spring" | "fixed" — Hard bilateral: `fixed` pins the shared anchor (3-DOF), `hinge` pins only the plane perpendicular to `axis` (free along the axis — translational cylindrical), `distance` holds a fixed separation. `spring` is a soft PD drive toward `restLength`.
- `JointOptions` (interface): interface JointOptions { bodyA: number; bodyB?: number; anchorA?: readonly [number, number, number]; anchorB?: readonly [number, number, number]; restLength?: number; stiffness?: number; damping?: number; maxImpulse?: number; axis?: readonly [number, number, numb… — ⚠ undocumented
- `MAX_BROADPHASE_CELLS` (const): const MAX_BROADPHASE_CELLS: 1000000 — Cap on `nx*ny*nz` broadphase cells — guards a huge-bounds/tiny-cellSize config from hanging `step()`.
- `PhysicsBounds` (interface): interface PhysicsBounds { min: readonly [number, number, number]; max: readonly [number, number, number] } — ⚠ undocumented
- `PhysicsPrecision` (type): type PhysicsPrecision = "low" | "standard" | "high" — Simulation fidelity intent: `low` (cheap — many bodies, loose stacks, forgiving sleep), `standard` (default), `high` (tight stacks, accurate joints, worth the extra solver work). Sets the solver knobs below to a matched preset; an individual knob left explicit always wins over the preset.
- `PhysicsStats` (interface): interface PhysicsStats { count: number; awake: number; sleeping: number; contacts: number; pairs: number; substeps: number; stepMs: number } — ⚠ undocumented
- `PhysicsWorld` (class): class PhysicsWorld — ⚠ undocumented
- `PhysicsWorldConfig` (interface): interface PhysicsWorldConfig { capacity: number; bounds: PhysicsBounds; gravity?: number; precision?: PhysicsPrecision; fixedDt?: number; maxSubsteps?: number; restitution?: number; restitutionThreshold?: number; friction?: number; linearDamping?: number; sleepLinearVe… — ⚠ undocumented
- `SHAPE_BOX` (const): const SHAPE_BOX: 0 — ⚠ undocumented
- `SHAPE_SPHERE` (const): const SHAPE_SPHERE: 1 — ⚠ undocumented
- `SphereBodyOptions` (interface): interface SphereBodyOptions extends BodyCommonOptions — The radius fills all three half-extent columns, so broadphase and bounds see the sphere's enclosing AABB.
- `cellCoord` (function): function cellCoord(value: number, min: number, cellSize: number, cells: number): number — Grid cell containing a point, clamped into the grid. Pure — exported for tests.
- `cellIndex` (function): function cellIndex(cx: number, cy: number, cz: number, nx: number, ny: number): number — Linear cell index from clamped 3D coords. Pure — exported for tests.

## @jgengine/core/physics/physicsWorldBackend

- `PhysicsWorldBackendOptions` (interface): interface PhysicsWorldBackendOptions extends PhysicsBackendConfig — Construction options: the `PhysicsWorld` capacity and bounds plus the shared backend config.
- `PhysicsWorldBackendState` (interface): interface PhysicsWorldBackendState — Serializable backend state: every live body and joint, with handles preserved.
- `createPhysicsWorldBackend` (function): function createPhysicsWorldBackend(options: PhysicsWorldBackendOptions): PhysicsBackend — `PhysicsWorld` behind the {@link PhysicsBackend} interface: zero dependencies, translation-only. Capsules, convex hulls, meshes, and heightfields collide as their bounding boxes; rotation, angular velocity, CCD, and hinge limits are accepted and ignored (see {@link PhysicsBackend.capabilities}). Reach for `@jgengine/rapier` when a game needs those for real; the seam is the same.

## @jgengine/core/physics/radialImpulse

- `RadialFalloff` (type): type RadialFalloff = "linear" | "quadratic" | "none" — How a radial impulse fades from the blast center to its edge.
- `RadialImpulse` (interface): interface RadialImpulse — A radial push: the impulse vector plus the 0..1 falloff sampled at the target.
- `RadialImpulseOptions` (interface): interface RadialImpulseOptions — Options for {@link radialImpulse}.
- `radialImpulse` (function): function radialImpulse(source: readonly [number, number], target: readonly [number, number], radius: number, power: number, options: RadialImpulseOptions = {}): RadialImpulse | null — Point-source radial impulse pushing a `target` away from a blast `source`: full `power` at the center fading to zero at `radius`. Returns `null` when the target sits at or beyond the radius (unaffected), so callers can early-out. At the exact center the direction is zero. This is the explosion/knockback/ shockwave push — every arena game hand-rolled the distance, falloff, and normalize.

## @jgengine/core/physics/ragdoll

- `Ragdoll` (class): class Ragdoll — A jointed multi-body character — floppy by default, or active-ragdoll when a balance motor is configured. Bones are `PhysicsWorld` bodies; links are joints on the joint API. `balance(dt, mx, mz)` drives the root toward its target height (staying upright) and pushes it by the move vector.
- `RagdollBalanceConfig` (interface): interface RagdollBalanceConfig { root: string; targetHeight: number; strength?: number; moveForce?: number } — ⚠ undocumented
- `RagdollBoneSpec` (interface): interface RagdollBoneSpec { name: string; position: readonly [number, number, number]; halfExtents: readonly [number, number, number]; mass?: number } — ⚠ undocumented
- `RagdollConfig` (interface): interface RagdollConfig { bones: RagdollBoneSpec[]; links: RagdollLinkSpec[]; balance?: RagdollBalanceConfig } — ⚠ undocumented · used by `ragdollConfigFromPoses` (@jgengine/core/anim/ragdollRig): A jointed ragdoll for a mapped rig from its bones' world poses at the moment of death: one box body per standard slot that has a shape, size…
- `RagdollLinkSpec` (interface): interface RagdollLinkSpec { a: string; b: string; kind?: "hinge" | "distance"; anchor?: readonly [number, number, number] } — ⚠ undocumented
- `createRagdoll` (function): function createRagdoll(world: PhysicsWorld, config: RagdollConfig): Ragdoll — ⚠ undocumented

## @jgengine/core/physics/spatialGrid

- `SpatialGrid` (class): class SpatialGrid — A uniform-grid broad-phase over the x/z plane, separate from the rigid-body sim, for cheap same-tick proximity across hundreds–thousands of simple movers (swarm enemies). Rebuild each tick from the caller's own position arrays, then `queryCircle` (enemies hitting the player / an AoE) or `forEachPair` (mutual separation). Both are precise: no false negatives, no false positives beyond the exact distance test.
- `SpatialGridConfig` (interface): interface SpatialGridConfig { bounds: PhysicsBounds; cellSize: number; capacity: number } — ⚠ undocumented

## @jgengine/core/physics/structure

- `CollapseEvent` (interface): interface CollapseEvent { fell: readonly string[]; collapsed: boolean } — ⚠ undocumented
- `DebrisConfig` (interface): interface DebrisConfig { impulse?: number; origin?: readonly [number, number, number] } — ⚠ undocumented
- `StructureEdgeSpec` (interface): interface StructureEdgeSpec { a: string; b: string; strength?: number } — ⚠ undocumented
- `StructureGraph` (class): class StructureGraph — A structural-integrity graph over a building — nodes are pieces (walls, beams, floors), edges are load-bearing connections, some nodes are anchored foundations. `damage`/`damageEdge` wear pieces and connections down; when a piece shatters or an edge severs, the graph recomputes which pieces still reach an anchor and hands back every newly-disconnected piece as one `CollapseEvent`. Feed that to `toDebris` to sink the fallen pieces into a `PhysicsWorld` as rigid bodies ("The Finals" smooth destruction, Rainbow Six walls). Coarse by design: it replicates the collapse event, not per fragment.
- `StructureMaterial` (interface): interface StructureMaterial { id: string; strength: number; mass?: number } — ⚠ undocumented
- `StructureMaterialTable` (type): type StructureMaterialTable = Readonly<Record<string, StructureMaterial>> — ⚠ undocumented
- `StructureNodeSpec` (interface): interface StructureNodeSpec { id: string; position: readonly [number, number, number]; halfExtents: readonly [number, number, number]; mass?: number; integrity?: number; material?: string; anchor?: boolean } — ⚠ undocumented

## @jgengine/core/physics/traversal

- `Glide` (class): class Glide — A reduced-gravity, forward-thrust glide over a physics body — wingsuit / glider / paraglider (Enshrouded, Grounded). Call `apply(dt, steerX, steerZ)` each frame *before* `world.step`: it feeds back most of the gravity the sim is about to apply (leaving `gravityScale` of it), pushes the body along the steer vector by `thrust`, and clamps descent to `maxFallSpeed`. Stop calling it to fall normally again — no attach/detach state to leak.
- `GlideConfig` (interface): interface GlideConfig { gravityScale?: number; thrust?: number; maxFallSpeed?: number } — ⚠ undocumented
- `Grapple` (class): class Grapple — A fired-anchor rope on the joint API — grapple (reel toward a hit point), zipline (rigid cable to a far anchor you then slide/reel along), swing (rigid rope + gravity = a pendulum). `fire` attaches a `distance`/`spring` joint from the traveller body to a fixed world point; `reel` shrinks its rest length so the constraint drags the body in; `moveAnchor` re-points it (zipline glide, grapple-to- moving-target). The pick — a raycast to find the anchor — is the caller's; core owns the constraint.
- `GrappleConfig` (interface): interface GrappleConfig { reelSpeed?: number; minLength?: number; maxLength?: number; elastic?: boolean; stiffness?: number; damping?: number } — ⚠ undocumented

## @jgengine/core/physics/vehicleBackendLink

- `VehicleBackendLink` (interface): interface VehicleBackendLink — A vehicle sim's presence in a physics backend: a kinematic chassis that shoves props, and a wall-aware move clamp.
- `VehicleBackendLinkOptions` (interface): interface VehicleBackendLinkOptions — Options for {@link createVehicleBackendLink}.
- `VehicleLinkHit` (interface): interface VehicleLinkHit — A wall the last clamped move ran into.
- `VehicleLinkPose` (interface): interface VehicleLinkPose — The pose fields {@link VehicleBackendLink.sync} reads; any vehicle step (`VehicleDynamicsStep`, `KinematicVehicleStep`) fits.
- `createVehicleBackendLink` (function): function createVehicleBackendLink(backend: PhysicsBackend, options: VehicleBackendLinkOptions): VehicleBackendLink — Puts a vehicle sim (`createVehicleDynamics`, `createKinematicVehicle`) into a {@link PhysicsBackend} world without handing its handling to the rigid-body solver: the sim still owns grip and balance, while a kinematic chassis box follows it so Rapier or `PhysicsWorld` props get shoved, and `clampMove` sweeps that box so walls and parked cars stop it and it slides along them.

## @jgengine/core/physics/vehicleBody

- `DEFAULT_GRIP_CURVE` (const): const DEFAULT_GRIP_CURVE: GripCurve — ⚠ undocumented
- `GripCurve` (interface): interface GripCurve { points: readonly (readonly [number, number])[] } — ⚠ undocumented · used by `sampleGripCurve`: Piecewise-linear tire-grip curve: normalized lateral slip → available grip (0..1).
- `VehicleBody` (class): class VehicleBody — Arcade vehicle over the {@link PhysicsWorld} rigid-body sim. The chassis is a single box body driven by an {@link AxisInput}: per-wheel suspension is a spring-damper held with G3's `springJoint` against the sampled ground, drive/brake push along the heading, and a tire-grip curve bleeds lateral velocity (cornering, and drift under handbrake). Because the chassis is a physics body it still collides — that contact feeds crash damage. Call `update(dt, input)` before the shared `world.step(dt)`.
- `VehicleBodyConfig` (interface): interface VehicleBodyConfig { position: readonly [number, number, number]; heading?: number; chassisHalfExtents?: readonly [number, number, number]; mass?: number; wheels?: readonly WheelSpec[]; engineAccel?: number; brakeAccel?: number; topSpeed?: number; reverseSpee… — ⚠ undocumented
- `WheelSpec` (interface): interface WheelSpec { offset: readonly [number, number, number]; radius?: number; restLength?: number; steered?: boolean; powered?: boolean; handbrakeLocks?: boolean } — ⚠ undocumented
- `WheelState` (interface): interface WheelState { worldX: number; worldY: number; worldZ: number; grounded: boolean; compression: number; steerAngle: number } — ⚠ undocumented
- `createVehicleBody` (function): function createVehicleBody(world: PhysicsWorld, config: VehicleBodyConfig): VehicleBody — ⚠ undocumented
- `sampleGripCurve` (function): function sampleGripCurve(curve: GripCurve, slip: number): number — Piecewise-linear tire-grip curve: normalized lateral slip → available grip (0..1). Grip peaks near the breakaway slip then falls off as the tire slides — the shape that separates a planted corner from a drift. Points are read in ascending slip order; ends clamp.

## @jgengine/core/physics/vehicleDamage

- `VehicleDamage` (interface): interface VehicleDamage — Fixed-zone crash damage for a vehicle: impacts accumulate into discrete stages, stages change handling and show a bounded dent, and a part can come off at a set stage. Data-driven and bounded by construction — the zone set is authored, each zone's deformation is one capped displacement, and no mesh is edited. Serializes through {@link snapshot}/{@link restore}, so a save, a replay or a host correction resumes mid-crash.
- `VehicleDamageConfig` (interface): interface VehicleDamageConfig — Everything {@link createVehicleDamage} needs.
- `VehicleDamageEffect` (interface): interface VehicleDamageEffect — Handling change one damage zone applies at its *last* stage. Multiplier fields read `1` = undamaged, and a zone part-way through its stages gets the fraction between; `steerPull` and `drag` are additive and reach their full value only at the last stage.
- `VehicleDamageEffectResolved` (interface): interface VehicleDamageEffectResolved — Every zone's handling cost summed into one set of numbers (all fields present, defaults filled).
- `VehicleDamageState` (interface): interface VehicleDamageState — Serializable damage state: {@link VehicleDamage.restore} needs only this.
- `VehicleDamageTransition` (interface): interface VehicleDamageTransition — A zone crossing a threshold this tick — the event a HUD feed, a smoke puff or a camera shake keys off.
- `VehicleDamageZone` (interface): interface VehicleDamageZone — One damageable zone: a fixed local body point, the impulse thresholds that step it through its stages, the bounded dent it shows, and the handling it costs. There is no mesh editing — a zone's deformation is one displacement it can never exceed, so the visual can never grow without limit.
- `VehicleDamageZoneState` (interface): interface VehicleDamageZoneState — Live state of one zone, as a HUD or a save reads it.
- `VehicleDeformation` (interface): interface VehicleDeformation — A zone's current dent: a bounded local displacement and whether the part has come off.
- `createVehicleDamage` (function): function createVehicleDamage(config: VehicleDamageConfig): VehicleDamage — Fixed-zone crash damage (issue #86's stage model) wired to handling and visuals: see {@link VehicleDamage}.
- `damagedAxis` (function): function damagedAxis(axis: AxisInput, effect: VehicleDamageEffectResolved): AxisInput — Apply a damage `steerPull` to a steer axis, clamped to the input range — a bent frame pulling one way.
- `damagedTuning` (function): function damagedTuning(base: KinematicVehicleTuning, effect: VehicleDamageEffectResolved): KinematicVehicleTuning — Bake a damage effect into a tuning — the lasting-damage path. Hand the result to the sim's `retune`, which keeps the vehicle's momentum; the base tuning is not mutated, so a repair is the same call with the undamaged base.

## @jgengine/core/physics/vehicleDynamics

- `VehicleAeroTuning` (interface): interface VehicleAeroTuning — Aero and resistance. Uses air density 1.225 kg/m³.
- `VehicleAirInput` (interface): interface VehicleAirInput — Air-control input, each `-1..1`: `pitch > 0` noses down, `yaw > 0` turns like `steer > 0`, `roll > 0` drops the left side.
- `VehicleAirTuning` (interface): interface VehicleAirTuning — Control of the body while airborne (needs `suspension`, the only way to leave the ground).
- `VehicleAssistTuning` (interface): interface VehicleAssistTuning — Electronic and arcade assists; each is a strength `0..1`, `0`/omitted = off.
- `VehicleDirectDriveTuning` (interface): interface VehicleDirectDriveTuning — Single-speed drive (electric, kart, arcade ball-car): force capped by power, so top speed comes out of drag.
- `VehicleDynamics` (interface): interface VehicleDynamics — Force-based planar car: a two-axle ("bicycle") model where yaw comes from tire forces rather than being commanded, so understeer, oversteer, lift-off rotation, trail-braking, power slides and handbrake turns emerge from the numbers instead of from special cases. Deterministic for a given `dt` sequence; ticks are split into fixed substeps. Pairs with `tickDrivableVehicle` for the entity pose and `measureHandling` for asserting feel.
- `VehicleDynamicsModifiers` (interface): interface VehicleDynamicsModifiers — Per-tick overrides layered over tuning: boost, grip zones, damage. Each scale defaults to `1`.
- `VehicleDynamicsOptions` (interface): interface VehicleDynamicsOptions — World hooks for one vehicle instance.
- `VehicleDynamicsState` (interface): interface VehicleDynamicsState — Serializable integrator state: everything {@link VehicleDynamics.restore} needs to resume bit-for-bit.
- `VehicleDynamicsStep` (interface): interface VehicleDynamicsStep — Result of one {@link VehicleDynamics.tick}: pose plus the telemetry camera, audio, haptics and HUD read.
- `VehicleDynamicsTuning` (interface): interface VehicleDynamicsTuning — Tuning for {@link createVehicleDynamics}. Every number is a physical quantity in SI units (kg, m, N, N·m, rad, s), so a feel target maps to a knob a person can reason about: more rear grip or a lower centre of mass for stability, softer tires for forgiveness, more drive to the rear for power oversteer.
- `VehicleGearboxTuning` (interface): interface VehicleGearboxTuning — Engine and gearbox. Drive force at the wheels = torque · curve(rpm) · gear · finalDrive · efficiency / wheelRadius.
- `VehicleJumpTuning` (interface): interface VehicleJumpTuning — Jumps from the ground and in the air.
- `VehicleLeanTuning` (interface): interface VehicleLeanTuning — Single-track lean for motorcycles, bicycles and scooters. Steer input asks for a lean angle; the front wheel then takes whatever angle a balanced turn at that lean needs (curvature = g·tan(lean) / v²), with a brief countersteer as the lean starts. Tire grip still limits the turn, so over-leaning on a low-grip surface slides.
- `VehicleSteeringTuning` (interface): interface VehicleSteeringTuning — Steering rack: lock, speed-sensitive lock, rack speed, and caster self-alignment.
- `VehicleSuspensionTuning` (interface): interface VehicleSuspensionTuning — Four sprung corners. With this block the chassis heaves, pitches and rolls on real springs, axle loads come from spring forces instead of a filtered estimate, slopes pull the car downhill, and the car can leave the ground and land. Omit it for the flat-ground model.
- `VehicleTireTuning` (interface): interface VehicleTireTuning — One axle's tire, in physical terms. Lateral force follows a simplified Pacejka curve `μ·Fz·sin(C·atan(B·α))` whose `B`/`C` are solved from `peakSlipAngle` and `slideGrip`, so the three numbers read the way a driver feels them: how much grip, how early it peaks, how much is left sliding.
- `createVehicleDynamics` (function): function createVehicleDynamics(initialTuning: VehicleDynamicsTuning, options: VehicleDynamicsOptions = {}): VehicleDynamics — Creates a {@link VehicleDynamics}.

## @jgengine/core/physics/vehicleObstacles

- `VehicleImpact` (interface): interface VehicleImpact — A single blocked-move event a car can react to (#1051): crash damage, screen shake, a metal-crunch cue. Reported once, when a move is first vetoed, then consumed by {@link VehicleObstacleClamp.takeImpact}.
- `VehicleObstacleClamp` (interface): interface VehicleObstacleClamp — A planar move clamp for a kinematic car: feed {@link clampMove} to a vehicle's `clampMove` hook so an attempted XZ displacement slides along world solids instead of driving through them, and read {@link takeImpact} once per tick for the crash it produced.
- `createVehicleObstacleClamp` (function): function createVehicleObstacleClamp(options: { /** Solids near the car this tick (already filtered to the relevant, solid set). */ obstacles: () => readonly CollisionObstacle[]; /** Vehicle body radius (units). Default {@link DEFAULT_VEHICLE_RADIUS}. */ radius?: number; /** Current tick dt (seconds)… — Build a slide-along move clamp for a kinematic car (#1051). `obstacles` is sampled fresh each tick — the caller hands back the already-filtered set of solids near the car — and `dt` supplies the current tick length so a blocked move's lost displacement converts to a closing speed. `radius` inflates each obstacle footprint by the car's body radius (default {@link DEFAULT_VEHICLE_RADIUS}).

## @jgengine/core/physics/vehicleParts

- `VehicleFeel` (interface): interface VehicleFeel — Comparable handling numbers derived from a tuning — what "the numbers and the feel" means to a shop screen, a HUD or a test. Grip is reported as the curve's own shape, so a compound change shows up as a moved peak rather than a single scalar.
- `VehiclePart` (interface): interface VehiclePart — One installable part. `slot` is the caller's own grouping ("tires", "engine", "front-bumper") — the engine does not name slots, so a game's upgrade tree stays its own. Effects compose in install order, and a part's `gripCurve` replaces the base tire compound outright (last one installed wins).
- `VehiclePartEffect` (interface): interface VehiclePartEffect — How one part moves a stat: multiply the base by `scale`, then add `add`. Both default to no change.
- `VehicleSetup` (interface): interface VehicleSetup — A composed vehicle: the tuning to hand the sim, the feel it produces, and what was installed.
- `VehicleStat` (type): type VehicleStat = | "engineAccel" | "brakeAccel" | "topSpeed" | "reverseSpeed" | "turnRate" | "turnSpeedRef" | "gripStrength" | "handbrakeGrip" | "rollingResistance" | "coastDeceleration" — A tunable vehicle number a part can move; each names a {@link KinematicVehicleTuning} field.
- `applyVehicleParts` (function): function applyVehicleParts(base: KinematicVehicleTuning, parts: readonly VehiclePart[]): VehicleSetup — Fold parts onto a base tuning: every effect scales then adds onto the running value, in array order, so a setup is deterministic and a caller can reason about which part moved what. The base tuning is never mutated, so the same base can seed several builds.
- `feelOf` (function): function feelOf(tuning: KinematicVehicleTuning): VehicleFeel — Read the handling numbers out of any tuning — base or parts-composed.
- `withPart` (function): function withPart(parts: readonly VehiclePart[], next: VehiclePart): VehiclePart[] — Swap a part into its slot: any part already in `next.slot` is removed and `next` takes its place in the same install position, so the order (and therefore the composed numbers) stays stable across an upgrade.

## @jgengine/core/physics/worldColliders

- `WorldColliderSync` (interface): interface WorldColliderSync — Handle for synchronizing authored static world collision with a physics backend.
- `syncWorldColliders` (function): function syncWorldColliders(backend: PhysicsBackend, ctx: GameContext): WorldColliderSync — Mirrors static scene-object physical colliders, `ctx.world.solids` and the context's ground field into a physics backend.

## @jgengine/core/procedural

- `DecayMeterSet` (interface): interface DecayMeterSet — Set of named survival meters (hunger/thirst/…) that drain and refill over game time.
- `Moodle` (interface): interface Moodle — One survival moodle (status icon) — severity, source, and label for HUD chips.
- `MoodleStack` (interface): interface MoodleStack — Ordered stack of active moodles derived from meters/ailments/buffs.
- `MultiRegionHealth` (interface): interface MultiRegionHealth — Per-limb / per-region health track with treat/damage/heal APIs.
- `createDecayMeterSet` (function): function createDecayMeterSet(configs: readonly DecayMeterConfig[]): DecayMeterSet — Named decay meters — hunger, thirst, oxygen, sanity, warmth, stamina. Each drains (or recovers) on game-time `dt` at a configurable rate, refills from consumables or actions, and raises moodle statuses at thresholds. Rate modifiers let the environment drive them (colder → faster warmth loss; toxic biome → oxygen drops), so a game reads an environment field then calls `setRateModifier`.
- `createMoodleStack` (function): function createMoodleStack(): MoodleStack — A stateful holder for timed status moodles (food buffs, temporary shelter, warmth). Meters and multi-region health derive their own moodles on read; combine all three through `stackMoodles(stack.list(), meterMoodles, ailmentMoodles)` for one display.
- `createMultiRegionHealth` (function): function createMultiRegionHealth(config: MultiRegionHealthConfig): MultiRegionHealth — Per-region/limb health tracked separately, so each body part takes and heals damage on its own.
- `stackMoodles` (function): function stackMoodles(...groups: readonly (readonly Moodle[])[]): Moodle[] — Merge any number of moodle groups into one stack — meters, ailments, and buffs share this display. Same-id moodles fold together (stacks add, worst severity wins); the result is ordered worst-first so the HUD reads critical statuses at a glance.

## @jgengine/core/scene/assetCatalog

- `AssetCatalog` (interface): interface AssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef> { register(id: string, asset: TMeta): void; resolve(id: string): TMeta | null; has(id: string): boolean; ids(): readonly string[] } — ⚠ undocumented · used by `buildCatalog` (@jgengine/assets): Builds a game's asset catalog from the generated CC0 pack index plus singles, extras, and aliases.
- `AssetRef` (type): type AssetRef = ModelAssetRef | GeneratorAssetRef — A catalog entry: a static GLB model, or a parametric generator.
- `GeneratorAssetRef` (interface): interface GeneratorAssetRef — A catalog entry backed by a registered {@link registerAssetGenerator} instead of a GLB URL — a slider-driven parametric prop (bookcase, building). `defaults` seeds a fresh placement's params. Placed instances persist `{ assetId, params, seed }` in the scene and re-resolve at runtime.
- `ModelAssetRef` (interface): interface ModelAssetRef { url: string; anchor?: "center" | "origin"; dims?: ModelDims; collisionMesh?: CollisionMeshData; space?: AssetSpace; clips?: readonly string[] } — ⚠ undocumented · used by `createHostedWorldSessionAsync` (@jgengine/core/runtime/hostedWorldSession): Build a hosted session from an asynchronous persistence backend.
- `ModelDims` (interface): interface ModelDims — Measured horizontal footprint, footprint center, and lowest Y of a model in model space.
- `createAssetCatalog` (function): function createAssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef>(): AssetCatalog<TMeta> — ⚠ undocumented

## @jgengine/core/scene/assetDiagnostics

- `AssetLoadDiagnosis` (interface): interface AssetLoadDiagnosis — The verdict for one model-asset fetch: its {@link AssetLoadKind} plus a ready-to-log message.
- `AssetLoadKind` (type): type AssetLoadKind = "ok" | "missing" | "html" | "corrupt" | "unsupported" — Pure, zero-dependency classification of a model-asset fetch before it reaches a GLTF parser. Runtime loaders hand the raw response (status, content type, and the first bytes) to {@link classifyAssetResponse} so a missing or mis-served file surfaces as an actionable diagnostic naming the broken asset contract, instead of the opaque "Unexpected token < in JSON" parse error a dev-server HTML fallback otherwise produces. No `fetch`, DOM, or three.js dependency lives here — callers supply the already-read bytes.
- `AssetResponseProbe` (interface): interface AssetResponseProbe — A probe of a model-asset fetch: the URL, an optional logical asset id for the diagnostic, and whatever the caller managed to read. Any field may be absent (e.g. a network error yields no `status` or `bytes`); the classifier degrades gracefully.
- `classifyAssetResponse` (function): function classifyAssetResponse(probe: AssetResponseProbe): AssetLoadDiagnosis — Turn a {@link AssetResponseProbe} into an {@link AssetLoadDiagnosis}. HTTP status is checked first (a `>= 400` or `0` status is `missing`), then the `Content-Type` and byte signature decide between an HTML fallback, a parseable model (`ok`), an unsupported-but-recognizable format, and otherwise corrupt bytes. The returned `message` always names the asset and URL and, for failures, points at the likely fix (provision the pack, check the serving path).
- `readByteSignature` (function): function readByteSignature(bytes: Uint8Array): AssetByteSignature — Classify the leading bytes of a response body by their format signature, with no HTTP context. Recognizes GLB (`glTF` magic), glTF-JSON (a leading `{`), an HTML fallback page (`<!doctype`, `<html`, or a bare `<`), and a few common non-model binaries (PNG, JPEG, ZIP) so they can be reported as unsupported rather than corrupt.

## @jgengine/core/scene/assetGenerator

- `AssetGeneratorDefinition` (interface): interface AssetGeneratorDefinition — A registered asset generator — schema drives the inspector; `generate` is a pure seeded function.
- `GeneratedAsset` (interface): interface GeneratedAsset — A resolved generator asset: its parts plus the overall local-space bounds (min/max corners).
- `GeneratedPart` (interface): interface GeneratedPart — One generated primitive part — a box/panel placed in the asset's local space.
- `partsBounds` (function): function partsBounds(parts: readonly GeneratedPart[]): GeneratedAsset["bounds"] — Compute bounds from parts (each part is an axis-aligned box at its center) — a helper generators return so callers can frame/ground the asset without re-deriving it.
- `registerAssetGenerator` (function): function registerAssetGenerator(definition: AssetGeneratorDefinition): void — Register a parametric asset generator. Idempotent per id (last wins); call at module load.

## @jgengine/core/scene/assetPreload

- `SceneAssetFetcher` (type): type SceneAssetFetcher = (url: string) => void — ⚠ undocumented
- `createSceneAssetPreloader` (function): function createSceneAssetPreloader(fetcher: SceneAssetFetcher): { preloadUrl(url: string): void; preloadUrls(urls: readonly string[]): void; hasPreloaded(url: string): boolean; reset(): void; } — ⚠ undocumented

## @jgengine/core/scene/assetSpace

- `AssetAnchor` (type): type AssetAnchor = "center" | "corner" | { readonly x: number; readonly z: number } — Where a model's pivot sits within its footprint: `center` (origin at the footprint center), `corner` (origin at the min-X/min-Z corner), or a normalized `{ x, z }` fraction in `[-0.5, 0.5]`.
- `AssetSpace` (interface): interface AssetSpace — Catalog-level asset-space metadata: how a model is authored relative to the engine, owned by the catalog entry rather than re-derived per game. Every field is optional so an unmeasured asset stays valid; {@link resolveFacingRotationY}/{@link assetUnitScale}/{@link resolveAnchorOffset} supply the documented defaults.
- `AssetSpaceIssue` (interface): interface AssetSpaceIssue — One problem found by {@link validateAssetSpace}: which metadata field and why it is invalid.
- `PlacementRotationPolicy` (type): type PlacementRotationPolicy = | { readonly mode: "locked"; readonly degrees?: number } | { readonly mode: "snap"; readonly snapDegrees: number } | { readonly mode: "free" } — A per-asset/per-tool rotation constraint, authored as data instead of hardcoded in build code: `locked` pins every placement to one heading, `snap` quantizes to an increment (15, 45, …), and `free` allows any heading. Serializable — this is the shape stored on a catalog entry or a tool.
- `applyRotationPolicy` (function): function applyRotationPolicy(degrees: number, policy: PlacementRotationPolicy | undefined): number — Resolve a raw drag/scroll heading through a {@link PlacementRotationPolicy} into the heading a placement should actually commit: `locked` ignores the input for its fixed heading, `snap` quantizes, `free` (or an absent policy) normalizes. Deterministic — the single interpreter preview, editor placement, and runtime spawning share instead of each re-implementing the modes.
- `headingToRotationY` (function): function headingToRotationY(headingDegrees: number): number — Convert a compass heading (degrees, `0` = engine north, increasing clockwise) into the Three.js Y-rotation (radians, wrapped to `(-PI, PI]`) a renderer applies. Sign matches `world/placementController.quarterTurnsToRotationY`, so heading `90` equals one clockwise quarter turn. This is the one place degrees cross into the private radian space Three.js requires.
- `normalizeDegrees` (function): function normalizeDegrees(degrees: number): number — Wrap `degrees` into `[0, 360)` — the canonical heading range every policy and conversion here works in. Non-finite input collapses to `0` so bad metadata never leaks a `NaN` heading downstream.
- `parseAssetSpace` (function): function parseAssetSpace(raw: unknown): AssetSpace | undefined — Parse untrusted JSON into an {@link AssetSpace}, dropping malformed fields, or `undefined` when nothing valid remains — the round-trippable read path for serialized catalog/scene metadata.
- `parseRotationPolicy` (function): function parseRotationPolicy(raw: unknown): PlacementRotationPolicy — Parse an untrusted rotation policy (from a scene document or catalog JSON) into a valid {@link PlacementRotationPolicy}, defaulting to `free` when absent or malformed. The lenient companion to {@link validateAssetSpace} for the read path.
- `resolveAnchorOffset` (function): function resolveAnchorOffset(space?: Pick<AssetSpace, "anchor" | "footprint">): Vec2 — The pivot's offset from the footprint center, in engine meters, implied by {@link AssetSpace.anchor} and {@link AssetSpace.footprint}. `center` yields `[0, 0]`; `corner` yields the min corner; a normalized `{ x, z }` scales by the footprint. Subtract it to seat a footprint centered on a point.
- `resolveFacingRotationY` (function): function resolveFacingRotationY(headingDegrees: number, space?: Pick<AssetSpace, "forwardDegrees">): number — The Three.js Y-rotation that makes a model whose front is authored at `forwardDegrees` visually point `headingDegrees` (engine north = `0`). This is the catalog-owned replacement for per-game corrective yaw: a model authored facing south (`forwardDegrees: 180`) placed toward north resolves to `Math.PI`.
- `rotatedFootprint` (function): function rotatedFootprint(footprint: Footprint, headingDegrees: number): Footprint — The axis-aligned footprint extent after rotating a rectangular {@link Footprint} by `headingDegrees` — footprint-aware placement: a 90-degree turn swaps width/depth, and arbitrary headings grow the bounding box so overlap and snap checks see the space the rotated asset truly occupies.
- `rotationYToHeading` (function): function rotationYToHeading(rotationY: number): number — Inverse of {@link headingToRotationY}: recover the `[0, 360)` compass heading from a Three.js Y-rotation. Lets a gizmo or inspector present radians as the degrees authors edit.
- `snapHeading` (function): function snapHeading(degrees: number, increment: number): number — Quantize `degrees` to the nearest multiple of `increment` (both in the `[0, 360)` convention). A non-positive increment is treated as free rotation and only normalizes. The math behind a `snap`-mode {@link PlacementRotationPolicy}.
- `toEngineUnits` (function): function toEngineUnits(sourceValue: number, space?: Pick<AssetSpace, "unitScale">): number — Convert a source-space length to engine meters through the asset's {@link AssetSpace.unitScale} — the data-owned replacement for per-game scale constants (a native ~4-unit kit tile down to a 1-unit grid).
- `validateAssetSpace` (function): function validateAssetSpace(raw: unknown): AssetSpaceIssue[] — Report contradictory or malformed asset-space metadata so catalog generation can reject it before it reaches a tool: non-finite headings, non-positive scales/sizes, inverted bounds, unknown anchors, and ill-formed rotation policies (a `snap` with a non-positive increment, an unknown `mode`). An empty array means valid. Validation lives here so tools consume resolved metadata instead of reinterpreting.

## @jgengine/core/scene/authoredTriggers

- `AuthoredTrigger` (interface): interface AuthoredTrigger — One resolved trigger binding from a document object.
- `AuthoredTriggerRuntime` (interface): interface AuthoredTriggerRuntime — Runtime handle that watches authored triggers against moving actors each tick.
- `BUILTIN_TRIGGER_ACTIONS` (const): const BUILTIN_TRIGGER_ACTIONS: readonly TriggerActionDefinition[] — The engine's built-in trigger actions — the shared `announce` / `win` / `advance` vocabulary every game gets for free, so "enter this zone → win" is authored entirely in the editor with no bespoke action code. Their params land flat on the object's `meta` like any registered action; drive them at runtime with the handlers from {@link createTriggerOutcome}.
- `TriggerActionDefinition` (interface): interface TriggerActionDefinition — A game-declared action the editor can assign to a volume/marker trigger. Schema drives the inspector params; `targets`/`events` optionally narrow where it appears.
- `TriggerDispatchEvent` (interface): interface TriggerDispatchEvent — Fired when a watched actor trips an authored trigger edge.
- `TriggerEvent` (type): type TriggerEvent = "enter" | "exit" | "interact" — Event edge that can fire an authored trigger.
- `TriggerHandlers` (type): type TriggerHandlers = Readonly<Record<string, (event: TriggerDispatchEvent) => void>> — Handler map keyed by action id — unknown actions are skipped unless `onDispatch` is set.
- `TriggerOutcome` (interface): interface TriggerOutcome — Serializable read-model the built-in trigger actions write — the HUD/game reads it each frame.
- `TriggerOutcomeStore` (interface): interface TriggerOutcomeStore — Outcome store: the built-in action handlers plus a subscribable snapshot of what they produced.
- `TriggerSourceKind` (type): type TriggerSourceKind = "marker" | "volume" — Document collection a trigger source lives on.
- `collectAuthoredTriggers` (function): function collectAuthoredTriggers(document: SceneDocumentLike): AuthoredTrigger[] — Collect every authored trigger on a document's markers and volumes. Pure — no runtime state. Action params use the live {@link registerTriggerAction} registry when present.
- `createAuthoredTriggerRuntime` (function): function createAuthoredTriggerRuntime(options: { document: SceneDocumentLike; handlers?: TriggerHandlers; /** Invoked for every dispatch after the matching handler (if any). */ onDispatch?: (event: TriggerDispatchEvent) => void; /** Override the collected trigger list (tests / hot-reload). Default: … — Build a runtime that watches a document's authored triggers against moving actors and dispatches to per-action handlers (and optional catch-all). Pure membership math; the game supplies actors each tick from its own player/entity poses.
- `createTriggerOutcome` (function): function createTriggerOutcome(): TriggerOutcomeStore — Default runtime for the built-in {@link BUILTIN_TRIGGER_ACTIONS}: a small serializable outcome the HUD renders, with no engine-side UI. Pass {@link TriggerOutcomeStore.handlers} to {@link createAuthoredTriggerRuntime} and read {@link TriggerOutcomeStore.get} from the HUD via `useSyncExternalStore` — that is the whole zero-code "reach the zone to win" wiring.
- `getTriggerAction` (function): function getTriggerAction(id: string): TriggerActionDefinition | undefined — Registered definition for an action id, or undefined when the game never declared it.
- `listTriggerActions` (function): function listTriggerActions(target?: TriggerSourceKind): TriggerActionDefinition[] — Every registered action, optionally filtered by target collection.
- `pointInVolume` (function): function pointInVolume(volume: SceneVolumeLike, point: { x: number; y: number; z: number }): boolean — True when `point` is inside an editor volume (sphere / cylinder / box). Cylinder height defaults to diameter when omitted; sphere ignores y for the common ground-plane case only when the volume radius covers the full vertical span — here y is tested for sphere and box too.
- `registerBuiltinTriggerActions` (function): function registerBuiltinTriggerActions(): void — Register the engine's built-in {@link BUILTIN_TRIGGER_ACTIONS} so they appear in the editor's trigger inspector. Idempotent; call at module load (a game may still register its own actions or re-register a built-in id to override it).
- `registerTriggerAction` (function): function registerTriggerAction(definition: TriggerActionDefinition): void — Declare a game action the editor can assign to volume/marker triggers. Idempotent per `id` (last registration wins). Call at module load next to catalogs.

## @jgengine/core/scene/autoTarget

- `AutoTargetDeps` (interface): interface AutoTargetDeps { candidates: (fromId: string) => readonly string[]; distance: (fromId: string, toId: string) => number | null; strength?: (toId: string) => number; progress?: (toId: string) => number; rng?: () => number } — ⚠ undocumented
- `AutoTargetPolicy` (type): type AutoTargetPolicy = | "nearest" | "farthest" | "random" | "strongest" | "weakest" | "first" | "last" — ⚠ undocumented
- `AutoTargeter` (interface): interface AutoTargeter { policy(): AutoTargetPolicy; setPolicy(policy: AutoTargetPolicy): void; pick(fromId: string): string | null } — ⚠ undocumented
- `createAutoTargeter` (function): function createAutoTargeter(policy: AutoTargetPolicy, deps: AutoTargetDeps): AutoTargeter — ⚠ undocumented
- `selectAutoTarget` (function): function selectAutoTarget(policy: AutoTargetPolicy, fromId: string, deps: AutoTargetDeps): string | null — ⚠ undocumented

## @jgengine/core/scene/behaviorRuntime

- `BehaviorAction` (type): type BehaviorAction = DecisionAction<BehaviorActionContext> — Callback used by a registered decision graph behavior action.
- `BehaviorActionContext` (interface): interface BehaviorActionContext — Context supplied to a registered decision graph action.
- `BehaviorActionOptions` (interface): interface BehaviorActionOptions — Optional hooks for a registered behavior action set.
- `BehaviorControl` (interface): interface BehaviorControl — Per-entity control surface for the behavior runtime — pause/resume/disable/enable an instance, seek it to semantic progress, serialize/restore its state, and inspect it, all keyed by stable entity id without a full-world scan. Obtain it with {@link behaviorControl}.
- `BehaviorInspection` (interface): interface BehaviorInspection — Inspection readout for editor/debug tooling, from {@link BehaviorControl.inspect}/{@link BehaviorControl.list}.
- `BehaviorResumePolicy` (type): type BehaviorResumePolicy = "freeze" | "advance" — Catch-up policy applied when a paused instance resumes. `freeze` (default, deterministic) discards the time spent paused; `advance` silently fast-forwards the instance by the paused duration without emitting intermediate pose writes. Only patrol honors `advance`; wander/pursue treat it as `freeze`.
- `BehaviorSnapshot` (type): type BehaviorSnapshot = | { readonly kind: "patrol"; readonly state: PathFollowState } | { readonly kind: "wander"; readonly origin: Waypoint; readonly target: Waypoint | null } | PursueBehaviorSnapshot | { readonly kind: "decisionGraph"; readonly graph: ReturnType<DecisionGraphRuntime["snapshot"]>;… — Serializable snapshot of one behavior instance — round-trips exactly through {@link BehaviorControl.serialize}/{@link BehaviorControl.restore}.
- `BehaviorStatus` (type): type BehaviorStatus = "active" | "paused" | "disabled" — Whether a behavior instance advances and writes pose (`active`), is temporarily suspended retaining state (`paused`), or is held off until re-enabled (`disabled`).
- `PursueBehaviorSnapshot` (interface): interface PursueBehaviorSnapshot — Plain pursuit progress, including its original spawn home and scheduled elapsed time.
- `advanceBehaviors` (function): function advanceBehaviors(ctx: GameContext, dt: number): void — Advance every spawned entity carrying a patrol, wander, pursuit or decision graph behavior one tick — the engine reads the descriptor, keeps the per-entity nav state itself, and poses the entity, so ambient traffic and idle NPC routes are register-once (attach the behavior at spawn) instead of a per-game per-frame `advancePathFollow` + `setPose` loop. Instances that are paused or disabled through {@link behaviorControl} retain their state and are skipped. The shell/host call this each frame; a game never does.
- `behaviorControl` (function): function behaviorControl(ctx: GameContext): BehaviorControl — Obtain the per-context {@link BehaviorControl} surface for suspending, resuming, seeking, serializing, and inspecting behavior instances by entity id — the lifecycle contract games use to hand pose ownership to possession/streaming/staggering code instead of bypassing the behavior runtime.
- `registerBehaviorActions` (function): function registerBehaviorActions(id: string, actions: Record<string, BehaviorAction>, options: BehaviorActionOptions = {}): () => void — Register the named actions used by decision graph behavior descriptors.

## @jgengine/core/scene/behaviors

- `BehaviorDescriptor` (type): type BehaviorDescriptor = | WanderBehavior | PatrolBehavior | PromptableBehavior | PlayerBehavior | PursueBehavior | DecisionGraphBehavior — ⚠ undocumented
- `DecisionGraphBehavior` (interface): interface DecisionGraphBehavior — Decision graph behavior descriptor using a named registered action set.
- `PatrolBehavior` (interface): interface PatrolBehavior { kind: "patrol"; waypoints: readonly Waypoint[]; speed: number; loop: boolean; startProgress?: PathProgress; groundClamp?: boolean } — ⚠ undocumented
- `PlayerBehavior` (interface): interface PlayerBehavior { kind: "player" } — ⚠ undocumented
- `PromptableBehavior` (interface): interface PromptableBehavior { kind: "promptable"; prompt: ProximityPrompt } — ⚠ undocumented
- `PursueBehavior` (interface): interface PursueBehavior — Scheduled chase/attack behavior; the default declares hostility toward player-role entities. GameDefinition.pursuit.eligible can further restrict every target source using the live world. Explicit targets and optional threat override nearest-player acquisition, not eligibility.
- `WanderBehavior` (interface): interface WanderBehavior { kind: "wander"; radius: number } — ⚠ undocumented
- `patrol` (function): function patrol({ waypoints, speed, loop = true, startProgress, groundClamp, }: { waypoints: readonly Waypoint[]; speed: number; loop?: boolean; startProgress?: PathProgress; groundClamp?: boolean; }): PatrolBehavior — ⚠ undocumented
- `player` (function): function player(): PlayerBehavior — ⚠ undocumented
- `promptable` (function): function promptable(prompt: ProximityPrompt): PromptableBehavior — ⚠ undocumented
- `pursue` (function): function pursue(options: Omit<PursueBehavior, "kind">): PursueBehavior — Attach aggro, collision-aware chase, cooldown attack and latched return-to-spawn as data.
- `talkable` (function): function talkable(dialogueId: string): PromptableBehavior — ⚠ undocumented
- `wander` (function): function wander({ radius }: { radius: number }): WanderBehavior — ⚠ undocumented

## @jgengine/core/scene/bodyBind

- `BodyBind` (interface): interface BodyBind — The lazily-keyed handle `ctx.scene.entity.bind(key)` returns.
- `BodyBindDeps` (interface): interface BodyBindDeps — Structural entity-store seam a {@link BodyBind} mirrors onto — satisfied by `ctx.scene.entity` itself.
- `BodyBindPose` (interface): interface BodyBindPose — The pose a {@link BodyBindDeps.setPose} call receives for an id already bound.
- `BodyBindSpawnInput` (interface): interface BodyBindSpawnInput — The options a {@link BodyBindDeps.spawn} call receives for an id seen for the first time.
- `BodySnapshot` (interface): interface BodySnapshot — One sim body's per-tick pose, as the game's simulation computed it — the shape a game already builds to hand to `setPose`, just declared instead of imperatively pushed. `kind` is the entity catalog name used only the first time `id` is seen (a respawn/despawn never re-reads it).
- `createBodyBind` (function): function createBodyBind(deps: BodyBindDeps): BodyBind — Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound, despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.

## @jgengine/core/scene/builtinSceneKinds

- `SCATTER_SCHEMA` (const): const SCATTER_SCHEMA: ParamSchema — The scatter/foliage region schema. `palette` (what fills the area) leads the schema body and `density` is the single coverage slider hoisted into the shared `CoverageSection` (see the kind's `coverage` descriptor), so a scatter region reads as Area → Assets → Density like every other scatterable kind; the rest is kind-specific tuning.

## @jgengine/core/scene/captureCheck

- `CaptureCheckInput` (interface): interface CaptureCheckInput { hpFraction: number; catchPower: number; difficulty?: number } — ⚠ undocumented
- `captureChance` (function): function captureChance(input: CaptureCheckInput): number — ⚠ undocumented
- `rollCapture` (function): function rollCapture(input: CaptureCheckInput, rng?: () => number): boolean — ⚠ undocumented

## @jgengine/core/scene/colliders

- `ColliderDef` (interface): interface ColliderDef { name: string; purpose: ColliderPurpose; shape: ColliderShape; damageEligible?: boolean; blocks?: boolean } — ⚠ undocumented
- `ColliderPurpose` (type): type ColliderPurpose = "physical" | "damage" — ⚠ undocumented
- `ColliderShape` (type): type ColliderShape = | { kind: "sphere"; radius: number; offset?: EntityPosition } | { kind: "aabb"; halfExtents: EntityPosition; offset?: EntityPosition } | { kind: "mesh"; /** Prepared triangle mesh in model space — engine-derived from an opted-in catalog asset, never hand-authored. */ mesh: Prepa… — Collision geometry in entity-local space. `sphere` and `aabb` are analytic; `mesh` carries a prepared triangle mesh so opted-in concave models raycast their real surface while bounds and broadphase keep reading the conservative `halfExtents`.
- `DEFAULT_ENTITY_BODY_HALF_EXTENTS` (const): const DEFAULT_ENTITY_BODY_HALF_EXTENTS: EntityPosition — Matches the shell's fallback actor capsule (~0.7m wide, feet at y=0 to head at ~1.8m).
- `DEFAULT_ENTITY_BODY_OFFSET` (const): const DEFAULT_ENTITY_BODY_OFFSET: EntityPosition — Entity-local center of the default body hitbox (half its height above the feet).
- `DEFAULT_ENTITY_HIT_RADIUS` (const): const DEFAULT_ENTITY_HIT_RADIUS: 0.5 — ⚠ undocumented
- `DEFAULT_OBJECT_HALF_EXTENTS` (const): const DEFAULT_OBJECT_HALF_EXTENTS: EntityPosition — ⚠ undocumented
- `EntityColliderSet` (interface): interface EntityColliderSet { body?: ColliderDef; hitboxes?: readonly ColliderDef[] } — ⚠ undocumented · used by `eyeHeightFromColliders` (@jgengine/core/combat): Eye height derived from a collider set: 90% of the tallest hitbox top, or the humanoid default when unknown.
- `MeasuredBounds` (interface): interface MeasuredBounds — Entity-local AABB of what the renderer actually mounted for a kind — the runtime counterpart to index-measured `dims`. Reported through `ctx.scene.entity.reportBounds` / `ctx.scene.object.reportBounds` (the shell does this automatically for custom `renderEntity`/`renderObject` content and models without index dims) so collider resolution can wrap the real rendered shape instead of a fixed-size guess.
- `ModelBodySource` (interface): interface ModelBodySource — The render-config subset collider fitting reads — structurally satisfied by a resolved `ModelConfig`, so the shell can hand its render config straight to the fitting math without a conversion step.
- `ResolvedCollider` (interface): interface ResolvedCollider { name: string; purpose: ColliderPurpose; shape: ColliderShape; damageEligible: boolean; blocks: boolean } — ⚠ undocumented

## @jgengine/core/scene/collisionMesh

- `CollisionMeshData` (interface): interface CollisionMeshData — Compact, serializable triangle collision mesh measured at asset reindex — the renderer-free source of mesh-accurate hitboxes. Positions are welded onto a 16-bit grid spanning `min`..`max` (model space) and stored base64-encoded, so an opted-in catalog asset ships its collision triangles inside the generated index without the runtime ever touching the rendered scene graph.
- `CollisionMeshHit` (interface): interface CollisionMeshHit — Nearest triangle impact from {@link raycastCollisionMesh}: world distance along the ray and the world-space geometric normal facing the ray.
- `CollisionMeshSource` (interface): interface CollisionMeshSource — Raw triangle soup for {@link encodeCollisionMesh}: model-space xyz triples plus triangle indices.
- `PreparedCollisionMesh` (interface): interface PreparedCollisionMesh — Decoded, BVH-indexed triangles ready for per-ray queries — build once per asset via {@link prepareCollisionMesh}. Treat the fields as opaque; they exist so the raycast hot path can run allocation-free over flat arrays.
- `encodeCollisionMesh` (function): function encodeCollisionMesh(source: CollisionMeshSource): CollisionMeshData | null — Quantize a triangle soup onto the 16-bit grid, weld coincident vertices, and drop triangles that collapse — the reindex-time compressor producing {@link CollisionMeshData}. Returns `null` when no finite, non-degenerate triangle survives.
- `prepareCollisionMesh` (function): function prepareCollisionMesh(data: CollisionMeshData): PreparedCollisionMesh | null — Decode a stored collision mesh and index it with a BVH. Memoized per data object, so the shell and a headless host preparing the same catalog entry share one build. Returns `null` (also memoized) when the payload is malformed.
- `prepareCollisionMeshSource` (function): function prepareCollisionMeshSource(source: CollisionMeshSource): PreparedCollisionMesh | null — Build a prepared BVH mesh straight from a runtime triangle soup (float positions + indices) — the renderer-fed counterpart to {@link prepareCollisionMesh}, feeding `ctx.scene.entity.reportCollisionMesh` / `ctx.scene.object.reportCollisionMesh` without a quantize/encode round-trip. Copies and sanitizes the input: triangles referencing out-of-range, non-finite, or repeated vertices are dropped. Returns `null` when no triangle survives.
- `raycastCollisionMesh` (function): function raycastCollisionMesh(mesh: PreparedCollisionMesh, origin: EntityPosition, direction: EntityPosition, maxDistance: number, position: EntityPosition, rotationY: number, scale: number, translate: EntityPosition): CollisionMeshHit | null — Nearest triangle hit for a world-space ray against a prepared mesh placed like its rendered model: model space scaled uniformly by `scale`, translated by entity-local `translate`, yaw-rotated by `rotationY`, and moved to `position` — the same composition {@link "scene/colliders".ModelBodySource} fitting applies to the AABB. Allocation-free until the returned hit. `distance` is world distance along `direction` (callers pass `direction` normalized); `normal` is the world-space geometric triangle normal facing the ray.

## @jgengine/core/scene/companion

- `CompanionAdoptOptions` (interface): interface CompanionAdoptOptions — Options for {@link CompanionRoster.adopt}.
- `CompanionCommand` (type): type CompanionCommand = "follow" | "stay" | "passive" | "neutral" | "aggressive" — A tamed companion's standing order. Genre-agnostic aggression + posture preset: - `follow` — heel to the owner and assist whatever the owner is fighting. - `stay` — hold at `home` and assist the owner's target from there. - `passive` — heel to the owner and never engage (a pacifist escort). - `neutral` — heel to the owner and only fight back nearby threats (defensive). - `aggressive` — heel to the owner and proactively engage nearby threats and the owner's target.
- `CompanionConfig` (interface): interface CompanionConfig — Per-companion configuration shared by every companion the roster mints.
- `CompanionIntent` (interface): interface CompanionIntent — The companion's decision for one tick, shaped for `ai/mobBrain`: feed `candidates` into `MobBrainDeps.candidates()`, treat `leashTo` as the brain's `home`, and pass `leashDistance` as `leashDistance`. `kind` summarises the posture for HUD/animation.
- `CompanionIntentContext` (interface): interface CompanionIntentContext — Per-tick world context the game supplies so a command resolves into a concrete intent.
- `CompanionRecord` (interface): interface CompanionRecord — Serializable per-companion state: who owns it, its standing order, where it holds, its leash radius, and its levelled stat pool. Plain data — JSON round-trips without loss.
- `CompanionRoster` (interface): interface CompanionRoster — A set of tamed companions keyed by companion id, scoped to owners. Wraps allegiance/command state, per-companion levelled stats, and intent resolution behind create/command/level/ snapshot/hydrate — the counterpart of `scene/roster` for creatures that fight beside you.
- `CompanionSpendResult` (type): type CompanionSpendResult = | { status: "ok"; record: CompanionRecord; stat: StatValue } | { status: "rejected"; reason: string } — Outcome of {@link CompanionRoster.spend}: the updated record + stat, or a rejection reason.
- `CompanionStatUpgrade` (interface): interface CompanionStatUpgrade — Rule for turning one spent level-point into a stat gain. Absent from config ⇒ the stat can't be upgraded.
- `createCompanionRoster` (function): function createCompanionRoster(config: CompanionConfig = {}): CompanionRoster — Build a {@link CompanionRoster}. Composes `scene/roster` ownership (via `ownerId`/`sourceId`), `scene/entityStats` for the per-companion stat pool, and {@link resolveCompanionIntent} for `ai/mobBrain`-shaped behavior — turning a captured creature into a loyal, levelling ally.
- `resolveCompanionIntent` (function): function resolveCompanionIntent(record: CompanionRecord, context: CompanionIntentContext): CompanionIntent — Pure command → intent resolver. Maps a companion's standing order plus this tick's owner position, owner target, and nearby threats into the {@link CompanionIntent} a game feeds into `ai/mobBrain` (or executes directly). Deterministic and allocation-light — no import of the `@internal` brain factory; the two interoperate purely by shape.

## @jgengine/core/scene/entityStats

- `EntityStatsApi` (interface): interface EntityStatsApi extends StatPoolAccess — Native entity-stat adapter over the portable {@link StatPoolAccess} contract.
- `PoolDeltaResult` (type): type PoolDeltaResult = | { status: "ok"; map: StatValueMap; stat: StatValue; hitMin: boolean; hitMax: boolean } | { status: "rejected"; reason: string } — ⚠ undocumented
- `StatCatalog` (type): type StatCatalog = Record<string, { max: number; min?: number; current?: number }> — ⚠ undocumented
- `StatValue` (interface): interface StatValue extends StatPool — Native entity-stat name retained as a compatibility bridge to the portable pool model.
- `StatValueMap` (type): type StatValueMap = Record<string, StatValue> — ⚠ undocumented
- `StatValuePatch` (interface): interface StatValuePatch extends StatPoolPatch — Native entity-stat patch retained as a compatibility bridge.

## @jgengine/core/scene/entityStore

- `EntityBlackboard` (interface): interface EntityBlackboard — Per-entity scratch and cooldown timers, auto-cleared on despawn (#533.8) — the home for AI state (next-shot-at, alert level) that would otherwise be smuggled through the serializable `meta` or a hand-pruned module-level map. Keys share one namespace per entity: `arm`/`ready`/`remaining` store a deadline under a key, `get`/`set` store arbitrary scratch.
- `EntityMovement` (interface): interface EntityMovement { walkSpeed?: number; frozen?: boolean } — ⚠ undocumented
- `EntityPose` (interface): interface EntityPose { position: SpawnPositionInput; rotationY?: number; rotationX?: number; rotationZ?: number; dt?: number } — ⚠ undocumented
- `EntityPosition` (type): type EntityPosition = readonly [number, number, number] — ⚠ undocumented · used by `resolveSourceWalkerStep` (@jgengine/core/movement/solidObstacles): {@link resolveWalkerStep} with no `GameContext`: gather plus slide against a bare {@link SolidObstacleSource} and a caller-owned {@link Obst…
- `EntityRole` (type): type EntityRole = "player" | "npc" | "prop" — ⚠ undocumented
- `EntityStore` (interface): interface EntityStore<TMeta = unknown> — Entity state, pose writes, keyed behavior notifications and snapshot/hydration under stable instance IDs.
- `EntityStoreOptions` (interface): interface EntityStoreOptions — Commit hook for a derived index; runs after the write and before existing subscribers. `undefined` denotes a whole-store replacement. Value overwrites keep membership false.
- `EntityUpdatePatch` (type): type EntityUpdatePatch<TMeta = unknown> = Partial< Pick<SceneEntity<TMeta>, "name" | "rotationY" | "rotationX" | "rotationZ" | "role" | "movement" | "behaviors" | "hidden" | "meta"> > & { /** Accepts the same friendly shapes as `spawn`/`setPose` (#286.13). Raw patch semantics — velocity is not deriv… — ⚠ undocumented
- `PoseConstraint` (type): type PoseConstraint = (frame: PoseConstraintFrame) => readonly [number, number, number] | undefined | void — Return a replacement position to constrain the step, or nothing to accept it.
- `PoseConstraintFrame` (interface): interface PoseConstraintFrame { entityId: string; current: EntityPosition; next: EntityPosition; dt?: number } — ⚠ undocumented
- `SceneEntity` (interface): interface SceneEntity<TMeta = unknown> { id: string; name: string; position: EntityPosition; rotationY: number; rotationX: number; rotationZ: number; velocity: EntityPosition; role: EntityRole; movement: EntityMovement; behaviors: readonly BehaviorDescriptor[]; hidden?: boolean;… — ⚠ undocumented · used by `entityMetaOf`: Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null` instead of lying to the type che…
- `SpawnOptions` (interface): interface SpawnOptions<TMeta = unknown> { id?: string; position?: SpawnPositionInput; rotationY?: number; rotationX?: number; rotationZ?: number; role?: EntityRole; movement?: EntityMovement; behaviors?: readonly BehaviorDescriptor[]; hidden?: boolean; meta?: TMeta; onExisting?: … — ⚠ undocumented
- `SpawnPose` (interface): interface SpawnPose { position: EntityPosition; rotationY: number } — ⚠ undocumented
- `SpawnPositionInput` (type): type SpawnPositionInput = EntityPosition | { x: number; y: number; z: number } — ⚠ undocumented
- `createEntityStore` (function): function createEntityStore<TMeta = unknown>(options: EntityStoreOptions = {}): EntityStore<TMeta> — ⚠ undocumented
- `entityMetaOf` (function): function entityMetaOf<T>(entity: SceneEntity<unknown>, isMeta: (value: unknown) => value is T): T | null — Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null` instead of lying to the type checker.
- `groundSpeed` (function): function groundSpeed(entity: SceneEntity<unknown>): number — Ground speed (horizontal magnitude of velocity) in world units per second. Scale to km/h or mph in game code.
- `movedWhileFrozen` (function): function movedWhileFrozen(entity: SceneEntity<unknown>, threshold = DEFAULT_FROZEN_MOVE_THRESHOLD): boolean — ⚠ undocumented

## @jgengine/core/scene/facing

- `DEFAULT_FORWARD` (const): const DEFAULT_FORWARD: readonly [number, number, number] — The forward-axis convention: a generator or scene kind declares which way its "front" faces (a bookcase's open/book face, a building's entrance) once, as data, instead of leaving every placement to hand-tuned `rotationY` trial-and-error. `StudioStage`'s `faceCamera` (`@jgengine/shell/scene/ StudioStage`) reads the declared axis to auto-orient a product shot; a placement tool can read the same field to face a freshly dropped asset toward the camera/path by default. `DEFAULT_FORWARD` (+Z) is what a generator/scene-kind gets when it omits `forward` — build your front toward it.

## @jgengine/core/scene/form

- `FormChangedEvent` (interface): interface FormChangedEvent { instanceId: string; formId: string | null } — ⚠ undocumented
- `FormDef` (interface): interface FormDef { id: string; movement?: EntityMovement; abilities?: readonly string[]; model?: string } — ⚠ undocumented
- `FormEntities` (interface): interface FormEntities { get(id: string): SceneEntity | null; update(id: string, patch: {movement?: EntityMovement; name?: string}): boolean } — ⚠ undocumented
- `FormEvents` (interface): interface FormEvents { emit(name: "form.changed", payload: FormChangedEvent): void } — ⚠ undocumented
- `FormTime` (interface): interface FormTime { after(seconds: number, callback: () => void): () => void } — ⚠ undocumented
- `Forms` (interface): interface Forms { register(defs: readonly FormDef[]): void; get(formId: string): FormDef | null; abilities(instanceId: string): readonly string[] | null; active(instanceId: string): string | null; shapeshift(instanceId: string, formId: string, durationSeco… — ⚠ undocumented
- `FormsDeps` (interface): interface FormsDeps { entities: FormEntities; time: FormTime; events?: FormEvents } — ⚠ undocumented
- `createForms` (function): function createForms(deps: FormsDeps): Forms — ⚠ undocumented

## @jgengine/core/scene/modelSockets

- `ModelNode` (interface): interface ModelNode — Generic named-socket reader for loaded 3D models. Walks a node tree (any object with `.name`, `.position`, and `.children` — structurally satisfied by `THREE.Object3D`) and collects the local offsets of nodes whose name marks an attachment point. Genre-agnostic: wire anchors on a pylon, muzzle/hand mounts on a character, hardpoints on a ship, seat/decal slots on furniture — anything an artist tags with an empty in the GLB. Pure data (no three.js import), so it lives in core.
- `ModelSocket` (interface): interface ModelSocket — One resolved socket: its node name and local-space offset from the model origin.
- `SOCKET_PATTERN` (const): const SOCKET_PATTERN: RegExp — Default socket-name matcher: "socket", "wire", "attach", "anchor", "mount", "hardpoint" (any case).
- `readNamedSockets` (function): function readNamedSockets(root: ModelNode, pattern: RegExp = SOCKET_PATTERN): ModelSocket[] — Depth-first collect every socket-named node's local offset, sorted by descending Y then ascending X so socket indices are stable across loads (top first, left-to-right). Empty when the model tags none — callers then fall back to computed offsets. Pass a custom `pattern` for a bespoke naming convention.

## @jgengine/core/scene/mount

- `MountController` (class): class MountController — Mount / rideable control-transfer (issue #83). Registers rideables (each with one or more seats — a control seat drives, the rest ride) and tracks who is on what. It owns no camera or physics: game code reads `cameraTarget(riderId)` to point the follow camera at the mount, and `driveTarget(riderId)` to route that rider's {@link import("../physics/vehicleBody").AxisInput}-driven input at the mount's movement kit — the same seam a horse, a truck, or a shared multi-seat ship all plug into.
- `MountKind` (type): type MountKind = "ground" | "boat" | "flying" | "swimming" — ⚠ undocumented
- `MountKit` (interface): interface MountKit { kind: MountKind; moveSpeed?: number; turnSpeed?: number } — ⚠ undocumented
- `MountResult` (type): type MountResult = { ok: true; seat: MountSeat } | { ok: false; reason: string } — ⚠ undocumented
- `MountSeat` (interface): interface MountSeat { id: string; offset: readonly [number, number, number]; control?: boolean } — ⚠ undocumented
- `MountedRider` (interface): interface MountedRider extends SeatRef — Occupancy only; register the world's rideables before restoring.
- `Occupant` (interface): interface Occupant { riderId: string; seatId: string } — ⚠ undocumented
- `RideableConfig` (interface): interface RideableConfig { id: string; kit: MountKit; seats?: readonly MountSeat[] } — ⚠ undocumented
- `SeatRef` (interface): interface SeatRef { mountId: string; seatId: string } — ⚠ undocumented
- `createMountController` (function): function createMountController(): MountController — ⚠ undocumented

## @jgengine/core/scene/movementSpeed

- `MovementSpeedConfig` (interface): interface MovementSpeedConfig { baseSpeed: number; multiplierStat?: string; flatBonusStat?: string } — ⚠ undocumented · used by `applyStatDrivenSpeed`: Recomputes `movement.walkSpeed` for an entity from its stats and writes it back via `deps.entities.update`.
- `MovementSpeedDeps` (interface): interface MovementSpeedDeps { stats: {get(instanceId: string, statId: string): StatValue | null}; entities: {get(id: string): {movement?: {walkSpeed?: number}} | null; update(id: string, patch: {movement: {walkSpeed: number}}): boolean;} } — ⚠ undocumented · used by `applyStatDrivenSpeed`: Recomputes `movement.walkSpeed` for an entity from its stats and writes it back via `deps.entities.update`.
- `MovementSpeedModifiers` (interface): interface MovementSpeedModifiers { multiplier?: number; flatBonus?: number } — ⚠ undocumented · used by `deriveWalkSpeed`: `base * (multiplier ?? 1) + (flatBonus ?? 0)`, clamped to never go negative.
- `applyStatDrivenSpeed` (function): function applyStatDrivenSpeed(deps: MovementSpeedDeps, instanceId: string, config: MovementSpeedConfig): boolean — Recomputes `movement.walkSpeed` for an entity from its stats and writes it back via `deps.entities.update`. Either stat id is optional; an omitted or unresolved stat contributes its neutral value (multiplier 1, flat bonus 0) rather than failing. Returns false only when the entity itself doesn't exist.
- `deriveWalkSpeed` (function): function deriveWalkSpeed(base: number, modifiers: MovementSpeedModifiers): number — `base * (multiplier ?? 1) + (flatBonus ?? 0)`, clamped to never go negative.

## @jgengine/core/scene/objectQuery

- `ObjectQueryBroadphase` (interface): interface ObjectQueryBroadphase — Optional broadphase for large object sets — typically `ObjectStore.inBox`.
- `ObjectRaycastHit` (interface): interface ObjectRaycastHit { instanceId: string; catalogId: string; distance: number; point: EntityPosition; normal: EntityPosition } — ⚠ undocumented
- `ObjectRaycastInput` (interface): interface ObjectRaycastInput { origin: EntityPosition; direction: EntityPosition; maxDistance: number; halfExtents?: EntityPosition; filter?: (object: SceneObject) => boolean } — ⚠ undocumented
- `ObjectRaycastSource` (type): type ObjectRaycastSource = readonly SceneObject[] | ObjectQueryBroadphase — ⚠ undocumented
- `intersectAabb` (function): function intersectAabb(origin: EntityPosition, direction: EntityPosition, min: EntityPosition, max: EntityPosition, maxDistance: number): { distance: number; normal: EntityPosition } | null — ⚠ undocumented
- `normalizeDirection` (function): function normalizeDirection(direction: EntityPosition): EntityPosition — ⚠ undocumented

## @jgengine/core/scene/objectStore

- `ObjectListFilter` (interface): interface ObjectListFilter { parentSpace?: string } — ⚠ undocumented
- `ObjectStore` (interface): interface ObjectStore { place(catalogId: string, x: number, y: number, z: number, options?: PlaceOptions): string; remove(instanceId: string): boolean; move(instanceId: string, x: number, y: number, z: number): boolean; rotate(instanceId: string, rotationY: numb… — ⚠ undocumented
- `ObjectVisual` (interface): interface ObjectVisual { scale?: number | readonly [number, number, number]; color?: string; opacity?: number } — ⚠ undocumented
- `PlaceOptions` (interface): interface PlaceOptions { instanceId?: string; parentSpace?: string; rotation?: number; visual?: ObjectVisual; state?: Record<string, unknown>; slots?: InventoryState; animation?: ModelAnimationConfig | "auto" | "none"; onExisting?: "throw" | "replace" | "keep" } — ⚠ undocumented
- `SceneObject` (interface): interface SceneObject { instanceId: string; catalogId: string; position: EntityPosition; rotationY: number; parentSpace?: string; visual?: ObjectVisual; animation?: ModelAnimationConfig | "auto" | "none"; state?: Record<string, unknown>; slots?: InventoryState } — ⚠ undocumented · used by `fromRuntimeObjectRow` (@jgengine/core/runtime/objectRows): Inverse of {@link toRuntimeObjectRow}: rebuild the live placed object a host persisted.
- `createObjectStore` (function): function createObjectStore(): ObjectStore — ⚠ undocumented
- `objectVisualScale` (function): function objectVisualScale(visual: ObjectVisual | undefined): readonly [number, number, number] — ⚠ undocumented

## @jgengine/core/scene/paintLayer

- `PaintLayer` (interface): interface PaintLayer { paint(instanceId: string, stroke: PaintStroke): void; strokes(instanceId: string): readonly PaintStroke[]; paintedIds(): readonly string[]; clear(instanceId?: string): void; version(instanceId: string): number; subscribe(listener: () => v… — ⚠ undocumented
- `PaintStroke` (interface): interface PaintStroke { u: number; v: number; radius: number; color: string } — ⚠ undocumented
- `createPaintLayer` (function): function createPaintLayer(): PaintLayer — ⚠ undocumented

## @jgengine/core/scene/possession

- `Possession` (interface): interface Possession { own(userId: string, entityId: string): void; disown(userId: string, entityId: string): void; owns(userId: string, entityId: string): boolean; ownerOf(entityId: string): string | undefined; listOwned(userId: string): readonly string[]; act… — ⚠ undocumented
- `PossessionDeps` (interface): interface PossessionDeps { entities: PossessionEntities; events?: PossessionEvents } — ⚠ undocumented
- `PossessionEntities` (interface): interface PossessionEntities { get(id: string): SceneEntity | null; update(id: string, patch: {role?: SceneEntity["role"]}): boolean } — ⚠ undocumented
- `PossessionEvents` (interface): interface PossessionEvents { emit(name: "possession.swapped", payload: PossessionSwappedEvent): void } — ⚠ undocumented
- `PossessionSnapshot` (interface): interface PossessionSnapshot { owned: Record<string, readonly string[]>; active: Record<string, string> } — ⚠ undocumented
- `PossessionSwappedEvent` (interface): interface PossessionSwappedEvent { userId: string; entityId: string; previousEntityId: string } — ⚠ undocumented
- `createPossession` (function): function createPossession(deps: PossessionDeps): Possession — ⚠ undocumented

## @jgengine/core/scene/roster

- `Roster` (interface): interface Roster { capture(userId: string, catalogId: string, options?: RosterCaptureOptions): RosterEntry; release(userId: string, entryId: string): boolean; has(userId: string, entryId: string): boolean; get(userId: string, entryId: string): RosterEntry |… — ⚠ undocumented
- `RosterCaptureOptions` (interface): interface RosterCaptureOptions { id?: string; capturedAt?: number } — ⚠ undocumented
- `RosterDeps` (interface): interface RosterDeps { now?: () => number } — ⚠ undocumented
- `RosterEntry` (interface): interface RosterEntry { id: string; catalogId: string; capturedAt: number; equipped: boolean } — ⚠ undocumented
- `createRoster` (function): function createRoster(deps: RosterDeps = {}): Roster — ⚠ undocumented

## @jgengine/core/scene/sceneKinds

- `ActionParamField` (interface): interface ActionParamField — A button row that runs a built-in inspector action on its group — currently `"randomize"` (reroll the group's numeric/seed/bool/select fields within their bounds) or `"reset"` (restore group defaults). Carries no persisted value; purely a control.
- `BoolParamField` (interface): interface BoolParamField — A checkbox.
- `ColorParamField` (interface): interface ColorParamField — A hex color picker.
- `NumberParamField` (interface): interface NumberParamField — A free numeric input, optionally clamped.
- `ParamField` (type): type ParamField = | RangeParamField | NumberParamField | BoolParamField | SelectParamField | ColorParamField | TextParamField | SeedParamField | WeightedListParamField | ActionParamField — One row in a kind's parameter schema — the union the generic inspector knows how to render.
- `ParamGroup` (interface): interface ParamGroup — A named, optionally-collapsed section the inspector groups fields under (by `field.group === id`).
- `ParamIssue` (interface): interface ParamIssue — One validation problem found by {@link validateParams}: which field and why.
- `ParamPreset` (interface): interface ParamPreset — A named slider/weight bundle for a kind — a saved set of field values the inspector (or the `apply_preset` verb) writes into an object's `meta` in one patch, ready to tweak afterwards. Presets are plain data on the schema, so kinds ship archetypes and games can override the registration with their own.
- `ParamSchema` (interface): interface ParamSchema — A kind's full parameter surface: an ordered list of fields the inspector renders top-to-bottom.
- `ParsedParams` (type): type ParsedParams = Record<string, number | boolean | string | WeightedParamEntry[]> — Parsed params after `parseParams`: every schema field present with a validated, defaulted value.
- `RangeParamField` (interface): interface RangeParamField — A numeric slider row: bounded range with a live readout.
- `SceneKindCoverage` (interface): interface SceneKindCoverage — Marks a kind as *scatterable* — it fills an authored area with instances at one density under a bounded budget — so the editor renders the shared `CoverageSection` (Area → Assets → Density slider + budget note) that gives grass/scatter/city one authoring gesture. `spec` selects the unit + budget from `@jgengine/core/world/scatterCoverage`; `densityKey` is the single density slider hoisted into the coverage header (and hidden from the schema body below); `assetsKey` is the optional weighted "what fills it" palette summarized in the header.
- `SceneKindDefinition` (interface): interface SceneKindDefinition<TResolved = unknown> — A registered scene kind — everything the editor/engine need to author and render a studio without bespoke code. `schema` drives the inspector + parse; `resolve` (optional) turns one document object into pure renderable data a matching `shell` renderer consumes; `add*` fields build the `+ Add` menu.
- `SceneKindObject` (interface): interface SceneKindObject — The raw document object a resolver receives — shape shared by markers, volumes, and paths.
- `SceneKindResolveContext` (interface): interface SceneKindResolveContext — Ground sampler + options a resolver may read (terrain height/normal snap).
- `SceneKindTarget` (type): type SceneKindTarget = "path" | "marker" | "volume" — Which document collection a scene kind lives in. Drives placement + which `meta` bag holds params.
- `ScenePathShape` (type): type ScenePathShape = "area" | "line" — A closed-polygon area vs an open polyline, for path-target kinds. Ignored for marker/volume kinds.
- `SeedParamField` (interface): interface SeedParamField — A seed string with a reroll button — same seed reproduces the same generated result.
- `SelectParamField` (interface): interface SelectParamField — A dropdown of fixed string options.
- `TextParamField` (interface): interface TextParamField — A free string input.
- `WeightedListParamField` (interface): interface WeightedListParamField — A repeatable list of weighted `{ item, weight }` rows (species palette, book set, …).
- `WeightedParamEntry` (interface): interface WeightedParamEntry — One weighted entry in a `weightedList` param — an item id and its relative spawn weight.
- `definePlaceableMarkerKind` (function): function definePlaceableMarkerKind(options: { kind: string; label: string; /** `+ Add` menu section header this kind groups under. Defaults to `"Custom"`. */ category?: string; /** Accent hex for the menu entry + inspector header. */ accent?: string; /** Optional inspector fields written into each m… — Declare a game's own **click-to-place** marker kind in one call — the light path for logical markers a game reads off the document by `kind` (a stash, checkpoint, spawn point, bounty…), with none of a full studio's schema/resolver boilerplate. Registering it makes the kind a click-to-place tool in the editor's `+ Add` menu (grouped under `category`) and gives its markers an inspector for any `fields` you pass. Call at module load from a module the editor loads (a game's `editorLayers` import graph). Rendering is unaffected — the game still reads `kind` off `editorLayers.markers`.
- `findSchemaPreset` (function): function findSchemaPreset(schema: ParamSchema, id: string): ParamPreset | undefined — Look up a schema preset by id, or undefined — the seam `apply_preset` and games resolve bundles through.
- `parseParams` (function): function parseParams(schema: ParamSchema, meta: Record<string, unknown> | undefined): ParsedParams — Parse a raw `meta` bag against a schema into typed params — every field present, invalid/missing values replaced by the field default, numbers clamped to their range. The single parser every studio shares instead of hand-writing its own `metaNumber`/`metaBool` ladder.
- `registerSceneKind` (function): function registerSceneKind<TResolved>(definition: SceneKindDefinition<TResolved>): void — Register a scene kind — the plug-in point for a new parametric studio. Idempotent per `kind` (last registration wins), so a game's registration overrides a default. Call at module load; the editor inspector, `+ Add` menu, and `AuthoredScene` renderer lookup all read this registry.

## @jgengine/core/scene/sceneRaycast

- `SceneEntityQuerySource` (interface): interface SceneEntityQuerySource { list(): readonly {id: string; position: EntityPosition; rotationY: number; name?: string}[]; collidersOf?(instanceId: string): EntityColliderSet | null | undefined; inRadius?(center: EntityPosition, radius: number): readonly string[]; get… — ⚠ undocumented
- `SceneObjectQuerySource` (interface): interface SceneObjectQuerySource { list(): readonly SceneObject[]; inBox?(min: EntityPosition, max: EntityPosition): readonly SceneObject[]; collidersOf?(instanceId: string): EntityColliderSet | null | undefined; halfExtentsOf?(catalogId: string): EntityPosition | null | u… — ⚠ undocumented
- `SceneRaycastApi` (interface): interface SceneRaycastApi { raycast(input: SceneRaycastInput): SceneRaycastHit | null; raycastAll(input: SceneRaycastInput): SceneRaycastHit[] } — ⚠ undocumented · used by `sceneCameraQuery` (@jgengine/shell/camera): `CameraCollisionQuery` over the scene's existing collision query (`ctx.scene.raycast`), which already reads world solids, scene-object colli…
- `SceneRaycastDeps` (interface): interface SceneRaycastDeps { entities?: SceneEntityQuerySource; objects?: SceneObjectQuerySource; terrain?: TerrainRaycastSource; walls?: readonly WallSegment[]; solids?: Pick<WorldSolids, "inBox" | "inRay"> } — ⚠ undocumented
- `SceneRaycastFilter` (interface): interface SceneRaycastFilter { entities?: boolean; objects?: boolean; terrain?: boolean; walls?: boolean } — ⚠ undocumented
- `SceneRaycastHit` (interface): interface SceneRaycastHit { targetKind: SceneRaycastTargetKind; instanceId: string; catalogId?: string; colliderName: string; purpose: ColliderPurpose; damageEligible: boolean; blocks: boolean; distance: number; point: EntityPosition; normal: EntityPosition } — ⚠ undocumented · used by `firstImpact`: First impact: nearest hit that blocks, or nearest hit if none block.
- `SceneRaycastInput` (interface): interface SceneRaycastInput { origin: EntityPosition; direction: EntityPosition; maxDistance: number; excludeInstanceIds?: ReadonlySet<string> | readonly string[]; filter?: SceneRaycastFilter; accept?: (hit: SceneRaycastHit) => boolean } — ⚠ undocumented
- `SceneRaycastTargetKind` (type): type SceneRaycastTargetKind = "entity" | "object" | "terrain" | "wall" — ⚠ undocumented
- `TerrainRaycastSource` (interface): interface TerrainRaycastSource { sampleHeight(x: number, z: number): number } — ⚠ undocumented
- `WallSegment` (interface): interface WallSegment { id: string; a: readonly [number, number]; b: readonly [number, number]; yCenter?: number; halfHeight?: number; thickness?: number } — ⚠ undocumented · used by `wallSolids` (@jgengine/core/world/worldSolids): One oriented solid per wall segment (see `wallSegments` in `world/walls`).
- `createSceneRaycast` (function): function createSceneRaycast(deps: SceneRaycastDeps): SceneRaycastApi — ⚠ undocumented
- `firstImpact` (function): function firstImpact(hits: readonly SceneRaycastHit[]): SceneRaycastHit | null — First impact: nearest hit that blocks, or nearest hit if none block.
- `hitsUntilBlocked` (function): function hitsUntilBlocked(hits: readonly SceneRaycastHit[]): SceneRaycastHit[] — Hits up to and including the first blocking collider (damage hitboxes before a wall stay).

## @jgengine/core/scene/selection

- `ScreenPoint` (interface): interface ScreenPoint { id: string; x: number; y: number } — ⚠ undocumented · used by `selectWithinRect`: Ids of the projected candidates whose screen point falls inside the marquee.
- `ScreenRect` (interface): interface ScreenRect { minX: number; minY: number; maxX: number; maxY: number } — ⚠ undocumented · used by `isMarquee`: True when the drag is large enough to be a marquee rather than a click.
- `SelectionSet` (interface): interface SelectionSet { add(id: string): void; remove(id: string): void; toggle(id: string): void; has(id: string): boolean; replace(ids: Iterable<string>): void; clear(): void; list(): string[]; size(): number } — ⚠ undocumented · used by `createSelectionSet`: An ordered, deduplicated set of selected instance ids for RTS unit-command routing.
- `createSelectionSet` (function): function createSelectionSet(initial?: Iterable<string>): SelectionSet — An ordered, deduplicated set of selected instance ids for RTS unit-command routing.
- `isMarquee` (function): function isMarquee(rect: ScreenRect, thresholdPx = 4): boolean — True when the drag is large enough to be a marquee rather than a click.
- `rectContainsPoint` (function): function rectContainsPoint(rect: ScreenRect, x: number, y: number): boolean — ⚠ undocumented
- `screenRect` (function): function screenRect(ax: number, ay: number, bx: number, by: number): ScreenRect — Normalize two drag corners (in any order) into a rectangle.
- `selectWithinRect` (function): function selectWithinRect(candidates: readonly ScreenPoint[], rect: ScreenRect): string[] — Ids of the projected candidates whose screen point falls inside the marquee.

## @jgengine/core/scene/selectionBookmarks

- `BookmarkRecallMode` (type): type BookmarkRecallMode = "replace" | "merge" — How a recalled bookmark folds into the active selection.
- `RecallBookmarkOptions` (interface): interface RecallBookmarkOptions — Caller hooks for {@link recallSelectionBookmark} — kept out of the store so focus and validity stay genre-owned.
- `SelectionBookmarkSnapshot` (interface): interface SelectionBookmarkSnapshot — The serializable shape of a {@link SelectionBookmarks} store: each key maps to its ordered, deduplicated id list. Plain data — safe to persist in a save file or replicate over the wire, and the exact input {@link createSelectionBookmarks} restores.
- `SelectionBookmarks` (interface): interface SelectionBookmarks — A generic, keyed store of saved id sets ("bookmarks") over stable string ids — the reusable layer under RTS control groups, camera bookmarks, saved squads, editor selection presets, and accessibility recall. It owns storage only: binding, recall, enumeration, pruning, and serialization. It never touches the active {@link SelectionSet} or the camera — replacement/merge and focus stay caller hooks (see {@link recallSelectionBookmark}) so one store serves any genre, input scheme, or focus policy.
- `SelectionPruneResult` (interface): interface SelectionPruneResult — Outcome of a {@link SelectionBookmarks.prune} pass — what the validity predicate removed.
- `createSelectionBookmarks` (function): function createSelectionBookmarks(snapshot?: SelectionBookmarkSnapshot): SelectionBookmarks — Create a keyed bookmark store, optionally restored from a {@link serialize} snapshot. Restoration re-dedupes and drops empty sets, so a hand-authored or migrated snapshot always normalizes to the same invariants a live store holds.
- `recallSelectionBookmark` (function): function recallSelectionBookmark(bookmarks: SelectionBookmarks, key: string, selection: SelectionSet, options: RecallBookmarkOptions = {}): string[] — Compose a bookmark recall onto an active {@link SelectionSet}: optionally prune stale ids (updating the stored bookmark), fold the survivors into the selection by `mode`, then fire the caller's focus hook. This is the one place the store, the selection, and the camera meet — kept as an explicit helper, not a store side effect, so games opt into the exact replacement/merge and focus policy they want. Returns the surviving ids that were applied.

## @jgengine/core/scene/sequenceDirector

- `CueListener` (type): type CueListener<Payload = unknown> = (emitted: EmittedCue<Payload>) => void — A cue listener, called once per cue as it fires. Returns nothing.
- `EmittedCue` (interface): interface EmittedCue<Payload = unknown> — A cue plus the resolved firing context passed to {@link SequenceDirector.onCue} listeners.
- `SequenceCue` (interface): interface SequenceCue<Payload = unknown> — One scheduled beat of a cutscene: a typed cue that fires when the playhead reaches `atMs`.
- `SequenceDirector` (interface): interface SequenceDirector<Payload = unknown> — A data-driven cutscene: an ordered timeline of typed cues that fire on a single injected clock. See {@link createSequenceDirector}.
- `SequenceDirectorOptions` (interface): interface SequenceDirectorOptions<Payload = unknown> — Options for {@link createSequenceDirector}.
- `SequenceSnapshot` (interface): interface SequenceSnapshot — Serializable snapshot — enough to resume a cutscene exactly where a save left it.
- `SequenceState` (interface): interface SequenceState — A read-only view of the director's playback state, returned by {@link SequenceDirector.state}.
- `createSequenceDirector` (function): function createSequenceDirector<Payload = unknown>(options: SequenceDirectorOptions<Payload>): SequenceDirector<Payload> — A serializable cutscene / sequence director: an ordered timeline of typed cues (`{ atMs, kind, payload }`) advanced by one injected clock, firing each cue once and in order as its time passes — even across a large seek — with play/pause/ seek/skip/stop controls. The director only *schedules and emits* cues; it never interprets what a `kind` means, so the same primitive drives camera moves, dialogue lines, fades, or any game event. `snapshot`/`restore` round-trip the playhead and which cues have fired. Deterministic (no wall clock beyond the injected `now`) and allocation-free on the tick path.

## @jgengine/core/scene/spatial

- `Aim` (type): type Aim = | { origin: EntityPosition; direction: EntityPosition } | { yaw: number; pitch: number; spread?: number } — ⚠ undocumented · used by `aimToPoint` (@jgengine/core/input/pointer): Build an `origin → point` aim for `item.use` / projectiles, firing toward the cursor.
- `MoveTowardOptions` (interface): interface MoveTowardOptions { speed: number; stopDistance?: number; dt: number; avoidSolids?: boolean } — ⚠ undocumented
- `QueryArcOptions` (interface): interface QueryArcOptions { from: string; aim: Aim; radius: number; halfAngleDeg?: number } — ⚠ undocumented
- `SpatialApi` (interface): interface SpatialApi { distance(aInstanceId: string, bInstanceId: string): number | null; inRadius(center: EntityPosition | string, radius: number, filter?: (instanceId: string) => boolean): string[]; hasLineOfSight(fromInstanceId: string, toInstanceId: string)… — ⚠ undocumented · used by `createSpatialApi`: Spatial queries with an optional notified incremental broadphase.
- `SpatialApiOptions` (interface): interface SpatialApiOptions { resolvePosition: (instanceId: string) => EntityPosition | undefined; candidates: () => readonly string[]; occluder?: (from: EntityPosition, to: EntityPosition) => boolean; grid?: SpatialGridOptions | false; getVersion?: () => number; incr… — ⚠ undocumented · used by `createSpatialApi`: Spatial queries with an optional notified incremental broadphase.
- `SpatialGridOptions` (interface): interface SpatialGridOptions { cellSize: number } — ⚠ undocumented
- `createSpatialApi` (function): function createSpatialApi(options: SpatialApiOptions): SpatialApi — Spatial queries with an optional notified incremental broadphase.
- `distanceBetween` (function): function distanceBetween(a: EntityPosition, b: EntityPosition): number — ⚠ undocumented

## @jgengine/core/scene/stationClaim

- `ClaimResult` (type): type ClaimResult = | { ok: true; station: Station } | { ok: false; reason: "unknown_vehicle" | "unknown_facet" | "station_taken" | "vehicle_full" } — ⚠ undocumented
- `SharedVehicleConfig` (interface): interface SharedVehicleConfig { id: string; kit: MountKit; stations: readonly Station[] } — ⚠ undocumented
- `Station` (interface): interface Station { id: string; facet: string; offset: readonly [number, number, number]; control?: boolean } — ⚠ undocumented
- `StationClaim` (class): class StationClaim — ⚠ undocumented
- `createStationClaim` (function): function createStationClaim(controller?: MountController): StationClaim — ⚠ undocumented

## @jgengine/core/scene/targeting

- `CycleTargetOptions` (interface): interface CycleTargetOptions { filter?: TargetFilter; direction?: "next" | "prev"; maxDistance?: number } — ⚠ undocumented
- `TargetFilter` (type): type TargetFilter = TargetRelation | "any" — ⚠ undocumented
- `TargetRelation` (type): type TargetRelation = "hostile" | "friendly" — ⚠ undocumented
- `Targeting` (interface): interface Targeting { setTarget(fromId: string, toId: string | null): void; getTarget(fromId: string): string | null; cycleTarget(fromId: string, options?: CycleTargetOptions): string | null; clearAll(instanceId: string): void } — ⚠ undocumented
- `TargetingOptions` (interface): interface TargetingOptions { candidates: () => string[]; classify?: (fromId: string, toId: string) => TargetRelation; orderBy?: (a: string, b: string) => number; distance?: (fromId: string, toId: string) => number | null } — ⚠ undocumented
- `createTargeting` (function): function createTargeting(options: TargetingOptions): Targeting — ⚠ undocumented

## @jgengine/core/scene/vehicleSeat

- `BoardVehicleOptions` (interface): interface BoardVehicleOptions extends EnterVehicleOptions — Seat selection and optional local camera policy for an explicit rider transition.
- `DismountOffset` (interface): interface DismountOffset — Where {@link VehicleSeats.exit} steps the rider out, relative to the vehicle's heading.
- `EnterVehicleOptions` (interface): interface EnterVehicleOptions — Options for {@link VehicleSeats.enter}.
- `EnterVehicleResult` (type): type EnterVehicleResult = | { ok: true; seat: MountSeat; /** Feed straight into `ctx.camera.follow(...)` — the vehicle while a control seat is taken, else the rider's own id. */ cameraTarget: string; /** Entity this rider's axis input should now drive (`scene/mount`'s `driveTarget`); `null` for a pa… — Result of {@link VehicleSeats.enter} — the resolved seat plus the camera/drive/movement patches to apply.
- `ExitVehicleResult` (type): type ExitVehicleResult = | { ok: true; vehicleId: string; /** Where to `setPose` the rider — alongside the vehicle's side door, facing its heading. */ placement: VehiclePose; cameraTarget: string; riderMovementPatch: RiderMovementPatch; } | { ok: false; reason: "not_seated" | "invalid_pose" } — Result of {@link VehicleSeats.exit} — the side-door placement plus the camera/movement patches to apply.
- `LeaveVehicleOptions` (interface): interface LeaveVehicleOptions extends DismountOffset — Exit placement and optional local camera restoration for an explicit rider.
- `RiderMovementPatch` (interface): interface RiderMovementPatch — Movement-lock patch for `entities.update(riderId, { movement: { ...current, ...patch } })` (#286.gameplay `movement.frozen`).
- `VehiclePose` (interface): interface VehiclePose — A vehicle's world-space position and heading, used for {@link VehicleSeats.exit}'s dismount placement math.
- `VehiclePosition` (type): type VehiclePosition = readonly [number, number, number] — World-space `[x, y, z]` for a vehicle's current position.
- `VehicleSeats` (class): class VehicleSeats — Composes `scene/mount`'s control-transfer bookkeeping with the seat/camera/movement-mode transition every enter/exit-vehicle flow needs (#533.2): boarding resolves a free seat and reports the camera target, drive target, and rider movement-lock patch in one call; leaving computes a side-door placement next to the vehicle and reports the same triad in reverse. Pure — no entity/camera side effects — the caller applies `riderMovementPatch`/`placement`/`cameraTarget` via its own `ctx`.
- `boardVehicle` (function): function boardVehicle(ctx: GameContext, seats: VehicleSeats, riderId: string, vehicleId: string, options: BoardVehicleOptions = {}): EnterVehicleResult — Apply an existing seat transition to the explicitly named rider. Motor/input policy stays caller-owned.
- `createVehicleSeats` (function): function createVehicleSeats(controller?: MountController): VehicleSeats — Builds a {@link VehicleSeats}, optionally over an existing `MountController` to share its occupancy.
- `leaveVehicle` (function): function leaveVehicle(ctx: GameContext, seats: VehicleSeats, riderId: string, options: LeaveVehicleOptions = {}): ExitVehicleResult | { ok: false; reason: "unknown_rider" | "unknown_vehicle" } — Apply dismount placement, restore rider movement/visibility and the configured camera rig.

## @jgengine/core/sensor/concealment

- `ColorHex` (type): type ColorHex = string — ⚠ undocumented
- `ConcealmentSample` (interface): interface ConcealmentSample { id: string; score: number; concealed: boolean; dwellSeconds: number } — ⚠ undocumented
- `ConcealmentSensor` (interface): interface ConcealmentSensor { tick(targets: readonly ConcealmentTarget[], dt: number): ConcealmentSample[]; reset(id?: string): void; snapshot(): ConcealmentSensorState; restore(next: ConcealmentSensorState): void } — ⚠ undocumented
- `ConcealmentSensorState` (interface): interface ConcealmentSensorState — Plain JSON state of a {@link ConcealmentSensor}: seconds each target has stayed concealed.
- `ConcealmentTarget` (interface): interface ConcealmentTarget { id: string; entityColors: readonly ColorHex[]; backgroundColors: readonly ColorHex[] } — ⚠ undocumented

## @jgengine/core/sensor/freezeMonitor

- `FreezeMonitor` (interface): interface FreezeMonitor { tick(subjects: readonly FreezeSubject[], frozenIds: ReadonlySet<string>, dt: number): FreezeViolation[]; reset(id?: string): void; snapshot(): FreezeMonitorState; restore(next: FreezeMonitorState): void } — ⚠ undocumented
- `FreezeMonitorState` (interface): interface FreezeMonitorState — Plain JSON state of a {@link FreezeMonitor}: seconds each frozen subject has kept moving.
- `FreezeSubject` (interface): interface FreezeSubject { id: string; groundSpeed: number } — ⚠ undocumented
- `FreezeViolation` (interface): interface FreezeViolation { id: string; speed: number; movedSeconds: number } — ⚠ undocumented

## @jgengine/core/sensor/frustumSensor

- `FramingConfig` (interface): interface FramingConfig { idealDistance?: number; centerWeight?: number; sizeWeight?: number } — ⚠ undocumented
- `FrustumCamera` (interface): interface FrustumCamera { position: EntityPosition; lookAt: EntityPosition; fovDeg?: number; aspect?: number; near?: number; far?: number } — ⚠ undocumented
- `FrustumProjection` (interface): interface FrustumProjection { inView: boolean; distance: number; screenX: number; screenY: number } — ⚠ undocumented
- `FrustumSample` (interface): interface FrustumSample { id: string; inView: boolean; distance: number; screenX: number; screenY: number; framing: number; dwellSeconds: number } — ⚠ undocumented
- `FrustumSensor` (interface): interface FrustumSensor { tick(camera: FrustumCamera, targets: readonly FrustumTarget[], dt: number): FrustumSample[]; reset(id?: string): void } — ⚠ undocumented
- `FrustumTarget` (interface): interface FrustumTarget { id: string; position: EntityPosition; radius?: number } — ⚠ undocumented

## @jgengine/core/sensor/hiddenStateProbe

- `HiddenStateSource` (interface): interface HiddenStateSource { id: string; position: EntityPosition; variables: Readonly<Record<string, HiddenStateValue>> } — ⚠ undocumented · used by `useHiddenStateProbe` (@jgengine/shell/vision/HiddenStateProbeHud): Reads a hidden zone/entity state variable in range (EMF / thermometer / geiger style sensor verb, #116).
- `HiddenStateValue` (type): type HiddenStateValue = number | string | boolean — ⚠ undocumented
- `SensorProbeOptions` (interface): interface SensorProbeOptions { range: number; variableId: string; falloff?: "linear" | "none" } — ⚠ undocumented · used by `useHiddenStateProbe` (@jgengine/shell/vision/HiddenStateProbeHud): Reads a hidden zone/entity state variable in range (EMF / thermometer / geiger style sensor verb, #116).
- `SensorReading` (interface): interface SensorReading { sourceId: string; variableId: string; value: HiddenStateValue; strength: number; distance: number } — ⚠ undocumented · used by `useHiddenStateProbe` (@jgengine/shell/vision/HiddenStateProbeHud): Reads a hidden zone/entity state variable in range (EMF / thermometer / geiger style sensor verb, #116).

## @jgengine/core/sensor/perception

- `PerceptionCandidate` (interface): interface PerceptionCandidate — A candidate target considered by a sight check.
- `PerceptionConfig` (interface): interface PerceptionConfig — Configuration for sight, hearing, memory decay, squad sharing and optional occlusion.
- `PerceptionMemory` (interface): interface PerceptionMemory — A remembered target and its linearly decaying confidence.
- `PerceptionObserver` (interface): interface PerceptionObserver — The observer pose used for a sight check.
- `PerceptionPosition` (type): type PerceptionPosition = readonly [number, number, number] — A world position used by perception, in `[x, y, z]` order.
- `PerceptionService` (interface): interface PerceptionService — Stateful perception API with retuning and save/restore support.
- `PerceptionSnapshot` (interface): interface PerceptionSnapshot — Serializable state for a perception service.
- `PerceptionStats` (interface): interface PerceptionStats — Counters a perf test or a devtools probe reads. Reset with {@link PerceptionService.resetStats}.
- `PerceptionStimulus` (interface): interface PerceptionStimulus — An event that can seed an observer's memory.
- `PerceptionStimulusKind` (type): type PerceptionStimulusKind = "sight" | "sound" | "damage" — The kinds of stimulus the perception service can retain.
- `createPerception` (function): function createPerception(initial: PerceptionConfig): PerceptionService — Creates a deterministic sight, sound, and damage perception service with expiring target memory. Signals are judged in the order the caller supplies them, never from the wall clock.

## @jgengine/core/sensor/recordingBuffer

- `RecordingBuffer` (interface): interface RecordingBuffer<T> { append(t: number, data: T): void; seek(t: number): RecordingFrame<T> | null; seekPair(t: number): RecordingPair<T>; range(fromT: number, toT: number): RecordingFrame<T>[]; clear(): void; duration(): number; frames(): readonly RecordingFra… — ⚠ undocumented · used by `useSessionRecorder` (@jgengine/shell/replay/useSessionRecorder): Session-recording buffer (#120) for replay / photo mode / kill-cam: records an entity's pose on game-time every frame into a `RecordingBuffe…
- `RecordingBufferOptions` (interface): interface RecordingBufferOptions { maxDurationSeconds?: number; maxFrames?: number } — ⚠ undocumented · used by `useSessionRecorder` (@jgengine/shell/replay/useSessionRecorder): Session-recording buffer (#120) for replay / photo mode / kill-cam: records an entity's pose on game-time every frame into a `RecordingBuffe…
- `RecordingFrame` (interface): interface RecordingFrame<T> { t: number; data: T } — ⚠ undocumented
- `RecordingPair` (interface): interface RecordingPair<T> { before: RecordingFrame<T> | null; after: RecordingFrame<T> | null } — ⚠ undocumented

## @jgengine/core/sensor/replayLoop

- `RecordedPoseLike` (interface): interface RecordedPoseLike { position: readonly [number, number, number]; rotationY?: number } — ⚠ undocumented
- `ReplayEntityDeps` (interface): interface ReplayEntityDeps { has(id: string): boolean; spawn(id: string): void; setPose(id: string, pose: {position: readonly [number, number, number]; rotationY?: number; dt?: number}): unknown; despawn(id: string): unknown } — ⚠ undocumented
- `ReplayLoop` (interface): interface ReplayLoop<T> — Replays a finished `RecordingBuffer` on a loop — modulo-time seek, frame interpolation, and spawn grace, the pieces every ghost-lap/echo feature hand-rolled (#286.4). `sample(t)` is a pure function of absolute time; `null` means "the ghost isn't on track right now".
- `ReplayLoopOptions` (interface): interface ReplayLoopOptions<T> { interpolate?: (before: T, after: T, alpha: number) => T; spawnGraceSeconds?: number } — ⚠ undocumented

## @jgengine/core/sensor/revealQuery

- `RevealHit` (interface): interface RevealHit { instanceId: string; distance: number; tags: readonly string[] } — ⚠ undocumented · used by `useRevealHits` (@jgengine/shell/vision/RevealVision): Occlusion-ignoring tagged-entity radius query (#115), bound to the live scene.
- `RevealQuery` (interface): interface RevealQuery { inRadius(center: EntityPosition | string, radius: number, tags: readonly string[]): RevealHit[] } — ⚠ undocumented
- `RevealQueryOptions` (interface): interface RevealQueryOptions { resolvePosition: (instanceId: string) => EntityPosition | undefined; resolveTags: (instanceId: string) => readonly string[]; candidates: () => string[] } — ⚠ undocumented

## @jgengine/core/sensor/visionCone

- `VisionCone` (interface): interface VisionCone — The guard-sight primitive every stealth game hand-rolled: an angle+range cone on the XZ plane whose sight lines are blocked by 2D wall segments (`world/walls` segments fit structurally). Pure math — feed entity positions and heading each tick.
- `VisionConeConfig` (interface): interface VisionConeConfig { range: number; angle: number } — ⚠ undocumented
- `VisionPoint` (type): type VisionPoint = readonly [number, number] — ⚠ undocumented
- `VisionTarget` (interface): interface VisionTarget<TId extends string = string> { id: TId; at: VisionPoint } — ⚠ undocumented
- `VisionWall` (interface): interface VisionWall — Structurally matches `world/walls` `WallSegment` — pass those straight in as occluders.

## @jgengine/core/time/accrueSince

- `Accrual` (interface): interface Accrual — Elapsed duration and the next anchor to persist with accrued effects.
- `accrueSince` (function): function accrueSince(anchorMs: number, nowMs: number, options: { capMs?: number } = {}): Accrual — Elapsed time since a persisted anchor, capped once; persist anchorMs with the accrued result.

## @jgengine/core/time/beatClock

- `BeatAccuracyTier` (interface): interface BeatAccuracyTier { id: string; windowSec: number } — ⚠ undocumented
- `BeatClock` (interface): interface BeatClock { advance(gameDt: number): BeatSnapshot; snapshot(): BeatSnapshot; now(): number; beatDurationSec(): number; bpm(): number } — ⚠ undocumented
- `BeatClockConfig` (interface): interface BeatClockConfig { bpm: number; beatsPerBar?: number } — ⚠ undocumented
- `BeatInputBuffer` (interface): interface BeatInputBuffer<T> { buffer(action: T, nowSec: number): number; advance(nowSec: number): T[]; pendingCount(): number; clear(): void } — ⚠ undocumented
- `BeatJudgement` (interface): interface BeatJudgement { tier: string; deltaSec: number } — ⚠ undocumented
- `BeatSnapshot` (interface): interface BeatSnapshot { beat: number; beatIndex: number; bar: number; beatInBar: number; phase: number } — ⚠ undocumented
- `BufferedAction` (interface): interface BufferedAction<T> { action: T; bufferedAtSec: number; fireAtSec: number } — ⚠ undocumented
- `DEFAULT_BEAT_TIERS` (const): const DEFAULT_BEAT_TIERS: readonly BeatAccuracyTier[] — ⚠ undocumented

## @jgengine/core/time/calendarClock

- `GameTime` (interface): interface GameTime { year: number; month: number; monthName: string; monthNameFull: string; dayOfMonth: number; hour: number; minute: number; second: number; formattedDate: string; formattedDateFull: string; formattedTime: string; formatted: string } — ⚠ undocumented

## @jgengine/core/time/dayNightCycle

- `DayNightCycle` (interface): interface DayNightCycle — A running, observable, serializable day-night cycle. A presenter renders `sample()`.
- `DayNightCycleOptions` (interface): interface DayNightCycleOptions — Options for {@link createDayNightCycle}.
- `DayNightKeyframe` (interface): interface DayNightKeyframe — Turnkey day-night cycle: one serializable brain that advances a normalized day fraction on an injected clock and blends per-keyframe phase labels and tint/light colors. A game wires this one model and drives an existing sky/daylight seam from `sample()` instead of hand-rolling a clock plus a color lerp.
- `DayNightSample` (interface): interface DayNightSample — The interpolated day-night look at a moment: day fraction, active phase, and blended colors.
- `DayNightSnapshot` (interface): interface DayNightSnapshot — Serializable day-night position — accumulated clock offset, pause state, and speed — for save/load.
- `createDayNightCycle` (function): function createDayNightCycle(options: DayNightCycleOptions): DayNightCycle — Creates a turnkey day-night cycle: a serializable model that advances a normalized day fraction on an injected clock and blends per-keyframe phase labels and tint/light colors. Wire this one model, then drive an existing sky/daylight seam from `sample()` (or drop it straight into a `{ calendar(): { dayFraction } }` seam via `calendar()`) to get a moving day-night cycle with color grading — no hand-rolled clock or lerp. `phase` labels and colors are free-form; the model never interprets their meaning.

## @jgengine/core/time/gameClock

- `DEFAULT_TIME_SCALE` (const): const DEFAULT_TIME_SCALE: 24 — Simulation clock: real time scaled into game time, plus the derived game-day counter.
- `SECONDS_PER_GAME_DAY` (const): const SECONDS_PER_GAME_DAY: number — ⚠ undocumented
- `computeGameDay` (function): function computeGameDay(createdAt: number, now: number = Date.now(), timeScale?: number | null): number — ⚠ undocumented
- `getCurrentGameTimestamp` (function): function getCurrentGameTimestamp(createdAt: number, now: number, timeScale?: number | null): number — ⚠ undocumented
- `getScaledElapsedMs` (function): function getScaledElapsedMs(createdAt: number, now: number, timeScale?: number | null): number — ⚠ undocumented
- `sanitizeGameTimeScale` (function): function sanitizeGameTimeScale(timeScale?: number | null): number — ⚠ undocumented

## @jgengine/core/time/idleProgress

- `ExponentialCatchUpInput` (interface): interface ExponentialCatchUpInput { current: number; factorPerSecond: number; min?: number; max?: number } — ⚠ undocumented
- `IdleWindow` (interface): interface IdleWindow { elapsedSeconds: number; effectiveSeconds: number; capped: boolean } — ⚠ undocumented
- `IdleWindowConfig` (interface): interface IdleWindowConfig { maxSeconds?: number; efficiency?: number } — ⚠ undocumented
- `LinearCatchUpInput` (interface): interface LinearCatchUpInput { current: number; ratePerSecond: number; min?: number; max?: number } — ⚠ undocumented
- `SteppedCatchUpResult` (interface): interface SteppedCatchUpResult { steps: number; remainderSeconds: number } — ⚠ undocumented

## @jgengine/core/time/rateWindow

- `RateWindowDecision` (interface): interface RateWindowDecision — Admission result, next stored timestamps, and wait before retrying.
- `RateWindowPolicy` (interface): interface RateWindowPolicy — Maximum accepted operations in a sliding duration.
- `decideRateWindow` (function): function decideRateWindow(timestamps: readonly number[], nowMs: number, policy: RateWindowPolicy): RateWindowDecision — A sliding rate window; persist timestamps only alongside the accepted operation.

## @jgengine/core/time/serverTick

- `PlanServerTickOptions` (type): type PlanServerTickOptions = { /** Cap catch-up runs per system per heartbeat to avoid spiral-of-death. Default 3. */ maxCatchUp?: number; } — ⚠ undocumented · used by `planServerTick`: Decides which systems a heartbeat should run.
- `ServerTickPlan` (interface): interface ServerTickPlan<TSystemId extends string = string> { due: TickSystemRun<TSystemId>[]; anchors: TickAnchors } — ⚠ undocumented · used by `planServerTick`: Decides which systems a heartbeat should run.
- `TickAnchors` (type): type TickAnchors = Record<string, number> — Last-run timestamp per system id.
- `TickSystemDefinition` (interface): interface TickSystemDefinition<TSystemId extends string = string> { id: TSystemId; intervalMs: number; scope?: "onlinePlayers" | "allServers"; batchSize?: number } — ⚠ undocumented · used by `planServerTick`: Decides which systems a heartbeat should run.
- `TickSystemRun` (interface): interface TickSystemRun<TSystemId extends string = string> — One due system and how many times this heartbeat owes it.
- `planServerTick` (function): function planServerTick<TSystemId extends string>(systems: readonly TickSystemDefinition<TSystemId>[], anchors: TickAnchors, now: number, options?: PlanServerTickOptions): ServerTickPlan<TSystemId> — Decides which systems a heartbeat should run. A system with no anchor runs immediately. When wall time stalls past multiple intervals the system's `runs` climbs (bounded by maxCatchUp), and the returned anchor moves by that many intervals — so a host that ignores `runs` loses the catch-up work. Excess lag past the bound resyncs the anchor to `now`. Returned anchors carry only systems present in the pipeline, so removed systems clean up.
- `tickRunCount` (function): function tickRunCount<TSystemId extends string>(plan: ServerTickPlan<TSystemId>, id: TSystemId): number — Times this plan owes `id`, or 0 when it is not due. Saves a host a lookup over {@link ServerTickPlan.due}.

## @jgengine/core/time/simClock

- `CalendarTime` (interface): interface CalendarTime { totalSeconds: number; day: number; hour: number; minute: number; second: number; dayFraction: number; year: number; dayOfYear: number; yearFraction: number; season?: string } — ⚠ undocumented
- `ClockSnapshot` (interface): interface ClockSnapshot { now: number; paused: boolean; speed: number; playSpeed: number; timescale: number; scale: number; speeds: readonly number[]; calendar: CalendarTime } — ⚠ undocumented
- `SimClock` (interface): interface SimClock { advance(realDt: number): number; now(): number; advancedSeconds?(): number; snapshot(): ClockSnapshot; hydrate(snapshot: ClockSnapshot): void; calendar(): CalendarTime; isPaused(): boolean; speed(): number; pause(): void; play(): void; to… — ⚠ undocumented · used by `createSimContext` (@jgengine/core/runtime/simContext): Build `ctx.sim` for a context; `createGameContext` calls this from `definition.simulation`.
- `SimClockOptions` (interface): interface SimClockOptions { config?: TimeConfig; onChange?: () => void } — ⚠ undocumented
- `TimeConfig` (interface): interface TimeConfig { scale?: number; speeds?: readonly number[]; dayLength?: number; start?: number; startPaused?: boolean; daysPerYear?: number; seasons?: readonly string[] } — ⚠ undocumented
- `createSimClock` (function): function createSimClock(options: SimClockOptions = {}): SimClock & { advancedSeconds(): number } — ⚠ undocumented

## @jgengine/core/time/stateSchedule

- `ClearWindowScan` (interface): interface ClearWindowScan { fromSeconds: number; horizonSeconds: number; stepSeconds: number; minDurationSeconds?: number } — ⚠ undocumented · used by `nextClearWindow`: Forward-scan any predicate-of-time — a timetable mover's "is the crossing clear at `t`" — for the next open window.
- `SchedulePhase` (interface): interface SchedulePhase<T> { state: T; durationSeconds: number } — ⚠ undocumented
- `ScheduleSample` (interface): interface ScheduleSample<T> { state: T; index: number; elapsedSeconds: number; remainingSeconds: number; fraction: number } — ⚠ undocumented
- `ScheduleWindow` (interface): interface ScheduleWindow { start: number; end: number } — ⚠ undocumented · used by `nextClearWindow`: Forward-scan any predicate-of-time — a timetable mover's "is the crossing clear at `t`" — for the next open window.
- `StateSchedule` (interface): interface StateSchedule<T> — A deterministic timeline of states — position-in-schedule is a pure function of absolute time, so a forecast preview and the live state can never disagree. One primitive behind zoned weather shifts, hazard cycles, and timetabled machinery: `stateAt`/`sampleAt` for the live state, `nextTransitionAt` for countdowns, `windowsOf`/`nextWindow` for "when is it safe" forecasts.
- `StateScheduleConfig` (interface): interface StateScheduleConfig<T> { phases: readonly SchedulePhase<T>[]; loop?: boolean; offsetSeconds?: number } — ⚠ undocumented
- `createStateSchedule` (function): function createStateSchedule<T>(config: StateScheduleConfig<T>): StateSchedule<T> — ⚠ undocumented
- `nextClearWindow` (function): function nextClearWindow(isClear: (t: number) => boolean, scan: ClearWindowScan): ScheduleWindow | null — Forward-scan any predicate-of-time — a timetable mover's "is the crossing clear at `t`" — for the next open window. Sampling-based: pick `stepSeconds` at or below half the shortest gap that matters.

## @jgengine/core/time/timerSet

- `TimerDirection` (type): type TimerDirection = "down" | "up" — A serializable set of named countdown / countup timers evaluated against an injected clock. One primitive covers round timers, respawn clocks, and ability cooldown/charge — they are the same mechanic (elapsed vs. duration on a clock), so `id` and any labels are free strings the engine never interprets.
- `TimerExpiryListener` (type): type TimerExpiryListener = (id: string) => void — Listener notified when a timer newly expires. Receives the timer id.
- `TimerRead` (interface): interface TimerRead — A single timer's resolved state for one read. All fields are plain numbers so a HUD can render without touching the model. For a looping timer the values describe the current cycle; `expired` is only ever `true` for a finished non-looping timer (loops signal completion through {@link TimerSet.poll}).
- `TimerSet` (interface): interface TimerSet — A named set of countdown / countup timers on an injected clock. Start, pause, resume, stop, reset, and read timers by free-string id; observe structural changes with {@link TimerSet.subscribe} and expiry edges with {@link TimerSet.poll} / {@link TimerSet.onExpire}.
- `TimerSetOptions` (interface): interface TimerSetOptions — Options for {@link createTimerSet}.
- `TimerSetSnapshot` (interface): interface TimerSetSnapshot — Serializable state of a whole {@link TimerSet}.
- `TimerSnapshot` (interface): interface TimerSnapshot — One timer's serializable state — elapsed resolved at snapshot time, ready to re-anchor on restore.
- `TimerStartOptions` (interface): interface TimerStartOptions — Options for {@link TimerSet.start}.
- `createTimerSet` (function): function createTimerSet(options: TimerSetOptions = {}): TimerSet — Create a serializable set of named countdown / countup timers on an injected clock — one primitive for round timers, respawn clocks, and ability cooldown/charge. Start/pause/resume/stop/reset timers by free-string id, read `{ remainingMs, elapsedMs, durationMs, progress01, running, expired }` for a mm:ss readout or a radial/bar fill, and `poll` for expiry edges. Ids and labels carry no genre meaning; `snapshot`/`restore` round-trip through a save.

## @jgengine/core/vfx/cameraShake

- `CameraShakeConfig` (interface): interface CameraShakeConfig — Configuration for {@link createCameraShake}. Every field has a game-feel default.
- `CameraShakeController` (interface): interface CameraShakeController — A live, dt-driven, trauma-based camera shake controller.
- `CameraShakeOffset` (interface): interface CameraShakeOffset — A per-frame camera shake offset: three positional axes plus three rotational axes (radians).
- `CameraShakeSnapshot` (interface): interface CameraShakeSnapshot — Serializable state for save/restore and deterministic replay.
- `createCameraShake` (function): function createCameraShake(config: CameraShakeConfig = {}): CameraShakeController — A seeded, serializable, trauma-based camera shake / impulse controller. A game calls `add(amount, kind?)` on impacts (a hit, an explosion, a landing) to raise trauma in `[0, 1]`; `update(dt)` bleeds it off over time; and `offset()` returns a pooled `{ x, y, z, pitch, yaw, roll }` kick equal to `trauma^exponent` times per-axis maxima times deterministic seeded value-noise sampled along an internal time cursor. A shell consumer applies that offset to the active camera each frame so the view visibly shakes. Nothing here is genre-specific: `kind` is a free label the game styles, all amplitudes/decay are parameters, and `snapshot`/ `restore` round-trips the shake through a save. Deterministic from `seed`: the same seed and dt sequence reproduce the same offsets.

## @jgengine/core/vfx/damageDirection

- `DamageDirectionOptions` (interface): interface DamageDirectionOptions — Options for {@link createDamageDirectionTracker}.
- `DamageDirectionSnapshot` (interface): interface DamageDirectionSnapshot — Serializable state for save/restore — the clock reading plus every live indicator.
- `DamageDirectionTracker` (interface): interface DamageDirectionTracker — A serializable, allocation-aware brain that tracks where recent damage came from. Each registered hit becomes a directional indicator that fades over a fixed duration on the injected clock; {@link DamageDirectionTracker.active} reports the live ones with their eased current strength.
- `DamageIndicator` (interface): interface DamageIndicator — A live directional indicator with its eased, time-decayed strength, produced by {@link DamageDirectionTracker.active}. The `intensity` here is the *current* eased value (peak faded over the elapsed lifetime), ready to drive opacity/scale.
- `HitInput` (interface): interface HitInput — A single incoming hit to register on a {@link DamageDirectionTracker}. The angle is relative to the player's facing (renderer-agnostic): `0` points at the front/top of the reticle and increases clockwise, so a game passes the bearing from the player toward the attacker without knowing anything about the screen.
- `createDamageDirectionTracker` (function): function createDamageDirectionTracker(options: DamageDirectionOptions = {}): DamageDirectionTracker — Create a damage-direction tracker: the classic "hit-from" feedback brain. A game calls `registerHit({ angle, intensity, kind })` with the bearing from the player toward the attacker (radians, `0` = front) and the tracker owns the fade timers and eased strength so the renderer just draws an arc per `active()` entry. It is renderer-free and genre-agnostic (the `kind` tag is never interpreted here), allocation-aware (a fixed pool, no per-frame garbage), and fully serializable via `snapshot`/`restore`. Optional angle merging collapses a burst from one direction into a single strong arc.

## @jgengine/core/vfx/effectLibrary

- `DEFAULT_EFFECT` (const): const DEFAULT_EFFECT: "sparks/weld" — The fallback effect used when a play call names an unknown effect — a typo still shows a spark.
- `EFFECT_LIBRARY` (const): const EFFECT_LIBRARY: readonly ParticleEffect[] — The shared library of named particle effects: fire, smoke, sparks, dust, splashes, muzzle flash, explosions, magic and weather. Each entry is authored parameters only — rate, lifetime, size, colour and the sprite texture — so a game calls `ctx.particles.play("explosion/core", at)` and the editor authors the same name instead of hand-tuning an `EmitterConfig`. Names are the contract; a config retune here changes every consumer deliberately.
- `EFFECT_PRIORITY` (const): const EFFECT_PRIORITY: { readonly weather: 20; readonly dust: 40; readonly smoke: 60; readonly magic: 70; readonly sparks: 70; readonly fire: 80; readonly splash: 80; readonly muzzle: 90; readonly explosion: 90; } — Ambient dressing drops first, then gameplay-loud effects last.
- `EffectGroup` (type): type EffectGroup = | "fire" | "smoke" | "sparks" | "dust" | "splash" | "muzzle" | "explosion" | "magic" | "weather" — The family an effect belongs to; groups the library browser and the contact sheet.
- `EffectOverride` (interface): interface EffectOverride — Per-call overrides merged over a library effect; each field wins over the authored default.
- `EffectTexture` (type): type EffectTexture = "soft" | "spark" | "flake" | "flame" | "smoke" | "ribbon" | "ring" — The procedural sprite family a particle draws with on the GPU path. Each family maps to a {@link ParticleRenderHint} shape: `soft` puffs, velocity-stretched `spark` streaks, `flake` crystals, `flame` tongues, `smoke` puffs, connected `ribbon` trails and flat `ring` ripples. There is no image file to load or credit — the field is the authored name for the sprite.
- `ParticleEffect` (interface): interface ParticleEffect — One named effect a game or the editor plays by name. Every field is data: the `config` is the same `EmitterConfig` a hand-authored emitter uses, so a library effect serializes, retunes and renders on the existing pooled GPU path without a second implementation.
- `ResolvedEffect` (interface): interface ResolvedEffect — A library effect resolved into the exact data the director and renderer consume.
- `effectNames` (function): function effectNames(): readonly string[] — Every library effect name, for editor pickers and runtime discovery.
- `findEffect` (function): function findEffect(name: string): ParticleEffect | undefined — The named effect, or `undefined` when the name is not in the library.
- `resolveEffect` (function): function resolveEffect(name: string, override?: EffectOverride): ResolvedEffect — Resolve a named effect into concrete emitter data, with any `override` winning field by field. An unknown name resolves to {@link DEFAULT_EFFECT} rather than throwing, so a typo shows *something*; call {@link findEffect} when the caller must reject an unknown name.

## @jgengine/core/vfx/feedbackMixer

- `FeedbackCurve` (type): type FeedbackCurve = readonly (readonly [number, number])[] — Piecewise-linear map from a signal value to an output value; points in ascending input order, ends clamp.
- `FeedbackEvent` (interface): interface FeedbackEvent<TSignal extends string> — A one-shot fired when a signal crosses a threshold (landing thud, gear-change clunk, impact rumble).
- `FeedbackMixer` (interface): interface FeedbackMixer<TSignal extends string, TTarget extends string> — Maps sim telemetry to presentation parameters through declared routes, curves and smoothing.
- `FeedbackMixerConfig` (interface): interface FeedbackMixerConfig<TSignal extends string, TTarget extends string> — Config for {@link createFeedbackMixer}.
- `FeedbackMixerState` (interface): interface FeedbackMixerState — Serializable mixer state: smoothed route values, last signal per event, and event cooldowns.
- `FeedbackRoute` (interface): interface FeedbackRoute<TSignal extends string, TTarget extends string> — One wire from a sim signal to a named output.
- `createFeedbackMixer` (function): function createFeedbackMixer<TSignal extends string, TTarget extends string>(initial: FeedbackMixerConfig<TSignal, TTarget>): FeedbackMixer<TSignal, TTarget> — Creates a {@link FeedbackMixer}: the one place a game declares how sim telemetry drives presentation — rpm to engine pitch, tire saturation to squeal and rumble, speed to FOV, landing speed to a thud — instead of hand-writing that glue per vehicle, aircraft or weapon. Deterministic, allocation-free per update.
- `sampleFeedbackCurve` (function): function sampleFeedbackCurve(curve: FeedbackCurve | undefined, x: number): number — Sample a {@link FeedbackCurve}; an empty curve is the identity.

## @jgengine/core/vfx/particleBudget

- `ParticleBudgetEntry` (interface): interface ParticleBudgetEntry — The graphics-tier particle budget. A tier caps the live particle count across every effect on screen; when the requested effects do not fit, whole effects are dropped in a defined order (lowest {@link ParticleBudgetEntry.priority} first) rather than every effect thinning out.
- `ParticleBudgetGrant` (interface): interface ParticleBudgetGrant — An admitted effect and the particles it may hold.
- `ParticleBudgetPlan` (interface): interface ParticleBudgetPlan — What the tier cap admits, and what it drops.
- `planParticleBudget` (function): function planParticleBudget(entries: readonly ParticleBudgetEntry[], cap: number): ParticleBudgetPlan — Allocate a tier's particle cap across the effects that want it.

## @jgengine/core/vfx/particleDirector

- `EffectRequest` (interface): interface EffectRequest extends EffectOverride — A library effect played by name: where it plays, plus per-call overrides.
- `ParticleAttachOptions` (interface): interface ParticleAttachOptions — Options for {@link ParticleDirector.attach}.
- `ParticleBlendHint` (type): type ParticleBlendHint = "additive" | "normal" — How a particle effect composites on screen: `additive` for sparks/fire/glow, `normal` for smoke/dust.
- `ParticleBurst` (interface): interface ParticleBurst — A one-shot burst request — consumed once by the renderer, never serialized.
- `ParticleCollisionEffect` (interface): interface ParticleCollisionEffect — A bounded collision child effect; children cannot spawn further collision children.
- `ParticleDirector` (interface): interface ParticleDirector — The game-side seam for particle effects. Game logic requests one-shot bursts and standing emitters as plain data; the shell renders them through `createParticleSystem`/`ParticleField`, applies the graphics-quality particle cap, and tracks `follow` entities. Nothing here touches a renderer, so commands and `onTick` systems can drive VFX headlessly and tests can assert the requested effects.
- `ParticleDirectorEvent` (interface): interface ParticleDirectorEvent extends ParticleEvent — A cosmetic simulation event, labelled with its emitting effect.
- `ParticleDirectorOptions` (interface): interface ParticleDirectorOptions — Bounded storage policy for transient effects and event exchange.
- `ParticleDirectorState` (interface): interface ParticleDirectorState — Serializable director state: the standing emitters (bursts are transient by nature).
- `ParticleEmitterSpec` (interface): interface ParticleEmitterSpec extends ParticleAttachOptions — A keyed continuous emitter owned by the director until detached.
- `ParticleRenderHint` (interface): interface ParticleRenderHint — Render output selected independently of particle spawn and simulation.
- `createParticleDirector` (function): function createParticleDirector(options: ParticleDirectorOptions = {}): ParticleDirector — Create the particle intent registry a `GameContext` exposes as `ctx.particles`. State is data-only and serializable: standing emitters survive `snapshot`/`restore`, queued bursts are transient. The renderer subscribes, drains bursts, and mirrors the emitter list — the director never allocates particle pools itself.
- `validateParticleAttachOptions` (function): function validateParticleAttachOptions(value: unknown): string[] — Validate serializable binding, output, and bounded collision-child descriptors.

## @jgengine/core/vfx/particles

- `Curve` (interface): interface Curve — A per-life start→end curve (linear interpolation from birth to death).
- `EmitterConfig` (interface): interface EmitterConfig — A particle emitter: how particles spawn and how each one evolves over its life. Every field is data — no functions — so an emitter is fully serializable and an editor/tunable can drive it. Genre-agnostic: smoke, sparks, rain, magic, dust.
- `ParticleBuffers` (interface): interface ParticleBuffers — Read-only packed buffers of the live particles, laid out for a renderer to upload directly (Structure-of-Arrays, no per-particle objects). Only the first `count` entries are live; the arrays themselves are reused every frame.
- `ParticleCollisionConfig` (interface): interface ParticleCollisionConfig — Bounded particle contact policy; a query adapter can replace the fallback horizontal plane.
- `ParticleCollisionHit` (interface): interface ParticleCollisionHit — One contact from an injected scene query, in simulation coordinates.
- `ParticleEvent` (interface): interface ParticleEvent — Presentation events never authorize gameplay damage or physical impulses.
- `ParticleSnapshot` (interface): interface ParticleSnapshot — Serializable simulation state for save/restore and deterministic replay.
- `ParticleSpawnShape` (interface): interface ParticleSpawnShape — Serializable spawn volume in emitter coordinates; cone widens from its base along +Y.
- `ParticleSystem` (interface): interface ParticleSystem — A live, dt-driven particle simulation.
- `ParticleSystemOptions` (interface): interface ParticleSystemOptions — Optional geometry adapter; queries are capped independently of rendering.
- `Range` (interface): interface Range — A `[min, max]` range a spawned particle draws uniformly from.
- `Vec3` (type): type Vec3 = readonly [number, number, number] — A 3D vector `[x, y, z]`.
- `createParticleSystem` (function): function createParticleSystem(config: EmitterConfig = {}, options: ParticleSystemOptions = {}): ParticleSystem — A generic, allocation-aware particle system: one emitter, a fixed pool, and Structure-of-Arrays buffers a renderer uploads straight to the GPU. It is dt-driven (call `update(dt)` each frame) and deterministic — all randomness flows from an injected `seed`, so the same seed and dt sequence reproduce the same frames, and `snapshot`/`restore` round-trips the live pool. Nothing here is combat- or genre-specific: configure it for smoke, sparks, rain, dust, embers, magic, or confetti. Travel/gameplay stays elsewhere; this owns only the spawn-integrate-fade lifecycle.
- `validateEmitterConfig` (function): function validateEmitterConfig(value: unknown): string[] — Validate the serializable spawn/update descriptor before authoring or loading it.

## @jgengine/core/vfx/screenEffects

- `ScreenEffect` (interface): interface ScreenEffect — A live effect in the current composite: its label, color, region, and the eased opacity `0..1` to draw *right now*. These objects are pooled and reused across {@link ScreenEffectsController.composite} calls — read them, don't retain.
- `ScreenEffectEasing` (type): type ScreenEffectEasing = "linear" | "easeIn" | "easeOut" | "easeInOut" — How a transient effect's intensity curves from peak to zero over its life.
- `ScreenEffectShape` (type): type ScreenEffectShape = "full" | "vignette" — The screen region an effect tints. `"full"` grades the whole frame (a flash); `"vignette"` grades only the edges, leaving the center clear (a directional or ambient border tint). Purely a shape hint for the renderer — no genre meaning.
- `ScreenEffectSpec` (interface): interface ScreenEffectSpec — One screen-feedback effect, fully data-first so a whole controller serializes. `kind` is a free label the game assigns and styles ("damage", "heal", "poison", "boost", …); the model never interprets it. Everything visible is a parameter: color, peak intensity, region shape, easing, and either a transient duration or a sustained (optionally oscillating) hold.
- `ScreenEffectsController` (interface): interface ScreenEffectsController — A live, clock-driven screen-feedback controller.
- `ScreenEffectsOptions` (interface): interface ScreenEffectsOptions — Options for {@link createScreenEffects}.
- `ScreenEffectsSnapshot` (interface): interface ScreenEffectsSnapshot — Serializable state of every active effect, for save/restore and replay.
- `StoredScreenEffect` (interface): interface StoredScreenEffect — A persisted effect record (all spec fields resolved plus its start time and id).
- `createScreenEffects` (function): function createScreenEffects(options: ScreenEffectsOptions = {}): ScreenEffectsController — A serializable screen-feedback controller: a game triggers transient flashes and edge vignettes (a red damage hit, a green heal flash) or sustained, optionally oscillating tints (a low-health pulse), and reads back a composite of the effects to draw right now with their eased opacities. It is clock-driven — call `advance()` each frame against an injected `now` — and allocation-aware: the composite array and its entries are pooled and reused, so steady-state ticking never allocates. Nothing here is genre-specific: `kind` is a free label the game owns and styles, and vignette / flash / pulse are just parameterizations of the same data (region shape, decay easing, sustained oscillation). A shell overlay subscribes and renders; `snapshot`/`restore` round-trips through a save.

## @jgengine/core/visibility/assetStreaming

- `AssetLoadResult` (interface): interface AssetLoadResult { readonly bytes?: number; readonly value?: unknown } — ⚠ undocumented
- `AssetLoadState` (type): type AssetLoadState = "queued" | "loading" | "loaded" | "unloaded" | "error" — ⚠ undocumented
- `AssetRecord` (interface): interface AssetRecord { readonly id: string; state: AssetLoadState; bytes: number; priority: number; refCount: number; pinned: boolean; lastActiveMs: number; value: unknown } — ⚠ undocumented
- `AssetStreamingOptions` (interface): interface AssetStreamingOptions { readonly load: (assetId: string, signal: CancelSignal) => Promise<AssetLoadResult>; readonly unload?: (assetId: string) => void; readonly settings?: Partial<StreamingSettings>; readonly now?: () => number } — ⚠ undocumented · used by `createAssetStreamingSystem`: Stream shared resources with bounded load concurrency, per-tick resident-byte eviction, and explicit inactive-history cleanup.
- `AssetStreamingSystem` (interface): interface AssetStreamingSystem { request(assetId: string, priority?: number): void; retain(assetId: string): void; release(assetId: string): void; pin(assetId: string): void; unpin(assetId: string): void; markActive(assetId: string): void; tick(dt: number): void; cancel(… — ⚠ undocumented · used by `createAssetStreamingSystem`: Stream shared resources with bounded load concurrency, per-tick resident-byte eviction, and explicit inactive-history cleanup.
- `CancelSignal` (interface): interface CancelSignal { readonly cancelled: boolean } — ⚠ undocumented
- `StreamingStats` (interface): interface StreamingStats — Current demand/residency gauges and cumulative unload/cancellation counters; clear resets totals.
- `createAssetStreamingSystem` (function): function createAssetStreamingSystem(options: AssetStreamingOptions): AssetStreamingSystem — Stream shared resources with bounded load concurrency, per-tick resident-byte eviction, and explicit inactive-history cleanup.

## @jgengine/core/visibility/bounds

- `BoundsCache` (interface): interface BoundsCache — BoundsSystem: caches resolved bounds per object and recomputes only when the caller's version advances — i.e. when a transform, geometry, or the bounds spec itself changed. The cached `RenderBounds` object is reused across recomputes, so a steady-state frame that touches thousands of objects performs zero bounds allocations.
- `BoundsSpec` (type): type BoundsSpec = | { readonly kind: "sphere"; readonly radius: number; readonly offset?: Vec3 } | { readonly kind: "aabb"; readonly half: Vec3; readonly offset?: Vec3 } | { readonly kind: "rect"; readonly halfWidth: number; readonly halfDepth: number; readonly halfHeight?: number; readonly offset?:… — How a renderable declares its extent. AABB, bounding sphere, and 2D rectangle cover the common cases; `point` is the degenerate zero-size default for objects that never override. `offset` shifts the volume from the object origin (e.g. a tall model whose pivot is at its feet).
- `DEFAULT_BOUNDS` (const): const DEFAULT_BOUNDS: BoundsSpec — Conservative default: a unit sphere. Objects without explicit bounds cull as a small volume, never a point.
- `RenderBounds` (interface): interface RenderBounds — World-space bounds a culler tests against. Kept as flat scalars (not tuples) so the hot culling path reads them without allocating. Carries both a bounding sphere (cheap broad reject) and a tight AABB (precise reject) — the standard "engine bounds" the frustum, distance, and spatial-index tests all consume.
- `Vec3` (type): type Vec3 = EntityPosition — ⚠ undocumented · used by `coverPoints` (@jgengine/core/ai/tacticalQueries): Returns boundary locations that are hidden from a threat.

## @jgengine/core/visibility/camera

- `CameraKind` (type): type CameraKind = "main" | "splitScreen" | "renderToTexture" | "editor" | "minimap" — ⚠ undocumented
- `CameraVisibilityContext` (interface): interface CameraVisibilityContext — A camera's contribution to visibility. The VisibilitySystem unions results across every active context: an object stays renderable/loaded if *any* relevant camera needs it. A camera can opt out of driving asset streaming (e.g. a minimap that only needs positions, not loaded meshes) via `influencesStreaming: false`.
- `cameraInfluencesStreaming` (function): function cameraInfluencesStreaming(context: CameraVisibilityContext): boolean — ⚠ undocumented

## @jgengine/core/visibility/config

- `VisibilityConfig` (interface): interface VisibilityConfig — Per-game visibility configuration, surfaced on `PlayableGame.visibility`. Everything is optional: an existing game that sets nothing gets the conservative engine defaults automatically. This is the scene-level and per-kind override seam (requirement: per-object, per-layer, per-scene, and global controls).

## @jgengine/core/visibility/diagnostics

- `VisibilityStats` (interface): interface VisibilityStats — Per-frame visibility + streaming counters. The VisibilitySystem fills the culling and timing fields; the AssetStreamingSystem fills the asset fields. Everything is a plain number so a HUD or the devtools hub can read it without adapters.
- `createVisibilityStats` (function): function createVisibilityStats(): VisibilityStats — ⚠ undocumented
- `nowMs` (function): function nowMs(): number — High-resolution clock that degrades to a monotonic-ish fallback when `performance` is absent.
- `resetCullingStats` (function): function resetCullingStats(stats: VisibilityStats): void — ⚠ undocumented

## @jgengine/core/visibility/distance

- `culledByDistance` (function): function culledByDistance(cameraX: number, cameraY: number, cameraZ: number, objectX: number, objectY: number, objectZ: number, minDistance: number, maxDistance: number, radius = 0, hysteresis = 0): boolean — Whether an object at `objectCenter` should be distance-culled from `cameraPos`. Compares squared distances against squared thresholds — no per-object square root. `nearestSurface` subtracts the object radius so a large object is not culled by the distance to its far side. `hysteresis` widens the max band by a fixed world-unit band for objects that were visible last check, so they don't flicker at the boundary.
- `distance` (function): function distance(a: Vec3, b: Vec3): number — ⚠ undocumented
- `distanceSquared` (function): function distanceSquared(ax: number, ay: number, az: number, bx: number, by: number, bz: number): number — ⚠ undocumented

## @jgengine/core/visibility/frustum

- `CameraView` (type): type CameraView = PerspectiveView | OrthographicView — ⚠ undocumented
- `Frustum` (interface): interface Frustum { readonly planes: Float64Array; readonly corners: Float64Array; minX: number; minY: number; minZ: number; maxX: number; maxY: number; maxZ: number } — ⚠ undocumented
- `OrthographicView` (interface): interface OrthographicView — 2D / orthographic camera (top-down, side-scroller, minimap).
- `PerspectiveView` (interface): interface PerspectiveView — 3D perspective camera (the default game camera).

## @jgengine/core/visibility/occlusion

- `AxisOccluderOptions` (interface): interface AxisOccluderOptions { enabled?: boolean; minOccluderRadius?: number } — ⚠ undocumented · used by `createAxisAlignedOcclusionTester`: A deliberately conservative bounding-volume occlusion tester.
- `OcclusionInput` (interface): interface OcclusionInput { readonly camera: CameraView; readonly bounds: RenderBounds; readonly occluders: Iterable<RenderBounds> } — ⚠ undocumented
- `OcclusionTester` (interface): interface OcclusionTester — Optional occlusion stage. Kept behind a feature flag and disabled by default: a fragile occlusion test that wrongly hides a visible object is worse than no occlusion at all. Any tester here MUST be conservative — it may return false (visible) for a truly hidden object, but must never return true (hidden) for an object the player can actually see.
- `createAxisAlignedOcclusionTester` (function): function createAxisAlignedOcclusionTester(options: AxisOccluderOptions = {}): OcclusionTester — A deliberately conservative bounding-volume occlusion tester. It hides an object only when a single large occluder's AABB fully contains the object's AABB on every axis AND sits strictly nearer the camera on the dominant view axis — the object is then provably in the occluder's shadow. Full containment (not just the two perpendicular axes) makes it stricter than it needs to be, which is the safe direction: it never hides a partially-visible object.
- `noOcclusion` (const): const noOcclusion: OcclusionTester — The safe default: never occludes anything.

## @jgengine/core/visibility/settings

- `CullingSettings` (interface): interface CullingSettings — Global render-culling behavior. Defaults favor correctness and visual stability over aggressive rejection: a generous preload margin, hysteresis, and a large default render distance so upgrading the engine never makes an existing game's objects vanish.
- `DEFAULT_CULLING_SETTINGS` (const): const DEFAULT_CULLING_SETTINGS: CullingSettings — ⚠ undocumented
- `DEFAULT_STREAMING_SETTINGS` (const): const DEFAULT_STREAMING_SETTINGS: StreamingSettings — ⚠ undocumented
- `ObjectVisibilityOverrides` (interface): interface ObjectVisibilityOverrides — Per-object visibility/streaming overrides. Also the shape used at the layer, scene, and global-override levels — resolution merges object → layer → scene → global-override, so a game can, say, mark a whole "hud" layer alwaysVisible without touching each object.
- `ResolvedOverrides` (interface): interface ResolvedOverrides { alwaysVisible: boolean; neverUnload: boolean; minRenderDistance: number | undefined; maxRenderDistance: number | undefined; preloadMargin: number | undefined; cullingDisabled: boolean; streamingDisabled: boolean; classification: "static" … — ⚠ undocumented · used by `resolveOverrides`: Merge override layers by precedence: earlier arguments win.
- `StreamingSettings` (interface): interface StreamingSettings { readonly enabled: boolean; readonly preloadMargin: number; readonly unloadGraceSeconds: number; readonly maxLoadsPerFrame: number; readonly maxConcurrentLoads: number; readonly maxUnloadsPerFrame: number; readonly maxResidentBytes: number… — ⚠ undocumented
- `mergeCullingSettings` (function): function mergeCullingSettings(base: CullingSettings, patch: Partial<CullingSettings>): CullingSettings — ⚠ undocumented
- `mergeStreamingSettings` (function): function mergeStreamingSettings(base: StreamingSettings, patch: Partial<StreamingSettings>): StreamingSettings — ⚠ undocumented
- `resolveOverrides` (function): function resolveOverrides(...layers: readonly (ObjectVisibilityOverrides | undefined)[]): ResolvedOverrides — Merge override layers by precedence: earlier arguments win. Pass object, then layer, then scene, then global.

## @jgengine/core/visibility/simulationCulling

- `SimulationCuller` (interface): interface SimulationCuller { enabled(): boolean; setEnabled(value: boolean): void; step(id: string, distance: number, dt: number): SimulationDecision; forget(id: string): void; clear(): void; snapshot(): SimulationCullerState; restore(next: SimulationCullerState): vo… — ⚠ undocumented
- `SimulationCullerState` (interface): interface SimulationCullerState — Plain JSON state of a {@link SimulationCuller}: the enabled flag and each id's throttle accumulator.
- `SimulationCullingOptions` (interface): interface SimulationCullingOptions — Simulation culling is a SEPARATE, opt-in system from render culling. Render culling only decides what is drawn; this decides whether a low-priority off-screen entity updates this tick. It is disabled by default and never throttles a protected entity — physics-critical, networking-critical, audio-critical, scripted, or explicitly-active entities always update. Gameplay correctness must never depend on an entity being on-screen, so opt in only where skipping updates is provably safe.
- `SimulationDecision` (interface): interface SimulationDecision { update: boolean; elapsed: number } — ⚠ undocumented
- `createSimulationCuller` (function): function createSimulationCuller(options: SimulationCullingOptions = {}): SimulationCuller — ⚠ undocumented

## @jgengine/core/visibility/spatialIndex

- `SpatialCellRange` (interface): interface SpatialCellRange — Integer cell bounds an object covers, inclusive on both ends.
- `SpatialIndex` (interface): interface SpatialIndex — A uniform 3D spatial hash the renderer and streaming system query for potentially-visible objects instead of scanning the whole scene. Objects are keyed by their world AABB into every overlapping cell; a moving object only rewrites the cells that actually changed. Static objects are inserted once and never touched again. Oversized objects (huge terrain chunks, world bounds) are held separately so they are always considered.
- `SpatialIndexOptions` (interface): interface SpatialIndexOptions { readonly cellSize?: number; readonly maxCellSpan?: number } — ⚠ undocumented
- `SpatialIndexState` (interface): interface SpatialIndexState — Plain JSON state of a {@link SpatialIndex}. Cells and their ids keep insertion order, so a restored index returns query results in the same order.
- `createSpatialIndex` (function): function createSpatialIndex(options: SpatialIndexOptions = {}): SpatialIndex — ⚠ undocumented

## @jgengine/core/visibility/visibilitySystem

- `Renderable` (interface): interface Renderable — A scene object the visibility system considers. A normal game object already carries a position and a version counter, so it becomes cullable automatically — no separate "cullable" component. Everything else is optional override.
- `VisibilityDebugSnapshot` (interface): interface VisibilityDebugSnapshot { cameras: {id: string; kind: CameraKind; corners: number[]; preloadMargin: number}[]; bounds: {id: string; minX: number; minY: number; minZ: number; maxX: number; maxY: number; maxZ: number; visible: boolean}[]; partitions: {key: string; c… — ⚠ undocumented
- `VisibilityResult` (interface): interface VisibilityResult { readonly visible: ReadonlySet<string>; readonly preload: ReadonlySet<string>; readonly stats: VisibilityStats } — ⚠ undocumented
- `VisibilitySystem` (interface): interface VisibilitySystem { update(): VisibilityResult; isVisible(id: string): boolean; isPreloaded(id: string): boolean; boundsOf(id: string): RenderBounds | undefined; settings(): CullingSettings; setSettings(patch: Partial<CullingSettings>): void; stats(): Visibi… — ⚠ undocumented
- `VisibilitySystemOptions` (interface): interface VisibilitySystemOptions { readonly renderables: () => Iterable<Renderable>; readonly cameras: () => readonly CameraVisibilityContext[]; readonly settings?: Partial<CullingSettings>; readonly sceneOverrides?: ObjectVisibilityOverrides; readonly globalOverrides?: Ob… — ⚠ undocumented
- `createVisibilitySystem` (function): function createVisibilitySystem(options: VisibilitySystemOptions): VisibilitySystem — ⚠ undocumented

## @jgengine/core/world

- `ANNOTATION_FEED_ACTION` (const): const ANNOTATION_FEED_ACTION: "map.annotation" — Feed action shared drawings ride by default (pair with the party feed, like pings).
- `Aabb` (interface): interface Aabb { minX: number; minZ: number; maxX: number; maxZ: number } — ⚠ undocumented · used by `polygonBounds`: Axis-aligned bounds of a polygon, or null if it has no points.
- `AcquisitionEnvelope` (type): type AcquisitionEnvelope = number | ((selfId: string, candidateId: string) => number) — Composable target acquisition: the "which enemy do I lock onto?" decision split into the independent concerns every aggro system tangles together — a bounded candidate provider, an eligibility filter, a per-pair acquisition envelope (dynamic range), a perception/LOS gate, scoring, deterministic tie-break, and retention hysteresis. This owns *policy*; threat, brains, and movement stay separate. Feed `candidates` a spatial-index query, never a full-world scan.
- `AcquisitionPolicy` (interface): interface AcquisitionPolicy — A fully composed acquisition policy. Every concern is an independent, injectable seam; the only required pieces are the bounded `candidates` provider and the `distance` metric. Omit the rest to fall back to the thin default — a static/unbounded range, everything eligible and perceptible, nearest-wins scoring, id tie-break, no hysteresis — which matches a plain proximity aggro radius.
- `AcquisitionResult` (interface): interface AcquisitionResult — Outcome of one acquisition pass.
- `AcquisitionRetention` (interface): interface AcquisitionRetention — Retention hysteresis that keeps an already-held target from flickering under churn.
- `AddBodyOptions` (type): type AddBodyOptions = BoxBodyOptions | SphereBodyOptions — ⚠ undocumented
- `Aim` (type): type Aim = | { origin: EntityPosition; direction: EntityPosition } | { yaw: number; pitch: number; spread?: number } — ⚠ undocumented · used by `aimToPoint` (@jgengine/core/input/pointer): Build an `origin → point` aim for `item.use` / projectiles, firing toward the cursor.
- `AircraftAxis` (type): type AircraftAxis = "pitch" | "roll" | "yaw" | "throttle" | "collective" | "airbrake" | "afterburner" | "vectoring" — Axes an aircraft can bind — which actions drive each flight control.
- `AircraftDynamics` (interface): interface AircraftDynamics — Stateful six-degree-of-freedom aircraft simulation.
- `AircraftKind` (type): type AircraftKind = "fixedWing" | "rotorcraft" | "vtol" — Supported aerodynamic/propulsion families.
- `AircraftOptions` (interface): interface AircraftOptions — Spawn state and injectable world-field samplers for an aircraft instance.
- `AircraftStep` (interface): interface AircraftStep — Pose and aerodynamic telemetry returned after one flight tick.
- `AircraftTuning` (interface): interface AircraftTuning — Data-first physical tuning shared by all aircraft instances of one catalog type.
- `AnnotationBroadcast` (type): type AnnotationBroadcast = | { op: "stroke"; from: string; id: string; points: readonly WorldXZ[]; tone?: MapLayerTone; width?: number } | { op: "shape"; from: string; id: string; shape: MapZoneShape; tone?: MapLayerTone; label?: string } | { op: "note"; from: string; id: string; position: WorldXZ; … — A serializable map-annotation edit broadcast to other players.
- `AnnotationFeedSink` (interface): interface AnnotationFeedSink — The feed sink shared annotations push to — an alias of the ping/feed `push` seam.
- `AnnotationLayer` (interface): interface AnnotationLayer — Player-drawn map annotation layer — strokes, shapes, and notes over caller-owned map data.
- `AnnotationLayerOptions` (interface): interface AnnotationLayerOptions — Options for {@link createAnnotationLayer}.
- `AnnotationSnapshot` (interface): interface AnnotationSnapshot — Whole serializable state of an annotation layer — drop into a save blob.
- `AreaDistribution` (type): type AreaDistribution = "uniform" | "edge" — Fill policy for a rect/box: `"uniform"` = even coverage; `"edge"` = biased to a boundary band.
- `AreaEffectEvent` (interface): interface AreaEffectEvent<P> — One membership edge emitted by `step`, `removeSource`, or `clear`.
- `AreaEffectField` (interface): interface AreaEffectField<P> — Runtime handle tracking continuous area membership across ticks.
- `AreaEventKind` (type): type AreaEventKind = "enter" | "refresh" | "leave" — The three membership edges a step can emit.
- `AreaFieldState` (interface): interface AreaFieldState<P> — Serialized field state: source descriptors (minus their transient shape) and per-member refresh phase.
- `AreaLeaveReason` (type): type AreaLeaveReason = "exit" | "source-removed" | "disabled" | "cleared" — Why a `leave` edge fired.
- `AreaMembership` (interface): interface AreaMembership<P> — One active (source, receiver) membership — feed a receiver's list to a stacking policy.
- `AreaShape` (type): type AreaShape = | { readonly kind: "sphere"; readonly center: EntityPosition; readonly radius: number } | { readonly kind: "custom"; /** Bounding-sphere center the caller's broad-phase `candidates` query is built from. */ readonly center: EntityPosition; /** Bounding-sphere radius the caller's broa… — The area a source occupies this tick. `sphere` is first-class; `custom` leaves a seam for authored volumes and other shapes while still exposing a bounding sphere (`center`/`radius`) for the caller's broad-phase candidate query.
- `AreaSourceSpec` (interface): interface AreaSourceSpec<P> — Descriptor for one continuous area source; re-supplied each tick so its shape follows the emitter.
- `AreaStackPolicy` (type): type AreaStackPolicy<P> = (memberships: readonly AreaMembership<P>[]) => AreaMembership<P>[] — Reduce one receiver's overlapping memberships to the subset that applies under a stacking rule.
- `AreaStepInput` (interface): interface AreaStepInput — Per-tick inputs the field needs to reconcile membership without scanning the world.
- `AssetAnchor` (type): type AssetAnchor = "center" | "corner" | { readonly x: number; readonly z: number } — Where a model's pivot sits within its footprint: `center` (origin at the footprint center), `corner` (origin at the min-X/min-Z corner), or a normalized `{ x, z }` fraction in `[-0.5, 0.5]`.
- `AssetCatalog` (interface): interface AssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef> { register(id: string, asset: TMeta): void; resolve(id: string): TMeta | null; has(id: string): boolean; ids(): readonly string[] } — ⚠ undocumented · used by `buildCatalog` (@jgengine/assets): Builds a game's asset catalog from the generated CC0 pack index plus singles, extras, and aliases.
- `AssetSpace` (interface): interface AssetSpace — Catalog-level asset-space metadata: how a model is authored relative to the engine, owned by the catalog entry rather than re-derived per game. Every field is optional so an unmeasured asset stays valid; {@link resolveFacingRotationY}/{@link assetUnitScale}/{@link resolveAnchorOffset} supply the documented defaults.
- `AssetSpaceIssue` (interface): interface AssetSpaceIssue — One problem found by {@link validateAssetSpace}: which metadata field and why it is invalid.
- `AttackMoveOrderPayload` (interface): interface AttackMoveOrderPayload — Payload for an attack-move: advance toward `point`, engaging hostiles encountered en route.
- `AudioBusDef` (interface): interface AudioBusDef { id: AudioBusId; gain?: number } — ⚠ undocumented · used by `withFeedbackCueSounds` (@jgengine/core/audio/feedbackCues): Merge the default feedback reactions into a game's sound catalog.
- `AudioFalloffConfig` (interface): interface AudioFalloffConfig { minDistance?: number; maxDistance?: number; curve?: FalloffCurve } — ⚠ undocumented
- `AuthoredNavLink` (interface): interface AuthoredNavLink — A connection the scene author places between two spots — a door through a wall, a ladder to a deck, a jump across a gap. Authored as world points, not polygon ids, so it survives a re-bake: {@link NavRuntime.applyMesh} resolves each end onto the nearest walkable polygon.
- `AuthoredTrigger` (interface): interface AuthoredTrigger — One resolved trigger binding from a document object.
- `AuthoredTriggerRuntime` (interface): interface AuthoredTriggerRuntime — Runtime handle that watches authored triggers against moving actors each tick.
- `AutoTargetPolicy` (type): type AutoTargetPolicy = | "nearest" | "farthest" | "random" | "strongest" | "weakest" | "first" | "last" — ⚠ undocumented
- `AvoidZone` (interface): interface AvoidZone — A circular clearance around a gameplay spot (spawn, plot, path point, POI): scatter is repelled from it and terrain is flattened toward its center. `feather` (meters) is the soft outer band — full effect within `radius - feather`, ramping to zero at `radius`.
- `AvoidanceAgent` (interface): interface AvoidanceAgent — A circular agent that avoidance may push on the XZ plane.
- `BallisticSweep` (type): type BallisticSweep = ( origin: readonly [number, number, number], velocity: readonly [number, number, number], gravity: number, maxTime: number, ) => BallisticSweepHit | null — ⚠ undocumented · used by `createBallisticSweep`: Sweeps each short chord of the closed-form arc through live body AABBs, including sleeping bodies.
- `BallisticSweepHit` (interface): interface BallisticSweepHit { point: [number, number, number]; time: number } — ⚠ undocumented
- `BandTrimOptions` (interface): interface BandTrimOptions extends JunctionGeometryOptions — Options for {@link trimBandAtJunctions} — junction geometry tunables plus a band-specific clearance.
- `BehaviorAction` (type): type BehaviorAction = DecisionAction<BehaviorActionContext> — Callback used by a registered decision graph behavior action.
- `BehaviorActionContext` (interface): interface BehaviorActionContext — Context supplied to a registered decision graph action.
- `BehaviorActionOptions` (interface): interface BehaviorActionOptions — Optional hooks for a registered behavior action set.
- `BehaviorControl` (interface): interface BehaviorControl — Per-entity control surface for the behavior runtime — pause/resume/disable/enable an instance, seek it to semantic progress, serialize/restore its state, and inspect it, all keyed by stable entity id without a full-world scan. Obtain it with {@link behaviorControl}.
- `BehaviorDescriptor` (type): type BehaviorDescriptor = | WanderBehavior | PatrolBehavior | PromptableBehavior | PlayerBehavior | PursueBehavior | DecisionGraphBehavior — ⚠ undocumented
- `BehaviorInspection` (interface): interface BehaviorInspection — Inspection readout for editor/debug tooling, from {@link BehaviorControl.inspect}/{@link BehaviorControl.list}.
- `BehaviorResumePolicy` (type): type BehaviorResumePolicy = "freeze" | "advance" — Catch-up policy applied when a paused instance resumes. `freeze` (default, deterministic) discards the time spent paused; `advance` silently fast-forwards the instance by the paused duration without emitting intermediate pose writes. Only patrol honors `advance`; wander/pursue treat it as `freeze`.
- `BehaviorSnapshot` (type): type BehaviorSnapshot = | { readonly kind: "patrol"; readonly state: PathFollowState } | { readonly kind: "wander"; readonly origin: Waypoint; readonly target: Waypoint | null } | PursueBehaviorSnapshot | { readonly kind: "decisionGraph"; readonly graph: ReturnType<DecisionGraphRuntime["snapshot"]>;… — Serializable snapshot of one behavior instance — round-trips exactly through {@link BehaviorControl.serialize}/{@link BehaviorControl.restore}.
- `BehaviorStatus` (type): type BehaviorStatus = "active" | "paused" | "disabled" — Whether a behavior instance advances and writes pose (`active`), is temporarily suspended retaining state (`paused`), or is held off until re-enabled (`disabled`).
- `BiomeBand` (interface): interface BiomeBand — A z-ordered ground palette zone — the linear-boundary counterpart to the radial `materialRegions`. Adjacent bands cross-fade into each other across a `fade`-wide window centered on the midpoint z between their centers, so a multi-biome world (vale → marsh → peaks along z) blends its ground color instead of hard-switching. Bands may also carry per-zone `fog`, `sky`, and `weather`. Order the list by ascending `z`.
- `BoardGround` (interface): interface BoardGround — A 2D surface you look at — grid games, solitaire, tabletop. Physics is often zero-gravity or omitted; the game owns the face it draws on the board.
- `BoardGroundSize` (interface): interface BoardGroundSize — Size of a `board` ground: a 2D surface you look at, in cells or layout units.
- `BoardVehicleOptions` (interface): interface BoardVehicleOptions extends EnterVehicleOptions — Seat selection and optional local camera policy for an explicit rider transition.
- `BookmarkRecallMode` (type): type BookmarkRecallMode = "replace" | "merge" — How a recalled bookmark folds into the active selection.
- `BoundsSpec` (type): type BoundsSpec = | { readonly kind: "sphere"; readonly radius: number; readonly offset?: Vec3 } | { readonly kind: "aabb"; readonly half: Vec3; readonly offset?: Vec3 } | { readonly kind: "rect"; readonly halfWidth: number; readonly halfDepth: number; readonly halfHeight?: number; readonly offset?:… — How a renderable declares its extent. AABB, bounding sphere, and 2D rectangle cover the common cases; `point` is the degenerate zero-size default for objects that never override. `offset` shifts the volume from the object origin (e.g. a tall model whose pivot is at its feet).
- `BoxFormationOptions` (interface): interface BoxFormationOptions — Options for {@link boxFormation}.
- `BuildRole` (type): type BuildRole = "owner" | "editor" | "viewer" — ⚠ undocumented
- `BuildingEnvironmentDescriptor` (type): type BuildingEnvironmentDescriptor = { kind: "building" } & Required< Pick<BuildingEnvironmentConfig, "count" | "footprint" | "stories" | "storyHeight" | "spacing" | "style"> > & Pick<BuildingEnvironmentConfig, "seed" | "position" | "palette" | "probabilities" | "along" | "kit" | "solid"> — ⚠ undocumented · used by `building`: Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style.
- `BuildingIndex` (interface): interface BuildingIndex { readonly buildings: readonly GeneratedBuilding[]; at(point: Vec2): GeneratedBuilding | undefined; within(area: Aabb): GeneratedBuilding[]; nearest(point: Vec2): BuildingHit | undefined; isInside(point: Vec2): boolean; blockers(margin?: nu… — ⚠ undocumented
- `BuildingPaletteOverrides` (type): type BuildingPaletteOverrides = Partial<BuildingPalette> — ⚠ undocumented
- `BuildingStyle` (type): type BuildingStyle = | "generic" | "capital" | "village" | "desert" | "industrial" | "coastal" | "neon" | "ruin" | "frontier" | "aerial" — ⚠ undocumented · used by `BUILDING_STYLE_PROBABILITIES` (@jgengine/core/world/buildings): Facade part probabilities per style, so an industrial yard, a ruined block and a coastal strip differ in shape as well as colour.
- `CITY_BUILDING_BUDGET` (const): const CITY_BUILDING_BUDGET: 2600 — Max buildings a single `city` district generates — the block/parcel pipeline's bounded lot cap.
- `CITY_DEFAULTS` (const): const CITY_DEFAULTS: CityRules — City defaults: a zoned mixed metropolis — towers downtown, slabs mid-ring, houses at the edge.
- `CITY_FILLER_CLASSES` (const): const CITY_FILLER_CLASSES: readonly CityFillerClass[] — All filler classes, for validation and interior-pass allow-lists.
- `CITY_KIND` (const): const CITY_KIND: "city" — The editor volume kind marking a box as a procedural city district.
- `CITY_LANDMARK_CLASSES` (const): const CITY_LANDMARK_CLASSES: readonly CityLandmarkClass[] — All landmark classes, for schema hints, validation, and default allow-lists.
- `CITY_LOT_CLASSES` (const): const CITY_LOT_CLASSES: readonly CityLotClass[] — All classes, for schema hints and validation.
- `CITY_PLOT_TIERS` (const): const CITY_PLOT_TIERS: readonly CityPlotTier[] — All plot tiers, for schema hints and validation.
- `CITY_SCHEMA` (const): const CITY_SCHEMA: ParamSchema — The city parameter schema — drives the inspector sliders and `meta` parse via the studio seam.
- `CITY_TREE_SPECIES` (const): const CITY_TREE_SPECIES: readonly CityTreeSpecies[] — All species, for schema hints and validation.
- `CITY_ZONE_KIND` (const): const CITY_ZONE_KIND: "cityzone" — The editor volume kind that locally overrides a city's zone band/mix — a district in a district.
- `CITY_ZONE_SCHEMA` (const): const CITY_ZONE_SCHEMA: ParamSchema — Zone-override schema for `cityzone` volumes: pin a band and optionally a bespoke class mix.
- `CREATIVE_FLIGHT_TUNING` (const): const CREATIVE_FLIGHT_TUNING: FreeFlightTuning — Preset for Minecraft-like creative flight — weightless, collides, yaw-relative strafe.
- `CameraShakeConfig` (interface): interface CameraShakeConfig — Configuration for {@link createCameraShake}. Every field has a game-feel default.
- `CameraShakeController` (interface): interface CameraShakeController — A live, dt-driven, trauma-based camera shake controller.
- `CameraShakeOffset` (interface): interface CameraShakeOffset — A per-frame camera shake offset: three positional axes plus three rotational axes (radians).
- `CameraShakeSnapshot` (interface): interface CameraShakeSnapshot — Serializable state for save/restore and deterministic replay.
- `CameraView` (type): type CameraView = PerspectiveView | OrthographicView — ⚠ undocumented
- `CameraVisibilityContext` (interface): interface CameraVisibilityContext — A camera's contribution to visibility. The VisibilitySystem unions results across every active context: an object stays renderable/loaded if *any* relevant camera needs it. A camera can opt out of driving asset streaming (e.g. a minimap that only needs positions, not loaded meshes) via `influencesStreaming: false`.
- `Cardinal` (type): type Cardinal = "N" | "NE" | "E" | "SE" | "S" | "SW" | "W" | "NW" — ⚠ undocumented
- `Carryable` (class): class Carryable — A grabbed physics object following a moving hold point through a spring constraint (the pick — a raycast — is the caller's/shell's job; core owns the constraint). Supports shared multi-owner carry (the follow point is the average of owners' hold points), an encumbrance read, and drop/throw. Reuses `PhysicsWorld.springJoint` to a world anchor moved each frame.
- `CarvableField` (class): class CarvableField implements TerrainField — A `TerrainField` you can write craters and mounds into at runtime — the height-field side of destructible terrain (Helldivers 2 explosion craters, engineer-deposited berms). Wraps a base field and layers smooth radial deformations on top, so `sampleHeight` (and therefore ground-snap, collision, and the shell's terrain mesh) all read the deformed surface. `carve` digs a bowl, `deposit` raises a mound.
- `CircleFormationOptions` (interface): interface CircleFormationOptions — Options for {@link circleFormation}.
- `CityBlock` (interface): interface CityBlock — One closed city block: a face of the road graph, inset to curb and land boundaries.
- `CityBlockKind` (type): type CityBlockKind = "buildable" | "park" | "plaza" | "field" | "buffer" — How a block (a face of the road graph) is used.
- `CityBridge` (interface): interface CityBridge — One bridge deck spanning water: bank-to-bank polyline plus the silhouette style.
- `CityContentOptions` (interface): interface CityContentOptions extends CityContentOverrides — Full options for {@link resolveCityLotContent}: the city geometry frame plus content overrides.
- `CityContentOverrides` (interface): interface CityContentOverrides — Tunable overrides for {@link resolveCityLotContent} (seed/halfExtents/laneFrontage are supplied).
- `CityDriveway` (interface): interface CityDriveway — One driveway ribbon from a street to a lot.
- `CityFillerClass` (type): type CityFillerClass = "garage" | "depot" — Filler classes used ONLY by the block-interior fill pass (`resolveCityLotContent` at a high `blockFill`). They are deliberately kept OUT of {@link CITY_LOT_CLASSES} so a zone mix can never weight them onto street frontage — they exist to pack the backs of Manhattan-style blocks with parking structures and warehouses/depots, mixed in with ordinary zone classes.
- `CityGeneratorOptions` (interface): interface CityGeneratorOptions — Options for {@link generateCity}: a seed, street-dial overrides, and plot pass-through options.
- `CityHedge` (interface): interface CityHedge — One hedge run: a thin box strip (estate perimeter).
- `CityIntersection` (interface): interface CityIntersection — One crossing of two through streets: patch center/radius plus crosswalk arm directions.
- `CityLandmarkClass` (type): type CityLandmarkClass = "hall" | "arena" | "market" | "campus" — A block-scale landmark class. Unlike {@link CityLotClass} these are never weighted into a zone mix — the landmark pass in `resolveCityLotContent` picks clusters of adjacent lots and stamps one of these over them. Each expresses with the same four piece shapes (box/gable/cylinder/dome) at a much larger footprint (~40–90 m).
- `CityLevelClassBias` (type): type CityLevelClassBias = Record<StreetLevel, Partial<Record<CityLotClass, number>>> — Per-street-level class weight multipliers applied to the band mix before the class pick, so towers and slabs bias toward wide boulevard/avenue frontage while houses bias toward lanes and quiet streets. A missing class ⇒ multiplier 1. Pure data modulating the weighted mixes.
- `CityLight` (interface): interface CityLight — One street light: curb position plus the yaw its arm faces (over the road).
- `CityLot` (interface): interface CityLot — One building lot: footprint, zone band, class, seeded floors, massing pieces, street anchor.
- `CityLotClass` (type): type CityLotClass = | "tower" | "slab" | "shop" | "rowhouse" | "house" | "mansion" | "farmhouse" | "barn" | "silo" — A building class a zone mix can weight — drives lot size, floors, setback, and massing.
- `CityLotPiece` (interface): interface CityLotPiece — One massing piece in LOT-LOCAL space: x along frontage width, z into the block, y up from grade.
- `CityParcel` (interface): interface CityParcel — One polygonal parcel subdivided from a block's street frontage.
- `CityParcelFrontageOut` (interface): interface CityParcelFrontageOut — One street-frontage edge of a parcel.
- `CityPark` (interface): interface CityPark — One intentional open space: an unbuilt block, a block-interior courtyard, or a buffer sliver.
- `CityParking` (interface): interface CityParking — One parking pad behind a commercial lot.
- `CityPieceRole` (type): type CityPieceRole = "wall" | "roof" | "trim" | "accent" — Palette role a piece colors from (wall/roof/trim/accent map onto the district's style palette).
- `CityPieceShape` (type): type CityPieceShape = "box" | "gable" | "cylinder" | "dome" — Primitive shapes massing pieces instance — the renderer keeps one InstancedMesh per shape.
- `CityPlot` (interface): interface CityPlot — One polygonal plot cut from a block's street frontage. Every plot fronts a street.
- `CityPlotFrontage` (interface): interface CityPlotFrontage — The street frontage a plot faces: which street, and the frontage chord along it.
- `CityPlotOptions` (interface): interface CityPlotOptions — Options for {@link deriveCityPlots}.
- `CityPlotResult` (interface): interface CityPlotResult — Output of {@link deriveCityPlots}: the plots plus whole-block park polygons.
- `CityPlotTier` (type): type CityPlotTier = "small" | "medium" | "large" | "grand" — Size tier a plot was cut at. `grand` is the block-scale tier that used to be a landmark pass.
- `CityResolveContext` (interface): interface CityResolveContext extends SceneKindResolveContext — Extended resolve context: sibling `cityzone` volumes that override the band/mix locally.
- `CityRules` (interface): interface CityRules — Fully-defaulted city params parsed from a volume's `meta`.
- `CityStreet` (interface): interface CityStreet — One synthesized street: a world-space XZ polyline with width, hierarchy level, and surface.
- `CityTree` (interface): interface CityTree — One placed tree: world XZ, species, and seeded scale/color jitter.
- `CityTreeSpecies` (type): type CityTreeSpecies = "broadleaf" | "conifer" | "palm" | "cypress" — Tree species a district's tree mix can weight — the renderer keeps one canopy mesh per species.
- `CityZoneBand` (type): type CityZoneBand = "core" | "mid" | "edge" — Zone band a lot falls in: dense core, middle ring, or the district edge.
- `CityZoneMixes` (interface): interface CityZoneMixes — Weighted building-class mix per zone band; the radial profile decides which band a lot falls in.
- `CityZoneProfile` (type): type CityZoneProfile = "core-out" | "inverted" | "uniform" — How the radial zone metric maps to bands.
- `ClockSnapshot` (interface): interface ClockSnapshot { now: number; paused: boolean; speed: number; playSpeed: number; timescale: number; scale: number; speeds: readonly number[]; calendar: CalendarTime } — ⚠ undocumented
- `CollapseEvent` (interface): interface CollapseEvent { fell: readonly string[]; collapsed: boolean } — ⚠ undocumented
- `ColliderPurpose` (type): type ColliderPurpose = "physical" | "damage" — ⚠ undocumented
- `CollisionEvent` (interface): interface CollisionEvent — A contact reported to `onCollision`. The object is reused each call — read/copy, never retain.
- `CollisionObstacle` (interface): interface CollisionObstacle — A placed scene object the walking player collides against as a circle-vs-AABB obstacle.
- `ConcealmentSensor` (interface): interface ConcealmentSensor { tick(targets: readonly ConcealmentTarget[], dt: number): ConcealmentSample[]; reset(id?: string): void; snapshot(): ConcealmentSensorState; restore(next: ConcealmentSensorState): void } — ⚠ undocumented
- `ContextMenu` (interface): interface ContextMenu { kind: ContextTargetKind; targetId: string; point?: readonly [number, number, number]; verbs: readonly ContextVerb[] } — ⚠ undocumented · used by `buildContextMenu`: Assemble a menu from a target's catalog verbs; null when the target lists none.
- `ContextVerb` (interface): interface ContextVerb — One right-click verb: a label plus the command it dispatches (walk-then-act supported by args).
- `ContourLine` (interface): interface ContourLine — A single iso-elevation contour traced across a region as a flat list of XZ line segments.
- `ContourOptions` (interface): interface ContourOptions — Shaping for {@link extractContours}: region, vertical spacing, emphasis cadence, and sample budget.
- `ControlGroupInput` (interface): interface ControlGroupInput — A decoded control-group key press plus the memory needed to detect a double-tap.
- `ControlGroupIntent` (type): type ControlGroupIntent = | { kind: "bind"; key: string } /** Digit: recall the set saved under `key` into the active selection. */ | { kind: "recall"; key: string } /** Second digit tap within the double-tap window: recall and focus the camera on `key`. */ | { kind: "focus"; key: string } — Optional RTS binding composition over the genre-agnostic selection-bookmark store (`@jgengine/core/scene/selectionBookmarks`). It maps the classic control- group idiom — Ctrl+digit binds, digit recalls, a second digit tap within a window focuses — onto opaque bookmark keys, without pulling input mapping into the store. Games that want a different scheme (named bookmarks, gamepad, touch) skip this and call the store directly.
- `ControlGroupOptions` (interface): interface ControlGroupOptions — Tuning for the control-group idiom: the double-tap focus window and the bookmark-key namespace.
- `CueListener` (type): type CueListener<Payload = unknown> = (emitted: EmittedCue<Payload>) => void — A cue listener, called once per cue as it fires. Returns nothing.
- `Curve` (interface): interface Curve — A per-life start→end curve (linear interpolation from birth to death).
- `DEFAULT_BLOCK_FILL` (const): const DEFAULT_BLOCK_FILL: 0.45 — Default `blockFill`: gently gapped frontage — plots with breathing room, parks reserved.
- `DEFAULT_CITY_LEVEL_BIAS` (const): const DEFAULT_CITY_LEVEL_BIAS: CityLevelClassBias — Default street-level bias — boulevards favor big massing, lanes favor small/rural massing.
- `DEFAULT_CITY_ZONE_MIXES` (const): const DEFAULT_CITY_ZONE_MIXES: CityZoneMixes — Default zoned-metropolis mixes: towers/slabs downtown, slabs+rowhouses mid, houses at the edge.
- `DEFAULT_FORWARD` (const): const DEFAULT_FORWARD: readonly [number, number, number] — The forward-axis convention: a generator or scene kind declares which way its "front" faces (a bookcase's open/book face, a building's entrance) once, as data, instead of leaving every placement to hand-tuned `rotationY` trial-and-error. `StudioStage`'s `faceCamera` (`@jgengine/shell/scene/ StudioStage`) reads the declared axis to auto-orient a product shot; a placement tool can read the same field to face a freshly dropped asset toward the camera/path by default. `DEFAULT_FORWARD` (+Z) is what a generator/scene-kind gets when it omits `forward` — build your front toward it.
- `DEFAULT_GRIP_CURVE` (const): const DEFAULT_GRIP_CURVE: GripCurve — ⚠ undocumented
- `DEFAULT_LANDMARK_SHARE` (const): const DEFAULT_LANDMARK_SHARE: 0.04 — Default grand-plot share dial — a handful of block-scale parcels per default city.
- `DEFAULT_MARKER_KINDS` (const): const DEFAULT_MARKER_KINDS: Record<string, MarkerKindStyle> — ⚠ undocumented
- `DEFAULT_MINIMAP_PALETTE` (const): const DEFAULT_MINIMAP_PALETTE: MinimapBakePalette — The built-in height→color ramp and water color a bake uses when no palette override is given.
- `DEFAULT_POLICE_TIERS` (const): const DEFAULT_POLICE_TIERS: readonly PoliceTier[] — The starting tier table: patrol until heat arrives, then investigate, pursue and finally cordon.
- `DEFAULT_POLICE_TUNING` (const): const DEFAULT_POLICE_TUNING: PoliceTuning — The starting policy: linear decay, a six-second escape and a search area that grows at 2 m/s.
- `DEFAULT_REPUTATION_TIERS` (const): const DEFAULT_REPUTATION_TIERS: readonly ReputationTier[] — ⚠ undocumented
- `DamageDirectionOptions` (interface): interface DamageDirectionOptions — Options for {@link createDamageDirectionTracker}.
- `DamageDirectionSnapshot` (interface): interface DamageDirectionSnapshot — Serializable state for save/restore — the clock reading plus every live indicator.
- `DamageDirectionTracker` (interface): interface DamageDirectionTracker — A serializable, allocation-aware brain that tracks where recent damage came from. Each registered hit becomes a directional indicator that fades over a fixed duration on the injected clock; {@link DamageDirectionTracker.active} reports the live ones with their eased current strength.
- `DamageIndicator` (interface): interface DamageIndicator — A live directional indicator with its eased, time-decayed strength, produced by {@link DamageDirectionTracker.active}. The `intensity` here is the *current* eased value (peak faded over the elapsed lifetime), ready to drive opacity/scale.
- `DayNightCycle` (interface): interface DayNightCycle — A running, observable, serializable day-night cycle. A presenter renders `sample()`.
- `DayNightCycleOptions` (interface): interface DayNightCycleOptions — Options for {@link createDayNightCycle}.
- `DayNightKeyframe` (interface): interface DayNightKeyframe — Turnkey day-night cycle: one serializable brain that advances a normalized day fraction on an injected clock and blends per-keyframe phase labels and tint/light colors. A game wires this one model and drives an existing sky/daylight seam from `sample()` instead of hand-rolling a clock plus a color lerp.
- `DayNightSample` (interface): interface DayNightSample — The interpolated day-night look at a moment: day fraction, active phase, and blended colors.
- `DayNightSnapshot` (interface): interface DayNightSnapshot — Serializable day-night position — accumulated clock offset, pause state, and speed — for save/load.
- `DecisionGraphBehavior` (interface): interface DecisionGraphBehavior — Decision graph behavior descriptor using a named registered action set.
- `DrapeOptions` (interface): interface DrapeOptions — Shaping for surface draping: subdivision spacing and a lift to keep the line off the ground.
- `EditableTerrain` (interface): interface EditableTerrain extends TerrainField { readonly cols: number; readonly rows: number; readonly cellSize: number; readonly gridBounds: Aabb; apply(edit: TerraformEdit): number; applyRecording(edit: TerraformEdit, record: TerraformDeltaRecorder): number; editDelta(edit: Terraform… — ⚠ undocumented · used by `beginSurfaceStroke`: Opens a paint-stroke recorder over `terrain`; stamp paint edits into it, then read one net delta.
- `ElevationReadout` (interface): interface ElevationReadout — Measurable elevation readout at a single world point — the cursor/hover feedback value.
- `ElevationSummary` (interface): interface ElevationSummary — Aggregate elevation statistics over a region — the selection min/max/mean and legend range.
- `EmittedCue` (interface): interface EmittedCue<Payload = unknown> — A cue plus the resolved firing context passed to {@link SequenceDirector.onCue} listeners.
- `EmitterConfig` (interface): interface EmitterConfig — A particle emitter: how particles spawn and how each one evolves over its life. Every field is data — no functions — so an emitter is fully serializable and an editor/tunable can drive it. Genre-agnostic: smoke, sparks, rain, magic, dust.
- `EmptyOrderPayload` (type): type EmptyOrderPayload = Record<string, never> — Payload for stop/hold orders — no data; the verb is the intent.
- `EnclosedFootprint` (interface): interface EnclosedFootprint { polygon: readonly Vec2[]; aabb: Aabb; area: number; perimeter: number; closed: boolean } — ⚠ undocumented
- `EngagementKindConfig` (interface): interface EngagementKindConfig extends OrderKindConfig — Move + engagement config carrying the default radii the payload may override.
- `EngagementOrderState` (interface): interface EngagementOrderState — Live intent an attack-move/targeted order writes into `Order.state`; the game reads it to run the actual attack. Serializable.
- `EntityColliderSet` (interface): interface EntityColliderSet { body?: ColliderDef; hitboxes?: readonly ColliderDef[] } — ⚠ undocumented · used by `eyeHeightFromColliders` (@jgengine/core/combat): Eye height derived from a collider set: 90% of the tallest hitbox top, or the humanoid default when unknown.
- `EntityPosition` (type): type EntityPosition = readonly [number, number, number] — ⚠ undocumented · used by `resolveSourceWalkerStep` (@jgengine/core/movement/solidObstacles): {@link resolveWalkerStep} with no `GameContext`: gather plus slide against a bare {@link SolidObstacleSource} and a caller-owned {@link Obst…
- `EntityStore` (interface): interface EntityStore<TMeta = unknown> — Entity state, pose writes, keyed behavior notifications and snapshot/hydration under stable instance IDs.
- `EnvironmentField` (interface): interface EnvironmentField { sample(x: number, z: number, time: number, y?: number): EnvironmentSample; temperature(x: number, z: number, time: number, y?: number): number; wetness(x: number, z: number, time: number): number; lightExposure(x: number, z: number, time:… — ⚠ undocumented · used by `createEnvironmentField`: A sampleable environment field: read temperature, wetness, sun/sky exposure, and ambient light at any world position and time.
- `EnvironmentWorldFeature` (interface): interface EnvironmentWorldFeature { kind: "environment"; terrain?: TerrainEnvironmentDescriptor; islands?: readonly TerrainIslandDescriptor[]; sky?: SkyEnvironmentDescriptor; weather?: readonly WeatherEnvironmentDescriptor[]; vegetation?: readonly VegetationEnvironmentDescr… — ⚠ undocumented · used by `environment`: Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
- `FactionDef` (interface): interface FactionDef { id: string; relations?: Readonly<Record<string, FactionRelation>>; towardSelf?: FactionRelation; towardOthers?: FactionRelation } — ⚠ undocumented
- `FallbackPolicy` (type): type FallbackPolicy<P extends SamplePoint = SamplePoint> = | "none" | "last-candidate" | { readonly point: P } — What to return when the attempt budget is exhausted. `"none"` yields no point (honest failure); `"last-candidate"` returns the final rejected draw (post-projection); `{ point }` returns a caller fixed fallback (a hand-placed safe spot). Explicit, so a caller never mistakes a fallback for a hit.
- `FastTravelNetwork` (interface): interface FastTravelNetwork<TMeta = unknown> — A network of fast-travel points with per-player discovery + distance queries.
- `FastTravelOptions` (interface): interface FastTravelOptions<TMeta = unknown> — Options for {@link createFastTravelNetwork}.
- `FastTravelSnapshot` (interface): interface FastTravelSnapshot — Serializable discovery state.
- `FireGrid` (interface): interface FireGrid { readonly cols: number; readonly rows: number; readonly cellSize: number; readonly origin: readonly [number, number]; step(dt: number, options?: FireStepOptions): void; igniteCell(col: number, row: number): void; extinguishCell(col: number… — ⚠ undocumented
- `FlatGround` (interface): interface FlatGround — A 3D walkable plane/slab. `Infinity` axes are unbounded; no separate "infinite" mode exists.
- `FlatGroundSize` (interface): interface FlatGroundSize — Size of a `flat` ground: extents in world units. `Infinity` on an axis means unbounded — an endless plain needs no bounds number invented for it. `y` optionally bounds vertical play space.
- `FlightControlInput` (interface): interface FlightControlInput — Normalized pilot inputs for one flight-simulation tick.
- `FlightControlRates` (interface): interface FlightControlRates — Angular authority, response, damping, and self-leveling configuration.
- `FlightVector` (type): type FlightVector = readonly [number, number, number] — Three-dimensional world-space vector used by the flight model.
- `FogCells` (interface): interface FogCells { cols: number; rows: number; minX: number; minZ: number; cellSize: number; revealed: readonly boolean[]; revealedCount: number } — ⚠ undocumented
- `FogField` (interface): interface FogField — Reveal-on-event fog of war over a fixed grid. Walking (`revealAlong`) and digging/acting (`reveal`) clear cells; once revealed a cell stays revealed. Pure and renderer-free — the shell/react map draws `cells()`.
- `FootprintRegion` (type): type FootprintRegion = RegionFootprint | MergedRegion — A standalone footprint or a pooled region carrying its original contributions.
- `ForceVolume` (class): class ForceVolume — A trigger region that pushes bodies passing through it — boost pads (`impulse` + `once`), conveyors (`velocity`), fans/wind (`accelerate`). Call `apply` each tick; `once` mode fires only on entry by tracking membership between ticks.
- `FormationSlotGenerator` (type): type FormationSlotGenerator = (count: number) => Vec2[] — Produces `count` slot offsets in the group's local frame — `[right, forward]` where `+forward` points where the group faces. Index order is the slot order; a generator must be pure (same `count` → same offsets) so placement stays deterministic. Sample generators below cover common shapes; games pass their own for anything else (crowds, convoys, sports positions) with no engine edit.
- `FramingConfig` (interface): interface FramingConfig { idealDistance?: number; centerWeight?: number; sizeWeight?: number } — ⚠ undocumented
- `FreeFlightBindings` (interface): interface FreeFlightBindings — Per-axis bindings for free-flight — which actions drive each flight axis. Positive is forward/right/up.
- `FreeFlightController` (interface): interface FreeFlightController — Stateful handle for any free-flight actor with snapshot/restore/retune.
- `FreeFlightIntent` (interface): interface FreeFlightIntent — Intent for one free-flight tick — forward/right from WASD/analog, vertical from jump/crouch.
- `FreeFlightMode` (type): type FreeFlightMode = "creative" | "spectator" | "noclip" | "hover" — Free-flight families — character-scale 6DOF movement, distinct from vehicle aerodynamics.
- `FreeFlightState` (interface): interface FreeFlightState — Velocity state for a free-flight actor — serializable and ownable by the caller.
- `FreeFlightStep` (interface): interface FreeFlightStep — World displacement produced by one free-flight tick.
- `FreeFlightTuning` (interface): interface FreeFlightTuning — Data-first tuning for one free-flight profile.
- `FreezeMonitor` (interface): interface FreezeMonitor { tick(subjects: readonly FreezeSubject[], frozenIds: ReadonlySet<string>, dt: number): FreezeViolation[]; reset(id?: string): void; snapshot(): FreezeMonitorState; restore(next: FreezeMonitorState): void } — ⚠ undocumented
- `FreezeViolation` (interface): interface FreezeViolation { id: string; speed: number; movedSeconds: number } — ⚠ undocumented
- `Frustum` (interface): interface Frustum { readonly planes: Float64Array; readonly corners: Float64Array; minX: number; minY: number; minZ: number; maxX: number; maxY: number; maxZ: number } — ⚠ undocumented
- `FrustumProjection` (interface): interface FrustumProjection { inView: boolean; distance: number; screenX: number; screenY: number } — ⚠ undocumented
- `FrustumSample` (interface): interface FrustumSample { id: string; inView: boolean; distance: number; screenX: number; screenY: number; framing: number; dwellSeconds: number } — ⚠ undocumented
- `FrustumSensor` (interface): interface FrustumSensor { tick(camera: FrustumCamera, targets: readonly FrustumTarget[], dt: number): FrustumSample[]; reset(id?: string): void } — ⚠ undocumented
- `FrustumTarget` (interface): interface FrustumTarget { id: string; position: EntityPosition; radius?: number } — ⚠ undocumented
- `GRASS_SCHEMA` (const): const GRASS_SCHEMA: ParamSchema — The grass parameter schema — drives the inspector and `meta` parse via the studio seam.
- `GROUND_DECAL_LAYERS` (const): const GROUND_DECAL_LAYERS: { readonly road: 0.06; readonly junction: 0.06; readonly marking: 0.11; readonly glow: 0.14; } — The single owning table of ground-decal Y offsets, in world units above the sampled terrain.
- `GeneratedAsset` (interface): interface GeneratedAsset — A resolved generator asset: its parts plus the overall local-space bounds (min/max corners).
- `GeneratedCity` (interface): interface GeneratedCity — A generated city: streets, plots (with rect building lots as a compat view), and park blocks.
- `GeneratedPart` (interface): interface GeneratedPart — One generated primitive part — a box/panel placed in the asset's local space.
- `Glide` (class): class Glide — A reduced-gravity, forward-thrust glide over a physics body — wingsuit / glider / paraglider (Enshrouded, Grounded). Call `apply(dt, steerX, steerZ)` each frame *before* `world.step`: it feeds back most of the gravity the sim is about to apply (leaving `gravityScale` of it), pushes the body along the steer vector by `thrust`, and clamps descent to `maxFallSpeed`. Stop calling it to fall normally again — no attach/detach state to leak.
- `Grapple` (class): class Grapple — A fired-anchor rope on the joint API — grapple (reel toward a hit point), zipline (rigid cable to a far anchor you then slide/reel along), swing (rigid rope + gravity = a pendulum). `fire` attaches a `distance`/`spring` joint from the traveller body to a fixed world point; `reel` shrinks its rest length so the constraint drags the body in; `moveAnchor` re-points it (zipline glide, grapple-to- moving-target). The pick — a raycast to find the anchor — is the caller's; core owns the constraint.
- `GrassEnvironmentDescriptor` (type): type GrassEnvironmentDescriptor = { kind: "grass" } & Required< Pick<GrassEnvironmentConfig, "area" | "density" | "bladeHeight" | "bladeWidth" | "windStrength" | "colors"> > & Pick<GrassEnvironmentConfig, "seed" | "bladeBend" | "tuftRadius" | "colorVariation" | "normalLift" | "groundCover"> — ⚠ undocumented · used by `grass`: Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
- `GravityField` (interface): interface GravityField — Position-dependent gravity source used by movement and vehicle simulations.
- `GravityVector` (type): type GravityVector = readonly [number, number, number] — Three-dimensional acceleration vector sampled from a gravity field.
- `GripCurve` (interface): interface GripCurve { points: readonly (readonly [number, number])[] } — ⚠ undocumented · used by `sampleGripCurve`: Piecewise-linear tire-grip curve: normalized lateral slip → available grip (0..1).
- `GroundConfig` (type): type GroundConfig = FlatGround | RoundGround | VoxelGround | BoardGround — The substrate of a place, discriminated by `mode` — TS rejects a `radius` on `flat` and `x`/`z` on `round`.
- `GroundGenerator` (interface): interface GroundGenerator — Serializable algorithm parameters for a procedural ground generator. Never a genre kit.
- `GroundMode` (type): type GroundMode = "flat" | "round" | "voxel" | "board" — Canonical ground modes after normalization (`stage` → `board`).
- `GroundPoint` (type): type GroundPoint = readonly [number, number] — A world-space point on the ground plane as an `[x, z]` pair.
- `GuideRegion` (interface): interface GuideRegion — An axis-aligned XZ rectangle to generate terrain-readability guides within.
- `HOVER_FLIGHT_TUNING` (const): const HOVER_FLIGHT_TUNING: FreeFlightTuning — Preset for hover/jetpack — gravity + thrust, useful for short bursts.
- `HeatConfig` (interface): interface HeatConfig — Tuning for {@link createHeatState}/{@link advanceHeat} — levels, decay, and pursuit-spawn ring.
- `HeatGain` (interface): interface HeatGain — One crime tick's contribution — only `witnessed` gains raise heat (unseen crimes are free, GTA-style).
- `HeatLevelDef` (interface): interface HeatLevelDef — One escalation tier — the heat threshold it begins at and the pursuer count it wants active.
- `HeatPoint` (type): type HeatPoint = readonly [number, number] — A world-space `[x, z]` used for the heat system's spawn ring and witness proximity checks.
- `HeatSource` (interface): interface HeatSource — A localized warmth source — campfire, forge, geothermal vent.
- `HeatState` (interface): interface HeatState — Serializable heat-system state — round-trips through `createHeatState`/`advanceHeat` each tick.
- `HeightSampler` (type): type HeightSampler = (x: number, z: number) => number — A height sampler over the ground: world elevation at any `x`/`z`.
- `HiddenStateSource` (interface): interface HiddenStateSource { id: string; position: EntityPosition; variables: Readonly<Record<string, HiddenStateValue>> } — ⚠ undocumented · used by `useHiddenStateProbe` (@jgengine/shell/vision/HiddenStateProbeHud): Reads a hidden zone/entity state variable in range (EMF / thermometer / geiger style sensor verb, #116).
- `HitInput` (interface): interface HitInput — A single incoming hit to register on a {@link DamageDirectionTracker}. The angle is relative to the player's facing (renderer-agnostic): `0` points at the front/top of the reticle and increases clockwise, so a game passes the bearing from the player toward the attacker without knowing anything about the screen.
- `InterestCensus` (interface): interface InterestCensus — Aggregate counts of active vs dormant gates — the metric the issue asks a scheduler to expose.
- `InterestCensusAccumulator` (interface): interface InterestCensusAccumulator — A running census accumulator; call `record` inside the caller's existing tick loop (no extra pass).
- `InterestGateInput` (interface): interface InterestGateInput — Per-tick input the caller supplies to a gate.
- `InterestGateState` (interface): interface InterestGateState — Per-agent serializable gate state. Round-trip the whole object; never read fields to drive logic.
- `InterestGateStep` (interface): interface InterestGateStep — Per-tick output that tells the caller whether to run expensive work.
- `InterestSchedulerConfig` (interface): interface InterestSchedulerConfig — Static configuration shared by every gate of one behavior class.
- `InterestState` (type): type InterestState = "active" | "dormant" — Interest scheduling: the scale primitive that lets far-away agents sleep instead of running acquisition and pathing every frame. A per-agent gate decides — from proximity to the nearest interest source plus explicit wake signals — whether this tick does expensive work, at what cadence, with hysteresis so it never thrashes at the boundary and deterministic staggering so a thousand siblings do not all wake on the same frame. State is a plain serializable object; the caller drives it from a bounded spatial query, never a full-world scan.
- `InterestTier` (interface): interface InterestTier — A distance-keyed cadence tier: nearer agents tick faster, farther-but-awake agents tick slower.
- `IntersectionStreet` (interface): interface IntersectionStreet — One street to trim + mesh through {@link buildTrimmedIntersections}.
- `Job` (interface): interface Job — ⚠ undocumented · used by `activeJobs` (@jgengine/core/gameplay): Jobs currently progressing.
- `JobDef` (interface): interface JobDef { id?: string; station: NavPoint; work: number; priority?: number; arriveRadius?: number; repeat?: boolean } — ⚠ undocumented
- `JobReport` (interface): interface JobReport { jobId: string; workerId: string; cycle: number } — ⚠ undocumented
- `JunctionApproach` (interface): interface JunctionApproach — One approach feeding {@link buildJunctionSurface}: the exact draped corner vertices a ribbon ends at.
- `JunctionGeometryOptions` (interface): interface JunctionGeometryOptions — Tunables shared by {@link trimPathAtJunctions}, {@link buildJunctionSurface}, and {@link buildTrimmedIntersections}.
- `KinematicChassisTuning` (interface): interface KinematicChassisTuning — Mass-and-force chassis layer (#1051); when present it supersedes `engineAccel`/`brakeAccel` with force/mass dynamics. Drive/brake become forces divided by `massKg`, a per-tick tire friction budget (`tireGrip` * grip curve * surface * downforce * m * g) is split lateral-first then longitudinal so hard slides and launches saturate, and `comHeight`/`trackWidth` set weight-transfer washout and body lean. Coasting decelerates from physical road load, not a per-vehicle constant: rolling resistance `μ_rr · m · g` always, plus engine braking `ENGINE_BRAKE_FRACTION · engineForce` routed through the current gear (so it strengthens as the car downshifts) whenever the throttle is lifted and a `powertrain` is configured. All fields are required; omit the whole block for the legacy model.
- `KinematicDynamicsTuning` (interface): interface KinematicDynamicsTuning — Aerodynamic and electronic-assist settings layered over tire grip.
- `KinematicPowertrainTuning` (interface): interface KinematicPowertrainTuning — Data-first gearbox and torque-curve tuning for a kinematic ground vehicle.
- `KinematicSteeringTuning` (interface): interface KinematicSteeringTuning — Bicycle-model steering settings; all angles are radians.
- `KinematicVehicle` (interface): interface KinematicVehicle — The pure-kinematic arcade car every racing game hand-rolled (#282.1): steer-yaw scaled by speed, throttle/brake acceleration, and a grip-curve lateral-slip bleed — no `PhysicsWorld`, no wheels, just the drift-friendly integration the three shipped racers proved out. Games keep their flavor (drift meters, boost, off-track rules) via `surfaceFriction`/`dragAt` hooks and the returned slip.
- `KinematicVehicleStep` (interface): interface KinematicVehicleStep { position: readonly [number, number, number]; heading: number; forwardSpeed: number; lateralSpeed: number; slip: number; surface: number; weightTransfer: number; loadGrip: number; gear: number; rpm: number; steerAngle: number; yawRate: num… — ⚠ undocumented · used by `tickDrivableVehicle`: Connects an `AxisInput` sample straight through a ground-vehicle sim (`KinematicVehicle` or `VehicleDynamics`) to a scene entity's pose for …
- `KinematicVehicleTuning` (interface): interface KinematicVehicleTuning { engineAccel: number; brakeAccel: number; topSpeed: number; reverseSpeed: number; turnRate: number; turnSpeedRef: number; grip?: GripCurve; gripStrength: number; handbrakeGrip: number; rollingResistance?: number; coastDeceleration?: number… — ⚠ undocumented · used by `applyVehicleParts`: Fold parts onto a base tuning: every effect scales then adds onto the running value, in array order, so a setup is deterministic and a calle…
- `KinematicWeightTransferTuning` (interface): interface KinematicWeightTransferTuning — Load-transfer handling for the arcade model. Weight moves under braking, traction and cornering; the tire that goes light loses more grip than the loaded one gains (load sensitivity), so the axle's combined grip falls. Every term is bounded by the geometry, and `sensitivity` caps the loss, so the transfer can never drive grip negative or diverge. For per-axle balance from tire forces, use `createVehicleDynamics` (`physics/vehicleDynamics`) instead.
- `LANDMARK_HARD_CAP` (const): const LANDMARK_HARD_CAP: 12 — Hard cap on grand plots emitted regardless of dial/city size.
- `LOCK_ACTIONS` (const): const LOCK_ACTIONS: readonly LockAction[] — The five pick actions, in display order (shallow → deep).
- `LaneEdgeConfig` (interface): interface LaneEdgeConfig — One directed lane span to resolve into the graph.
- `LaneGraph` (interface): interface LaneGraph — Authored lane topology: junctions, directed spans with speed limits and arc lengths, crossings with their right-of-way, and parking spots. Positions come from the spans themselves, so a traffic runtime never re-derives geometry or runs a path search per vehicle.
- `LaneGraphConfig` (interface): interface LaneGraphConfig — The authored lane graph: junctions, directed spans, crossings and parking spots.
- `LaneGraphDocumentOptions` (interface): interface LaneGraphDocumentOptions — How the document reader recognizes authored lane content.
- `LaneIntersection` (interface): interface LaneIntersection — A resolved crossing: the lanes that feed it, the lanes that leave it, and its right-of-way.
- `LaneIntersectionConfig` (interface): interface LaneIntersectionConfig — Right-of-way and signal timing for one authored crossing.
- `LaneNode` (interface): interface LaneNode — A junction where lane spans meet.
- `LanePose` (interface): interface LanePose — World pose of a lane at an arc position.
- `LaneRightOfWay` (type): type LaneRightOfWay = "signal" | "priority" — How an intersection resolves which approach may enter next.
- `LaneSignalProgram` (interface): interface LaneSignalProgram — Signal timing for one intersection; phases list the in-lanes each green window serves.
- `LaneSpan` (interface): interface LaneSpan — A resolved lane span: centerline, arc lengths, limit and adjacency.
- `LaneSpot` (interface): interface LaneSpot — A parking spot projected onto one lane at an arc position.
- `LeaveVehicleOptions` (interface): interface LeaveVehicleOptions extends DismountOffset — Exit placement and optional local camera restoration for an explicit rider.
- `LineFormationOptions` (interface): interface LineFormationOptions — Options for {@link lineFormation}.
- `LocalAvoidanceOptions` (interface): interface LocalAvoidanceOptions — Tuning for {@link resolveLocalAvoidance}.
- `LockAction` (type): type LockAction = "hardSet" | "set" | "steady" | "ease" | "drop" — One discrete pick move: how far the pick drives into the lock this step.
- `LockCell` (interface): interface LockCell — One cell inside the fogged {@link visibleCells} window: its board position and kind.
- `LockSpec` (interface): interface LockSpec — A generated lock board. `open[col]` holds every enterable row in that column.
- `LockStepResult` (type): type LockStepResult = "advanced" | "slip" | "bind" | "trap" | "success" — Outcome of one {@link stepLock} call: `advanced`/`success` move the pick, `slip`/`bind`/`trap` do not and should cost a life.
- `LockTierSpec` (interface): interface LockTierSpec — Difficulty dials for one lock: board size, forgiveness band, gates, fog window, traps.
- `MOVEMENT_TUNING` (const): const MOVEMENT_TUNING: { readonly standEyeHeight: 1.7; readonly crouchEyeHeight: 1.15; readonly walkSpeedMultiplier: 1.75; readonly runSpeedMultiplier: 2.25; readonly crouchSpeedMultiplier: 0.45; readonly backpedalSpeedMultiplier: 0.65; readonly groundAcceleration: 26; readonly airAcceleration: 12; … — Kinematics + feel tuning for the first-person controller. Centralised here so movement feel lives in one place rather than scattered through the renderer.
- `MagnitudeOf` (type): type MagnitudeOf<P> = (membership: AreaMembership<P>) => number — Read a comparable magnitude from a membership (e.g. buff strength, damage per tick).
- `MapCellStates` (interface): interface MapCellStates { id: string; origin: MapXZ; cellSize: number; cells: readonly {col: number; row: number; tone: MapLayerTone; opacity?: number}[] } — ⚠ undocumented
- `MapMarker` (interface): interface MapMarker<TMeta = unknown> extends MarkerView<TMeta> — A marker owned by {@link MarkerSet}, including its lifecycle and query fields.
- `MapNote` (interface): interface MapNote — A text note pinned at a world point.
- `MapRoute` (interface): interface MapRoute { id: string; points: readonly MapXZ[]; tone?: MapLayerTone; forecast?: boolean; width?: number; closed?: boolean } — ⚠ undocumented
- `MapShapeAnnotation` (interface): interface MapShapeAnnotation — A drawn area annotation (circle/rect/polygon), reusing the map-zone shape vocabulary.
- `MapStroke` (interface): interface MapStroke — A freehand drawn line on the map — a world-XZ polyline.
- `MapZone` (interface): interface MapZone { id: string; shape: MapZoneShape; tone?: MapLayerTone; opacity?: number; forecast?: boolean; label?: string } — ⚠ undocumented
- `MarkerCollection` (type): type MarkerCollection<TMarker extends MarkerView = MarkerView> = | readonly TMarker[] | MarkerSource<TMarker> | MarkerSet — Marker data accepted by portable consumers: static views, an external source, or a native set.
- `MarkerKindStyle` (interface): interface MarkerKindStyle — Visual descriptor for a marker kind. Games supply their own palette; the engine ships `DEFAULT_MARKER_KINDS` as a content-agnostic starting set that the react minimap/compass read for colors and glyphs.
- `MarkerSet` (interface): interface MarkerSet<TMeta = unknown> { add(marker: MarkerInput<TMeta>): string; remove(id: string): boolean; get(id: string): MapMarker<TMeta> | null; list(): readonly MapMarker<TMeta>[]; query(query: MarkerQuery): MapMarker<TMeta>[]; prune(now: number): number; clear(): void;… — ⚠ undocumented · used by `useLiveMarkers` (@jgengine/react): A self-ticking {@link MarkerSet} kept in sync with the live scene: on a heartbeat (default 100ms, and once immediately) it clears the set an…
- `MarkerSource` (interface): interface MarkerSource<TMarker extends MarkerView = MarkerView> — Observable marker snapshots owned by an external project. `getSnapshot` must return the same array identity until the source changes and calls its subscribers, matching React's external-store contract.
- `MarkerSourceOptions` (interface): interface MarkerSourceOptions<TEntity, TMarker extends MarkerView = MarkerView> — Configuration for projecting a caller-owned collection into display-only markers.
- `MarkerView` (interface): interface MarkerView<TMeta = unknown> — Small, display-only marker shape consumed by map renderers. Existing games can project their own entities to this view without adopting marker lifecycle storage or duplicating them into a {@link MarkerSet}.
- `MassingFootprint` (interface): interface MassingFootprint — Axis-aligned massing extents (lot-local): full width along x and depth along z.
- `MergedRegion` (interface): interface MergedRegion extends RegionFootprint — Plain JSON pooled region. Contributions partition its cells and sum to its capacity.
- `MinimapBake` (interface): interface MinimapBake — A baked minimap image: RGBA pixels plus the world bounds they span.
- `MinimapBakeBounds` (interface): interface MinimapBakeBounds — Deterministic minimap terrain bake (#1036): rasterize an authored world's terrain (plus optional biome zones and water) into a top-down RGBA image and a matching world-bounds rectangle, then encode it as a PNG data URI. The editor runs this as a bake action and stores the result on the scene document; runtime feeds it straight into the existing `Minimap` / `WorldMap` `background` + `mapBounds` props — no new runtime render path, and the same authored world always bakes the same image (safe for verify/CI). Pure: no canvas, no DOM, `core` still imports nothing external.
- `MinimapBakeOptions` (interface): interface MinimapBakeOptions — Options for {@link bakeMinimapImage}.
- `MinimapBakePalette` (interface): interface MinimapBakePalette — The height→color ramp and water color used by the bake.
- `MinimapBakeSource` (interface): interface MinimapBakeSource — The authored world a bake reads — a height sampler, its bounds, and optional zones/water.
- `MinimapBakeZone` (interface): interface MinimapBakeZone — One biome/region tint painted over the terrain shade where the ground falls inside its polygon.
- `MinimapView` (interface): interface MinimapView { center: WorldXZ; worldRadius: number; size: number; rotate?: number } — ⚠ undocumented · used by `projectToMinimap`: Project a world XZ (or XYZ) point into minimap pixel space.
- `ModelAssetRef` (interface): interface ModelAssetRef { url: string; anchor?: "center" | "origin"; dims?: ModelDims; collisionMesh?: CollisionMeshData; space?: AssetSpace; clips?: readonly string[] } — ⚠ undocumented · used by `createHostedWorldSessionAsync` (@jgengine/core/runtime/hostedWorldSession): Build a hosted session from an asynchronous persistence backend.
- `ModelDims` (interface): interface ModelDims — Measured horizontal footprint, footprint center, and lowest Y of a model in model space.
- `ModelNode` (interface): interface ModelNode — Generic named-socket reader for loaded 3D models. Walks a node tree (any object with `.name`, `.position`, and `.children` — structurally satisfied by `THREE.Object3D`) and collects the local offsets of nodes whose name marks an attachment point. Genre-agnostic: wire anchors on a pylon, muzzle/hand mounts on a character, hardpoints on a ship, seat/decal slots on furniture — anything an artist tags with an empty in the GLB. Pure data (no three.js import), so it lives in core.
- `MountController` (class): class MountController — Mount / rideable control-transfer (issue #83). Registers rideables (each with one or more seats — a control seat drives, the rest ride) and tracks who is on what. It owns no camera or physics: game code reads `cameraTarget(riderId)` to point the follow camera at the mount, and `driveTarget(riderId)` to route that rider's {@link import("../physics/vehicleBody").AxisInput}-driven input at the mount's movement kit — the same seam a horse, a truck, or a shared multi-seat ship all plug into.
- `MoveOrderPayload` (interface): interface MoveOrderPayload — Payload for a move order: go to a point and complete on arrival.
- `MovementPose` (type): type MovementPose = "standing" | "crouch" | "prone" | "running" — ⚠ undocumented
- `MusicInstrument` (type): type MusicInstrument = | "strings" | "flute" | "harp" | "horn" | "choir" | "bell" | "timpani" | "bass" | "stacc" | "pad" | "lute" | "dulcimer" | "frameDrum" | "warDrum" | "reed" | "pipe" | "squareLead" | "woodBlock" | "tinyBell" | "piano" | "shaker" | "brassStab" | "cymSwell" | "oboe" — Named synthesised instrument. Each maps to a voice in the shell's instrument library (`@jgengine/shell/audio/musicVoices`); an unknown name falls back to a plain sine voice so a theme is never silent.
- `MusicTheme` (interface): interface MusicTheme — A through-composed, looping music track. `events` need not be sorted; the director schedules them ahead against a fixed anchor so loops are seamless.
- `NOCLIP_FLIGHT_TUNING` (const): const NOCLIP_FLIGHT_TUNING: FreeFlightTuning — Preset for noclip — weightless, noclips, yaw-relative with independent vertical.
- `NavCrowd` (interface): interface NavCrowd — Agents that cross an editor-baked nav mesh: each one plans a corridor with {@link NavRuntime}, walks the funnel-smoothed waypoints, and keeps its distance through reciprocal velocity obstacle avoidance. Goals, arrivals and replans are serializable; a mesh edit only re-plans the agents whose remaining route actually crossed the rebuilt region.
- `NavCrowdAgentSpec` (interface): interface NavCrowdAgentSpec — How one crowd agent was configured when it joined.
- `NavCrowdAgentView` (interface): interface NavCrowdAgentView — One crowd agent's live state, as a game or the devtools overlay reads it.
- `NavCrowdOptions` (interface): interface NavCrowdOptions — Tunables for {@link createNavCrowd}, every one retunable in play.
- `NavCrowdRevalidate` (interface): interface NavCrowdRevalidate — Result of telling the crowd the nav mesh changed.
- `NavCrowdSnapshot` (interface): interface NavCrowdSnapshot — Serializable crowd state: agents, their routes, and the avoidance tuning they run under.
- `NavCrowdStats` (interface): interface NavCrowdStats — Counters a devtools probe or test reads.
- `NavGrid` (interface): interface NavGrid { readonly cols: number; readonly rows: number; readonly cellSize: number; readonly bounds: Aabb; readonly diagonal: boolean; isWalkable(col: number, row: number): boolean; setWalkable(col: number, row: number, walkable: boolean): void; blo… — ⚠ undocumented · used by `findPath`: A* over the walkable grid.
- `NavLinkKind` (type): type NavLinkKind = "door" | "ladder" | "jump" | "link" — What an authored off-mesh connection crosses; the runtime prices it by kind unless the author sets a cost.
- `NavMeshAdjacency` (interface): interface NavMeshAdjacency — Neighbor relationship for one navigation polygon.
- `NavMeshData` (interface): interface NavMeshData — Serializable polygon navigation mesh data. Treat it as immutable once queried; queries cache derived geometry per object.
- `NavMeshLink` (interface): interface NavMeshLink — Explicit traversable connection between two navigation polygons.
- `NavMeshPath` (interface): interface NavMeshPath — Route points and polygons selected through a navigation mesh.
- `NavMeshQuery` (interface): interface NavMeshQuery — Cached, allocation-light queries over one {@link NavMeshData}.
- `NavMeshQueryOptions` (interface): interface NavMeshQueryOptions — Tunable pricing and bounds for a {@link NavMeshQuery}.
- `NavMeshQuerySnapshot` (interface): interface NavMeshQuerySnapshot — Serializable tuning of a {@link NavMeshQuery}.
- `NavPoint` (type): type NavPoint = readonly [number, number] — ⚠ undocumented · used by `findPath`: A* over the walkable grid.
- `NavRebuildStats` (interface): interface NavRebuildStats — How one {@link NavRuntime.applyMesh} exchange changed the mesh.
- `NavRegion` (interface): interface NavRegion — An XZ box naming the authored area a scene edit touched, so routing state elsewhere is left alone.
- `NavRuntime` (interface): interface NavRuntime — Runtime seam over a baked {@link NavMeshData}: route, price areas, resolve authored links, rebuild in place.
- `NavRuntimeOptions` (interface): interface NavRuntimeOptions extends NavMeshQueryOptions — Options for {@link createNavRuntime}.
- `NavRuntimeSnapshot` (interface): interface NavRuntimeSnapshot — Serializable tuning and authored links of a {@link NavRuntime}; the baked geometry is replaced by `applyMesh`.
- `NoiseFieldConfig` (interface): interface NoiseFieldConfig — Configuration for {@link noiseField}: seed, amplitude, and fractal noise shaping.
- `NoiseVoice` (interface): interface NoiseVoice — A filtered white-noise burst — impacts, whooshes, breath, crackle. Realised from a shared 1s noise buffer at a randomised playback rate and start offset, decaying exponentially to silence at `duration * decay`.
- `NoteEvent` (interface): interface NoteEvent — One scheduled note in a theme, positioned on the loop's quarter-note grid.
- `ObjectSlotRejection` (type): type ObjectSlotRejection = | "unknown-object" | "no-slot-inventory" | "unknown-inventory" | "no-space" | "wrong-kind" | "slot-occupied" | "invalid-slot" | "insufficient" — Why an object slot mutation was refused — the instance, its catalog entry, the player inventory, or the declared `accepts`/capacity.
- `ObjectSlotResult` (type): type ObjectSlotResult = { status: "ok" } | { status: "rejected"; reason: ObjectSlotRejection } — Outcome of an object slot mutation: applied, or refused with a reason and no state change on either side.
- `ObjectSlotTransfer` (interface): interface ObjectSlotTransfer — Which player inventory a transfer moves between, and what it moves.
- `ObjectVisual` (interface): interface ObjectVisual { scale?: number | readonly [number, number, number]; color?: string; opacity?: number } — ⚠ undocumented
- `OceanEnvironmentDescriptor` (type): type OceanEnvironmentDescriptor = { kind: "ocean" } & Required< Pick<OceanEnvironmentConfig, "bounds" | "level" | "waveHeight" | "waveScale" | "waveSpeed" | "color"> > & Pick<OceanEnvironmentConfig, "position" | "levelAt"> — ⚠ undocumented · used by `ocean`: Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
- `Order` (interface): interface Order<TPayload = unknown> — One issued order. Fully serializable: `kind` is a registry key (not a closure), `payload` is the caller's plain data, and `state` is the kind's own plain progress scratch (e.g. a patrol waypoint index) written during `start`/`update`. Never holds functions, so the whole queue round-trips through `JSON`/`structuredClone`.
- `OrderCancelReason` (type): type OrderCancelReason = "replaced" | "preempted" | "requested" | "invalid" | "failed" | "cleared" — Why an order left the queue without completing. `replaced`/`preempted` come from a newer order taking over; `requested` from explicit `cancelActive`; `invalid` when the kind's `start` rejects; `failed` when `update` reports failure; `cleared` from a full `clear`/`cancelAll`.
- `OrderEvent` (interface): interface OrderEvent — A lifecycle event emitted synchronously as orders move through the queue.
- `OrderIssueResult` (type): type OrderIssueResult<TPayload = unknown> = | { status: "accepted"; order: Order<TPayload> } | { status: "queued"; order: Order<TPayload> } | { status: "rejected"; reason: string } — Outcome of `issue`: `accepted` entered the queue, `queued` entered behind an uninterruptible/active order, `rejected` was refused (validation or `reject` policy).
- `OrderKind` (interface): interface OrderKind<TCtx, TPayload = unknown> — The composition seam for one order verb. `TCtx` is the game's world adapter (movement, targeting, effects) shared by every kind in a registry; `TPayload` is this verb's caller data. `start` seeds `order.state`, `update` advances it and reports lifecycle, and `finish` releases anything the kind held. Kinds are pure over their injected `ctx` -- no globals, no direct scene reach.
- `OrderKindConfig` (interface): interface OrderKindConfig — Shared factory config: override the verb key so a game can register the composition under its own name.
- `OrderMoveResult` (interface): interface OrderMoveResult — Result of one movement step, from the game's motion adapter.
- `OrderMover` (interface): interface OrderMover — Narrow motion adapter an order kind drives. The game implements it over its own controller/motor (`scene.moveToward`, a nav follower, physics) for one entity; the kind never touches the scene directly.
- `OrderOutcome` (interface): interface OrderOutcome — Terminal outcome handed to a kind's `finish` cleanup hook.
- `OrderPhase` (type): type OrderPhase = "queued" | "active" | "completed" | "canceled" — Lifecycle phase of a single order. `queued` waits behind the active order; `active` is ticking; `completed`/`canceled` are terminal.
- `OrderProgress` (type): type OrderProgress = { status: "running" } | { status: "completed" } | { status: "failed"; reason: string } — Result of a kind's `update` tick. `running` keeps the order active; the completion predicate lives in the kind (returns `completed`); `failed` cancels the order (reason `failed`) so the queue advances to the next one.
- `OrderQueue` (interface): interface OrderQueue<TCtx, TPayload = unknown> — A per-entity order queue: one commandable unit's lifecycle of intent. The game ticks it with its world adapter; it activates, advances, completes, and cancels orders and enforces preemption policy. State is serializable for save and host-authoritative replication.
- `OrderQueueOptions` (interface): interface OrderQueueOptions<TPayload = unknown> — Construction options for a queue.
- `OrderQueuePolicy` (type): type OrderQueuePolicy = "replace" | "append" | "front" | "reject" — How a newly issued order interacts with what's already queued. `replace` preempts the active order and clears pending; `append` queues it behind everything (shift-queue); `front` makes it the next to run without touching the active order; `reject` refuses it while anything is queued.
- `OrderQueueState` (interface): interface OrderQueueState<TPayload = unknown> — Serializable snapshot of a queue: the active order plus the pending list, in order.
- `OrderRegistry` (interface): interface OrderRegistry<TCtx> — Registry of order kinds keyed by verb string; the queue dispatches through it so engine code never switches on a verb.
- `OrderRejection` (interface): interface OrderRejection — A kind's refusal of a payload (from `validate`) — surfaced to the issuer as a rejection reason.
- `OrderRequest` (interface): interface OrderRequest<TPayload = unknown> — A request to issue an order; `policy` defaults to `replace`, `id` is generated when omitted.
- `OrderStartResult` (type): type OrderStartResult = { ok: true } | { ok: false; reason: string } — Result of a kind's `start`: `ok:false` skips the order and cancels it with reason `invalid`. The kind seeds `order.state` directly when `ok:true`.
- `OrderTargeting` (interface): interface OrderTargeting — Narrow targeting adapter for engagement verbs. `acquire` returns the id of a hostile within `radius` (nearest, or whatever policy the game injects), and `positionOf` locates a known target. Actual damage/effects stay game-side.
- `OrderTickReport` (interface): interface OrderTickReport<TPayload = unknown> — What one `tick` did this frame, for tests and game reactions (play a bark on activation, flash on completion). Bounded per tick.
- `OrderVec3` (type): type OrderVec3 = readonly [number, number, number] — Composable entity orders: a serializable command queue with lifecycle, preemption, and pluggable order kinds (#912). Player- or AI-issued intent ("move here", "attack that", "patrol this route") becomes reusable data instead of a hard-coded RTS verb kit. The queue owns issue -> activate -> tick -> complete/cancel lifecycle and deterministic preemption policy; each order KIND owns what "running" means, composed over narrow world adapters. Engine code never branches on `move`, `attack`, or any game verb -- kinds are looked up by string in a registry, so a game adds a verb by registering data.
- `POLE_LINE_SCHEMA` (const): const POLE_LINE_SCHEMA: ParamSchema — The pole-line parameter schema — drives the inspector and `meta` parse via the studio seam.
- `POSE_HITBOX` (const): const POSE_HITBOX: Record<MovementPose, PoseHitbox> — ⚠ undocumented
- `PadEnvironmentDescriptor` (type): type PadEnvironmentDescriptor = { kind: "pad" } & Required< Pick<PadEnvironmentConfig, "center" | "size" | "height" | "color"> > & Pick<PadEnvironmentConfig, "rotationY" | "elevation"> — ⚠ undocumented · used by `padFlattenMasks` (@jgengine/core/world/features): Derives implicit `TerrainFlattenMask`s carving each pad's footprint into the terrain beneath it.
- `PadSize` (type): type PadSize = readonly [number, number] | { radius: number } — ⚠ undocumented
- `PaintStroke` (interface): interface PaintStroke { u: number; v: number; radius: number; color: string } — ⚠ undocumented
- `ParamField` (type): type ParamField = | RangeParamField | NumberParamField | BoolParamField | SelectParamField | ColorParamField | TextParamField | SeedParamField | WeightedListParamField | ActionParamField — One row in a kind's parameter schema — the union the generic inspector knows how to render.
- `ParamPreset` (interface): interface ParamPreset — A named slider/weight bundle for a kind — a saved set of field values the inspector (or the `apply_preset` verb) writes into an object's `meta` in one patch, ready to tweak afterwards. Presets are plain data on the schema, so kinds ship archetypes and games can override the registration with their own.
- `ParamSchema` (interface): interface ParamSchema — A kind's full parameter surface: an ordered list of fields the inspector renders top-to-bottom.
- `ParsedParams` (type): type ParsedParams = Record<string, number | boolean | string | WeightedParamEntry[]> — Parsed params after `parseParams`: every schema field present with a validated, defaulted value.
- `ParticleBuffers` (interface): interface ParticleBuffers — Read-only packed buffers of the live particles, laid out for a renderer to upload directly (Structure-of-Arrays, no per-particle objects). Only the first `count` entries are live; the arrays themselves are reused every frame.
- `ParticleSnapshot` (interface): interface ParticleSnapshot — Serializable simulation state for save/restore and deterministic replay.
- `ParticleSystem` (interface): interface ParticleSystem — A live, dt-driven particle simulation.
- `PathFollowConfig` (interface): interface PathFollowConfig { waypoints: readonly Waypoint[]; speed: number; loop?: boolean } — ⚠ undocumented · used by `advancePathFollow`: Advance a path-follower by `speed * dt` along its authored polyline.
- `PathFollowProgress` (interface): interface PathFollowProgress — Read-only progress readout for inspection/debug tooling, produced by {@link pathFollowProgress}.
- `PathFollowState` (interface): interface PathFollowState { position: Waypoint; target: number; heading: number; done: boolean; distanceTravelled: number } — ⚠ undocumented · used by `advancePathFollow`: Advance a path-follower by `speed * dt` along its authored polyline.
- `PathHeightPolicy` (type): type PathHeightPolicy = | { readonly kind: "sample" } | { readonly kind: "fixed"; readonly height: number } | { readonly kind: "grade"; readonly start: number; readonly end: number } — Where a path corridor drives its centerline height: - `sample` — follow the base terrain under the centerline, so the corridor drapes level across its width while still tracking the hills the path crosses (the natural policy for a road or trail). - `fixed` — hold one constant height for the whole corridor (a level causeway, runway, or dam crest). - `grade` — interpolate linearly from `start` to `end` height along the path's arc length, a constant-slope ramp between two anchors (a switchback, a graded rail bed, an accessibility ramp).
- `PathProgress` (type): type PathProgress = | { readonly kind: "normalized"; readonly value: number } /** World-distance travelled from the first waypoint (looping paths wrap; clamped otherwise). */ | { readonly kind: "distance"; readonly value: number } /** Segment `index` (0-based) plus `fraction` `0..1` along that segme… — Semantic seek target for {@link pathFollowSeek} — the caller-facing progress vocabulary a stateful path behavior restores from, so a follower can start at a distributed phase or resume a serialized route without knowing waypoint internals. `direction` (forward heading) falls out of the resulting {@link PathFollowState.heading}, so it is an output rather than a seek input.
- `PathRetaining` (interface): interface PathRetaining — Retaining behavior for a path corridor's shoulders. A wall rises only where the corridor already cuts or fills into the surrounding ground by at least `threshold` — gentle stretches stay open — so a road through a canyon gets held banks while the same profile on flat ground does not. The wall fades in smoothly across `taper` above the threshold so it never steps on or off between adjacent samples.
- `PatrolOrderPayload` (interface): interface PatrolOrderPayload — Payload for a patrol: walk a waypoint route, optionally looping forever.
- `PatrolOrderState` (interface): interface PatrolOrderState — Serializable patrol progress.
- `PerceptionCandidate` (interface): interface PerceptionCandidate — A candidate target considered by a sight check.
- `PerceptionConfig` (interface): interface PerceptionConfig — Configuration for sight, hearing, memory decay, squad sharing and optional occlusion.
- `PerceptionMemory` (interface): interface PerceptionMemory — A remembered target and its linearly decaying confidence.
- `PerceptionObserver` (interface): interface PerceptionObserver — The observer pose used for a sight check.
- `PerceptionPosition` (type): type PerceptionPosition = readonly [number, number, number] — A world position used by perception, in `[x, y, z]` order.
- `PerceptionService` (interface): interface PerceptionService — Stateful perception API with retuning and save/restore support.
- `PerceptionSnapshot` (interface): interface PerceptionSnapshot — Serializable state for a perception service.
- `PerceptionStats` (interface): interface PerceptionStats — Counters a perf test or a devtools probe reads. Reset with {@link PerceptionService.resetStats}.
- `PerceptionStimulus` (interface): interface PerceptionStimulus — An event that can seed an observer's memory.
- `PerceptionStimulusKind` (type): type PerceptionStimulusKind = "sight" | "sound" | "damage" — The kinds of stimulus the perception service can retain.
- `PhysicsStats` (interface): interface PhysicsStats { count: number; awake: number; sleeping: number; contacts: number; pairs: number; substeps: number; stepMs: number } — ⚠ undocumented
- `PhysicsWorld` (class): class PhysicsWorld — ⚠ undocumented
- `PlaceAssetResult` (interface): interface PlaceAssetResult — Shared place-asset verb: one resolved payload for editor `place_asset` and in-game build-mode commits. Convert with {@link toStructureInput} / {@link toEditorMarker}.
- `PlaceConfig` (interface): interface PlaceConfig — Input to {@link world}: place identity, substrate, and the laws of this place.
- `PlaceWorldFeature` (interface): interface PlaceWorldFeature — A declared place — the `world()` result carried on `GameDefinition.world`.
- `PlacedStructure` (interface): interface PlacedStructure { id: string; catalogId: string; position: StructureVec3; rotationY: number; plotId?: string; data?: Readonly<Record<string, unknown>> } — ⚠ undocumented
- `PlacementCommit` (interface): interface PlacementCommit { center: Vec2; y: number; rotationY: number; quarterTurns: number; footprint: Footprint; aabb: Aabb; slotId?: string } — ⚠ undocumented · used by `placeAssetFromCommit`: Bridge a {@link PlacementCommit} into the shared place-asset verb.
- `PlacementController` (interface): interface PlacementController { hover(hit: PlacementHit): PlacementPreview; current(): PlacementPreview | null; rotate(steps?: number): PlacementPreview | null; setSnapMode(mode: SnapMode): PlacementPreview | null; cycleSnapMode(): SnapMode; setFootprint(footprint: Foot… — ⚠ undocumented · used by `createPlacementController`: Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit.
- `PlacementPreview` (interface): interface PlacementPreview { center: Vec2; y: number; quarterTurns: number; footprint: Footprint; aabb: Aabb; valid: boolean; reason?: "out-of-bounds" | "overlap" | "no-slot" | "territory.blocked"; snapMode: SnapMode; normal: PlacementVec3; slotId?: string } — ⚠ undocumented
- `PlacementRotationPolicy` (type): type PlacementRotationPolicy = | { readonly mode: "locked"; readonly degrees?: number } | { readonly mode: "snap"; readonly snapDegrees: number } | { readonly mode: "free" } — A per-asset/per-tool rotation constraint, authored as data instead of hardcoded in build code: `locked` pins every placement to one heading, `snap` quantizes to an increment (15, 45, …), and `free` allows any heading. Serializable — this is the shape stored on a catalog entry or a tool.
- `PlacementRules` (interface): interface PlacementRules { bounds?: Aabb; obstacles?: readonly PlacementObstacle[]; snap?: number; territory?: (aabb: Aabb) => {ok: boolean} } — ⚠ undocumented · used by `validatePlacement`: Footprint validity: bounds + obstacle overlap after optional grid snap.
- `PlatformCarry` (class): class PlatformCarry — Carries bodies standing on a moving platform by composing their transform with the platform's per-`step` delta — moving/rotating lifts and conveyor floors (Fall Guys, Gang Beasts). The platform is a body the game repositions each frame; riders are detected by overlap on its top face.
- `Point3` (type): type Point3 = readonly [number, number, number] — Deterministic spatial sampling — draw one or many positions from a geometric region under explicit constraints, with an injected RNG, bounded attempts, and a structured pass/fail result.
- `PointGravityOptions` (interface): interface PointGravityOptions — Center, strength, and falloff for radial gravity.
- `PoliceLaneHit` (interface): interface PoliceLaneHit — A lane near a world point: its id, the arc of the nearest point on it, and how far away that is.
- `PoliceResponse` (interface): interface PoliceResponse — Stateful wanted/pursuit API with retuning and save/restore support.
- `PoliceResponseConfig` (interface): interface PoliceResponseConfig extends Partial<PoliceTuning> — Everything {@link createPoliceResponse} needs: the witness seam, the roster and the caller's policy.
- `PoliceResponseKind` (type): type PoliceResponseKind = "patrol" | "investigate" | "pursue" | "roadblock" — How police answer the current heat tier — watching the streets up to cordoning them.
- `PoliceResponseState` (interface): interface PoliceResponseState — Serializable response state — the heat curve, the sight timer, the anchor and the counters.
- `PoliceRoadblockSite` (interface): interface PoliceRoadblockSite — A roadblock site on a lane, resolved from authored road data.
- `PoliceRoads` (interface): interface PoliceRoads — Road data the response reads: nearby lanes for the search area, authored sites for roadblocks.
- `PoliceRoadsOptions` (interface): interface PoliceRoadsOptions — How the document reader recognizes authored road content.
- `PoliceSearchArea` (interface): interface PoliceSearchArea — Where the search is, as the last sighting places it.
- `PoliceSighting` (interface): interface PoliceSighting — One remembered sighting of the suspect, as the perception service reports it — `PerceptionMemory` from `sensor/perception` satisfies this shape.
- `PoliceStats` (interface): interface PoliceStats — Counters a devtools probe, a HUD or a test reads.
- `PoliceStep` (interface): interface PoliceStep — One tick's answer: the heat, the tier, the search area, the cordon and the escape.
- `PoliceTickContext` (interface): interface PoliceTickContext — Per-tick world facts {@link PoliceResponse.tick} needs but cannot derive itself.
- `PoliceTier` (interface): interface PoliceTier — One response tier: the heat it begins at, what it puts on the street, and how wide it searches.
- `PoliceTuning` (interface): interface PoliceTuning — The serializable policy of a response: the tier table, the heat curve and the search shape.
- `PoliceWitness` (interface): interface PoliceWitness — The witness seam: perception memory, queried by observer id. Pass `createPerception` (`sensor/perception`) straight in — a crime is witnessed when an observer still holds the suspect in view, so there is no second sight path to keep in step.
- `PositionedPrompt` (interface): interface PositionedPrompt { id: string; position: PromptPoint; priority?: number; prompt: ProximityPrompt } — ⚠ undocumented · used by `resolveActivePrompt`: Nearest prompt strictly within its radius wins; a higher-priority prompt in range beats any lower-priority one regardless of distance; equal…
- `PositionedPromptPatch` (type): type PositionedPromptPatch = Partial<Omit<PositionedPrompt, "id">> — A partial edit applied to an already-registered {@link PositionedPrompt} by {@link PromptRegistry.update}. Any subset of the mutable fields — everything but the stable `id` — may be supplied; omitted fields keep their prior value.
- `PromptRegistry` (interface): interface PromptRegistry — A live, observable set of interaction prompts that OWNS the registered {@link PositionedPrompt}s and tracks which one is active for a player. It is a thin stateful layer over {@link resolveActivePrompt}: registration/order lives here, the nearest-within-radius / higher-priority selection stays in the pure resolver. {@link resolve} is the per-frame hot path — call it as the player moves; subscribers fire only when the active prompt actually CHANGES.
- `PromptRegistrySnapshot` (interface): interface PromptRegistrySnapshot — The serializable shape {@link PromptRegistry.snapshot} returns and {@link PromptRegistry.restore} consumes: the full set of positioned prompts (in registration order) plus the id of the prompt that was active when the snapshot was taken. Prompt display/command payloads are free strings and ids — keep them serializable and this round-trips through a save cleanly.
- `ProximityPrompt` (interface): interface ProximityPrompt { radius: number; display: ProximityPromptDisplay; invoke: PromptCommand | null } — ⚠ undocumented
- `PursueBehavior` (interface): interface PursueBehavior — Scheduled chase/attack behavior; the default declares hostility toward player-role entities. GameDefinition.pursuit.eligible can further restrict every target source using the live world. Explicit targets and optional threat override nearest-player acquisition, not eligibility.
- `PursueBehaviorSnapshot` (interface): interface PursueBehaviorSnapshot — Plain pursuit progress, including its original spawn home and scheduled elapsed time.
- `QteStep` (interface): interface QteStep { id: string; action: string; windowStart: number; windowEnd: number } — ⚠ undocumented · used by `evaluateQteSequence`: Evaluate a quick-time-event input sequence against timed hit windows.
- `RadialDistribution` (type): type RadialDistribution = "area" | "radial" — Fill policy for a circle/ring: `"area"` = area-uniform (even density); `"radial"` = radius-uniform (clumps toward center).
- `RainEnvironmentDescriptor` (type): type RainEnvironmentDescriptor = { kind: "rain" } & Required< Pick<RainEnvironmentConfig, "area" | "density" | "speed" | "dropLength" | "wind" | "color" | "width" | "opacity"> > — ⚠ undocumented · used by `rain`: Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
- `Range` (interface): interface Range — A `[min, max]` range a spawned particle draws uniformly from.
- `RecallBookmarkOptions` (interface): interface RecallBookmarkOptions — Caller hooks for {@link recallSelectionBookmark} — kept out of the store so focus and validity stay genre-owned.
- `RecordingBuffer` (interface): interface RecordingBuffer<T> { append(t: number, data: T): void; seek(t: number): RecordingFrame<T> | null; seekPair(t: number): RecordingPair<T>; range(fromT: number, toT: number): RecordingFrame<T>[]; clear(): void; duration(): number; frames(): readonly RecordingFra… — ⚠ undocumented · used by `useSessionRecorder` (@jgengine/shell/replay/useSessionRecorder): Session-recording buffer (#120) for replay / photo mode / kill-cam: records an entity's pose on game-time every frame into a `RecordingBuffe…
- `RecordingBufferOptions` (interface): interface RecordingBufferOptions { maxDurationSeconds?: number; maxFrames?: number } — ⚠ undocumented · used by `useSessionRecorder` (@jgengine/shell/replay/useSessionRecorder): Session-recording buffer (#120) for replay / photo mode / kill-cam: records an entity's pose on game-time every frame into a `RecordingBuffe…
- `RegionContribution` (interface): interface RegionContribution — Original footprint identity and capacity retained when regions pool.
- `RegionField` (interface): interface RegionField<T = unknown> extends TerrainField { sampleRegion(x: number, z: number): RegionSample<T>; readonly regions: readonly RegionDef<T>[]; readonly seaLevel: number; readonly seed: number } — ⚠ undocumented · used by `scatterItems`: Deterministically place opaque items across `area`, grounded on a region field.
- `RegionFootprint` (interface): interface RegionFootprint — Caller-owned logical footprint. Cells must be unique, safe integer addresses and cardinally connected.
- `RegionSplitIds` (interface): interface RegionSplitIds — Identities for split sides containing multiple contributions; singletons retain their original id.
- `RegionWorkBudget` (interface): interface RegionWorkBudget — Optional caller work limits, checked before cell traversal. Omitted limits follow input size.
- `Renderable` (interface): interface Renderable — A scene object the visibility system considers. A normal game object already carries a position and a version counter, so it becomes cullable automatically — no separate "cullable" component. Everything else is optional override.
- `ResolvedCity` (interface): interface ResolvedCity — A resolved city district: world-space network, zoned lots, parks, and furniture.
- `ResolvedCityLot` (interface): interface ResolvedCityLot — One plot enriched with its zone/class/floors/massing — the renderer instances `pieces` at `center`.
- `ResolvedCollider` (interface): interface ResolvedCollider { name: string; purpose: ColliderPurpose; shape: ColliderShape; damageEligible: boolean; blocks: boolean } — ⚠ undocumented
- `ResolvedGround` (type): type ResolvedGround = FlatGround | RoundGround | VoxelGround | ResolvedBoardGround — A place's ground after `world()` normalization.
- `ResolvedPoleLine` (interface): interface ResolvedPoleLine — The renderable payload the resolver returns and the shell renderer consumes.
- `ResolvedTerrainDetail` (type): type ResolvedTerrainDetail = Required<Omit<TerrainDetailConfig, "waterLevel" | "material" | "sweeps">> & { waterLevel: number; material?: ResolvedTerrainDetailMaterial; sweeps: { dry: readonly [number, number, number]; wet: readonly [number, number, number] }; } — A {@link TerrainDetailConfig} with every field resolved to a concrete value — the shape the shell's detail material consumes.
- `ResolvedWeather` (interface): interface ResolvedWeather { grip: number; visibility: number; structureDamage: number; chill: number; ignition: number; spread: number } — ⚠ undocumented
- `ResponseCurve` (type): type ResponseCurve = | { readonly kind: "linear"; readonly from: number; readonly to: number } /** Same shape as `linear`, raised to `exponent` (default `2`), so appeal stays flat until it matters. */ | { readonly kind: "quadratic"; readonly from: number; readonly to: number; readonly exponent?: num… — How one need's satisfaction maps to an option's appeal: `1` at `from`, `0` at `to`, clamped outside. Read satisfaction `1` as a full meter; pair with {@link UtilityTerm.invert} when a full meter is what makes the option attractive.
- `RevealHit` (interface): interface RevealHit { instanceId: string; distance: number; tags: readonly string[] } — ⚠ undocumented · used by `useRevealHits` (@jgengine/shell/vision/RevealVision): Occlusion-ignoring tagged-entity radius query (#115), bound to the live scene.
- `RevealQuery` (interface): interface RevealQuery { inRadius(center: EntityPosition | string, radius: number, tags: readonly string[]): RevealHit[] } — ⚠ undocumented
- `RoadCut` (interface): interface RoadCut — One trim of a ribbon end back to a junction boundary — the seam the welded surface attaches to.
- `RoadEnvironmentDescriptor` (type): type RoadEnvironmentDescriptor = { kind: "road" } & Required< Pick<RoadEnvironmentConfig, "path" | "width" | "color" | "markings" | "markingColor" | "elevation"> > & { /** Resolved sidewalk band, or `false` when the road has none. */ sidewalk: { width: number; color: string } | false; /** Procedural… — Resolved road descriptor produced by {@link road} and rendered by the shell environment scene.
- `RoadJunctionInput` (interface): interface RoadJunctionInput — The minimal junction shape this geometry needs — a node position plus its outgoing arms. Matches the structural subset of `StreetJunction` (streetGenerator) so a network's `junctions` can be fed straight in. Arm `angle` follows the generator convention `atan2(dx, dz)`, i.e. the outward unit direction of an arm is `[sin(angle), cos(angle)]`.
- `RoadSurfaceOptions` (interface): interface RoadSurfaceOptions — Grip levels and blend width for {@link roadSurfaceSampler}; each field is optional and defaulted.
- `RoofPlan` (interface): interface RoofPlan { style: RoofStyle; ridge: readonly [Vec2, Vec2]; apexHeight: number; eaveHeight: number; faces: readonly (readonly WallVec3[])[] } — ⚠ undocumented
- `RosterEntry` (interface): interface RosterEntry { id: string; catalogId: string; capturedAt: number; equipped: boolean } — ⚠ undocumented
- `RoundGround` (interface): interface RoundGround — A planet/sphere you play on the outside of. Sized by `radius` only.
- `RoundGroundSize` (interface): interface RoundGroundSize — Size of a `round` ground: the planet/sphere radius in world units. Nothing else.
- `RvoAgentSpec` (interface): interface RvoAgentSpec — One agent's circular footprint and top speed; positions and velocities live in the crowd.
- `RvoAgentView` (interface): interface RvoAgentView — One agent's live kinematics, as the crowd exposes them.
- `RvoCrowd` (interface): interface RvoCrowd — Many circular agents steering around each other. `setPreferredVelocity` states where each agent wants to go; `step` turns that into reciprocal collision-free velocities and integrates them. Deterministic: agents are visited in slot order, neighbours in grid and slot order, and head-on ties break on slot index rather than chance.
- `RvoCrowdOptions` (interface): interface RvoCrowdOptions extends Partial<RvoTunables> — Options for {@link createRvoCrowd}.
- `RvoSnapshot` (interface): interface RvoSnapshot — Serializable crowd state: tuning plus every agent's position, velocity and footprint.
- `RvoTunables` (interface): interface RvoTunables — Serializable avoidance tuning, retunable in play through {@link RvoCrowd.retune}.
- `SCATTER_COVERAGE_SPECS` (const): const SCATTER_COVERAGE_SPECS: Record<ScatterCoverageKind, ScatterCoverageSpec> — The coverage spec per scatterable kind — the single source for its unit + budget.
- `SCATTER_INSTANCE_BUDGET` (const): const SCATTER_INSTANCE_BUDGET: 250000 — Max blade/placement instances a single `grass_field` or `scatter` patch places. Mirrors the grass renderer's instance-buffer ceiling; the scatter resolver truncates to it too, so a patch never renders more than this many placements regardless of density × area.
- `SCATTER_PATH_KIND` (const): const SCATTER_PATH_KIND: "scatter" — The editor path kind that marks a closed polyline as a foliage/scatter region.
- `SHAPE_BOX` (const): const SHAPE_BOX: 0 — ⚠ undocumented
- `SHAPE_SPHERE` (const): const SHAPE_SPHERE: 1 — ⚠ undocumented
- `SOIL_KIND` (const): const SOIL_KIND: "soil" — The editor volume kind marking a box as a soil crack/moss patch.
- `SOIL_SCHEMA` (const): const SOIL_SCHEMA: ParamSchema — The soil parameter schema — drives the inspector and `meta` parse via the studio seam.
- `SPECTATOR_FLIGHT_TUNING` (const): const SPECTATOR_FLIGHT_TUNING: FreeFlightTuning — Preset for spectator — weightless, noclips, flies where the camera looks.
- `SampleBatchOptions` (interface): interface SampleBatchOptions<P extends SamplePoint = SamplePoint> — Inputs for a {@link sampleBatch} draw of many spaced points.
- `SampleBatchResult` (interface): interface SampleBatchResult<P extends SamplePoint = SamplePoint> — Structured batch outcome: the placed points plus whether the full count was met.
- `SampleConstraints` (interface): interface SampleConstraints<P extends SamplePoint = SamplePoint> — Post-draw gates a candidate must clear. All are optional; an empty constraint set accepts every in-region draw. `exclude` discs/spheres are the keep-out distance primitive ("no closer than R to this center"); `accept` is a free-form caller predicate (biome, slope, ownership); `project` snaps a candidate onto a surface/navmesh before validation and may reject by returning `null`.
- `SamplePoint` (type): type SamplePoint = readonly number[] — A sampled point: 2D `[x, z]` or 3D `[x, y, z]`. Every point in one run shares its dimensionality.
- `SamplePointOptions` (interface): interface SamplePointOptions<P extends SamplePoint = SamplePoint> — Inputs for a single {@link samplePoint} draw.
- `SampleReason` (type): type SampleReason = "accepted" | "exhausted" | "empty-region" — Why a sample ended: a clean hit, budget exhausted, or the region was degenerate.
- `SampleRegion` (interface): interface SampleRegion<P extends SamplePoint = SamplePoint> — A geometric region a sampler can draw from. Built-ins cover point sets, rect/box, circle/sphere, annulus/shell, polygon, and weighted composites; {@link customRegion} wraps a caller-defined sampler + bounds. `sample` draws one raw candidate under the region's own distribution policy; `contains` is the membership test reused for include/exclude constraints and rejection.
- `SampleResult` (interface): interface SampleResult<P extends SamplePoint = SamplePoint> — Structured single-sample outcome — never a bare point, so failure and fallback are visible.
- `ScatterCoverage` (interface): interface ScatterCoverage — A resolved coverage readout: how many instances an authored patch WANTS (`requested`, when it can be computed cheaply from geometry × density), how many it will actually place after the budget clamp (`count`), the `budget` ceiling, and whether the request hit it (`capped`). `requested` is `null` for kinds whose pre-cap ask is not knowable without running the generator (city, where the count comes from the resolved street fabric).
- `ScatterCoverageKind` (type): type ScatterCoverageKind = "grass_field" | "scatter" | "city" — The shared "how much stuff grows here" contract for scatterable scene kinds (`grass_field` / `scatter` / `city`). Every scatterable kind fills an authored AREA with instances at a DENSITY, and every kind caps the placed count at a bounded BUDGET so a huge or dense request can never generate unbounded work. Before this module each kind hand-rolled its own readout and clamp story (grass silently capped in the renderer, scatter never capped, city had no budget note); this is the one place that
- `ScatterCoverageSpec` (interface): interface ScatterCoverageSpec — Per-kind coverage descriptor: the unit noun, whether density is per-m², and the placement budget.
- `ScatterInstance` (interface): interface ScatterInstance — ⚠ undocumented · used by `resolveScatter`: Every scatter region's placements across a document, grounded on `terrain` when provided.
- `ScatterPoint` (interface): interface ScatterPoint { x: number; z: number; index: number } — ⚠ undocumented
- `ScatterTerrain` (interface): interface ScatterTerrain — Ground sampler a scatter resolve reads height/normal from (the sculpt terrain or the game's ground).
- `SceneBake` (interface): interface SceneBake — A bake stored on an editor scene document, structurally compatible with `EditorBake`.
- `SceneEntity` (interface): interface SceneEntity<TMeta = unknown> { id: string; name: string; position: EntityPosition; rotationY: number; rotationX: number; rotationZ: number; velocity: EntityPosition; role: EntityRole; movement: EntityMovement; behaviors: readonly BehaviorDescriptor[]; hidden?: boolean;… — ⚠ undocumented · used by `entityMetaOf`: Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null` instead of lying to the type che…
- `SceneKindObject` (interface): interface SceneKindObject — The raw document object a resolver receives — shape shared by markers, volumes, and paths.
- `SceneKindResolveContext` (interface): interface SceneKindResolveContext — Ground sampler + options a resolver may read (terrain height/normal snap).
- `SceneObject` (interface): interface SceneObject { instanceId: string; catalogId: string; position: EntityPosition; rotationY: number; parentSpace?: string; visual?: ObjectVisual; animation?: ModelAnimationConfig | "auto" | "none"; state?: Record<string, unknown>; slots?: InventoryState } — ⚠ undocumented · used by `fromRuntimeObjectRow` (@jgengine/core/runtime/objectRows): Inverse of {@link toRuntimeObjectRow}: rebuild the live placed object a host persisted.
- `SceneObjectSlots` (interface): interface SceneObjectSlots — Per-instance container contents for placed objects whose catalog entry declares `slotInventory` — the engine side of "install a GPU into a rack", "put an item in a chest". Contents live on `SceneObject.slots`, so they replicate and save with the object rather than needing a game-owned table keyed by `instanceId`, and every mutation is validated against the declared `accepts` and stack limits.
- `SceneRaycastApi` (interface): interface SceneRaycastApi { raycast(input: SceneRaycastInput): SceneRaycastHit | null; raycastAll(input: SceneRaycastInput): SceneRaycastHit[] } — ⚠ undocumented · used by `sceneCameraQuery` (@jgengine/shell/camera): `CameraCollisionQuery` over the scene's existing collision query (`ctx.scene.raycast`), which already reads world solids, scene-object colli…
- `SceneRaycastHit` (interface): interface SceneRaycastHit { targetKind: SceneRaycastTargetKind; instanceId: string; catalogId?: string; colliderName: string; purpose: ColliderPurpose; damageEligible: boolean; blocks: boolean; distance: number; point: EntityPosition; normal: EntityPosition } — ⚠ undocumented · used by `firstImpact`: First impact: nearest hit that blocks, or nearest hit if none block.
- `ScreenEffect` (interface): interface ScreenEffect — A live effect in the current composite: its label, color, region, and the eased opacity `0..1` to draw *right now*. These objects are pooled and reused across {@link ScreenEffectsController.composite} calls — read them, don't retain.
- `ScreenEffectEasing` (type): type ScreenEffectEasing = "linear" | "easeIn" | "easeOut" | "easeInOut" — How a transient effect's intensity curves from peak to zero over its life.
- `ScreenEffectShape` (type): type ScreenEffectShape = "full" | "vignette" — The screen region an effect tints. `"full"` grades the whole frame (a flash); `"vignette"` grades only the edges, leaving the center clear (a directional or ambient border tint). Purely a shape hint for the renderer — no genre meaning.
- `ScreenEffectSpec` (interface): interface ScreenEffectSpec — One screen-feedback effect, fully data-first so a whole controller serializes. `kind` is a free label the game assigns and styles ("damage", "heal", "poison", "boost", …); the model never interprets it. Everything visible is a parameter: color, peak intensity, region shape, easing, and either a transient duration or a sustained (optionally oscillating) hold.
- `ScreenEffectsController` (interface): interface ScreenEffectsController — A live, clock-driven screen-feedback controller.
- `ScreenEffectsOptions` (interface): interface ScreenEffectsOptions — Options for {@link createScreenEffects}.
- `ScreenEffectsSnapshot` (interface): interface ScreenEffectsSnapshot — Serializable state of every active effect, for save/restore and replay.
- `ScreenRect` (interface): interface ScreenRect { minX: number; minY: number; maxX: number; maxY: number } — ⚠ undocumented · used by `isMarquee`: True when the drag is large enough to be a marquee rather than a click.
- `SelectionBookmarkSnapshot` (interface): interface SelectionBookmarkSnapshot — The serializable shape of a {@link SelectionBookmarks} store: each key maps to its ordered, deduplicated id list. Plain data — safe to persist in a save file or replicate over the wire, and the exact input {@link createSelectionBookmarks} restores.
- `SelectionBookmarks` (interface): interface SelectionBookmarks — A generic, keyed store of saved id sets ("bookmarks") over stable string ids — the reusable layer under RTS control groups, camera bookmarks, saved squads, editor selection presets, and accessibility recall. It owns storage only: binding, recall, enumeration, pruning, and serialization. It never touches the active {@link SelectionSet} or the camera — replacement/merge and focus stay caller hooks (see {@link recallSelectionBookmark}) so one store serves any genre, input scheme, or focus policy.
- `SelectionPruneResult` (interface): interface SelectionPruneResult — Outcome of a {@link SelectionBookmarks.prune} pass — what the validity predicate removed.
- `SelectionSet` (interface): interface SelectionSet { add(id: string): void; remove(id: string): void; toggle(id: string): void; has(id: string): boolean; replace(ids: Iterable<string>): void; clear(): void; list(): string[]; size(): number } — ⚠ undocumented · used by `createSelectionSet`: An ordered, deduplicated set of selected instance ids for RTS unit-command routing.
- `SensorProbeOptions` (interface): interface SensorProbeOptions { range: number; variableId: string; falloff?: "linear" | "none" } — ⚠ undocumented · used by `useHiddenStateProbe` (@jgengine/shell/vision/HiddenStateProbeHud): Reads a hidden zone/entity state variable in range (EMF / thermometer / geiger style sensor verb, #116).
- `SensorReading` (interface): interface SensorReading { sourceId: string; variableId: string; value: HiddenStateValue; strength: number; distance: number } — ⚠ undocumented · used by `useHiddenStateProbe` (@jgengine/shell/vision/HiddenStateProbeHud): Reads a hidden zone/entity state variable in range (EMF / thermometer / geiger style sensor verb, #116).
- `SequenceCue` (interface): interface SequenceCue<Payload = unknown> — One scheduled beat of a cutscene: a typed cue that fires when the playhead reaches `atMs`.
- `SequenceDirector` (interface): interface SequenceDirector<Payload = unknown> — A data-driven cutscene: an ordered timeline of typed cues that fire on a single injected clock. See {@link createSequenceDirector}.
- `SequenceDirectorOptions` (interface): interface SequenceDirectorOptions<Payload = unknown> — Options for {@link createSequenceDirector}.
- `SequenceSnapshot` (interface): interface SequenceSnapshot — Serializable snapshot — enough to resume a cutscene exactly where a save left it.
- `SequenceState` (interface): interface SequenceState — A read-only view of the director's playback state, returned by {@link SequenceDirector.state}.
- `SharedAnnotations` (interface): interface SharedAnnotations — Local annotation edits that also broadcast, plus `apply` for inbound edits. `add*`/`remove`/`clear` mirror {@link AnnotationLayer} but return globally-unique ids so two clients never collide.
- `SharedAnnotationsDeps` (interface): interface SharedAnnotationsDeps — Construction options for {@link createSharedAnnotations}.
- `SimClock` (interface): interface SimClock { advance(realDt: number): number; now(): number; advancedSeconds?(): number; snapshot(): ClockSnapshot; hydrate(snapshot: ClockSnapshot): void; calendar(): CalendarTime; isPaused(): boolean; speed(): number; pause(): void; play(): void; to… — ⚠ undocumented · used by `createSimContext` (@jgengine/core/runtime/simContext): Build `ctx.sim` for a context; `createGameContext` calls this from `definition.simulation`.
- `SkillCheckConfig` (interface): interface SkillCheckConfig { trackWidth: number; zone: SkillCheckZone; markerPeriod: number; window: number; zoneDriftPerSecond?: number } — ⚠ undocumented · used by `skillCheckZoneAt`: A timing-bar skill check that succeeds when the moving marker is released inside the target zone.
- `SkillCheckResult` (interface): interface SkillCheckResult { success: boolean; timedOut: boolean; markerPosition: number; zone: SkillCheckZone } — ⚠ undocumented
- `SkyEnvironmentDescriptor` (type): type SkyEnvironmentDescriptor = { kind: "sky" } & Required< Pick<SkyEnvironmentConfig, "preset" | "timeOfDay"> > & Omit<SkyEnvironmentConfig, "preset" | "timeOfDay"> — ⚠ undocumented
- `SlotAssignmentOptions` (interface): interface SlotAssignmentOptions — Tuning for {@link assignFormationSlots}' stable, low-churn matching.
- `SnapMode` (type): type SnapMode = "grid" | "free" | "surface" — ⚠ undocumented
- `SnowEnvironmentDescriptor` (type): type SnowEnvironmentDescriptor = { kind: "snow" } & Required< Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color" | "opacity"> > — ⚠ undocumented · used by `snow`: Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
- `SoilRules` (interface): interface SoilRules — Fully-defaulted soil params parsed from a volume's `meta`.
- `SoundDef` (interface): interface SoundDef { id: string; url?: string; synth?: SynthPatch; bus: AudioBusId; gain?: number; loop?: boolean; maxVoices?: number; priority?: number; positional?: boolean; falloff?: AudioFalloffConfig; doppler?: number; spatial?: {panning: "hrtf" | "equal… — ⚠ undocumented · used by `DEFAULT_FEEDBACK_CUE_SOUNDS` (@jgengine/core/audio/feedbackCues): Short procedural reactions - no samples to load, so every game has impact feedback without authoring audio.
- `SpatialGrid` (class): class SpatialGrid — A uniform-grid broad-phase over the x/z plane, separate from the rigid-body sim, for cheap same-tick proximity across hundreds–thousands of simple movers (swarm enemies). Rebuild each tick from the caller's own position arrays, then `queryCircle` (enemies hitting the player / an AoE) or `forEachPair` (mutual separation). Both are precise: no false negatives, no false positives beyond the exact distance test.
- `SpawnDirectorConfig` (interface): interface SpawnDirectorConfig { waves: readonly WaveManifest[]; maxAlive?: number; escalationPerSecond?: number; alertBudgetPerSecond?: number; alertDecayPerSecond?: number; playerBudgetPerSecond?: number; maxSpawnsPerTick?: number; loop?: boolean; seed?: number; spawnP… — ⚠ undocumented
- `SpawnDirectorState` (interface): interface SpawnDirectorState { wave: number; elapsed: number; waveElapsed: number; budget: number; alert: number; spawnedThisWave: number; spawnedTotal: number; rng: RandomSeed; done: boolean } — ⚠ undocumented
- `SpawnEntry` (interface): interface SpawnEntry { id: string; cost: number; weight?: number; minWave?: number } — ⚠ undocumented
- `SpawnRequest` (interface): interface SpawnRequest { entryId: string; cost: number; wave: number; point?: NavPoint; laneId?: number } — ⚠ undocumented
- `StatCatalog` (type): type StatCatalog = Record<string, { max: number; min?: number; current?: number }> — ⚠ undocumented
- `StatValue` (interface): interface StatValue extends StatPool — Native entity-stat name retained as a compatibility bridge to the portable pool model.
- `Station` (interface): interface Station — ⚠ undocumented
- `StoredScreenEffect` (interface): interface StoredScreenEffect — A persisted effect record (all spec fields resolved plus its start time and id).
- `StratifiedOptions` (interface): interface StratifiedOptions — Inputs for {@link sampleStratified}: a grid over `area` with one jittered point per cell.
- `StructureGraph` (class): class StructureGraph — A structural-integrity graph over a building — nodes are pieces (walls, beams, floors), edges are load-bearing connections, some nodes are anchored foundations. `damage`/`damageEdge` wear pieces and connections down; when a piece shatters or an edge severs, the graph recomputes which pieces still reach an anchor and hands back every newly-disconnected piece as one `CollapseEvent`. Feed that to `toDebris` to sink the fallen pieces into a `PhysicsWorld` as rigid bodies ("The Finals" smooth destruction, Rainbow Six walls). Coarse by design: it replicates the collapse event, not per fragment.
- `StructureMaterial` (interface): interface StructureMaterial { id: string; strength: number; mass?: number } — ⚠ undocumented
- `SupportResult` (interface): interface SupportResult { supported: readonly string[]; unsupported: readonly string[]; distance: Readonly<Record<string, number>> } — ⚠ undocumented
- `SurfaceDelta` (interface): interface SurfaceDelta — A compact record of the surface-material cells a paint stroke touched: parallel `indices`/`before`/`after` arrays into the per-cell surface grid. One per stroke keeps paint undo history small.
- `SurfaceGridLine` (interface): interface SurfaceGridLine — One draped grid line from {@link surfaceGridLines}: its axis, emphasis, and draped vertices.
- `SurfaceGridOptions` (interface): interface SurfaceGridOptions — Shaping for {@link surfaceGridLines}: region, spacing, emphasis cadence, and draping.
- `SurfaceLaws` (interface): interface SurfaceLaws — The place model: a world is the place you play in — substrate (ground) plus laws (physics, surface) — never a dressed diorama. Sky look, foliage scatter, props, and sculpt are content: they are authored in the editor (or by a content preset that writes into the scene document) and consumed through the authored-scene seams, not declared on the world.
- `SurfaceStroke` (interface): interface SurfaceStroke — Accumulates a whole paint drag — many surface stamps — into one compact {@link SurfaceDelta}. Keeps each cell's first `before` and latest `after`, so undo replays the paint as a single step.
- `SynthPatch` (interface): interface SynthPatch — A procedural sound cue: a set of voices triggered together, each with its own `delay`, summed into one one-shot. Pure serialisable data — the shell realises it on Web Audio, so the same catalog runs headless in tests with no `AudioContext`.
- `TERRAIN_MATERIAL_PALETTES` (const): const TERRAIN_MATERIAL_PALETTES: Record<TerrainMaterial, TerrainPalette> — ⚠ undocumented
- `TargetAcquirer` (interface): interface TargetAcquirer — A stateful acquirer that holds the current target across passes — sugar over {@link acquireTarget}.
- `TargetedOrderPayload` (interface): interface TargetedOrderPayload — Payload for a targeted action: pursue one target until in range, holding within a leash.
- `TerraformDelta` (interface): interface TerraformDelta — A compact record of the vertices a sculpt stroke touched: parallel `indices`/`before`/`after` arrays into the offset grid. Storing one of these per stroke keeps undo history small — the whole terrain document is never copied.
- `TerraformEdit` (interface): interface TerraformEdit — A single sculpt stamp: which brush, where, and its shaping parameters.
- `TerraformFalloff` (type): type TerraformFalloff = "smooth" | "linear" | "none" — How a brush's strength fades from its center to its rim.
- `TerraformMode` (type): type TerraformMode = "raise" | "lower" | "smooth" | "flatten" | "noise" | "ramp" | "paint" — A sculpt operation kind: heightfield brushes plus the surface-paint brush.
- `TerraformShape` (type): type TerraformShape = "circle" | "square" — A brush footprint: a round disc or an axis-aligned square.
- `TerraformSnapshot` (interface): interface TerraformSnapshot { bounds: Aabb; cellSize: number; cols: number; rows: number; offsets: readonly number[]; surfaces: readonly (string | null)[]; layers?: readonly TerrainMaterialLayer[]; weights?: readonly number[] } — ⚠ undocumented · used by `applyDeltaToSnapshot`: Returns a new snapshot with a delta's `after` offsets applied (copy-on-write — inputs untouched).
- `TerraformStroke` (interface): interface TerraformStroke — Accumulates a whole drag — many brush stamps — into one compact {@link TerraformDelta}. Keeps each vertex's first `before` and latest `after`, so undo replays the stroke as a single step even though the pointer fired dozens of moves.
- `TerrainCircleRegion` (interface): interface TerrainCircleRegion extends TerrainRegionStyle — A circular palette zone painted over the base terrain palette — snow caps, ash wastes, spawn circles.
- `TerrainDetailConfig` (interface): interface TerrainDetailConfig — Procedural detail-surface layer for terrain: a noise-driven shader that keeps the biome-tinted base ground (from `colors`/`biomeBands`) and blends distinct rock, sand, and snow over it by slope, height, and waterline — turning a flat vertex-colour surface into varied, textured-reading ground with no image assets.
- `TerrainDetailMaterialConfig` (interface): interface TerrainDetailMaterialConfig — Real PBR texture applied over the ground surface — the seam that lets a game put a `buildMaterialCatalog` material on terrain. Blends with, never replaces, the procedural detail shader: color/roughness/ao tile the maps by world position, `strength` fades them over the existing vertex-colour + noise look.
- `TerrainEnvironmentDescriptor` (type): type TerrainEnvironmentDescriptor = { kind: "terrain" } & Required< Pick<TerrainEnvironmentConfig, "bounds" | "height"> > & Omit<TerrainEnvironmentConfig, "bounds" | "height"> — ⚠ undocumented · used by `terrain`: Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
- `TerrainField` (interface): interface TerrainField — A sampleable ground surface: height and normal at any x/z, with optional bounds and water level.
- `TerrainFlattenMask` (interface): interface TerrainFlattenMask { center: EnvironmentVec2; radius: number; height?: number; falloff?: number } — ⚠ undocumented · used by `padFlattenMasks` (@jgengine/core/world/features): Derives implicit `TerrainFlattenMask`s carving each pad's footprint into the terrain beneath it.
- `TerrainMaterialLayer` (interface): interface TerrainMaterialLayer — One material layer in a terrain's reorderable stack: a palette `surface` id (drives the base color) plus its render parameters. Array order is the stack order — lower index paints under higher. `roughness`/`tiling`/`triplanar`/`tint`/`opacity` are carried as data so a runtime game reads them straight off the snapshot.
- `TerrainMaterialRegion` (type): type TerrainMaterialRegion = TerrainCircleRegion | TerrainPolylineRegion | TerrainRectRegion — A palette zone painted over the base terrain palette. Circle (the default when no `shape` is given), `polyline` ribbons for roads/rivers, and rotatable `rect` districts all paint fully inside their core and blend back across `falloff`; later regions in the list win overlaps.
- `TerrainPalette` (interface): interface TerrainPalette { low: string; high: string; waterline: string } — ⚠ undocumented
- `TerrainPathProfile` (interface): interface TerrainPathProfile — A serializable path-driven terrain modifier. The `points` centerline reshapes the heightfield across a corridor of `width`, feathering back to the surrounding ground across `shoulder`. `height` sets the centerline target (sample / fixed / grade); `depth` carves a channel below it (deepest at the centerline, easing to zero at the core edge — rivers and trenches); `retaining` raises walls where the cut/fill exceeds a threshold; `maxCut`/`maxFill` cap how far the ground may move from its base height. All fields are plain data (numbers, string enums, point arrays) so a profile round-trips through the scene document and evaluates identically at author time and runtime.
- `TerrainPolylineRegion` (interface): interface TerrainPolylineRegion extends TerrainRegionStyle — A ribbon palette zone following a centerline — roads and rivers, instead of chaining overlapping circles.
- `TerrainRectRegion` (interface): interface TerrainRectRegion extends TerrainRegionStyle — A rectangular palette zone, optionally rotated about the world y axis — plazas, fields, districts.
- `TerrainRegionStyle` (interface): interface TerrainRegionStyle — Palette and blend fields shared by every `TerrainMaterialRegion` shape.
- `TerrainSurfaceRule` (interface): interface TerrainSurfaceRule — A height/slope predicate for auto-painting a surface layer (e.g. rock on steep slopes, snow up high).
- `ThreatTable` (interface): interface ThreatTable { add(sourceId: string, amount: number): number; set(sourceId: string, amount: number): void; threatOf(sourceId: string): number; decay(dt: number): void; highest(options?: HighestThreatOptions): string | null; ranked(): ThreatEntry[]; taun… — ⚠ undocumented
- `TimerDirection` (type): type TimerDirection = "down" | "up" — A serializable set of named countdown / countup timers evaluated against an injected clock. One primitive covers round timers, respawn clocks, and ability cooldown/charge — they are the same mechanic (elapsed vs. duration on a clock), so `id` and any labels are free strings the engine never interprets.
- `TimerExpiryListener` (type): type TimerExpiryListener = (id: string) => void — Listener notified when a timer newly expires. Receives the timer id.
- `TimerRead` (interface): interface TimerRead — A single timer's resolved state for one read. All fields are plain numbers so a HUD can render without touching the model. For a looping timer the values describe the current cycle; `expired` is only ever `true` for a finished non-looping timer (loops signal completion through {@link TimerSet.poll}).
- `TimerSet` (interface): interface TimerSet — A named set of countdown / countup timers on an injected clock. Start, pause, resume, stop, reset, and read timers by free-string id; observe structural changes with {@link TimerSet.subscribe} and expiry edges with {@link TimerSet.poll} / {@link TimerSet.onExpire}.
- `TimerSetOptions` (interface): interface TimerSetOptions — Options for {@link createTimerSet}.
- `TimerSetSnapshot` (interface): interface TimerSetSnapshot — Serializable state of a whole {@link TimerSet}.
- `TimerSnapshot` (interface): interface TimerSnapshot — One timer's serializable state — elapsed resolved at snapshot time, ready to re-anchor on restore.
- `TimerStartOptions` (interface): interface TimerStartOptions — Options for {@link TimerSet.start}.
- `ToneVoice` (interface): interface ToneVoice — A pitched oscillator voice: a 12ms linear attack to `gain`, then an exponential decay to silence across `duration`, with an optional exponential pitch slide from `freq` to `slideTo`.
- `Traffic` (interface): interface Traffic — Traffic on an authored lane graph: cars follow lane spans with IDM car-following, hold at stop lines, cross intersections under a signal phase or first-come right-of-way, change lanes, park in authored spots, and grow or shrink with the caller's `demand`. Deterministic — cars advance in insertion order, ties break on id, and the injected generator is the only source of variety. Bounded per tick: one pass over the cars, one sorted pass per occupied lane, no path search.
- `TrafficCarView` (interface): interface TrafficCarView — One car's live state, as a renderer, a game or the devtools overlay reads it.
- `TrafficOptions` (interface): interface TrafficOptions — Everything {@link createTraffic} needs: the graph, the injected generator and the caller's policies.
- `TrafficRoutePolicy` (type): type TrafficRoutePolicy = (context: { carId: string; laneId: string; nodeId: string; /** Outbound lanes that are not the lane the car arrived on, sorted by id. */ options: readonly string[]; }) => string | null — Caller-supplied exit choice at a junction: return one of `options`, or `null` to leave the graph.
- `TrafficSignalState` (interface): interface TrafficSignalState — An intersection's signal right now: which phase is green and for how long.
- `TrafficSnapshot` (interface): interface TrafficSnapshot — Serializable traffic state: the fleet, the parking occupancy, the signal clocks and the demand.
- `TrafficStats` (interface): interface TrafficStats — Counters a devtools probe, a HUD or a test reads.
- `TrafficTuning` (interface): interface TrafficTuning — Every per-car behaviour number, retunable in play.
- `TravelPointDef` (interface): interface TravelPointDef<TMeta = unknown> — A fast-travel destination the game defines. Discovery is tracked separately.
- `TravelPointView` (interface): interface TravelPointView<TMeta = unknown> extends TravelPointDef<TMeta> — A destination plus its discovery state (and distance from a query origin, when given).
- `TriggerActionDefinition` (interface): interface TriggerActionDefinition — A game-declared action the editor can assign to a volume/marker trigger. Schema drives the inspector params; `targets`/`events` optionally narrow where it appears.
- `TriggerDispatchEvent` (interface): interface TriggerDispatchEvent — Fired when a watched actor trips an authored trigger edge.
- `TriggerEvent` (type): type TriggerEvent = "enter" | "exit" | "interact" — Event edge that can fire an authored trigger.
- `TriggerHandlers` (type): type TriggerHandlers = Readonly<Record<string, (event: TriggerDispatchEvent) => void>> — Handler map keyed by action id — unknown actions are skipped unless `onDispatch` is set.
- `TriggerSourceKind` (type): type TriggerSourceKind = "marker" | "volume" — Document collection a trigger source lives on.
- `TrimmedIntersections` (interface): interface TrimmedIntersections — Renderer-ready output of {@link buildTrimmedIntersections}: trimmed ribbons + welded junction surfaces.
- `TrimmedRoad` (interface): interface TrimmedRoad — A street sub-path after trimming, plus the cuts (0–2) that shortened it. Feed `path` to {@link buildRoadRibbon}.
- `UtilityBrain` (interface): interface UtilityBrain — Utility-scored action selection over decaying needs: score every option's appeal through response curves, pick the best reachable candidate minus its cost, and hold that pick until a rival clears the hysteresis margin — unless a declared interrupt fires.
- `UtilityBrainConfig` (interface): interface UtilityBrainConfig extends UtilityTunables — Everything a utility brain needs: the shared need set, its scored options, and selection policy.
- `UtilityBrainSnapshot` (interface): interface UtilityBrainSnapshot — Serializable brain state: the held pick plus any in-play retuning. Needs save separately.
- `UtilityCandidate` (interface): interface UtilityCandidate — One reachable instance of an option this tick; `cost` is the caller's own effort number.
- `UtilityDebugSnapshot` (interface): interface UtilityDebugSnapshot — JSON-safe view of a brain for the devtools overlay and bug reports.
- `UtilityDecision` (interface): interface UtilityDecision — The outcome of one {@link UtilityBrain.decide}. Valid until the next `decide` call.
- `UtilityInterrupt` (interface): interface UtilityInterrupt — A need level that overrides the sticky pick the moment it is crossed.
- `UtilityOption` (interface): interface UtilityOption — A thing an agent can decide to do, scored against its needs.
- `UtilityScore` (interface): interface UtilityScore — One option's need-driven score, ignoring candidate cost.
- `UtilitySwitchReason` (type): type UtilitySwitchReason = "initial" | "score" | "interrupt" | "unavailable" — Why the brain's pick changed on the tick it changed.
- `UtilityTerm` (interface): interface UtilityTerm — One need's contribution to an option's appeal.
- `UtilityTunables` (interface): interface UtilityTunables — In-play dials that stay reachable through {@link UtilityBrain.retune}.
- `VEGETATION_VOLUME_KIND` (const): const VEGETATION_VOLUME_KIND: "vegetation" — The editor volume kind that marks an area as vegetation fill.
- `VISIBILITY_HIDDEN` (const): const VISIBILITY_HIDDEN: 0 — Numeric code for a cell no group member has seen, or has fully forgotten.
- `VISIBILITY_OBSERVED` (const): const VISIBILITY_OBSERVED: 2 — Numeric code for a cell a group currently observes.
- `VISIBILITY_REMEMBERED` (const): const VISIBILITY_REMEMBERED: 1 — Numeric code for a cell seen before but not currently in view (last-known).
- `Vec3` (type): type Vec3 = EntityPosition — ⚠ undocumented · used by `catenaryCurve`: True hyperbolic catenary between two anchors — the shape a uniform cable actually takes under gravity.
- `VehicleDamage` (interface): interface VehicleDamage — Fixed-zone crash damage for a vehicle: impacts accumulate into discrete stages, stages change handling and show a bounded dent, and a part can come off at a set stage. Data-driven and bounded by construction — the zone set is authored, each zone's deformation is one capped displacement, and no mesh is edited. Serializes through {@link snapshot}/{@link restore}, so a save, a replay or a host correction resumes mid-crash.
- `VehicleDamageConfig` (interface): interface VehicleDamageConfig — Everything {@link createVehicleDamage} needs.
- `VehicleDamageEffect` (interface): interface VehicleDamageEffect — Handling change one damage zone applies at its *last* stage. Multiplier fields read `1` = undamaged, and a zone part-way through its stages gets the fraction between; `steerPull` and `drag` are additive and reach their full value only at the last stage.
- `VehicleDamageEffectResolved` (interface): interface VehicleDamageEffectResolved — Every zone's handling cost summed into one set of numbers (all fields present, defaults filled).
- `VehicleDamageState` (interface): interface VehicleDamageState — Serializable damage state: {@link VehicleDamage.restore} needs only this.
- `VehicleDamageTransition` (interface): interface VehicleDamageTransition — A zone crossing a threshold this tick — the event a HUD feed, a smoke puff or a camera shake keys off.
- `VehicleDamageZone` (interface): interface VehicleDamageZone — One damageable zone: a fixed local body point, the impulse thresholds that step it through its stages, the bounded dent it shows, and the handling it costs. There is no mesh editing — a zone's deformation is one displacement it can never exceed, so the visual can never grow without limit.
- `VehicleDamageZoneState` (interface): interface VehicleDamageZoneState — Live state of one zone, as a HUD or a save reads it.
- `VehicleDeformation` (interface): interface VehicleDeformation — A zone's current dent: a bounded local displacement and whether the part has come off.
- `VehicleFeel` (interface): interface VehicleFeel — Comparable handling numbers derived from a tuning — what "the numbers and the feel" means to a shop screen, a HUD or a test. Grip is reported as the curve's own shape, so a compound change shows up as a moved peak rather than a single scalar.
- `VehicleImpact` (interface): interface VehicleImpact — A single blocked-move event a car can react to (#1051): crash damage, screen shake, a metal-crunch cue. Reported once, when a move is first vetoed, then consumed by {@link VehicleObstacleClamp.takeImpact}.
- `VehicleObstacleClamp` (interface): interface VehicleObstacleClamp — A planar move clamp for a kinematic car: feed {@link clampMove} to a vehicle's `clampMove` hook so an attempted XZ displacement slides along world solids instead of driving through them, and read {@link takeImpact} once per tick for the crash it produced.
- `VehiclePart` (interface): interface VehiclePart — One installable part. `slot` is the caller's own grouping ("tires", "engine", "front-bumper") — the engine does not name slots, so a game's upgrade tree stays its own. Effects compose in install order, and a part's `gripCurve` replaces the base tire compound outright (last one installed wins).
- `VehiclePartEffect` (interface): interface VehiclePartEffect — How one part moves a stat: multiply the base by `scale`, then add `add`. Both default to no change.
- `VehicleSeats` (class): class VehicleSeats — Composes `scene/mount`'s control-transfer bookkeeping with the seat/camera/movement-mode transition every enter/exit-vehicle flow needs (#533.2): boarding resolves a free seat and reports the camera target, drive target, and rider movement-lock patch in one call; leaving computes a side-door placement next to the vehicle and reports the same triad in reverse. Pure — no entity/camera side effects — the caller applies `riderMovementPatch`/`placement`/`cameraTarget` via its own `ctx`.
- `VehicleSetup` (interface): interface VehicleSetup — A composed vehicle: the tuning to hand the sim, the feel it produces, and what was installed.
- `VehicleStat` (type): type VehicleStat = | "engineAccel" | "brakeAccel" | "topSpeed" | "reverseSpeed" | "turnRate" | "turnSpeedRef" | "gripStrength" | "handbrakeGrip" | "rollingResistance" | "coastDeceleration" — A tunable vehicle number a part can move; each names a {@link KinematicVehicleTuning} field.
- `VisibilityCells` (interface): interface VisibilityCells — Dense per-cell readout for one group, shaped for minimap/overlay drawing.
- `VisibilityConfig` (interface): interface VisibilityConfig — Per-game visibility configuration, surfaced on `PlayableGame.visibility`. Everything is optional: an existing game that sets nothing gets the conservative engine defaults automatically. This is the scene-level and per-kind override seam (requirement: per-object, per-layer, per-scene, and global controls).
- `VisibilityDelta` (interface): interface VisibilityDelta — The cells that changed state for one group in a single {@link VisibilityField.observe} call — a pure incremental readout for rendering, minimaps, AI, UI, and authoritative replication. Never lists unchanged cells, so it stays bounded by how much the group's view actually moved.
- `VisibilityField` (interface): interface VisibilityField — A gameplay (fog-of-war) knowledge field: per viewer group, every grid cell is hidden, remembered, or observed. Distinct from render culling in `core/visibility` — this models what a team KNOWS, not what a camera can draw. It generalizes `world/fog`'s single-group reveal-once model to many groups with configurable terrain memory, and keeps each group's knowledge isolated so one group's hidden state can never be derived from another's.
- `VisibilityFieldConfig` (interface): interface VisibilityFieldConfig — Construction options for {@link createVisibilityField}.
- `VisibilityFieldState` (interface): interface VisibilityFieldState — Serializable snapshot of a whole field — JSON round-trips losslessly.
- `VisibilityGroupState` (interface): interface VisibilityGroupState — Sparse serialized knowledge for one group — only non-hidden cells are stored.
- `VisibilityMemory` (type): type VisibilityMemory = | { readonly kind: "permanent" } | { readonly kind: "none" } | { readonly kind: "decay"; readonly updates: number } — How a cell decays after a group stops observing it — the terrain-memory policy. `permanent` keeps last-known terrain forever (RTS explored map); `none` drops it straight back to hidden the moment it leaves view (pure line-of-sight stealth); `decay` remembers it for `updates` observe cycles, then hides it. Day/night, height, sensor, and stealth rules are NOT encoded here — the caller bakes those into which cells it reports as observed each update.
- `VisibilityState` (type): type VisibilityState = "hidden" | "remembered" | "observed" — One viewer group's knowledge of a cell: never/forgotten, last-known, or live.
- `VisibilitySystem` (interface): interface VisibilitySystem { update(): VisibilityResult; isVisible(id: string): boolean; isPreloaded(id: string): boolean; boundsOf(id: string): RenderBounds | undefined; settings(): CullingSettings; setSettings(patch: Partial<CullingSettings>): void; stats(): Visibi… — ⚠ undocumented
- `VolumeDistribution` (type): type VolumeDistribution = "volume" | "radial" — Fill policy for a sphere/shell: `"volume"` = volume-uniform (even density); `"radial"` = radius-uniform.
- `VolumetricCloudsConfig` (interface): interface VolumetricCloudsConfig — Volumetric cloud layer config for `sky()` — a raymarched cloud slab mounted from the environment `sky` seam. Pure config + defaulting here; the raymarch shader lives in the `shell` renderer (`environment/VolumetricClouds.tsx`), mounted alongside `SkyDome` whenever a sky descriptor carries this field. Off by default — omit `volumetricClouds` on `sky({...})` and no layer mounts.
- `VolumetricCloudsRules` (interface): interface VolumetricCloudsRules — Fully-defaulted volumetric cloud params, resolved from a `VolumetricCloudsConfig`.
- `VoxelFace` (type): type VoxelFace = "px" | "nx" | "py" | "ny" | "pz" | "nz" — ⚠ undocumented
- `VoxelGround` (interface): interface VoxelGround — A procedural volume of blocks. `size` is the generator domain; `generator` is algorithm params only.
- `VoxelGroundSize` (interface): interface VoxelGroundSize — Size of a `voxel` ground: the generator's domain per axis; axes may be `Infinity` for streaming volumes.
- `VoxelMaterial` (interface): interface VoxelMaterial { id: number; name: string; strength: number; drop?: string } — ⚠ undocumented
- `VoxelVolume` (class): class VoxelVolume — A runtime-editable dense voxel grid — the carve/deposit op behind destructible dig worlds (Deep Rock Galactic tunnels, Astroneer terrain). Cells hold a material id (0 = empty); `carve` clears a sphere of solid cells that a tool is strong enough to break and returns how many it removed (feed that to a loot roll), `deposit` fills a sphere with a material. World↔cell mapping is `origin`+`scale`.
- `WATER_SCHEMA` (const): const WATER_SCHEMA: ParamSchema — The water parameter schema — drives the inspector and `meta` parse via the studio seam.
- `WaterRules` (interface): interface WaterRules — Fully-defaulted water surface params parsed from a volume's `meta`.
- `WaterSurface` (interface): interface WaterSurface { readonly level: number; readonly waves: readonly GerstnerWave[]; height(x: number, z: number, time: number): number; normal(x: number, z: number, time: number): WaterNormal; displace(x: number, z: number, time: number): readonly [number, … — ⚠ undocumented
- `WaveManifest` (interface): interface WaveManifest { budget: number; entries: readonly SpawnEntry[]; duration?: number; budgetPerSecond?: number } — ⚠ undocumented
- `WaveRunner` (interface): interface WaveRunner — A live, observable, serializable wave/spawn runner over a seeded spawn director.
- `WaveRunnerConfig` (interface): interface WaveRunnerConfig extends SpawnDirectorConfig — Configuration for {@link createWaveRunner}: the full {@link SpawnDirectorConfig} (escalating waves, budgets, seed, spawn points) plus an optional {@link WaveSpawnSink}. The runner owns the director state — you never pass a `SpawnDirectorState` here.
- `WaveSpawnSink` (type): type WaveSpawnSink = (request: SpawnRequest) => void — A callback the wave runner hands each {@link SpawnRequest} the underlying spawn director emits. The runner never instantiates entities itself — it forwards the request (a free-string `entryId` "kind", cost, wave, optional point/lane) to the game, which decides what to build. Keeps the runner genre-agnostic.
- `WaveView` (interface): interface WaveView — A pooled, per-frame readout of the current wave — the "brain behind WAVE 3". Reused across {@link WaveRunner.view} calls (never per-frame allocated), so read it and render it, don't retain it.
- `Waypoint` (type): type Waypoint = readonly [number, number, number] — ⚠ undocumented · used by `planSolidRoute` (@jgengine/core/nav/solidRoute): Plan an exact-endpoint local route over indexed movement boxes using the shared nav grid.
- `WaypointEntry` (interface): interface WaypointEntry — A single player-placed waypoint. World-XZ only — serializable and renderer-free.
- `WaypointGuidance` (interface): interface WaypointGuidance — Direction/range to the tracked waypoint, for an on-screen guide arrow.
- `WaypointSnapshot` (interface): interface WaypointSnapshot — Whole serializable state of a {@link WaypointStore} — drop into a save blob.
- `WaypointStore` (interface): interface WaypointStore — Player-owned waypoint layer — place/track/clear pins, mirror to a `MarkerSet`, and read guide-arrow data.
- `WaypointStoreDeps` (interface): interface WaypointStoreDeps — Construction options for {@link createWaypointStore}.
- `WeatherEnvironmentDescriptor` (type): type WeatherEnvironmentDescriptor = RainEnvironmentDescriptor | SnowEnvironmentDescriptor — ⚠ undocumented
- `WeatherModifierTable` (type): type WeatherModifierTable<K extends string = string> = Record<K, WeatherModifier> — ⚠ undocumented
- `WeatherState` (interface): interface WeatherState { kind: WeatherKind; intensity: number; wind?: WindVector } — ⚠ undocumented
- `WedgeFormationOptions` (interface): interface WedgeFormationOptions — Options for {@link wedgeFormation}.
- `WeightedParamEntry` (interface): interface WeightedParamEntry — One weighted entry in a `weightedList` param — an item id and its relative spawn weight.
- `WeightedRegionEntry` (interface): interface WeightedRegionEntry<P extends SamplePoint = SamplePoint> — A weighted member of a {@link weightedRegion} composite.
- `WindField` (interface): interface WindField { readonly direction: WindVector; readonly speed: number; at(time: number): WindVector; atPoint(x: number, z: number, time: number): WindVector; strengthAt(x: number, z: number, time: number): number } — ⚠ undocumented
- `WorldFeature` (type): type WorldFeature = | PlaceWorldFeature | ({ kind: "biomes" } & BiomesWorldConfig) | ({ kind: "voxel" } & VoxelWorldConfig) | ({ kind: "plots" } & PlotsWorldConfig) | ({ kind: "tilemap" } & TilemapWorldConfig) | EnvironmentWorldFeature | { kind: "flat" } — A declared world shape passed to `defineGame`. The preferred model is the place feature from `world()` (`@jgengine/core/world/place`): substrate + laws, with all dressing authored in the editor. The remaining members — biomes, voxel grid, plots, tilemap, environment, flat — are the legacy code-declared shapes kept for existing games.
- `WorldGridCell` (interface): interface WorldGridCell { x: number; z: number; height?: number; color?: string } — ⚠ undocumented
- `WorldGridConfig` (interface): interface WorldGridConfig — Shared by `biomes()`/`voxel()`/`plots()`/`tilemap()` so the shell can render their declared content as instanced boxes without a hand-written renderer.
- `WorldXZ` (type): type WorldXZ = readonly [number, number] — ⚠ undocumented · used by `compassBearing`: Compass bearing (radians, 0 = map north = −Z, increasing clockwise toward +X = east) from one world XZ point to another.
- `acquireTarget` (function): function acquireTarget(policy: AcquisitionPolicy, selfId: string, held: string | null = null): AcquisitionResult — Run one acquisition pass and pick the best target under `policy`. Pass the currently `held` target so retention hysteresis (`switchMargin`, `dropRangeScale`) can keep the lock stable; pass `null` for a cold acquire. Pure and allocation-light — the caller owns the held-target state.
- `advanceBehaviors` (function): function advanceBehaviors(ctx: GameContext, dt: number): void — Advance every spawned entity carrying a patrol, wander, pursuit or decision graph behavior one tick — the engine reads the descriptor, keeps the per-entity nav state itself, and poses the entity, so ambient traffic and idle NPC routes are register-once (attach the behavior at spawn) instead of a per-game per-frame `advancePathFollow` + `setPose` loop. Instances that are paused or disabled through {@link behaviorControl} retain their state and are skipped. The shell/host call this each frame; a game never does.
- `advanceFreeFlight` (function): function advanceFreeFlight(state: FreeFlightState, intent: FreeFlightIntent, yaw: number, pitch: number | undefined, dt: number, tuning: FreeFlightTuning, options?: Pick<MotionFrameOptions, "authoritativeStep">): FreeFlightStep — Advance one frame of free-flight kinematics. Horizontal uses yaw-relative strafe (A = left, D = right) — never roll/bank. Vertical is independent of pitch unless `alignWithLook` is true (spectator).
- `advanceInterestGate` (function): function advanceInterestGate(state: InterestGateState, config: InterestSchedulerConfig, dt: number, input: InterestGateInput = {}): InterestGateStep — Advance one gate by `dt` seconds against this tick's `input`, mutating `state` in place and returning what the caller should do. Sleeping skips the expensive work (`active: false`) while the gate's timers keep advancing, so state is preserved; a `wake` signal or crossing `wakeRadius` flips it back to active and fires an immediate tick.
- `advancePathFollow` (function): function advancePathFollow(config: PathFollowConfig, state: PathFollowState, dt: number): PathFollowState — Advance a path-follower by `speed * dt` along its authored polyline. Pure — returns the next state. Crosses multiple waypoints in one step, loops when configured, and reports `done` at the end of a non-looping path. No navmesh required (#52); feed it a navmesh route via `pathFromNav` for click-to-move (#51).
- `advanceSpawnDirector` (function): function advanceSpawnDirector(config: SpawnDirectorConfig, state: SpawnDirectorState, dt: number, ctx: DirectorContext): DirectorStep — ⚠ undocumented
- `advanceWave` (function): function advanceWave(config: SpawnDirectorConfig, state: SpawnDirectorState): SpawnDirectorState — ⚠ undocumented
- `annulusRegion` (function): function annulusRegion(center: Vec2, innerRadius: number, outerRadius: number, options: { distribution?: RadialDistribution } = {}): SampleRegion<Vec2> — A ring (annulus) between `innerRadius` and `outerRadius`. `"area"` fills the band with even density; `"radial"` spreads uniformly in radius. Angle first, then radius.
- `applyDeltaToSnapshot` (function): function applyDeltaToSnapshot(snapshot: TerraformSnapshot, delta: TerraformDelta): TerraformSnapshot — Returns a new snapshot with a delta's `after` offsets applied (copy-on-write — inputs untouched).
- `applyPathProfiles` (function): function applyPathProfiles(field: TerrainField, profiles: readonly TerrainPathProfile[]): TerrainField — Composes authored path profiles onto a field — the shared seam that turns a scene road/river/ramp path into flattened, graded, carved, or retained ground. Applies after `flatten` masks in `resolveTerrainField` so a corridor grades over already-leveled pads; call it directly to layer profiles onto any field a game builds by hand. Returns the field unchanged when no profile is given.
- `applyRotationPolicy` (function): function applyRotationPolicy(degrees: number, policy: PlacementRotationPolicy | undefined): number — Resolve a raw drag/scroll heading through a {@link PlacementRotationPolicy} into the heading a placement should actually commit: `locked` ignores the input for its fixed heading, `snap` quantizes, `free` (or an absent policy) normalizes. Deterministic — the single interpreter preview, editor placement, and runtime spawning share instead of each re-implementing the modes.
- `applySurfaceDeltaToSnapshot` (function): function applySurfaceDeltaToSnapshot(snapshot: TerraformSnapshot, delta: SurfaceDelta): TerraformSnapshot — Returns a new snapshot with a surface delta's `after` ids applied (copy-on-write).
- `applyVehicleParts` (function): function applyVehicleParts(base: KinematicVehicleTuning, parts: readonly VehiclePart[]): VehicleSetup — Fold parts onto a base tuning: every effect scales then adds onto the running value, in array order, so a setup is deterministic and a caller can reason about which part moved what. The base tuning is never mutated, so the same base can seed several builds.
- `assignFormationSlots` (function): function assignFormationSlots(members: readonly Vec2[], slots: readonly Vec2[], options: SlotAssignmentOptions = {}): number[] — Match `members` to `slots` by a deterministic greedy nearest assignment: every (member, slot) pair is ranked by squared travel distance (minus a stickiness bonus for a member's previous slot) and assigned in order while both ends are free. Returns `assignment[member] = slot`, or `-1` for members left unmatched when there are fewer slots than members. Ties break by member then slot index, so the result is stable across runs and independent of input ordering — the property replay and lockstep multiplayer rely on. Groups are bounded, so the `O(members·slots·log)` sort is fine; this is not a per-frame whole-world pass.
- `bakeMinimapBackground` (function): function bakeMinimapBackground(source: MinimapBakeSource, options: MinimapBakeOptions = {}): { background: string; mapBounds: MinimapBakeBounds } — One-call convenience: rasterize a source and return `{ background, mapBounds }` for a minimap.
- `bakeMinimapImage` (function): function bakeMinimapImage(source: MinimapBakeSource, options: MinimapBakeOptions = {}): MinimapBake — Rasterizes a top-down terrain image: height maps onto a low→high color ramp (normalized over the sampled height range), slope darkens the shade, water fills below `waterLevel`, and each zone polygon tints the ground it covers. Deterministic for a fixed source. The bounds are preserved so a player-centered minimap pans the image correctly.
- `bearingToCardinal` (function): function bearingToCardinal(bearing: number): Cardinal — ⚠ undocumented
- `beginSurfaceStroke` (function): function beginSurfaceStroke(terrain: Pick<EditableTerrain, "paintRecording">): SurfaceStroke — Opens a paint-stroke recorder over `terrain`; stamp paint edits into it, then read one net delta.
- `beginTerraformStroke` (function): function beginTerraformStroke(terrain: Pick<EditableTerrain, "applyRecording">): TerraformStroke — Opens a stroke recorder over `terrain`; stamp edits into it, then read one net delta.
- `behaviorControl` (function): function behaviorControl(ctx: GameContext): BehaviorControl — Obtain the per-context {@link BehaviorControl} surface for suspending, resuming, seeking, serializing, and inspecting behavior instances by entity id — the lifecycle contract games use to hand pose ownership to possession/streaming/staggering code instead of bypassing the behavior runtime.
- `biomes` (function): function biomes(config: BiomesWorldConfig): WorldFeature — Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain.
- `boardVehicle` (function): function boardVehicle(ctx: GameContext, seats: VehicleSeats, riderId: string, vehicleId: string, options: BoardVehicleOptions = {}): EnterVehicleResult — Apply an existing seat transition to the explicitly named rider. Motor/input policy stays caller-owned.
- `boundaryNeighbors` (function): function boundaryNeighbors(grid: FootprintGrid, cells: readonly GridCell[]): AdjacentCell[] — Every occupied cell orthogonally touching `cells` but outside them — the connective-piece neighbor set.
- `boxFormation` (function): function boxFormation(options: BoxFormationOptions): FormationSlotGenerator — A rectangular grid centered on the destination, front row toward `+forward` — a marching block or a phalanx. Rows fill front-to-back, left-to-right.
- `boxRegion` (function): function boxRegion(min: Point3, max: Point3): SampleRegion<Point3> — An axis-aligned box `[min..max]` in 3D. Uniform density; draws x, y, z in order.
- `budgetWarning` (function): function budgetWarning(coverage: ScatterCoverage): string — The shared clamp-and-warn clause every scatterable kind appends, worded identically: `""` when under budget, else ` · requested N, capped at M (budget)` when the pre-cap ask is known, or ` · capped at M (budget)` when only the ceiling is (city). This is the "surfaced, never silent" budget signal from #1112.
- `buildContextMenu` (function): function buildContextMenu(input: BuildContextMenuInput): ContextMenu | null — Assemble a menu from a target's catalog verbs; null when the target lists none.
- `buildJunctionSurface` (function): function buildJunctionSurface(junction: { x: number; z: number }, approaches: readonly JunctionApproach[], sampleHeight: (x: number, z: number) => number, options: JunctionGeometryOptions = {}): RoadRibbon — Weld one triangulated junction surface onto the corner vertices its incident ribbons END at (from {@link trimPathAtJunctions}). Corners are grouped by approach (so unequal widths cannot interleave a neighbour between a mouth pair), ordered around the node, and bridged as follows:
- `buildNavAdjacency` (function): function buildNavAdjacency(mesh: NavMeshData): NavMeshAdjacency[] — Build polygon adjacency from shared edges and explicit off-mesh links.
- `buildRoadRibbon` (function): function buildRoadRibbon(path: readonly RoadPoint[], width: number, sampleHeight: (x: number, z: number) => number, options: RoadRibbonOptions = {}): RoadRibbon — Triangulate a road centerline into a ground-draped ribbon mesh: the polyline is subdivided, each vertex is offset half a `width` along the local perpendicular, and every vertex sits at `sampleHeight(x, z) + elevation`. Pure geometry — the shell (or any renderer) turns the result into a mesh, and tests can assert on it directly.
- `buildTrimmedIntersections` (function): function buildTrimmedIntersections(streets: readonly IntersectionStreet[], junctions: readonly RoadJunctionInput[], sampleHeight: (x: number, z: number) => number, options: JunctionGeometryOptions = {}): TrimmedIntersections — Trim a set of streets against a set of junctions and weld the crossing surfaces in one call — the ergonomic entry the shell/playground consume for meshing.
- `building` (function): function building(config: BuildingEnvironmentConfig = {}): BuildingEnvironmentDescriptor — Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style. Pass `along` to line road frontage instead of gridding around `position`.
- `buildingIndex` (function): function buildingIndex(buildings: readonly GeneratedBuilding[]): BuildingIndex — ⚠ undocumented
- `canMerge` (function): function canMerge(a: FootprintRegion, b: FootprintRegion, budget: RegionWorkBudget = {}): boolean — Matching kind/tier, disjoint valid source identities/cells, and cardinal contact. Linear in input size.
- `cappedStacks` (function): function cappedStacks<P>(limit: number, magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P> — Keep at most `limit` memberships per `stackKey` (the highest-magnitude ones when `magnitudeOf` is given, else the first-seen). Models capped stacks — e.g. a poison that stacks up to 5 times.
- `carrySpeedMultiplier` (function): function carrySpeedMultiplier(mass: number, carryCapacity: number, owners: number): number — Movement multiplier (1 = unhindered, →0 = crushed) for a body of `mass` carried by `owners`. Pure — the HUD/movement kit reads it to slow a laden hauler (Lethal Company) and to gate items that need 2+ people (R.E.P.O.).
- `carvableTerrain` (function): function carvableTerrain(base: TerrainField): CarvableField — ⚠ undocumented
- `catenaryCurve` (function): function catenaryCurve(a: Vec3, b: Vec3, slack: number, segments: number): Vec3[] — True hyperbolic catenary between two anchors — the shape a uniform cable actually takes under gravity. `slack` is the extra length beyond the straight-line distance, as a fraction (0.1 = 10% longer than taut); larger slack droops deeper. Falls back to {@link sagCurve} for a near-taut cable. Returns `segments + 1` points. Anchors may differ in height; the curve interpolates the chord.
- `chooseContourInterval` (function): function chooseContourInterval(range: number, targetLines = 12): number — Picks a human-friendly contour interval — a `1/2/2.5/5 × 10ⁿ` step — so an elevation `range` splits into roughly `targetLines` bands. Drives adaptive contour density: a tall terrain gets a coarse interval, a shallow one a fine interval, without the author choosing a number. Returns `0` when the range is non-positive (nothing to contour).
- `circleFormation` (function): function circleFormation(options: CircleFormationOptions): FormationSlotGenerator — An evenly spaced ring around the destination — a guard cordon, a huddle, or a surround. Slot 0 sits `startAngle` from forward; slots advance evenly around the circle.
- `clampToMinimapEdge` (function): function clampToMinimapEdge(point: MinimapPoint, size: number): { x: number; y: number } — Clamp a projected point to the minimap edge, preserving direction (edge markers).
- `clearanceZonesFrom` (function): function clearanceZonesFrom(doc: SceneDocumentLike, options: ClearanceOptions = {}): AvoidZone[] — Point-pad clearance **discs** from a document's markers/volumes — the terrain-flatten set (spawns, plots, POIs get a level pad). A marker/volume contributes a disc when it carries `meta.clearance` or its kind is in `kinds`. Paths are *not* included (they render draped, never flattened — see {@link clearanceMasksFrom} for their foliage corridor). Pass `ids`/`kinds` to scope it.
- `closestPoint` (function): function closestPoint(mesh: NavMeshData, point: Vec3): Vec3 | null — Return the closest point on the mesh surface, or null for an empty mesh.
- `collectAuthoredTriggers` (function): function collectAuthoredTriggers(document: SceneDocumentLike): AuthoredTrigger[] — Collect every authored trigger on a document's markers and volumes. Pure — no runtime state. Action params use the live {@link registerTriggerAction} registry when present.
- `combineGravity` (function): function combineGravity(fields: readonly GravityField[]): GravityField — Adds several gravity sources into one field.
- `command` (function): function command(name: string, input?: unknown): PromptCommand — ⚠ undocumented
- `compassBearing` (function): function compassBearing(from: WorldXZ, to: WorldXZ): number — Compass bearing (radians, 0 = map north = −Z, increasing clockwise toward +X = east) from one world XZ point to another. Feeds both the minimap direction and the compass strip.
- `composeRealm` (function): function composeRealm(base: RealmBase, cards: readonly RealmCard[]): ComposedRealm — Assemble a played realm instance at runtime from a deck of modifier cards — the Nightingale "realm card" model. A major card is the biome base; minor cards layer weather, day length, and spawn edits. The result recomposes both the environment (into a sampleable field via `environmentField()`) and the spawn table, and it depends on the weather hooks in this group (#92) to turn its `weather` into gameplay modifiers. Cards apply in array order; sort your deck (majors first) before composing.
- `computeFalloffGain` (function): function computeFalloffGain(distance: number, config: AudioFalloffConfig = {}): number — ⚠ undocumented
- `constrainToNavGrid` (function): function constrainToNavGrid(grid: NavGrid, options?: NavConstrainOptions): (proposed: NavConstrainProposed, entity: NavConstrainEntity) => NavConstrainProposed | null — ⚠ undocumented
- `contextVerb` (function): function contextVerb(label: string, command: string, args?: Record<string, unknown>): ContextVerb — Builds a {@link ContextVerb} for a right-click menu entry.
- `contextVerbInput` (function): function contextVerbInput(menu: ContextMenu, verb: ContextVerb): Record<string, unknown> — Command input a chosen verb dispatches: the verb's own args, plus the target id and the world point, so a single handler can walk the actor to the target then perform it.
- `controlGroupKey` (function): function controlGroupKey(digit: number, options: ControlGroupOptions = {}): string — The stable bookmark key for a control-group `digit` under `options.keyPrefix` — the key a caller passes to `SelectionBookmarks.bind`/`recall` to store a group without going through {@link resolveControlGroupIntent}.
- `createAircraftDynamics` (function): function createAircraftDynamics(initialTuning: AircraftTuning, options: AircraftOptions = {}): AircraftDynamics — Six-degree-of-freedom arcade flight model for fixed-wing, helicopter, and VTOL aircraft.
- `createAnnotationLayer` (function): function createAnnotationLayer(options: AnnotationLayerOptions = {}): AnnotationLayer — Player-drawn map annotation layer: freehand `strokes`, area `shapes`, and pinned `notes`, all world-XZ and serializable. `routes()`/`zones()` project strokes/shapes into the exact shapes `Minimap`/`WorldMap`/`FullscreenMap` already render via their `routes`/`zones` props, so drawing needs no new renderer. State is plain data; `snapshot`/`restore` round-trip through a save.
- `createAreaEffectField` (function): function createAreaEffectField<P = unknown>(state?: AreaFieldState<P>): AreaEffectField<P> — Build a continuous area-effect field. Drive it with `setSource` (once per live source per tick, so shapes follow their emitters) and `step` (to reconcile membership and drain enter/refresh/leave edges). Optionally restore prior membership by passing a `serialize()` snapshot; re-`setSource` live shapes before the first `step` after restore, since shapes are transient.
- `createAssetCatalog` (function): function createAssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef>(): AssetCatalog<TMeta> — ⚠ undocumented
- `createAuthoredTriggerRuntime` (function): function createAuthoredTriggerRuntime(options: { document: SceneDocumentLike; handlers?: TriggerHandlers; /** Invoked for every dispatch after the matching handler (if any). */ onDispatch?: (event: TriggerDispatchEvent) => void; /** Override the collected trigger list (tests / hot-reload). Default: … — Build a runtime that watches a document's authored triggers against moving actors and dispatches to per-action handlers (and optional catch-all). Pure membership math; the game supplies actors each tick from its own player/entity poses.
- `createBallisticSweep` (function): function createBallisticSweep(world: PhysicsWorld, options: BallisticSweepOptions = {}): BallisticSweep — Sweeps each short chord of the closed-form arc through live body AABBs, including sleeping bodies. Thin cover between samples blocks; `step` controls the approximation of the curved path.
- `createBodyBind` (function): function createBodyBind(deps: BodyBindDeps): BodyBind — Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound, despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
- `createBuoyantBody` (function): function createBuoyantBody(world: PhysicsWorld, config: BuoyantBodyConfig): BuoyantBody — ⚠ undocumented
- `createCameraShake` (function): function createCameraShake(config: CameraShakeConfig = {}): CameraShakeController — A seeded, serializable, trauma-based camera shake / impulse controller. A game calls `add(amount, kind?)` on impacts (a hit, an explosion, a landing) to raise trauma in `[0, 1]`; `update(dt)` bleeds it off over time; and `offset()` returns a pooled `{ x, y, z, pitch, yaw, roll }` kick equal to `trauma^exponent` times per-axis maxima times deterministic seeded value-noise sampled along an internal time cursor. A shell consumer applies that offset to the active camera each frame so the view visibly shakes. Nothing here is genre-specific: `kind` is a free label the game styles, all amplitudes/decay are parameters, and `snapshot`/ `restore` round-trips the shake through a save. Deterministic from `seed`: the same seed and dt sequence reproduce the same offsets.
- `createContributionPool` (function): function createContributionPool(goal: ContributionGoal): ContributionPool — ⚠ undocumented
- `createDamageDirectionTracker` (function): function createDamageDirectionTracker(options: DamageDirectionOptions = {}): DamageDirectionTracker — Create a damage-direction tracker: the classic "hit-from" feedback brain. A game calls `registerHit({ angle, intensity, kind })` with the bearing from the player toward the attacker (radians, `0` = front) and the tracker owns the fade timers and eased strength so the renderer just draws an arc per `active()` entry. It is renderer-free and genre-agnostic (the `kind` tag is never interpreted here), allocation-aware (a fixed pool, no per-frame garbage), and fully serializable via `snapshot`/`restore`. Optional angle merging collapses a burst from one direction into a single strong arc.
- `createDamageModel` (function): function createDamageModel(config: DamageModelConfig): DamageModel — ⚠ undocumented
- `createDayNightCycle` (function): function createDayNightCycle(options: DayNightCycleOptions): DayNightCycle — Creates a turnkey day-night cycle: a serializable model that advances a normalized day fraction on an injected clock and blends per-keyframe phase labels and tint/light colors. Wire this one model, then drive an existing sky/daylight seam from `sample()` (or drop it straight into a `{ calendar(): { dayFraction } }` seam via `calendar()`) to get a moving day-night cycle with color grading — no hand-rolled clock or lerp. `phase` labels and colors are free-form; the model never interprets their meaning.
- `createEditableTerrain` (function): function createEditableTerrain(config: EditableTerrainConfig): EditableTerrain — ⚠ undocumented
- `createEnvironmentField` (function): function createEnvironmentField(config: EnvironmentFieldConfig = {}): EnvironmentField — A sampleable environment field: read temperature, wetness, sun/sky exposure, and ambient light at any world position and time. Built on the same renderer-free footing as terrain/wind/water so meters, spawn gating, and damage-in-sunlight read the world the shell renders — no three.js. Instantaneous and pure (no accumulation); stateful build-up belongs to a decay meter reading this field.
- `createFactionGraph` (function): function createFactionGraph(config: FactionGraphConfig): FactionGraph — ⚠ undocumented
- `createFactionRoster` (function): function createFactionRoster(graph: FactionGraph): FactionRoster — ⚠ undocumented
- `createFastTravelNetwork` (function): function createFastTravelNetwork<TMeta = unknown>(options: FastTravelOptions<TMeta>): FastTravelNetwork<TMeta> — A fast-travel network: defined destinations plus per-player discovery, with distance-sorted queries, a `nearest` lookup, a `canTravel` gate, an `onDiscover` seam, and serializable `snapshot`/`restore`. Travel itself is a teleport the game applies to `TravelPointView.position`; this owns the unlock/where-can-I-go state. Points marked `initial` start discovered.
- `createFireGrid` (function): function createFireGrid(config: FireGridConfig): FireGrid — ⚠ undocumented
- `createFogField` (function): function createFogField(config: FogConfig): FogField — ⚠ undocumented
- `createFootprintGrid` (function): function createFootprintGrid(options: FootprintGridOptions = {}): FootprintGrid — Multi-cell footprint occupancy/reservation on a shared build grid — `world/placementController` only owns the ghost preview; this is the persistent claim a committed placement holds so the next hover's `isFree` check (or another player's, in a shared world) sees it. Bridge into `world/placement`'s `PlacementRules.obstacles` with {@link footprintObstacles} instead of hand-rolling an occupancy map per game.
- `createFreeFlightController` (function): function createFreeFlightController(initialTuning: FreeFlightTuning, options: { yaw?: number; pitch?: number; state?: FreeFlightState } = {}): FreeFlightController — Totally free flight for any actor — character, camera, drone, or debug rig. Horizontal is always yaw-relative strafe; vertical is jump/crouch. Use `alignWithLook` for a 6DOF spectator that flies where the camera looks.
- `createFreeFlightState` (function): function createFreeFlightState(): FreeFlightState — Create an empty flight velocity state.
- `createGlideModel` (function): function createGlideModel(config: GlideModelConfig = {}): GlideModel — Gliding/wingsuit descent control — lift, drag, and steering from a launch.
- `createGrappleSwing` (function): function createGrappleSwing(config: GrappleSwingConfig = {}): GrappleSwing — Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.
- `createInterestCensus` (function): function createInterestCensus(): InterestCensusAccumulator — Create a census accumulator so the caller can tally active/dormant gates during the loop it already runs, avoiding any separate full-world scan just to report scheduler metrics.
- `createInterestGateState` (function): function createInterestGateState(config: InterestSchedulerConfig, phase = 0): InterestGateState — Create a dormant gate state, staggered by `phase` (`[0,1)`, typically {@link interestPhase} of the agent id) so siblings created together do not all fire their first active tick on the same frame.
- `createKinematicVehicle` (function): function createKinematicVehicle(initialTuning: KinematicVehicleTuning, options: KinematicVehicleOptions = {}): KinematicVehicle — Arcade ground-vehicle sim (car, kart, bike) with throttle, brake, steer, drift and retunable handling.
- `createLaneGraph` (function): function createLaneGraph(config: LaneGraphConfig): LaneGraph — Read handle over the graph resolved once at construction. The build mutates its working set; this object never changes, so a save system rebuilds it from the scene document instead of serializing it.
- `createLeaderTrail` (function): function createLeaderTrail(config: LeaderTrailConfig): LeaderTrail — A trailing follower formation that chases a leader along its past path — snake/convoy trails.
- `createLodScheduler` (function): function createLodScheduler(config: LodSchedulerConfig): LodScheduler — ⚠ undocumented
- `createMarkerSet` (function): function createMarkerSet<TMeta = unknown>(now: () => number = Date.now): MarkerSet<TMeta> — ⚠ undocumented
- `createMarkerSource` (function): function createMarkerSource<TEntity, TMarker extends MarkerView = MarkerView>(options: MarkerSourceOptions<TEntity, TMarker>): MarkerSource<TMarker> — Adapt a caller-owned array/store to an observable marker source. Projection is cached between source changes, so React reads do not copy the collection per frame. The caller retains ownership of entities, updates, persistence, and subscription scheduling.
- `createMountController` (function): function createMountController(): MountController — ⚠ undocumented
- `createNavCrowd` (function): function createNavCrowd(options: NavCrowdOptions & { nav: NavRuntime }): NavCrowd — Compose {@link createNavRuntime} and {@link createRvoCrowd} into a moving crowd: plan on the mesh, follow the smoothed corridor, avoid each other. Deterministic — agents advance in insertion order and the avoidance solve breaks ties by slot, not chance.
- `createNavGrid` (function): function createNavGrid(config: NavGridConfig): NavGrid — ⚠ undocumented
- `createNavMeshQuery` (function): function createNavMeshQuery(mesh: NavMeshData, options: NavMeshQueryOptions = {}): NavMeshQuery — Create a cached query over a nav mesh: height-aware polygon lookup through a uniform grid, binary-heap A* priced by area costs and bounded by `maxNodes`, portal-funnel path straightening, and edge-walking raycasts.
- `createNavRuntime` (function): function createNavRuntime(options: NavRuntimeOptions & { mesh: NavMeshData }): NavRuntime — Route agents over the nav mesh an editor baked. Wraps {@link createNavMeshQuery}, resolves authored off-mesh links (doors, ladders, jumps) onto the current surface, and exchanges the mesh one scene region at a time so untouched polygons keep their ids and the agents routing over them keep their paths.
- `createOrderQueue` (function): function createOrderQueue<TCtx, TPayload = unknown>(registry: OrderRegistry<TCtx>, options: OrderQueueOptions<TPayload> = {}): OrderQueue<TCtx, TPayload> — Create a per-entity order queue over a shared kind registry. The queue owns the deterministic lifecycle and preemption policy; the kinds own behavior. Nothing here is random or unbounded: id generation is injected, activation is bounded by the pending count, and a single `tick` advances at most the active order plus one activation.
- `createOrderRegistry` (function): function createOrderRegistry<TCtx>(): OrderRegistry<TCtx> — Build an empty order-kind registry. Register the built-in compositions from `orders/orderKinds` or your own verbs, then hand it to `createOrderQueue`. One registry is shared by many per-entity queues.
- `createParticleSystem` (function): function createParticleSystem(config: EmitterConfig = {}, options: ParticleSystemOptions = {}): ParticleSystem — A generic, allocation-aware particle system: one emitter, a fixed pool, and Structure-of-Arrays buffers a renderer uploads straight to the GPU. It is dt-driven (call `update(dt)` each frame) and deterministic — all randomness flows from an injected `seed`, so the same seed and dt sequence reproduce the same frames, and `snapshot`/`restore` round-trips the live pool. Nothing here is combat- or genre-specific: configure it for smoke, sparks, rain, dust, embers, magic, or confetti. Travel/gameplay stays elsewhere; this owns only the spawn-integrate-fade lifecycle.
- `createPathFollow` (function): function createPathFollow(config: PathFollowConfig): PathFollowState — ⚠ undocumented
- `createPerception` (function): function createPerception(initial: PerceptionConfig): PerceptionService — Creates a deterministic sight, sound, and damage perception service with expiring target memory. Signals are judged in the order the caller supplies them, never from the wall clock.
- `createPlacedStructureStore` (function): function createPlacedStructureStore(): PlacedStructureStore — ⚠ undocumented
- `createPlacementController` (function): function createPlacementController(config: PlacementControllerConfig): PlacementController — Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit. Pair with `@jgengine/shell/structures` `PlacementGhost` and {@link placeAssetFromCommit}.
- `createPlotPermissions` (function): function createPlotPermissions(config: PlotPermissionConfig): PlotPermissions — ⚠ undocumented
- `createPoliceResponse` (function): function createPoliceResponse(config: PoliceResponseConfig): PoliceResponse — The wanted level a crime sandbox needs, over the shared heat curve: a crime raises heat only while a witness holds the suspect in view, the heat bleeds on a stated linear curve once the suspect has been out of every witness's sight for `escapeSeconds`, the tier table decides what police do (patrol → investigate → pursue → roadblock), the search area sits where the suspect was last seen and grows while the trail is cold, and a roadblock tier cordons it with authored sites off the lane graph. Heat, tiers and curves are caller policy; witness facts come from `sensor/perception` memory (`sourceId`/`sourceTick` kept), so there is no second sight path.
- `createPoseState` (function): function createPoseState(resolveAllowed: (instanceId: string) => PoseAllowedStates | null | undefined): PoseState — Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.
- `createPromptRegistry` (function): function createPromptRegistry(): PromptRegistry — Create a live, observable interaction-prompt registry over the pure {@link resolveActivePrompt} resolver. Register positioned "press E" prompts, `resolve(playerPosition)` each frame as the hero moves, and read `active()` — the nearest strictly-in-range prompt (higher `priority` beats closer). The set is owned here (register/update/unregister/clear/all); selection stays pure. Subscribers are notified only when the active prompt *changes*, so a HUD does not thrash per frame, and `snapshot`/`restore` round-trip the prompts plus the active id through a save (display payloads are free strings/ids the game owns — the registry never branches on their meaning). Allocation-aware: `all()` and `resolve()` reuse a cached array instead of rebuilding per call.
- `createRagdoll` (function): function createRagdoll(world: PhysicsWorld, config: RagdollConfig): Ragdoll — ⚠ undocumented
- `createRegionField` (function): function createRegionField<T = unknown>(config: RegionFieldConfig<T>): RegionField<T> — ⚠ undocumented
- `createReputationLedger` (function): function createReputationLedger(config: ReputationLedgerConfig = {}): ReputationLedger — ⚠ undocumented
- `createRvoCrowd` (function): function createRvoCrowd(options: RvoCrowdOptions = {}): RvoCrowd — Reciprocal velocity obstacle avoidance over circular agents. Each nearby pair contributes one or two half-plane constraints on the agent's velocity, and a small linear program picks the velocity closest to the preferred one that satisfies them all. The neighbour search is a uniform grid capped at `maxNeighbors`, so a tick costs the same for 50 agents and 5,000.
- `createScreenEffects` (function): function createScreenEffects(options: ScreenEffectsOptions = {}): ScreenEffectsController — A serializable screen-feedback controller: a game triggers transient flashes and edge vignettes (a red damage hit, a green heal flash) or sustained, optionally oscillating tints (a low-health pulse), and reads back a composite of the effects to draw right now with their eased opacities. It is clock-driven — call `advance()` each frame against an injected `now` — and allocation-aware: the composite array and its entries are pooled and reused, so steady-state ticking never allocates. Nothing here is genre-specific: `kind` is a free label the game owns and styles, and vignette / flash / pulse are just parameterizations of the same data (region shape, decay easing, sustained oscillation). A shell overlay subscribes and renders; `snapshot`/`restore` round-trips through a save.
- `createSelectionBookmarks` (function): function createSelectionBookmarks(snapshot?: SelectionBookmarkSnapshot): SelectionBookmarks — Create a keyed bookmark store, optionally restored from a {@link serialize} snapshot. Restoration re-dedupes and drops empty sets, so a hand-authored or migrated snapshot always normalizes to the same invariants a live store holds.
- `createSelectionSet` (function): function createSelectionSet(initial?: Iterable<string>): SelectionSet — An ordered, deduplicated set of selected instance ids for RTS unit-command routing.
- `createSequenceDirector` (function): function createSequenceDirector<Payload = unknown>(options: SequenceDirectorOptions<Payload>): SequenceDirector<Payload> — A serializable cutscene / sequence director: an ordered timeline of typed cues (`{ atMs, kind, payload }`) advanced by one injected clock, firing each cue once and in order as its time passes — even across a large seek — with play/pause/ seek/skip/stop controls. The director only *schedules and emits* cues; it never interprets what a `kind` means, so the same primitive drives camera moves, dialogue lines, fades, or any game event. `snapshot`/`restore` round-trip the playhead and which cues have fired. Deterministic (no wall clock beyond the injected `now`) and allocation-free on the tick path.
- `createSharedAnnotations` (function): function createSharedAnnotations(deps: SharedAnnotationsDeps): SharedAnnotations — Make a map annotation layer collaborative: local `addStroke`/`addShape`/ `addNote`/`remove`/`clear` apply then broadcast a serializable edit over the party feed (the same seam `createPingSystem` uses), and `apply` mirrors inbound edits from other players — dropping our own echoes. Ids are globally unique per client so two players' strokes never collide. Transport-agnostic: wire `feed` to any replicated feed and route received entries into `apply`.
- `createSpawnDirectorState` (function): function createSpawnDirectorState(config: SpawnDirectorConfig): SpawnDirectorState — ⚠ undocumented
- `createStationClaim` (function): function createStationClaim(controller?: MountController): StationClaim — ⚠ undocumented
- `createTargetAcquirer` (function): function createTargetAcquirer(policy: AcquisitionPolicy): TargetAcquirer — Wrap an {@link AcquisitionPolicy} in a small object that remembers the held target between passes, so callers get retention hysteresis for free without threading the previous target by hand. The only state is the held id (a string) — trivially serializable; round-trip it with {@link TargetAcquirer.hold}.
- `createTerraformBrush` (function): function createTerraformBrush(terrain: Pick<EditableTerrain, "apply">, config: TerraformBrushConfig = {}): TerraformBrush — ⚠ undocumented
- `createTerrainSnapshot` (function): function createTerrainSnapshot(config: EditableTerrainConfig): TerraformSnapshot — A fresh, unedited terrain snapshot sized to `bounds`/`cellSize` — the seed for a new sculpt document.
- `createThreatTable` (function): function createThreatTable(config: ThreatTableConfig = {}): ThreatTable — ⚠ undocumented
- `createTimerSet` (function): function createTimerSet(options: TimerSetOptions = {}): TimerSet — Create a serializable set of named countdown / countup timers on an injected clock — one primitive for round timers, respawn clocks, and ability cooldown/charge. Start/pause/resume/stop/reset timers by free-string id, read `{ remainingMs, elapsedMs, durationMs, progress01, running, expired }` for a mm:ss readout or a radial/bar fill, and `poll` for expiry edges. Ids and labels carry no genre meaning; `snapshot`/`restore` round-trip through a save.
- `createTraffic` (function): function createTraffic(options: TrafficOptions): Traffic — Traffic for an authored lane graph (see {@link createLaneGraph}).
- `createUtilityBrain` (function): function createUtilityBrain(config: UtilityBrainConfig): UtilityBrain — Create a utility brain over an existing {@link NeedSet}. The need set is injected, not owned, so the game shows the same hunger the brain scores and persists one copy.
- `createVehicleBody` (function): function createVehicleBody(world: PhysicsWorld, config: VehicleBodyConfig): VehicleBody — ⚠ undocumented
- `createVehicleDamage` (function): function createVehicleDamage(config: VehicleDamageConfig): VehicleDamage — Fixed-zone crash damage (issue #86's stage model) wired to handling and visuals: see {@link VehicleDamage}.
- `createVehicleObstacleClamp` (function): function createVehicleObstacleClamp(options: { /** Solids near the car this tick (already filtered to the relevant, solid set). */ obstacles: () => readonly CollisionObstacle[]; /** Vehicle body radius (units). Default {@link DEFAULT_VEHICLE_RADIUS}. */ radius?: number; /** Current tick dt (seconds)… — Build a slide-along move clamp for a kinematic car (#1051). `obstacles` is sampled fresh each tick — the caller hands back the already-filtered set of solids near the car — and `dt` supplies the current tick length so a blocked move's lost displacement converts to a closing speed. `radius` inflates each obstacle footprint by the car's body radius (default {@link DEFAULT_VEHICLE_RADIUS}).
- `createVehicleSeats` (function): function createVehicleSeats(controller?: MountController): VehicleSeats — Builds a {@link VehicleSeats}, optionally over an existing `MountController` to share its occupancy.
- `createVisibilityField` (function): function createVisibilityField(config: VisibilityFieldConfig): VisibilityField — Build a per-group gameplay visibility field. First adopters: an RTS/stealth team whose scout observes terrain (which stays remembered after it leaves) while enemy units re-hide once no scout observes their cell, and any authoritative host that must filter hidden entities out of a client's replica.
- `createVisibilitySystem` (function): function createVisibilitySystem(options: VisibilitySystemOptions): VisibilitySystem — ⚠ undocumented
- `createVoxelField` (function): function createVoxelField<T extends string = string>(config?: VoxelFieldConfig): VoxelField<T> — ⚠ undocumented
- `createWaveRunner` (function): function createWaveRunner(config: WaveRunnerConfig): WaveRunner — A thin, stateful, observable wrapper around the seeded {@link createSpawnDirectorState} / {@link advanceSpawnDirector} model. It OWNS a {@link SpawnDirectorState}, ticks it from `update(dt, ctx?)`, keeps the new state, and forwards each emitted {@link SpawnRequest} to an optional `onSpawn` sink so the model never instantiates entities. `view()` returns a pooled per-frame readout — the "brain behind WAVE 3": the 1-based wave number, wave progress `0..1`, banked budget, per-wave and total spawn counts, alert, and done flag. `forceNextWave` / `raiseAlert` drive it, `subscribe` observes it, and `snapshot`/`restore` round-trip the plain serializable state object through a save. Nothing here is genre-specific: spawn-entry `kind`s (the director's `entryId`s) stay free strings the runner never interprets.
- `createWaypointStore` (function): function createWaypointStore(deps: WaypointStoreDeps = {}): WaypointStore — Player-owned waypoint layer: place/track/clear pins, mirror them into a shared `MarkerSet` (so `Minimap`/`WorldMap`/`Compass` render them for free), and read bearing/distance guidance for an on-screen arrow to the tracked one. State is plain data — `snapshot()`/`restore()` round-trip through any save blob.
- `customRegion` (function): function customRegion<P extends SamplePoint>(spec: { dimensions: 2 | 3; sample: (rng: () => number) => P; contains: (point: P) => boolean; isEmpty?: boolean; }): SampleRegion<P> — Wrap a caller-defined sampler and bounds test as a {@link SampleRegion} — the escape hatch for regions the built-ins do not cover (a navmesh cell, a heightfield mask, a spline tube).
- `damagedAxis` (function): function damagedAxis(axis: AxisInput, effect: VehicleDamageEffectResolved): AxisInput — Apply a damage `steerPull` to a steer axis, clamped to the input range — a bent frame pulling one way.
- `damagedTuning` (function): function damagedTuning(base: KinematicVehicleTuning, effect: VehicleDamageEffectResolved): KinematicVehicleTuning — Bake a damage effect into a tuning — the lasting-damage path. Hand the result to the sim's `retune`, which keeps the vehicle's momentum; the base tuning is not mutated, so a repair is the same call with the undamaged base.
- `dashSegments` (function): function dashSegments(path: readonly RoadPoint[], dashLength = 3, gapLength = 3, exclude: readonly DashExclusion[] = []): readonly (readonly RoadPoint[])[] — Split a centerline into dash sub-polylines for lane markings: `dashLength` of painted line, `gapLength` of asphalt, repeated along the path's arc length. Feed each returned sub-path back through {@link buildRoadRibbon} with a thin width to mesh the dashes. Pass `exclude` circles (junction patches) to interrupt the center line through intersections — any dash whose midpoint lands inside an exclusion is dropped.
- `defineAttackMoveOrder` (function): function defineAttackMoveOrder<TCtx extends OrderMover & OrderTargeting>(config: EngagementKindConfig = {}): OrderKind<TCtx, AttackMoveOrderPayload> — Attack-move: advance toward a destination but break off to engage any hostile acquired within `aggroRadius`, pursuing it to `attackRange` and writing the engagement intent into `order.state` for the game to act on. Completes on reaching the destination with nothing to engage.
- `defineHoldOrder` (function): function defineHoldOrder<TCtx extends OrderMover>(config: OrderKindConfig = {}): OrderKind<TCtx, EmptyOrderPayload> — Hold position: stand ground indefinitely (never completes on its own) until preempted or canceled — the "guard here" verb.
- `defineMoveOrder` (function): function defineMoveOrder<TCtx extends OrderMover>(config: OrderKindConfig & { arriveRadius?: number } = {}): OrderKind<TCtx, MoveOrderPayload> — The plain "go here" verb: step toward a point each tick, complete on arrival, fail if the entity despawns. The completion predicate is arrival within `arriveRadius`.
- `definePatrolOrder` (function): function definePatrolOrder<TCtx extends OrderMover>(config: OrderKindConfig & { arriveRadius?: number } = {}): OrderKind<TCtx, PatrolOrderPayload> — Patrol: walk a waypoint route, advancing the serialized `index` as each point is reached. Loops forever by default, or completes at the last waypoint when `loop` is `false`.
- `defineStopOrder` (function): function defineStopOrder<TCtx extends OrderMover>(config: OrderKindConfig = {}): OrderKind<TCtx, EmptyOrderPayload> — Stop: halt immediately and complete the same tick — the interrupt that clears a unit's intent to standstill.
- `defineTargetedOrder` (function): function defineTargetedOrder<TCtx extends OrderMover & OrderTargeting>(config: EngagementKindConfig = {}): OrderKind<TCtx, TargetedOrderPayload> — Targeted action: pursue one specific target until within `range`, writing the engagement intent into `order.state`. Completes when the target is gone (despawned/dead), so the game's effect loop runs while `inRange` is true.
- `densityCoverage` (function): function densityCoverage(kind: "grass_field" | "scatter", area: number, density: number): ScatterCoverage — Coverage for a per-m² kind (`grass_field` / `scatter`): `requested = floor(density × area)`, clamped to the kind's budget. `capped` is true when the request exceeds the budget.
- `deriveCityPlots` (function): function deriveCityPlots(network: StreetNetwork, options: CityPlotOptions): CityPlotResult — Subdivide every buildable block's street frontage into size-tiered polygonal plots. Blocks come from the street network's planar faces ({@link extractBlocks}), so every plot fronts a real street; block interiors stay open (courtyards) and a seeded fraction of whole blocks becomes parks. Grand plots — the old "landmarks" — are just the biggest tier of the same pass. Deterministic per seed, bounded by `maxPlots` and per-block caps.
- `describeScatterCoverage` (function): function describeScatterCoverage(coverage: ScatterCoverage): string — The full one-line coverage readout: `≈ N unit · A m²` plus the {@link budgetWarning} when capped.
- `discRegion` (function): function discRegion(center: Vec2, radius: number, options: { distribution?: RadialDistribution } = {}): SampleRegion<Vec2> — A filled circle. `"area"` is area-uniform (√-corrected radius, even density); `"radial"` is radius-uniform (clumps toward the center). Angle is drawn first, then radius — matching the common `angle = rng()·2π; r = rng()·R` idiom so migrations keep their stream.
- `distance` (function): function distance(a: Vec3, b: Vec3): number — ⚠ undocumented
- `distance3` (function): function distance3(a: { x: number; y: number; z: number }, b: { x: number; y: number; z: number }): number — ⚠ undocumented
- `distanceToPolygonEdge` (function): function distanceToPolygonEdge(point: Vec2, polygon: readonly Vec2[]): number — Shortest distance from a point to a polygon's boundary.
- `distanceToRoadEdge` (function): function distanceToRoadEdge(roads: readonly RoadEnvironmentDescriptor[], x: number, z: number): number — Signed planar distance from `(x, z)` to the nearest road *surface edge* across every segment of every road (#1051): negative inside the asphalt (magnitude = how far in from the closest edge, so `-width/2` on the centerline), `~0` right at the curb, and positive off the road (the gap to the nearest edge). Point-to-segment distance minus the road's half width, minimised over all segments — the "am I on the road, and by how much" seam driving grip, tyre audio, and off-road penalties.
- `drapePolyline` (function): function drapePolyline(sampleHeight: HeightSampler, points: readonly GroundPoint[], options: DrapeOptions = {}): number[] — Drapes an XZ polyline onto the surface: subdivides each span to at most `spacing` and lifts every vertex to `sampleHeight + offset`, returning flat `[x, y, z, ...]` world triples. The reusable seam behind surface-following placement guides and grid lines — a straight guide bends to follow terrain.
- `editableTerrainFromSnapshot` (function): function editableTerrainFromSnapshot(snapshot: TerraformSnapshot, base?: TerrainField): EditableTerrain — Rebuilds a live {@link EditableTerrain} from a snapshot, layered over `base` ground.
- `effectiveRelation` (function): function effectiveRelation(input: EffectiveRelationInput): FactionRelation — ⚠ undocumented
- `encodeBakePng` (function): function encodeBakePng(bake: MinimapBake): Uint8Array — Encodes an RGBA bake to raw PNG bytes (pure; stored DEFLATE, valid for any decoder).
- `entityMetaOf` (function): function entityMetaOf<T>(entity: SceneEntity<unknown>, isMeta: (value: unknown) => value is T): T | null — Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null` instead of lying to the type checker.
- `environment` (function): function environment(config: EnvironmentWorldConfig = {}): EnvironmentWorldFeature — Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
- `evaluateQteSequence` (function): function evaluateQteSequence(steps: readonly QteStep[], inputs: readonly QteInputEvent[]): QteOutcome — Evaluate a quick-time-event input sequence against timed hit windows.
- `evaluateSkillCheck` (function): function evaluateSkillCheck(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckResult — ⚠ undocumented
- `extractContours` (function): function extractContours(sampleHeight: HeightSampler, options: ContourOptions): ContourLine[] — Traces surface-following contour lines from a height field via marching squares: samples a bounded grid over the region, then for every multiple of `interval` strictly inside the sampled height range emits the iso-line as XZ segments (saddle cells disambiguated by the cell-center average). Because a contour is exact constant elevation, drawing each segment at `y = level` makes it hug the terrain — the readable, scale-bearing overlay a flat ground grid cannot give. Pure math, renderer-agnostic.
- `extremumStack` (function): function extremumStack<P>(magnitudeOf: MagnitudeOf<P>, weakest = false): AreaStackPolicy<P> — Reduce to the single strongest membership overall (`weakest = false` picks the weakest); ties broken by `sourceId`. Use when only the best or worst overlapping source should apply.
- `facingYaw` (function): function facingYaw(from: Vec2, to: Vec2): number — Engine yaw (`rotationY`, radians) that faces from `from` toward `to` on the XZ plane, matching the `forward = (sin yaw, cos yaw)` convention. Feed the result as the `facing` of {@link placeFormation} to orient a formation along its travel direction. Returns `0` when the points coincide.
- `feelOf` (function): function feelOf(tuning: KinematicVehicleTuning): VehicleFeel — Read the handling numbers out of any tuning — base or parts-composed.
- `findPath` (function): function findPath(grid: NavGrid, from: NavPoint, to: NavPoint, options: FindPathOptions = {}): NavPoint[] | null — A* over the walkable grid. Returns a polyline of world-space `[x, z]` waypoints from `from` to `to`, or `null` when no route exists. Blocked start/goal snap to the nearest walkable cell so a click on an obstacle still routes to its edge.
- `findSchemaPreset` (function): function findSchemaPreset(schema: ParamSchema, id: string): ParamPreset | undefined — Look up a schema preset by id, or undefined — the seam `apply_preset` and games resolve bundles through.
- `firstImpact` (function): function firstImpact(hits: readonly SceneRaycastHit[]): SceneRaycastHit | null — First impact: nearest hit that blocks, or nearest hit if none block.
- `flat` (function): function flat(): WorldFeature — Declares an empty flat world — the minimal `WorldFeature` for games with no terrain of their own.
- `footprintObstacles` (function): function footprintObstacles(grid: FootprintGrid): PlacementObstacle[] — Bridges live reservations into `world/placement`'s `PlacementRules.obstacles` so `validatePlacement`/`createPlacementController` see the grid's committed footprints unchanged.
- `furnitureSpots` (function): function furnitureSpots(road: RoadEnvironmentDescriptor, options: FurnitureSpotOptions = {}): readonly FurnitureSpot[] — Evenly spaced street-furniture anchors along a road's curb lines — streetlights, palms, signs, hydrants, benches. Each spot sits just outside the asphalt (plus `outset`), faces away from the street, and alternates sides by default so lights stagger like a real avenue. This is the answer to "where do I put it": furniture is an asset of the street, never a hand-typed coordinate.
- `gauge` (function): function gauge(gaugeId: string): GaugePromptDisplay — ⚠ undocumented
- `generateCity` (function): function generateCity(options: CityGeneratorOptions, hx: number, hz: number): GeneratedCity — Grow a street network inside the `hx`/`hz` half-extents, extract its blocks, and subdivide their frontage into plots. Deterministic: identical options ⇒ identical city.
- `generateLock` (function): function generateLock(seed: string | number, tier: LockTierSpec): LockSpec — Generate a solvable depth-puzzle lock: a "Tumbler's Path" board with a guaranteed solution path carved first, an open-row forgiveness band wrapped around it, tumbler gate columns that pinch to a single exact row, and optional ward-traps that look open but jam on contact. Deterministic: the same (seed, tier) always yields the same board.
- `getCurrentGameTimestamp` (function): function getCurrentGameTimestamp(createdAt: number, now: number, timeScale?: number | null): number — ⚠ undocumented
- `getTriggerAction` (function): function getTriggerAction(id: string): TriggerActionDefinition | undefined — Registered definition for an action id, or undefined when the game never declared it.
- `grass` (function): function grass(config: GrassEnvironmentConfig = {}): GrassEnvironmentDescriptor — Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
- `groundSpeed` (function): function groundSpeed(entity: SceneEntity<unknown>): number — Ground speed (horizontal magnitude of velocity) in world units per second. Scale to km/h or mph in game code.
- `grounded` (function): function grounded(ctx: Pick<GameContext, "world">, x: number, z: number): readonly [number, number, number] — Ground an XZ point onto the live world surface as `[x, groundY, z]`.
- `hasValidAdjacency` (function): function hasValidAdjacency(grid: FootprintGrid, cells: readonly GridCell[], accepts: (neighborKind: string) => boolean, requireConnection = false): boolean — Connective-piece adjacency validity: every occupied neighbor of `cells` must satisfy `accepts` (no incompatible piece touching), and when `requireConnection` is true at least one neighbor must (a road/pipe/belt segment placed with nothing to connect to is invalid). An empty-bordered footprint (no occupied neighbors at all) passes unless `requireConnection` demands one.
- `headingToBearing` (function): function headingToBearing(yaw: number): number — Bearing of an entity facing direction given its `rotationY` (yaw) in radians.
- `headingToRotationY` (function): function headingToRotationY(headingDegrees: number): number — Convert a compass heading (degrees, `0` = engine north, increasing clockwise) into the Three.js Y-rotation (radians, wrapped to `(-PI, PI]`) a renderer applies. Sign matches `world/placementController.quarterTurnsToRotationY`, so heading `90` equals one clockwise quarter turn. This is the one place degrees cross into the private radian space Three.js requires.
- `hitsUntilBlocked` (function): function hitsUntilBlocked(hits: readonly SceneRaycastHit[]): SceneRaycastHit[] — Hits up to and including the first blocking collider (damage hitboxes before a wall stay).
- `independentStacks` (function): function independentStacks<P>(): AreaStackPolicy<P> — Every overlapping membership applies independently (no deduplication) — the default for hazards, fields, and lights where two sources genuinely stack.
- `interestPhase` (function): function interestPhase(seed: string | number): number — A deterministic `[0,1)` cadence phase derived from a stable id, for staggering sibling gates so a batch of agents spawned together does not fire their first active tick on the same frame. Pass the result as the `phase` argument to {@link createInterestGateState}.
- `isMarquee` (function): function isMarquee(rect: ScreenRect, thresholdPx = 4): boolean — True when the drag is large enough to be a marquee rather than a click.
- `isPlaceWorld` (function): function isPlaceWorld(worldFeature: { kind: string } | undefined): worldFeature is PlaceWorldFeature — Type guard for the place-model world feature.
- `isRegionField` (function): function isRegionField(field: TerrainField): field is RegionField — ⚠ undocumented
- `isScatterPath` (function): function isScatterPath(path: ScenePathLike): boolean — True when an editor path is a foliage/scatter region.
- `keybind` (function): function keybind(actionId: string, label?: string): KeybindPromptDisplay — ⚠ undocumented
- `label` (function): function label(text: string): LabelPromptDisplay — ⚠ undocumented
- `laneCenters` (function): function laneCenters(road: RoadEnvironmentDescriptor): readonly [StreetLane, StreetLane] — Two right-hand-traffic lane centerlines for a road — each offset a quarter of the drivable width from the center and ordered in its direction of travel. Feed a lane's `path` straight into `nav/pathFollow` for traffic AI, or use its endpoints as directed car spawn points.
- `laneGraphFromDocument` (function): function laneGraphFromDocument(doc: Pick<EditorDocument, "paths" | "markers">, options: LaneGraphDocumentOptions = {}): LaneGraph — Read a lane graph out of an authored scene document. `traffic_lane` paths are one directed lane each; `road` paths (the editor's street bake) become a lane per direction, offset onto their own side of the road; `traffic_intersection` markers carry a signal program and right-of-way in `meta`; `traffic_parking` markers place parking spots. Runtime positions come from the paths, so editing a road moves its traffic instead of leaving a duplicate lane behind.
- `leaveVehicle` (function): function leaveVehicle(ctx: GameContext, seats: VehicleSeats, riderId: string, options: LeaveVehicleOptions = {}): ExitVehicleResult | { ok: false; reason: "unknown_rider" | "unknown_vehicle" } — Apply dismount placement, restore rider movement/visibility and the configured camera rig.
- `lineFormation` (function): function lineFormation(options: LineFormationOptions): FormationSlotGenerator — A single rank abreast, centered on the destination and facing forward — a skirmish line or a chorus row. Slots run left→right along the group's right axis.
- `listTriggerActions` (function): function listTriggerActions(target?: TriggerSourceKind): TriggerActionDefinition[] — Every registered action, optionally filtered by target collection.
- `mapLayerColor` (function): function mapLayerColor(tone: MapLayerTone | undefined): string — ⚠ undocumented
- `markerCatalogId` (function): function markerCatalogId(marker: AuthoredObjectMarkerLike): string | null — Catalog id for a marker: first-class `catalogId` field, else `meta.catalogId` migration alias. Returns null when the marker is not an authored catalog prop (spawn, mob, generator, …).
- `markerKindStyle` (function): function markerKindStyle(kind: string | undefined, styles: Record<string, MarkerKindStyle> = DEFAULT_MARKER_KINDS): MarkerKindStyle — ⚠ undocumented
- `mergeFootprints` (function): function mergeFootprints(a: FootprintRegion, b: FootprintRegion, id: string, budget: RegionWorkBudget = {}): MergedRegion | null — Pool compatible footprints under caller-owned `id`, retaining original capacities and identities. Returns null for invalid data, kind/tier mismatch, overlap, no cardinal contact or exhausted budget. Does not mutate inputs or grid reservations; costs, merge width and upgrade policy remain caller-owned. Capacity is the ordered JavaScript-number sum of original contributions, independent of cell area.
- `migrateTerrainSnapshot` (function): function migrateTerrainSnapshot(snapshot: TerraformSnapshot): TerraformSnapshot — Upgrades a pre-2.0 snapshot in place-safe (copy-on-write) form: derives a {@link TerrainMaterialLayer} stack from the distinct painted surfaces (first-seen order, default params) when none exists. Leaves the lazy `weights` buffer absent — a single-layer terrain stays compact until blended. Idempotent: a snapshot that already carries `layers` is returned unchanged.
- `minimapBakeToPngDataUri` (function): function minimapBakeToPngDataUri(bake: MinimapBake): string — Encodes a bake as a `data:image/png;base64,...` URI — the exact string the `Minimap` / `WorldMap` `background` prop takes. Deterministic for a fixed bake.
- `mtof` (function): function mtof(midi: number): number — Standard equal-temperament MIDI-to-frequency (A4 = 440 Hz at MIDI 69).
- `navMeshFromBake` (function): function navMeshFromBake(bakes: readonly SceneBake[] | undefined, id = "main"): NavMeshData | null — Read the named navigation bake an editor wrote onto a scene document. Returns `null` when the document holds no such bake yet, and throws when the stored bake is not a valid nav mesh — a corrupt bake should fail at load, not as agents walking through walls.
- `normalizeDegrees` (function): function normalizeDegrees(degrees: number): number — Wrap `degrees` into `[0, 360)` — the canonical heading range every policy and conversion here works in. Non-finite input collapses to `0` so bad metadata never leaks a `NaN` heading downstream.
- `notesInWindow` (function): function notesInWindow(theme: MusicTheme, anchorSec: number, fromSec: number, toSec: number): ScheduledNote[] — Pure lookahead scheduler: every note occurrence of `theme` whose onset falls in the half-open window `(fromSec, toSec]`, given the theme's loop-zero at `anchorSec`. Handles any number of loop wraps, so a director calls it once per tick with a non-overlapping window and never double-schedules a note.
- `objectVisualScale` (function): function objectVisualScale(visual: ObjectVisual | undefined): readonly [number, number, number] — ⚠ undocumented
- `ocean` (function): function ocean(config: OceanEnvironmentConfig = {}): OceanEnvironmentDescriptor — Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
- `offsetPath` (function): function offsetPath(path: readonly RoadPoint[], offset: number): readonly RoadPoint[] — Offset a centerline sideways by a signed distance along its local perpendicular — the building block for lanes, curb lines, and sidewalk paths. Positive offsets fall on the left of the direction of travel, negative on the right.
- `pad` (function): function pad(config: PadEnvironmentConfig): PadEnvironmentDescriptor — ⚠ undocumented
- `parkingSpots` (function): function parkingSpots(road: RoadEnvironmentDescriptor, options: ParkingSpotOptions = {}): readonly ParkingSpot[] — Curbside parking anchors along a road: hugging the edge of the asphalt, headed parallel to the street in that side's direction of travel. Spawn parked vehicles here instead of eyeballing coordinates in the middle of the carriageway.
- `parseAssetSpace` (function): function parseAssetSpace(raw: unknown): AssetSpace | undefined — Parse untrusted JSON into an {@link AssetSpace}, dropping malformed fields, or `undefined` when nothing valid remains — the round-trippable read path for serialized catalog/scene metadata.
- `parseParams` (function): function parseParams(schema: ParamSchema, meta: Record<string, unknown> | undefined): ParsedParams — Parse a raw `meta` bag against a schema into typed params — every field present, invalid/missing values replaced by the field default, numbers clamped to their range. The single parser every studio shares instead of hand-writing its own `metaNumber`/`metaBool` ladder.
- `parseRotationPolicy` (function): function parseRotationPolicy(raw: unknown): PlacementRotationPolicy — Parse an untrusted rotation policy (from a scene document or catalog JSON) into a valid {@link PlacementRotationPolicy}, defaulting to `free` when absent or malformed. The lenient companion to {@link validateAssetSpace} for the read path.
- `partsBounds` (function): function partsBounds(parts: readonly GeneratedPart[]): GeneratedAsset["bounds"] — Compute bounds from parts (each part is an axis-aligned box at its center) — a helper generators return so callers can frame/ground the asset without re-deriving it.
- `pathFollowProgress` (function): function pathFollowProgress(config: PathFollowConfig, state: PathFollowState): PathFollowProgress — Read a follower's current progress in every semantic form — the inverse of {@link pathFollowSeek}, for editor/debug inspection and progress HUDs. Pure and allocation-light.
- `pathFollowSeek` (function): function pathFollowSeek(config: PathFollowConfig, target: PathProgress): PathFollowState — Place a follower at a semantic {@link PathProgress} without simulating from the start — the seek adapter behavior lifecycles use to seed distributed phases and restore serialized routes. Pure; returns a fresh {@link PathFollowState} whose `heading` gives travel direction. Looping paths wrap the distance; non-looping paths clamp to `[0, pathLength]` and report `done` at the end.
- `pathFromNav` (function): function pathFromNav(points: readonly NavPoint[], elevation: number | HeightSampler = 0, offset = 0): Waypoint[] — ⚠ undocumented
- `pathLength` (function): function pathLength(config: PathFollowConfig): number — Total world-distance of a path — sum of every segment, including the wrap segment back to the first waypoint when `loop` is set. Zero for a degenerate (0- or 1-waypoint) path.
- `patrol` (function): function patrol({ waypoints, speed, loop = true, startProgress, groundClamp, }: { waypoints: readonly Waypoint[]; speed: number; loop?: boolean; startProgress?: PathProgress; groundClamp?: boolean; }): PatrolBehavior — ⚠ undocumented
- `pendingQteStep` (function): function pendingQteStep(steps: readonly QteStep[], elapsedSeconds: number): QteStep | null — ⚠ undocumented
- `pickSpawnPoint` (function): function pickSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null — Selects a candidate spawn point using a semantic distance preference and caller-supplied randomness.
- `pickWeighted` (function): function pickWeighted<T>(entries: readonly { value: T; weight: number }[], roll: number): T | null — Weighted pick from opaque entries; `roll` in [0, 1). Returns null when empty.
- `placeAlongPath` (function): function placeAlongPath(points: readonly { x: number; z: number }[], options: PlaceAlongPathOptions): PathInstance[] — Evenly place transforms along `points` (XZ polyline). The run length is divided into the whole number of equal spans closest to `spacing`, so instances always land on both endpoints and stay evenly distributed. Returns `spans + 1` instances. Empty for fewer than 2 points.
- `placeAssetFromCommit` (function): function placeAssetFromCommit(commit: PlacementCommit, assetId: string, options: PlaceAssetFromCommitOptions = {}): PlaceAssetResult — Bridge a {@link PlacementCommit} into the shared place-asset verb.
- `placeAuthoredObjects` (function): function placeAuthoredObjects(store: AuthoredObjectPlaceTarget, objects: readonly AuthoredObject[], sampleHeight: (x: number, z: number) => number, options: PlaceAuthoredObjectsOptions = {}): string[] — Places resolved authored objects into an object store, grounding each on `sampleHeight(x,z)` plus per-object and options vertical offsets. Returns the instance ids that were placed (or kept).
- `placeAuthoredObjectsFromDocument` (function): function placeAuthoredObjectsFromDocument(store: AuthoredObjectPlaceTarget, document: AuthoredObjectsDocumentLike, sampleHeight: (x: number, z: number) => number, options: PlaceAuthoredObjectsOptions = {}): string[] — Convenience: resolve a document then place every authored catalog prop.
- `placeFormation` (function): function placeFormation(destination: Vec2, facing: number, count: number, generator: FormationSlotGenerator): Vec2[] — Transform a generator's local slot offsets into world XZ positions around a `destination`, rotated by `facing` (engine yaw). Slot `i` in the returned array is `generator(count)[i]` mapped through the group frame, so it stays aligned with {@link assignFormationSlots}' slot indices. Pure and allocation- light: one array of `count` points, no per-call closures retained.
- `placedCoverage` (function): function placedCoverage(kind: ScatterCoverageKind, area: number, placed: number): ScatterCoverage — Coverage for a kind whose placed `count` is already known from its generator (city, from its resolved lots). No pre-cap `requested` is available — the generator stops at the budget — so `capped` is inferred from the placed count reaching the ceiling.
- `player` (function): function player(): PlayerBehavior — ⚠ undocumented
- `plots` (function): function plots(config: PlotsWorldConfig = {}): WorldFeature — Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts.
- `pointGravity` (function): function pointGravity(options: PointGravityOptions): GravityField — Radial gravity toward one center, with optional inverse-square falloff for planetary worlds.
- `pointInPolygon` (function): function pointInPolygon(point: Vec2, polygon: readonly Vec2[]): boolean — Ray-casting point-in-polygon test on the XZ plane.
- `pointInVolume` (function): function pointInVolume(volume: SceneVolumeLike, point: { x: number; y: number; z: number }): boolean — True when `point` is inside an editor volume (sphere / cylinder / box). Cylinder height defaults to diameter when omitted; sphere ignores y for the common ground-plane case only when the volume radius covers the full vertical span — here y is tested for sphere and box too.
- `pointSetRegion` (function): function pointSetRegion(points: readonly Vec2[], options: { weights?: readonly number[] } = {}): SampleRegion<Vec2> — A fixed set of candidate points sampled by (optionally weighted) selection — the "spawn point table" region. `contains` is exact membership. Empty when the set is empty.
- `policeRoadsFromLaneGraph` (function): function policeRoadsFromLaneGraph(graph: LaneGraph, markers: readonly EditorMarker[] = [], options: PoliceRoadsOptions = {}): PoliceRoads — Read the police road data out of an authored lane graph: `traffic_roadblock` markers become cordon sites projected onto the lane they block, and lanes are indexed so `lanesNear` answers from the local cells rather than a scan of every lane. With no roadblock markers authored, the graph's intersections are the sites, so a cordon still sits where streets meet. Built once; the index is rebuildable from the document, so it is never serialized.
- `polygonArea` (function): function polygonArea(polygon: readonly Vec2[]): number — Shoelace area of a polygon (always non-negative), in square meters.
- `polygonBounds` (function): function polygonBounds(polygon: readonly Vec2[]): Aabb | null — Axis-aligned bounds of a polygon, or null if it has no points.
- `polygonRegion` (function): function polygonRegion(polygon: readonly Vec2[]): SampleRegion<Vec2> — An arbitrary closed polygon on the XZ plane. Candidates are drawn uniformly from the polygon's bounding box and gated by point-in-polygon `contains`, so a run's draw count stays fixed (the sampler's attempt budget bounds the rejection, not a hidden inner loop).
- `populateNavGridFromEnvironment` (function): function populateNavGridFromEnvironment(grid: NavObstacleGrid, world: EnvironmentWorldFeature): number — Blocks the footprint of every solid building an environment feature's `structures` generate — the same set `ctx.world.solids` holds for it. Returns the number of buildings blocked.
- `projectToMinimap` (function): function projectToMinimap(world: WorldXZ | readonly [number, number, number], view: MinimapView): MinimapPoint — Project a world XZ (or XYZ) point into minimap pixel space. Origin is the top-left of the `size×size` box; north (−Z) maps to −Y (up). Pass `view.rotate` to spin the map under a fixed north-up player arrow.
- `proximityPrompt` (function): function proximityPrompt({ radius, display, invoke = null }: ProximityPromptConfig): ProximityPrompt — ⚠ undocumented
- `pursue` (function): function pursue(options: Omit<PursueBehavior, "kind">): PursueBehavior — Attach aggro, collision-aware chase, cooldown attack and latched return-to-spawn as data.
- `quarterTurnsToRotationY` (function): function quarterTurnsToRotationY(quarterTurns: number): number — Maps 0–3 quarter turns onto radians for ghost/commit rotation.
- `rain` (function): function rain(config: RainEnvironmentConfig = {}): RainEnvironmentDescriptor — Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
- `raiseAlert` (function): function raiseAlert(state: SpawnDirectorState, amount: number): SpawnDirectorState — ⚠ undocumented
- `raycastNav` (function): function raycastNav(mesh: NavMeshData, from: Vec3, to: Vec3): boolean — True when the segment remains over walkable polygons.
- `readNamedSockets` (function): function readNamedSockets(root: ModelNode, pattern: RegExp = SOCKET_PATTERN): ModelSocket[] — Depth-first collect every socket-named node's local offset, sorted by descending Y then ascending X so socket indices are stable across loads (top first, left-to-right). Empty when the model tags none — callers then fall back to computed offsets. Pass a custom `pattern` for a bespoke naming convention.
- `readScatterPalette` (function): function readScatterPalette(meta: Record<string, unknown> | undefined): ScatterPaletteEntry[] — Parses a scatter region's palette from meta: a weighted `palette` array, else a single `item`.
- `readScatterRules` (function): function readScatterRules(path: ScenePathLike): ScatterRegionRules | null — The path's scatter rules with defaults filled in; null for non-scatter paths.
- `recallSelectionBookmark` (function): function recallSelectionBookmark(bookmarks: SelectionBookmarks, key: string, selection: SelectionSet, options: RecallBookmarkOptions = {}): string[] — Compose a bookmark recall onto an active {@link SelectionSet}: optionally prune stale ids (updating the stored bookmark), fold the survivors into the selection by `mode`, then fire the caller's focus hook. This is the one place the store, the selection, and the camera meet — kept as an explicit helper, not a store side effect, so games opt into the exact replacement/merge and focus policy they want. Returns the surviving ids that were applied.
- `rectRegion` (function): function rectRegion(area: Aabb, options: { distribution?: AreaDistribution; edgeThickness?: number } = {}): SampleRegion<Vec2> — An axis-aligned rectangle on the XZ plane. `"uniform"` spreads evenly (draws x then z); `"edge"` biases onto a boundary band of `edgeThickness` meters (perimeter-weighted side, then inward depth) — the two are never conflated, the caller opts in.
- `registerAssetGenerator` (function): function registerAssetGenerator(definition: AssetGeneratorDefinition): void — Register a parametric asset generator. Idempotent per id (last wins); call at module load.
- `registerBehaviorActions` (function): function registerBehaviorActions(id: string, actions: Record<string, BehaviorAction>, options: BehaviorActionOptions = {}): () => void — Register the named actions used by decision graph behavior descriptors.
- `registerSceneKind` (function): function registerSceneKind<TResolved>(definition: SceneKindDefinition<TResolved>): void — Register a scene kind — the plug-in point for a new parametric studio. Idempotent per `kind` (last registration wins), so a game's registration overrides a default. Call at module load; the editor inspector, `+ Add` menu, and `AuthoredScene` renderer lookup all read this registry.
- `registerTriggerAction` (function): function registerTriggerAction(definition: TriggerActionDefinition): void — Declare a game action the editor can assign to volume/marker triggers. Idempotent per `id` (last registration wins). Call at module load next to catalogs.
- `relativeBearing` (function): function relativeBearing(bearing: number, reference: number): number — Signed offset of `bearing` from `reference`, wrapped into (−π, π].
- `resolveActivePrompt` (function): function resolveActivePrompt<T extends PositionedPrompt>(playerPosition: PromptPoint, prompts: readonly T[]): T | null — Nearest prompt strictly within its radius wins; a higher-priority prompt in range beats any lower-priority one regardless of distance; equal priority and distance keep the earliest prompt in the list.
- `resolveAnchorOffset` (function): function resolveAnchorOffset(space?: Pick<AssetSpace, "anchor" | "footprint">): Vec2 — The pivot's offset from the footprint center, in engine meters, implied by {@link AssetSpace.anchor} and {@link AssetSpace.footprint}. `center` yields `[0, 0]`; `corner` yields the min corner; a normalized `{ x, z }` scales by the footprint. Subtract it to seat a footprint centered on a point.
- `resolveAuthoredObjects` (function): function resolveAuthoredObjects(document: AuthoredObjectsDocumentLike, options: ResolveAuthoredObjectsOptions = {}): AuthoredObject[] — Every marker carrying a catalog id, as placeable props — pure, no terrain sample. Parallel to {@link resolveScatter}: games and headless tests read the same list `<AuthoredObjects>` places. Entity-spawn kinds (`mob`/`boss`) are skipped by default — they carry a `catalogId` for their entity definition, but are spawned via `authoredEntitySpawns`, not placed as static meshes.
- `resolveCityLotContent` (function): function resolveCityLotContent(city: Pick<GeneratedCity, "network" | "lots"> & Partial<Pick<GeneratedCity, "plots" | "parks">>, options: CityContentOptions): ResolvedCityLot[] — Enrich a generated city's plots into classed, massed buildings: each plot gets its zone band (radial position under a {@link CityZoneProfile}), a building class rolled from the band's weighted mix — biased by street level AND plot size, with grand plots rolling a landmark class — floors, and the deterministic massing pieces the class composes, sized to the plot's building rect. Deterministic per `seed` via {@link seededStreams}, bounded (one pass over `city.lots`), and pure. Same seed + city ⇒ identical resolved lots.
- `resolveCityObject` (function): function resolveCityObject(object: SceneKindObject, context?: CityResolveContext): ResolvedCity | null — Synthesize the deterministic city plan for one `city` volume: streets → bridges → parks → zoned frontage lots with massing pieces → furniture, all in the volume's local frame and then rotated/translated into world space. Same volume (id, footprint, meta) over the same terrain always resolves to the identical plan. When `context` provides a ground sampler, lots respect the `maxSlope` cliff rule — hillside and canyon districts keep their steep faces open. When `context.zoneOverrides` carries sibling `cityzone` volumes, lots inside them adopt the override band/mix. Returns null without a usable footprint.
- `resolveControlGroupIntent` (function): function resolveControlGroupIntent(input: ControlGroupInput, options: ControlGroupOptions = {}): ControlGroupIntent — Resolve a control-group key press into a {@link ControlGroupIntent}: Ctrl+digit binds, a bare digit recalls, and a second recall of the same group within `doubleTapMs` focuses. Pure — the caller applies the intent against the store and its own focus hook, and records the returned recall for the next call.
- `resolveEmitterGain` (function): function resolveEmitterGain(distance: number, sound: Pick<SoundDef, "gain" | "positional" | "falloff">, busGain: number): number — ⚠ undocumented
- `resolveFacingRotationY` (function): function resolveFacingRotationY(headingDegrees: number, space?: Pick<AssetSpace, "forwardDegrees">): number — The Three.js Y-rotation that makes a model whose front is authored at `forwardDegrees` visually point `headingDegrees` (engine north = `0`). This is the catalog-owned replacement for per-game corrective yaw: a model authored facing south (`forwardDegrees: 180`) placed toward north resolves to `Math.PI`.
- `resolveFlightStep` (function): function resolveFlightStep(position: readonly [number, number, number], stepX: number, stepY: number, stepZ: number, obstacles: readonly CollisionObstacle[], radius: number = DEFAULT_OBSTACLE_PLAYER_RADIUS): { stepX: number; stepY: number; stepZ: number } — Resolve a flight step against world solids (XZ slide + Y clamp).
- `resolveFreeFlightIntent` (function): function resolveFreeFlightIntent(keys: MovementKeysState, analog: AnalogMoveIntent | null | undefined): FreeFlightIntent — Translate held keys + analog into a free-flight intent. Vertical is `space - (control|c)` so jump ascends and crouch descends — the same keys that walk/jump/crouch use, re-mapped for flight without re-binding.
- `resolveFreeFlightIntentFromInput` (function): function resolveFreeFlightIntentFromInput(isDown: (action: string) => boolean, value: (action: string) => number, pointer: PointerAxisState | null, bindings?: FreeFlightBindings): FreeFlightIntent — Translate live input (held actions + analog + pointer) into a flight intent using per-profile axis bindings. Unlisted bindings fall back to the defaults above so existing games keep WASD/Space/Ctrl/Shift without declaring anything.
- `resolveGridInstances` (function): function resolveGridInstances(config: WorldGridConfig | GridWorldFeature): readonly GridInstanceTransform[] — ⚠ undocumented
- `resolveLocalAvoidance` (function): function resolveLocalAvoidance(agents: AvoidanceAgent[], options: LocalAvoidanceOptions = {}): number — Resolve overlaps in `agents` in place and return how many overlapping pairs remained on the final pass (`0` = fully separated). Uses a bounded uniform hash grid sized to the largest agent, so only nearby agents are ever compared. Deterministic: corrections are accumulated then applied per pass, independent of agent order. Pass `weights` to pin or differentially push agents.
- `resolvePlaceAsset` (function): function resolvePlaceAsset(input: ResolvePlaceAssetInput): PlaceAssetResult — Resolve a place-asset intent into a shared payload (editor + games, one verb).
- `resolvePlayerMovementTuning` (function): function resolvePlayerMovementTuning(opts: { collision?: VoxelCollisionConfig; movement?: PlayerMovementConfig; physics?: PhysicsConfig; world?: WorldFeature; }): PlayerMovementTuning — Gather a game's collision/movement/physics/world config into a {@link PlayerMovementTuning} — call once per world; both the shell and a host pass the result to {@link stepPlayerMovement}.
- `resolvePoleLine` (function): function resolvePoleLine(object: SceneKindObject, params: ParsedParams, context?: SceneKindResolveContext): ResolvedPoleLine — Resolve poles + cables from a document object's points and parsed params. Poles come from the generic `placeAlongPath` sampler; between each consecutive pair, `wireCount` parallel cables are strung with lateral offset and quadratic-Bézier `sag` (deeper on longer spans). Pure data.
- `resolveScatter` (function): function resolveScatter(doc: SceneDocumentLike, terrain?: ScatterTerrain, options: ResolveScatterOptions = {}): ScatterInstance[] — Every scatter region's placements across a document, grounded on `terrain` when provided. Regions honor clearance masks: their own manual `avoid` discs, plus (when the region's `autoAvoid` is on and `options.autoAvoid !== false`) the document-wide discs + path corridors from {@link clearanceMasksFrom} — so foliage auto-clears spawns, plots, and paths without hand-carving the polygon.
- `resolveScatterRegion` (function): function resolveScatterRegion(region: ScatterRegion, terrain?: ScatterTerrain, avoid?: AvoidMasks): ScatterInstance[] — Deterministic placements for one scatter region: scatter its polygon footprint at `density` items/m² (respecting `minSpacing`), clip to the polygon, thin near the edge, drop placements outside the slope/height mask, and derive item/scale/yaw from the region id + seed — so the same saved region always grows the same field. Grounds each instance on `terrain` when provided.
- `resolveStructureBuildings` (function): function resolveStructureBuildings(descriptor: BuildingEnvironmentDescriptor): GeneratedBuilding[] — ⚠ undocumented
- `resolveWeather` (function): function resolveWeather<TTable extends WeatherModifierTable>(state: WeatherState, table: TTable): ResolvedWeather — ⚠ undocumented
- `resolveWorldPhysics` (function): function resolveWorldPhysics(worldFeature: { kind: string; physics?: PhysicsConfig } | undefined, base: PhysicsConfig | undefined): PhysicsConfig | undefined — Resolves the physics laws in effect for the active world: a place world's own `physics` wins field-by-field over the game-level default. Non-place worlds (and games with no world) keep the game-level config unchanged.
- `revertDeltaFromSnapshot` (function): function revertDeltaFromSnapshot(snapshot: TerraformSnapshot, delta: TerraformDelta): TerraformSnapshot — Returns a new snapshot with a delta's `before` offsets restored (copy-on-write undo).
- `revertSurfaceDeltaFromSnapshot` (function): function revertSurfaceDeltaFromSnapshot(snapshot: TerraformSnapshot, delta: SurfaceDelta): TerraformSnapshot — Returns a new snapshot with a surface delta's `before` ids restored (copy-on-write undo).
- `road` (function): function road(config: RoadEnvironmentConfig): RoadEnvironmentDescriptor — Declare a road ribbon for an `environment()` world; the shell drapes and renders it over the terrain.
- `roadSurfaceSampler` (function): function roadSurfaceSampler(roads: readonly RoadEnvironmentDescriptor[], options: RoadSurfaceOptions = {}): (x: number, z: number) => number — A `surfaceFriction`-compatible sampler (the `(x, z) => grip` hook a kinematic car reads each tick) that turns road geometry into grip (#1051): full `onRoad` grip on the asphalt, a monotonic linear ramp down across a `shoulder`-wide band at the curb, and flat `offRoad` grip beyond it — so a car that clips onto the grass loses bite progressively instead of snapping. Closes over {@link distanceToRoadEdge}, so the returned sampler is itself allocation-free per call.
- `rotatedFootprint` (function): function rotatedFootprint(footprint: Footprint, headingDegrees: number): Footprint — The axis-aligned footprint extent after rotating a rectangular {@link Footprint} by `headingDegrees` — footprint-aware placement: a 90-degree turn swaps width/depth, and arbitrary headings grow the bounding box so overlap and snap checks see the space the rotated asset truly occupies.
- `rotationYToHeading` (function): function rotationYToHeading(rotationY: number): number — Inverse of {@link headingToRotationY}: recover the `[0, 360)` compass heading from a Three.js Y-rotation. Lets a gizmo or inspector present radians as the degrees authors edit.
- `sagCurve` (function): function sagCurve(a: Vec3, b: Vec3, sag: number, segments: number): Vec3[] — Quadratic-Bézier sag between two anchors: the control point is pulled straight down so the mid-span lowest point droops by exactly `sag` meters below the chord. Cheap and stable; the go-to for cables where exact catenary physics don't matter. Returns `segments + 1` points.
- `sampleBatch` (function): function sampleBatch<P extends SamplePoint>(options: SampleBatchOptions<P>): SampleBatchResult<P> — Place up to `count` points from `region`, each clearing the shared constraints and honoring `minSeparation` against every point already placed in this batch (via a spatial hash, not an O(n²) scan). Order is deterministic for a given `rng` stream. Batches never silently under-fill: the result reports `placed`, `complete`, and the total attempt count.
- `sampleElevation` (function): function sampleElevation(sampleHeight: HeightSampler, x: number, z: number, reference = 0): ElevationReadout — Reads the ground elevation under a world point and its signed delta from a reference plane — the measurable cursor/hover feedback ("+3.4 above the pad") an author needs to judge sculpted height.
- `sampleGripCurve` (function): function sampleGripCurve(curve: GripCurve, slip: number): number — Piecewise-linear tire-grip curve: normalized lateral slip → available grip (0..1). Grip peaks near the breakaway slip then falls off as the tire slides — the shape that separates a planted corner from a drift. Points are read in ascending slip order; ends clamp.
- `samplePoint` (function): function samplePoint<P extends SamplePoint>(options: SamplePointOptions<P>): SampleResult<P> — Draw one point from `region` that clears every constraint, retrying up to `maxAttempts` times with the injected `rng`, then apply the `fallback` policy. Returns a structured {@link SampleResult} — a clean hit is `ok: true`; exhaustion or a degenerate region is reported with the attempt count and an explicit fallback flag, never a silently-accepted bad point.
- `sampleResponseCurve` (function): function sampleResponseCurve(curve: ResponseCurve, satisfaction: number): number — Sample a response curve at a `0..1` satisfaction. Deterministic, allocation-free.
- `sampleStratified` (function): function sampleStratified(options: StratifiedOptions): Vec2[] — Stratified 2D sampling: one jittered point per grid cell over `area`, in deterministic row-major order. Unlike pure rejection sampling this guarantees even coverage (no clumps, no gaps) — the distinct "stratified" distribution policy, kept separate from area-uniform draws.
- `sanitizeGameTimeScale` (function): function sanitizeGameTimeScale(timeScale?: number | null): number — ⚠ undocumented
- `scatter` (function): function scatter(config: ScatterConfig): ScatterPoint[] — ⚠ undocumented
- `scatterCoverageSpec` (function): function scatterCoverageSpec(kind: string): ScatterCoverageSpec | null — The coverage spec for a scatterable kind, or `null` when the kind is not scatterable.
- `scatterFootprintArea` (function): function scatterFootprintArea(object: { points?: readonly { x: number; z: number }[]; halfExtents?: { x: number; z: number }; radius?: number; }): number — Footprint area (m²) of a scatterable object: a closed path polygon (shoelace), a volume box (`halfExtents`), or a disc (`radius`). Structural so it accepts a `SceneKindObject`, an editor volume, or a scatter path without a hard type dependency.
- `scatterItems` (function): function scatterItems<T>(field: RegionField<T>, area: Aabb, layersFor: (sample: RegionSample<T>) => readonly ScatterLayer[], options: { cell?: number; max?: number; saltKey?: number } = {}): ScatterInstance[] — Deterministically place opaque items across `area`, grounded on a region field. For each grid cell it asks `layersFor` which items may appear in that region and rolls one against their densities. The engine never interprets `item` — a game maps it to a mesh or entity. Content scatter (region-driven density) as opposed to `scatter` in `./scatter`, which is renderer-free geometric point distribution.
- `scatterRegionEstimate` (function): function scatterRegionEstimate(path: ScenePathLike): { area: number; count: number } — Estimated placement count for a scatter path — density × polygon area, for a live UI readout.
- `scatterRegionFromPath` (function): function scatterRegionFromPath(path: ScenePathLike): ScatterRegion | null — Builds a resolvable {@link ScatterRegion} from a scatter path (XZ polygon + rules), or null.
- `screenRect` (function): function screenRect(ax: number, ay: number, bx: number, by: number): ScreenRect — Normalize two drag corners (in any order) into a rectangle.
- `seedForPlace` (function): function seedForPlace(worldId: string, runSeed = ""): string — The engine-side seed derivation for a place: a stable string from the world `id` plus the save/run seed. Generators and scatter receive this — never a `seed` field in the world definition — so a save replays its world deterministically and a fresh run can vary by `runSeed` alone.
- `selectAutoTarget` (function): function selectAutoTarget(policy: AutoTargetPolicy, fromId: string, deps: AutoTargetDeps): string | null — ⚠ undocumented
- `selectWithinRect` (function): function selectWithinRect(candidates: readonly ScreenPoint[], rect: ScreenRect): string[] — Ids of the projected candidates whose screen point falls inside the marquee.
- `shellRegion` (function): function shellRegion(center: Point3, innerRadius: number, outerRadius: number, options: { distribution?: VolumeDistribution } = {}): SampleRegion<Point3> — A spherical shell between `innerRadius` and `outerRadius`. `"volume"` fills the shell with even density; `"radial"` spreads uniformly in radius. Direction first, then radius.
- `sidewalkPoint` (function): function sidewalkPoint(road: RoadEnvironmentDescriptor, side: "left" | "right", fraction: number): RoadPoint | null — A deterministic point on one of a road's sidewalks at a normalized position — `side` picks the band, `fraction` (0..1) picks how far along. The canonical pedestrian spawn helper.
- `sidewalkWidthOf` (function): function sidewalkWidthOf(road: RoadEnvironmentDescriptor): number — Resolved sidewalk band widths for a road; zero when the road declares no sidewalk.
- `skillCheckZoneAt` (function): function skillCheckZoneAt(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckZone — A timing-bar skill check that succeeds when the moving marker is released inside the target zone.
- `sky` (function): function sky(config: SkyEnvironmentConfig = {}): SkyEnvironmentDescriptor — ⚠ undocumented
- `slopeStepCost` (function): function slopeStepCost(field: { sampleHeight(x: number, z: number): number }, weight = DEFAULT_SLOPE_STEP_WEIGHT): (from: NavPoint, to: NavPoint) => number — `FindPathOptions.stepCost` factory that penalizes steep terrain: cost is `1 + weight * |Δheight| / horizontalDistance`, so with the default weight a 45° slope roughly doubles the step cost.
- `snapHeading` (function): function snapHeading(degrees: number, increment: number): number — Quantize `degrees` to the nearest multiple of `increment` (both in the `[0, 360)` convention). A non-positive increment is treated as free rotation and only normalizes. The math behind a `snap`-mode {@link PlacementRotationPolicy}.
- `snapToNearest` (function): function snapToNearest(registry: ConnectorRegistry, placed: readonly PlacedPiece[], movingDef: ConnectorPieceDef, cursor: ConnectorVec3, options: SnapOptions = {}): SnapResult | null — ⚠ undocumented
- `snow` (function): function snow(config: SnowEnvironmentConfig = {}): SnowEnvironmentDescriptor — Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
- `socketWorldPosition` (function): function socketWorldPosition(socket: ConnectorSocket, origin: ConnectorVec3, rotationY: number): ConnectorVec3 — ⚠ undocumented
- `socketsCompatible` (function): function socketsCompatible(a: ConnectorSocket, b: ConnectorSocket): boolean — ⚠ undocumented
- `solveLock` (function): function solveLock(spec: LockSpec): boolean — Whether the board has a path from the start row to the bolt seat at all.
- `solveLockPath` (function): function solveLockPath(spec: LockSpec): number[] | null — Return a concrete row-per-column solution, or null if the board is unsolvable.
- `solveSupport` (function): function solveSupport(pieces: readonly SupportPiece[], links: readonly SupportLink[], config: SupportConfig = {}): SupportResult — ⚠ undocumented
- `sphereRegion` (function): function sphereRegion(center: Point3, radius: number, options: { distribution?: VolumeDistribution } = {}): SampleRegion<Point3> — A filled ball. `"volume"` is volume-uniform (∛-corrected radius); `"radial"` is radius-uniform. Direction is drawn first (two draws), then radius.
- `splitRegion` (function): function splitRegion(region: MergedRegion, leftIds: readonly string[], ids: RegionSplitIds = {}, budget: RegionWorkBudget = {}): [FootprintRegion, FootprintRegion] | null — Partition whole original contributions by `leftIds`; both sides must remain cardinally connected. Singletons restore their original id and capacity; larger sides require explicit output identities. Returns null for invalid provenance/budget, unknown or duplicate ids, empty/disconnected sides, or conflicting output identities (including identities from the opposite side's contributions). An output may reuse its own side's source identity. Cell cuts/capacity repricing require caller policy. Both sides inherit the current region kind/tier. Inputs and grid reservations remain unchanged.
- `steerYaw` (function): function steerYaw(yaw: number, steerRight: number, turnRatePerSecond: number, dt: number): number — Integrate one steering step. `steerRight` is the signed steer input (+1 = turn right, matching `DRIVE_AXIS_BINDINGS`' KeyD/ArrowRight), `turnRatePerSecond` is radians per second at full lock. Steering right decreases yaw in the engine frame; this helper owns that sign so game code never re-derives it.
- `stepLock` (function): function stepLock(spec: LockSpec, col: number, row: number, action: LockAction): { result: LockStepResult; col: number; row: number } — Authoritative single step. The caller owns the lives economy: a slip/bind/trap does not advance the pick and should cost a life; advanced/success move the pick.
- `stepPlayerMovement` (function): function stepPlayerMovement(ctx: GameContext, userId: string, input: InputFrame, dt: number, tuning: PlayerMovementTuning, heading?: number, pitch?: number): void — Integrate one player's movement for a tick from their held-input frame and commit the pose — the single genre-agnostic controller both the shell (its local player) and a host (each connected player in `onTick`) call, so single-player and server-authoritative movement are identical. Reads the player's controlled entity, terrain, scene solids, and pending motion impulses; writes the entity pose via `setPose`. Retains heading + kinematic body per `userId` on the `ctx`. Pass `heading` to override the internally-integrated yaw (the shell owns yaw for its camera); omit it and the controller turns from the frame's `turnLeft`/`turnRight` actions. Pass `pitch` for 6DOF spectator flight when `alignWithLook` is set.
- `sumMagnitude` (function): function sumMagnitude<P>(memberships: readonly AreaMembership<P>[], magnitudeOf: MagnitudeOf<P>): number — Sum a numeric magnitude across memberships — additive aggregation for a total field strength (total damage per tick, total slow). A terminal reducer, not a filter, so it returns the number.
- `summarizeElevation` (function): function summarizeElevation(sampleHeight: HeightSampler, region: GuideRegion, resolution = 64, maxSamples = 256): ElevationSummary — Summarises elevation across a region on a bounded sample grid: min, max, mean, relief range, and the world points of the extremes — the selection min/max and legend feedback the readability overlay reports, and the input to {@link chooseContourInterval}. Pure math, renderer-agnostic.
- `summarizeEnvironment` (function): function summarizeEnvironment(feature: EnvironmentWorldFeature): EnvironmentSummary — ⚠ undocumented
- `surfaceGridLines` (function): function surfaceGridLines(sampleHeight: HeightSampler, options: SurfaceGridOptions): SurfaceGridLine[] — Builds a surface-following major/minor grid over a region: constant-`x` and constant-`z` lines at `spacing`, each draped onto the terrain so the reference grid climbs sculpted surfaces instead of being occluded by them (the flat `y = 0` grid's core failure). Draping subdivides to `drape.spacing`. Pure math, renderer-agnostic.
- `surfaceRing` (function): function surfaceRing(sampleHeight: HeightSampler, center: GroundPoint, radius: number, segments = 48, options: DrapeOptions = {}): number[] — A closed circle draped on the surface — the surface-following placement guide ring under a cursor or a selected object. Returns flat `[x, y, z, ...]` world triples forming a loop (last vertex repeats the first). `segments` sets the smoothness of the ring.
- `talkable` (function): function talkable(dialogueId: string): PromptableBehavior — ⚠ undocumented
- `terrain` (function): function terrain(config: TerrainEnvironmentConfig = {}): TerrainEnvironmentDescriptor — Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
- `terrainContourGuides` (function): function terrainContourGuides(field: Pick<TerrainField, "sampleHeight">, region: GuideRegion, targetLines = 12, resolution = 128): { interval: number; summary: ElevationSummary; contours: ContourLine[] } — Convenience over {@link extractContours} that auto-picks the interval from the field's own relief: summarises the region, chooses a readable interval for `targetLines` bands, and traces the contours — the one call the editor overlay makes to turn a `TerrainField` into ready-to-draw guides. Returns an empty list for flat ground.
- `themeLoopSeconds` (function): function themeLoopSeconds(theme: MusicTheme): number — Loop length of a theme in seconds.
- `tickDrivableVehicle` (function): function tickDrivableVehicle<TStep extends DrivableSimStep = KinematicVehicleStep, TModifiers = KinematicVehicleModifiers>(vehicle: DrivableSim<TModifiers, TStep>, dt: number, axis: AxisInput, options: DrivableVehicleOptions<TModifiers> = {}): DrivableVehicleStep<TStep> — Connects an `AxisInput` sample straight through a ground-vehicle sim (`KinematicVehicle` or `VehicleDynamics`) to a scene entity's pose for one tick (#533.1) — the throttle/steer/handbrake → sim → `setPose` loop every drivable-vehicle game hand-rolled. Ground-snaps the result when `groundHeight` is given (terrain-following cars, not just flat racetracks). Pair with `scene/vehicleSeat` for who is allowed to drive and where the camera points; this function only steps the sim and shapes the pose patch, nothing else.
- `tierForStanding` (function): function tierForStanding(tiers: readonly ReputationTier[], standing: number): ReputationTier — Map a faction standing value to its named reputation tier.
- `tilemap` (function): function tilemap(config: TilemapWorldConfig): WorldFeature — Declares a 2D tilemap world from a map string.
- `toDebrisBodies` (function): function toDebrisBodies(pieces: readonly SupportPiece[], collapsedIds: readonly string[], options: DebrisOptions = {}): AddBodyOptions[] — ⚠ undocumented
- `toEditorMarker` (function): function toEditorMarker(result: PlaceAssetResult): { id: string; kind: string; position: PlaceAssetVec3; rotationY: number; label: string; color: string; meta: Record<string, unknown>; } — Scene-document form: feed editor `addMarker` / `place_asset` path.
- `toEngineUnits` (function): function toEngineUnits(sourceValue: number, space?: Pick<AssetSpace, "unitScale">): number — Convert a source-space length to engine meters through the asset's {@link AssetSpace.unitScale} — the data-owned replacement for per-game scale constants (a native ~4-unit kit tile down to a 1-unit grid).
- `toStructureInput` (function): function toStructureInput(result: PlaceAssetResult): AddStructureInput — Game-state form: feed {@link createPlacedStructureStore}.add.
- `trimBandAtJunctions` (function): function trimBandAtJunctions(bandPath: readonly RoadPoint[], bandWidth: number, junctions: readonly RoadJunctionInput[], options: BandTrimOptions = {}): RoadPoint[][] — Cut an offset band (a polyline running PARALLEL to a street — e.g. a sidewalk from `Street.sidewalks.{left,right}`) out of every junction's apron, so the band stops at the crossing instead of sailing straight through it. Unlike {@link trimPathAtJunctions} the band never passes through a node, so it is clipped by DISTANCE: each junction contributes a circular apron of radius `max arm half-width + apronMargin + bandWidth/2 + clearance` (plus a small curb-return allowance), and any part of the band inside any apron circle is removed, splitting the band into the sub-paths that survive outside. Entry/exit points land exactly on the apron boundary. A band that never enters an apron passes through as a single untouched copy.
- `trimPathAtJunctions` (function): function trimPathAtJunctions(path: readonly RoadPoint[], width: number, junctions: readonly RoadJunctionInput[], options: JunctionGeometryOptions = {}): TrimmedRoad[] — Cut a street centerline back from the junctions it passes through so its ribbon ENDS at the junction boundary instead of ploughing through the node. Junctions are matched to path vertices within `nodeEpsilon` (endpoints and interior vertices alike); a junction sitting on an interior vertex SPLITS the path into two independently-trimmed sub-paths. Each cut records the exact boundary point and the road's left/right edge corners there, so {@link buildJunctionSurface} can weld its polygon onto the identical vertices with no overlap.
- `uniformGravity` (function): function uniformGravity(vector: GravityVector = [0, -9.81, 0]): GravityField — Constant vector gravity for ordinary worlds, space stations, and sideways-gravity levels.
- `uniqueByStackKey` (function): function uniqueByStackKey<P>(magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P> — Keep at most one membership per `stackKey`. With `magnitudeOf` the strongest per key wins (ties broken by `sourceId` for determinism); without it the first-seen per key wins. Use for unique-by-key buffs where reapplying the same aura should not stack.
- `unprojectFromMinimap` (function): function unprojectFromMinimap(point: { x: number; y: number }, view: MinimapView): WorldXZ — Invert `projectToMinimap` (#285.6): minimap pixel → world XZ, rotate-aware — click-to-pin, tap-to-ping, drag-to-set-waypoint map interactions.
- `validateAssetSpace` (function): function validateAssetSpace(raw: unknown): AssetSpaceIssue[] — Report contradictory or malformed asset-space metadata so catalog generation can reject it before it reaches a tool: non-finite headings, non-positive scales/sizes, inverted bounds, unknown anchors, and ill-formed rotation policies (a `snap` with a non-positive increment, an unknown `mode`). An empty array means valid. Validation lives here so tools consume resolved metadata instead of reinterpreting.
- `validatePlacement` (function): function validatePlacement(request: PlacementRequest, rules: PlacementRules = {}): PlacementResult — Footprint validity: bounds + obstacle overlap after optional grid snap.
- `visibleCells` (function): function visibleCells(spec: LockSpec, col: number, window: number): LockCell[] — The render-safe slice: every open cell in columns [0, col + window]. The single source of truth for fog and the anti-cheat boundary — never serialize the full spec to a client.
- `voxel` (function): function voxel(config: VoxelWorldConfig): WorldFeature — Declares a voxel-grid world for block-based games.
- `wander` (function): function wander({ radius }: { radius: number }): WanderBehavior — ⚠ undocumented
- `waterSurface` (function): function waterSurface(config: WaterSurfaceConfig = {}): WaterSurface — ⚠ undocumented
- `waterSurfaceFromDescriptor` (function): function waterSurfaceFromDescriptor(descriptor: OceanEnvironmentDescriptor, waves?: number): WaterSurface — ⚠ undocumented
- `wedgeFormation` (function): function wedgeFormation(options: WedgeFormationOptions): FormationSlotGenerator — A "V"/arrowhead with the apex at the destination and arms trailing back — a flying-wedge charge or a goose skein. Slot 0 is the tip; later slots alternate right then left, each rank stepping one `spacing` outward and backward.
- `weightedRegion` (function): function weightedRegion<P extends SamplePoint>(entries: readonly WeightedRegionEntry<P>[]): SampleRegion<P> — A composite that first picks one member by weight, then delegates to its sampler — the "weighted subregions" distribution policy. `contains` is true when any member contains the point.
- `windField` (function): function windField(config: WindFieldConfig = {}): WindField — ⚠ undocumented
- `withPart` (function): function withPart(parts: readonly VehiclePart[], next: VehiclePart): VehiclePart[] — Swap a part into its slot: any part already in `next.slot` is removed and `next` takes its place in the same install position, so the order (and therefore the composed numbers) stays stable across an upgrade.
- `withPathProfiles` (function): function withPathProfiles(base: (x: number, z: number) => number, profiles: readonly TerrainPathProfile[]): (x: number, z: number) => number — Wraps a height sampler so each authored `TerrainPathProfile` reshapes it. Profiles apply in list order (later profiles compose over earlier ones, so an intersection's last profile wins its core); each reads the running height as its surrounding ground and the original `base` for `sample` centerline heights. The returned sampler is pure and deterministic. Degenerate profiles (fewer than two points, non-positive width or length) are skipped; with no usable profile the original `base` is returned unchanged.
- `world` (function): function world(config: PlaceConfig): PlaceWorldFeature — Declares the place a game is played in: substrate (`ground`) + laws (`physics`, `ground.surface`). The thin default start — `flat` with `Infinity` axes and default physics, `board` for 2D — is a complete world; dressing it (sky, foliage, props, sculpt) is editor-authored scene content. Multiple worlds per game are first-class: declare one `world()` per place, each with its own id, ground, and physics. Games that are not a spatial place (pure UI/rules) omit `world` entirely.
- `worldSockets` (function): function worldSockets(def: ConnectorPieceDef, piece: PlacedPiece): WorldSocket[] — ⚠ undocumented

## @jgengine/core/world/authoredAnimation

- `AuthoredAnimationDiagnostic` (interface): interface AuthoredAnimationDiagnostic — Rejected saved animation data with a document location and a repair.
- `AuthoredAnimationDocumentLike` (interface): interface AuthoredAnimationDocumentLike — Structural marker input; immutable editor scene documents satisfy it.
- `AuthoredAnimationResult` (interface): interface AuthoredAnimationResult — Resolved marker animation or the caller's unchanged default, with rejected-value diagnostics.
- `createAuthoredAnimationReader` (function): function createAuthoredAnimationReader(getDocument: () => AuthoredAnimationDocumentLike, markerId: string, defaults?: AuthoredAnimation): () => AuthoredAnimationResult — Reads the latest immutable document each call, validating only when document identity changes. The caller owns the marker-to-character association and its asset-specific animation defaults.
- `readAuthoredAnimation` (function): function readAuthoredAnimation(document: AuthoredAnimationDocumentLike, markerId: string, defaults?: AuthoredAnimation): AuthoredAnimationResult — Resolves a caller-selected marker's animation. Authored configuration replaces game defaults; omitted or malformed data retains the exact default. Partial roles remain available for editing. Asset clip and rig compatibility is diagnosed by the animation renderer.
- `readAuthoredAnimationValue` (function): function readAuthoredAnimationValue(value: unknown, path: string, defaults?: AuthoredAnimation): AuthoredAnimationResult — Validates one saved animation value at the caller's document path without scanning markers. Omitted or malformed values retain the exact default; valid authored configuration replaces it whole.

## @jgengine/core/world/authoredEntities

- `AuthoredEntityDocumentLike` (interface): interface AuthoredEntityDocumentLike — The minimal document shape {@link authoredEntitySpawns} walks; any `EditorDocument` satisfies it.
- `AuthoredEntityMarkerLike` (type): type AuthoredEntityMarkerLike = AuthoredObjectMarkerLike — The minimal marker shape entity spawns read; any `EditorMarker` satisfies it.
- `AuthoredEntitySpawn` (interface): interface AuthoredEntitySpawn — One resolved entity to spawn from the authored scene — its marker id, catalog id, and pose.
- `ENTITY_MARKER_KINDS` (const): const ENTITY_MARKER_KINDS: readonly string[] — Marker kinds that are spawnable entities (materialized by `authoredEntitySpawns`), not static catalog props. {@link resolveAuthoredObjects} skips them by default so a placed `mob`/`boss` is spawned once as an entity and never also placed as a static mesh.
- `authoredEntitySpawns` (function): function authoredEntitySpawns(document: AuthoredEntityDocumentLike, kinds: readonly string[] = ENTITY_MARKER_KINDS): AuthoredEntitySpawn[] — Every authored entity marker (`mob`/`boss` by default) that carries a `catalogId`, as a spawn plan the runtime feeds to `ctx.scene.entity.spawn(catalogId, { id, position })`. Reads the same document the editor authors, so placing a mob and setting its catalog id in the editor is all it takes to spawn it — no coordinates or spawn tables copied into game code. Markers without a catalog id are skipped (they are placement-only, e.g. a boss arena marker a game handles specially).

## @jgengine/core/world/authoredObjects

- `AuthoredAnimation` (type): type AuthoredAnimation = ModelAnimationConfig | "auto" | "none" — A placement's authored rig animation override — the stored `marker.meta.animation` contract (#1274).
- `AuthoredObject` (interface): interface AuthoredObject — One authored catalog prop resolved from an editor marker — grounded at `x`/`z` with yaw, ready for `ctx.scene.object.place` or {@link placeAuthoredObjects}.
- `AuthoredObjectMarkerLike` (interface): interface AuthoredObjectMarkerLike extends SceneMarkerLike — Minimal marker shape {@link resolveAuthoredObjects} reads; any `EditorMarker` satisfies it.
- `AuthoredObjectPlaceTarget` (interface): interface AuthoredObjectPlaceTarget — Structural place target — any `ObjectStore` satisfies it.
- `AuthoredObjectsDocumentLike` (interface): interface AuthoredObjectsDocumentLike — Minimal document shape {@link resolveAuthoredObjects} walks; any `EditorDocument` satisfies it.
- `AuthoredObjectsResult` (interface): interface AuthoredObjectsResult — Resolved catalog props and located repairs for rejected per-placement animation overrides.
- `ENTITY_MARKER_KINDS` (const): const ENTITY_MARKER_KINDS: readonly string[] — Marker kinds that are spawnable entities (materialized by `authoredEntitySpawns`), not static catalog props. {@link resolveAuthoredObjects} skips them by default so a placed `mob`/`boss` is spawned once as an entity and never also placed as a static mesh.
- `PlaceAuthoredObjectsOptions` (interface): interface PlaceAuthoredObjectsOptions — Options for {@link placeAuthoredObjects}.
- `ResolveAuthoredObjectsOptions` (interface): interface ResolveAuthoredObjectsOptions — Options for {@link resolveAuthoredObjects}.
- `markerAnimation` (function): function markerAnimation(marker: AuthoredObjectMarkerLike): AuthoredAnimation | undefined — Validated per-placement animation from `marker.meta.animation`. Missing or malformed overrides return undefined so the placed object retains its catalog animation; valid data replaces it whole.
- `markerCatalogId` (function): function markerCatalogId(marker: AuthoredObjectMarkerLike): string | null — Catalog id for a marker: first-class `catalogId` field, else `meta.catalogId` migration alias. Returns null when the marker is not an authored catalog prop (spawn, mob, generator, …).
- `placeAuthoredObjects` (function): function placeAuthoredObjects(store: AuthoredObjectPlaceTarget, objects: readonly AuthoredObject[], sampleHeight: (x: number, z: number) => number, options: PlaceAuthoredObjectsOptions = {}): string[] — Places resolved authored objects into an object store, grounding each on `sampleHeight(x,z)` plus per-object and options vertical offsets. Returns the instance ids that were placed (or kept).
- `placeAuthoredObjectsFromDocument` (function): function placeAuthoredObjectsFromDocument(store: AuthoredObjectPlaceTarget, document: AuthoredObjectsDocumentLike, sampleHeight: (x: number, z: number) => number, options: PlaceAuthoredObjectsOptions = {}): string[] — Convenience: resolve a document then place every authored catalog prop.
- `resolveAuthoredObjects` (function): function resolveAuthoredObjects(document: AuthoredObjectsDocumentLike, options: ResolveAuthoredObjectsOptions = {}): AuthoredObject[] — Every marker carrying a catalog id, as placeable props — pure, no terrain sample. Parallel to {@link resolveScatter}: games and headless tests read the same list `<AuthoredObjects>` places. Entity-spawn kinds (`mob`/`boss`) are skipped by default — they carry a `catalogId` for their entity definition, but are spawned via `authoredEntitySpawns`, not placed as static meshes.
- `resolveAuthoredObjectsWithDiagnostics` (function): function resolveAuthoredObjectsWithDiagnostics(document: AuthoredObjectsDocumentLike, options: ResolveAuthoredObjectsOptions = {}): AuthoredObjectsResult — Resolves catalog props and validates their animation in one document pass. Rejected overrides are omitted so each model inherits its original catalog setting. Excluded and unplaced markers remain the responsibility of their own consumers.
- `syncAuthoredObjects` (function): function syncAuthoredObjects(store: AuthoredObjectPlaceTarget & { remove(instanceId: string): boolean }, objects: readonly AuthoredObject[], previousObjects: readonly AuthoredObject[], sampleHeight: (x: number, z: number) => number, options: Pick<PlaceAuthoredObjectsOptions, "verticalOffset"> = {}):… — Update changed authored placements and remove previous authored ids absent from the next document. Initial placement keeps game onInit state; unrelated document edits preserve runtime prop state. Call on document changes, never on simulation ticks; runtime-created objects remain untouched.

## @jgengine/core/world/authoredSimulation

- `AuthoredFlockState` (interface): interface AuthoredFlockState — A habitat's live poses; game species determine appearance and gameplay actor policy.
- `AuthoredSimulationRuntime` (interface): interface AuthoredSimulationRuntime — Engine-owned authority uses the caller's simulation clock; render quality cannot change it.
- `AuthoredSimulationSnapshot` (interface): interface AuthoredSimulationSnapshot — Runtime state excludes authored configuration and cosmetic particle pools.
- `AuthoredSurface` (interface): interface AuthoredSurface extends WeatherExposureSurface — A watched surface is sampled in metres. Its accumulation survives runtime save/restore.
- `EnvironmentAppearanceSignals` (interface): interface EnvironmentAppearanceSignals — Appearance adapters consume these units without owning weather state or its clock.
- `createAuthoredSimulation` (function): function createAuthoredSimulation(options: { document?: EditorDocument; timeSeconds: () => number; particles?: ParticleDirector; maxSurfaces?: number }): AuthoredSimulationRuntime — Compose authored weather, shelter, accumulation, named effect intents and fire with one clock.

## @jgengine/core/world/authoredSolids

- `AUTHORED_SOLID_LAYER_PREFIX` (const): const AUTHORED_SOLID_LAYER_PREFIX: "authored:" — Layer prefix `syncAuthoredSolids` owns in `ctx.world.solids`; one layer per document object.
- `AuthoredSolidsDocumentLike` (interface): interface AuthoredSolidsDocumentLike — Minimal editor document shape {@link resolveAuthoredSolids} walks; any `EditorDocument` satisfies it.
- `resolveAuthoredSolids` (function): function resolveAuthoredSolids(document: AuthoredSolidsDocumentLike, sampleHeight?: (x: number, z: number) => number): Map<string, readonly WorldSolid[]> — Solids for every document object whose scene kind declares `solids`, keyed by object id. Objects whose kind has no `solids` hook, or whose hook returns none, are left out.
- `syncAuthoredSolids` (function): function syncAuthoredSolids(solids: WorldSolids, document: AuthoredSolidsDocumentLike, sampleHeight?: (x: number, z: number) => number): void — Write a document's studio solids into `solids` (usually `ctx.world.solids`), one `authored:<objectId>` layer per object, dropping authored layers the document no longer has. Call again whenever the document changes.

## @jgengine/core/world/authoredSpawn

- `AuthoredSpawnDocumentLike` (interface): interface AuthoredSpawnDocumentLike — Minimal document shape spawn queries walk; any `EditorDocument` satisfies it.
- `AuthoredSpawnMarkerLike` (interface): interface AuthoredSpawnMarkerLike extends SceneMarkerLike — Minimal marker shape spawn queries read; any `EditorMarker` satisfies it.
- `AuthoredSpawnOptions` (interface): interface AuthoredSpawnOptions — Options for {@link authoredSpawnPosition}: pick a specific marker id or a non-default kind.
- `PLAYER_SPAWN_KIND` (const): const PLAYER_SPAWN_KIND: "player_spawn" — Marker kind {@link authoredSpawnPosition} resolves by default.
- `authoredSpawnPosition` (function): function authoredSpawnPosition(document: AuthoredSpawnDocumentLike, options: AuthoredSpawnOptions = {}): [number, number, number] | null — Position of the authored spawn marker as a spawn-ready `[x, y, z]` tuple, or null when the document has none. Reads the first `player_spawn` marker by default, so dragging the marker in the editor moves where players spawn — no coordinates copied into game code.
- `authoredSpawnRotation` (function): function authoredSpawnRotation(document: AuthoredSpawnDocumentLike, options: AuthoredSpawnOptions = {}): number — Facing (yaw radians) of the authored spawn marker, or 0 when the document has none — pair with {@link authoredSpawnPosition} to spawn players where and how the editor placed them.
- `markersOfKind` (function): function markersOfKind<TMarker extends AuthoredSpawnMarkerLike>(document: { markers: readonly TMarker[] }, kind: string): TMarker[] — Every marker of `kind`, in document order — the generic query behind gameplay that references authored markers by kind instead of copying coordinates into code.

## @jgengine/core/world/authoredWeather

- `AuthoredWeather` (interface): interface AuthoredWeather — Pure spatial weather queries using the caller’s authoritative simulation clock.
- `AuthoredWeatherConfig` (interface): interface AuthoredWeatherConfig — Serializable weather lists capped at 256 entries. Wind amplitudes and direction components are bounded to 1e6, gust frequency to 1000 Hz; coordinates and times to 1e12 metres/seconds.
- `AuthoredWeatherMode` (type): type AuthoredWeatherMode = "clear" | "rain" | "snow" | "mixed" | "dust" — Wind is metres/second along world X,Z; world Y points up. Times are simulation seconds.
- `AuthoredWeatherProfile` (interface): interface AuthoredWeatherProfile extends WeatherConditions — A named set of conditions referenced by the authored schedule.
- `AuthoredWeatherSample` (interface): interface AuthoredWeatherSample extends WeatherConditions — Resolved conditions and wind at a world point and absolute simulation time.
- `AuthoredWeatherTransition` (interface): interface AuthoredWeatherTransition — An absolute simulation-time profile change with an optional continuous blend.
- `AuthoredWeatherZone` (interface): interface AuthoredWeatherZone — A local weather override and additive wind source centered in world X,Z metres.
- `WeatherConditions` (interface): interface WeatherConditions — Precipitation intensity, temperature offset in degrees, and normalized lightning brightness.
- `WeatherExposure` (interface): interface WeatherExposure — Bounded surface accumulation with restoration, live rate tuning and explicit release.
- `WeatherExposureConfig` (interface): interface WeatherExposureConfig — Surface capacity and normalized wetting, drying, snowfall and melting rates per second.
- `WeatherExposureSample` (interface): interface WeatherExposureSample — Retained normalized wetness and snow coverage, temperature, and sky exposure.
- `WeatherExposureSnapshot` (interface): interface WeatherExposureSnapshot — Detached accumulation values keyed by retained surface id.
- `WeatherExposureStorage` (interface): interface WeatherExposureStorage — Injected persistence for detached surface accumulation snapshots.
- `WeatherExposureSurface` (interface): interface WeatherExposureSurface — A stable surface id and world X,Z position with explicit sky exposure and temperature.
- `createAuthoredWeather` (function): function createAuthoredWeather(source: AuthoredWeatherConfig = {}): AuthoredWeather — Pure authored weather sampling; the caller's simulation clock owns pause, replay and restore.
- `createWeatherEnvironmentField` (function): function createWeatherEnvironmentField(weather: AuthoredWeather, config: Omit<EnvironmentFieldConfig, "rain"> = {}): EnvironmentField — Environment temperature, sunlight and shelter read the same authored precipitation as rendering.
- `createWeatherExposure` (function): function createWeatherExposure(config: WeatherExposureConfig = {}, storage?: WeatherExposureStorage): WeatherExposure — Bounded surface accumulation shared by gameplay and material adapters, with injected persistence.
- `validateAuthoredWeather` (function): function validateAuthoredWeather(config: AuthoredWeatherConfig): void — Validate authoring references and work bounds before persisting a weather document.

## @jgengine/core/world/buildPermissions

- `BuildActor` (interface): interface BuildActor { userId: string; guildId?: string } — ⚠ undocumented
- `BuildRole` (type): type BuildRole = "owner" | "editor" | "viewer" — ⚠ undocumented
- `ContributionGoal` (type): type ContributionGoal = Readonly<Record<string, number>> — ⚠ undocumented
- `ContributionPool` (interface): interface ContributionPool { contribute(userId: string, resource: string, amount: number): ContributionResult; totals(): Readonly<Record<string, number>>; remaining(): Readonly<Record<string, number>>; byContributor(userId: string): Readonly<Record<string, number>>; … — ⚠ undocumented
- `ContributionResult` (interface): interface ContributionResult { accepted: number; overflow: number; complete: boolean } — ⚠ undocumented
- `PlotPermissionConfig` (interface): interface PlotPermissionConfig { plotId: string; ownerId: string; guildId?: string; roles?: Readonly<Record<string, BuildRole>>; guildRole?: BuildRole } — ⚠ undocumented
- `PlotPermissionSnapshot` (interface): interface PlotPermissionSnapshot { plotId: string; ownerId: string; guildId?: string; roles: Readonly<Record<string, BuildRole>>; guildRole?: BuildRole } — ⚠ undocumented
- `PlotPermissions` (interface): interface PlotPermissions { roleOf(actor: BuildActor): BuildRole | null; canEdit(actor: BuildActor): boolean; canView(actor: BuildActor): boolean; grant(userId: string, role: BuildRole): void; revoke(userId: string): void; setGuild(guildId: string | null, role?: Bui… — ⚠ undocumented
- `createContributionPool` (function): function createContributionPool(goal: ContributionGoal): ContributionPool — ⚠ undocumented
- `createPlotPermissions` (function): function createPlotPermissions(config: PlotPermissionConfig): PlotPermissions — ⚠ undocumented

## @jgengine/core/world/buildSockets

- `BuildCell` (interface): interface BuildCell — One integer grid cell — structurally the `GridCell` of `world/footprintGrid` (no import needed).
- `BuildFootprint` (interface): interface BuildFootprint — A rectangular footprint (world units) a piece occupies on the build grid — the occupancy bridge.
- `BuildPieceDef` (interface): interface BuildPieceDef — A registered piece type: its named sockets and, optionally, the footprint it claims when placed.
- `BuildSocketCatalog` (interface): interface BuildSocketCatalog — Handle returned by {@link createBuildSocketCatalog}.
- `BuildSocketCatalogConfig` (interface): interface BuildSocketCatalogConfig — Serializable catalog config; also the shape returned by {@link BuildSocketCatalog.toJSON}.
- `ConnectionRule` (interface): interface ConnectionRule — Declares that two socket kinds may snap together; `mutual` (default `true`) also allows `b`→`a`.
- `ModelSocketLike` (interface): interface ModelSocketLike — A `{ name, offset }` attach point — structurally the `ModelSocket` of `scene/modelSockets`.
- `PieceTransform` (interface): interface PieceTransform — World transform of a placed piece: position plus a yaw about +Y.
- `PlacedPiece` (interface): interface PlacedPiece — An already-placed piece the resolver snaps candidates against.
- `PlacedSocket` (interface): interface PlacedSocket — A piece's socket resolved into world space.
- `ResolveSnapsOptions` (interface): interface ResolveSnapsOptions — Options for {@link BuildSocketCatalog.resolveSnaps}.
- `SnapCandidate` (interface): interface SnapCandidate — A resolved snap: which sockets mate and the world transform that lands the candidate onto the target.
- `SocketDef` (interface): interface SocketDef — One named socket on a piece: where it sits and which horizontal direction it faces (yaw about Y).
- `SocketVec3` (type): type SocketVec3 = readonly [number, number, number] — Data-driven modular build-piece snap system: a catalog of piece types, each declaring named sockets (local position + outward facing + a generic "kind"), plus a connection-rule table saying which socket kinds may mate. Given a placed piece and a candidate type it resolves every valid snap — the world transform that lands the candidate's socket exactly on the placed piece's socket, facing back into it. Genre-agnostic: foundation/wall/ceiling/pillar/edge snapping falls out of the catalog data, with no game-specific piece names baked in. Pure and serializable; composes with `world/footprintGrid` occupancy (via an injected `isFree` predicate — never imported) and with `scene/modelSockets` named attach points (via {@link pieceSocketsFromModel}).
- `createBuildSocketCatalog` (function): function createBuildSocketCatalog(config: BuildSocketCatalogConfig): BuildSocketCatalog — Build a modular snap catalog from piece definitions and a connection-rule table. Resolves the set of valid snap transforms when hovering a candidate piece near a placed one: for every compatible socket pair it computes the world transform that seats the candidate's socket onto the placed socket, oriented to face back into it. Deterministic ordering (nearest a cursor when given, else declaration order) and an optional occupancy predicate keep it drop-in for a build-mode controller.
- `footprintCells` (function): function footprintCells(position: SocketVec3, footprint: BuildFootprint, yaw = 0, cellSize = 1): BuildCell[] — The grid cells a piece `footprint` centered on `position` (world units) covers, honoring `yaw` (snapped to the nearest quarter turn). Mirrors `world/footprintGrid`'s `cellsFor` so a game can feed the result straight into `grid.isFree`/`grid.reserve` after committing a resolved snap — without this module importing the grid.
- `pieceSocketsFromModel` (function): function pieceSocketsFromModel(sockets: readonly ModelSocketLike[], kindOf: (name: string) => string, yawOf?: (name: string) => number): SocketDef[] — Turn a model's named attach points (from `scene/modelSockets`' `readNamedSockets`) into {@link SocketDef}s, classifying each into a connection `kind` via `kindOf` and, optionally, an outward `yaw` via `yawOf`. Lets an artist author snap sockets as empties in a GLB instead of by hand in the catalog. Pure and structural — no three.js or scene import.

## @jgengine/core/world/buildingGenerator

- `BUILDING_GENERATOR_ID` (const): const BUILDING_GENERATOR_ID: "building" — The generator id a catalog entry / placed marker references.
- `BUILDING_GENERATOR_SCHEMA` (const): const BUILDING_GENERATOR_SCHEMA: ParamSchema — The building generator's slider schema — drives the inspector via #809.

## @jgengine/core/world/buildingIndex

- `BuildingHit` (interface): interface BuildingHit { building: GeneratedBuilding; distance: number } — ⚠ undocumented
- `BuildingIndex` (interface): interface BuildingIndex { readonly buildings: readonly GeneratedBuilding[]; at(point: Vec2): GeneratedBuilding | undefined; within(area: Aabb): GeneratedBuilding[]; nearest(point: Vec2): BuildingHit | undefined; isInside(point: Vec2): boolean; blockers(margin?: nu… — ⚠ undocumented
- `buildingIndex` (function): function buildingIndex(buildings: readonly GeneratedBuilding[]): BuildingIndex — ⚠ undocumented

## @jgengine/core/world/buildingKit

- `BuildingKit` (interface): interface BuildingKit — Binds a building's generated part slots to models. A kit is plain serializable data — scene documents can carry one — and is deliberately unopinionated about art direction: the engine ships the seam, games ship the bindings.
- `BuildingKitBinding` (type): type BuildingKitBinding = | { readonly type: "model"; readonly part: BuildingKitPart; readonly fit: BuildingKitFit } | { readonly type: "box" } | { readonly type: "omit" } — What a renderer should do with one generated part.
- `BuildingKitFit` (type): type BuildingKitFit = "stretch" | "contain" | "cover" | "native" — How a kit model's native bounds are mapped onto the slot box `BuildingPartPlacement.scale` describes.
- `BuildingKitInput` (interface): interface BuildingKitInput — The authoring shape {@link defineBuildingKit} normalizes into a {@link BuildingKit}.
- `BuildingKitPart` (interface): interface BuildingKitPart — One bindable variant for a building part slot. `model` is an opaque reference the host resolves (an asset id, a pack-relative path, or a URL) — core never loads anything.
- `BuildingKitPartInput` (type): type BuildingKitPartInput = string | BuildingKitPart — A variant as authored: a bare model reference, or the full {@link BuildingKitPart} when it needs fit or transform tuning.
- `buildingKitVariantCounts` (function): function buildingKitVariantCounts(kit: BuildingKit): Partial<BuildingVariantCounts> — The variant counts a kit actually supplies, shaped for `BuildingConfigInput.variants`. Feed this into `generateBuilding` so seeded picks spread across exactly the models the kit binds instead of indexing past them and wrapping unevenly.
- `defineBuildingKit` (function): function defineBuildingKit(input: BuildingKitInput): BuildingKit — Validates and normalizes a kit description, accepting bare model strings as single-field variants. Throws on empty variants or invalid editor material references/selectors before loading models.
- `resolveBuildingKitPart` (function): function resolveBuildingKitPart(kit: BuildingKit | undefined, kind: BuildingPartKind, slot?: BuildingKitSlot): BuildingKitBinding — Resolves one generated part against a kit. Pass the placement's `kind` and its `kit` slot; the slot's `variant` wraps around the bound list, so a kit may carry any number of variants independent of the generator's `variants` counts.

## @jgengine/core/world/buildingLots

- `BuildingLotOptions` (interface): interface BuildingLotOptions — Options for {@link deriveBuildingLots}.
- `FRONTAGE_FILL_REFERENCE` (const): const FRONTAGE_FILL_REFERENCE: 0.45 — Frontage-fill reference point: at this dial value the compaction is a no-op (legacy spacing/width), so callers can leave `blockFill` unset for the classic look and this value reproduces it exactly.
- `LotArea` (interface): interface LotArea — Rectangular clip region lots must fall within (world center + half-extents).
- `PlacedBuildingLot` (interface): interface PlacedBuildingLot — One placed building lot: where a building stands and how it is turned to face its road.
- `PlotVariant` (interface): interface PlotVariant extends WorldBounds — One weighted plot size a frontage can mix in: `w` along the road, `d` into the block.
- `RoadFrontage` (interface): interface RoadFrontage — One road the frontage placer lines with buildings: a centerline polyline and its full width.
- `deriveBuildingLots` (function): function deriveBuildingLots(options: BuildingLotOptions): PlacedBuildingLot[] — Derive street-aligned building lots (PLOTS) from road frontage. Each side of each road walks the frontage placing plots at `plot.w + spacing` pitch — rolling the next plot size from the weighted `footprint` variants when several are given — offset outward by `width / 2 + setback + plot.d / 2` and turned to face the road. The PLOT CONTRACT is enforced here, exactly: no two plots ever overlap (true oriented-rect separation with the spacing gap, so corners and curved frontage can't stack buildings), and no plot footprint ever touches any road corridor in `roads` or `avoid` — not just its own frontage road. Deterministic: identical inputs (including seed) always yield the identical list.

## @jgengine/core/world/buildings

- `BUILDING_STYLE_PALETTES` (const): const BUILDING_STYLE_PALETTES: Record<BuildingStyle, Record<BuildingPartKind, string>> — ⚠ undocumented
- `BUILDING_STYLE_PROBABILITIES` (const): const BUILDING_STYLE_PROBABILITIES: Record<BuildingStyle, Partial<BuildingProbabilities>> — Facade part probabilities per style, so an industrial yard, a ruined block and a coastal strip differ in shape as well as colour. Unset parts keep the generic probabilities.
- `BUILDING_STYLE_WALL_TONES` (const): const BUILDING_STYLE_WALL_TONES: Record<BuildingStyle, readonly string[]> — Per-style facade-tone family: the wall colours a district spreads across its buildings so neighbours differ in hue and value while the block stays one palette. Index 0 is the palette's own `wall`; the rest fan warmer/cooler and lighter/darker around it.
- `BuildingCellRef` (interface): interface BuildingCellRef { facade: BuildingFacade; level: number; bay: number } — ⚠ undocumented
- `BuildingConfig` (interface): interface BuildingConfig { id: string; seed: BuildingSeed; center: Vec2; floors: number; baysWide: number; baysDeep: number; bayWidth: number; floorHeight: number; facadeDepth: number; roofOverhang: number; probabilities: BuildingProbabilities; variants: BuildingVa… — ⚠ undocumented · used by `createBuildingConfig`: Fill a partial building description out to a complete {@link BuildingConfig}, clamping counts and probabilities.
- `BuildingConfigInput` (type): type BuildingConfigInput = Partial< Omit<BuildingConfig, "probabilities" | "variants"> > & { probabilities?: Partial<BuildingProbabilities>; variants?: Partial<BuildingVariantCounts>; } — ⚠ undocumented · used by `createBuildingConfig`: Fill a partial building description out to a complete {@link BuildingConfig}, clamping counts and probabilities.
- `BuildingFacade` (type): type BuildingFacade = "front" | "back" | "left" | "right" | "roof" — ⚠ undocumented
- `BuildingGridConfig` (interface): interface BuildingGridConfig { rows: number; columns: number; origin?: Vec2; lotSize?: Footprint; streetWidth?: number; seed?: BuildingSeed; idPrefix?: string; base?: BuildingConfigInput; floorRange?: readonly [number, number] } — ⚠ undocumented · used by `generateBuildingDistrict`: Generate a grid of buildings on lots sized by `lotSize` and separated by `streetWidth`, each with its floor count rolled from `floorRange`.
- `BuildingKitSlot` (interface): interface BuildingKitSlot { key: string; variant: number } — ⚠ undocumented · used by `resolveBuildingKitPart` (@jgengine/core/world/buildingKit): Resolves one generated part against a kit.
- `BuildingLot` (interface): interface BuildingLot { id: string; center: Vec2; footprint: Footprint; quarterTurns: number; config: BuildingConfig } — ⚠ undocumented
- `BuildingPalette` (type): type BuildingPalette = Record<BuildingPartKind, BuildingSurface> — ⚠ undocumented
- `BuildingPaletteOverrides` (type): type BuildingPaletteOverrides = Partial<BuildingPalette> — ⚠ undocumented
- `BuildingPartKind` (type): type BuildingPartKind = | "wall" | "window" | "awning" | "airConditioner" | "clothesline" | "storefront" | "shutter" | "storeSign" | "roof" | "roofProp" | "guardrail" | "corner" — ⚠ undocumented · used by `resolveBuildingKitPart` (@jgengine/core/world/buildingKit): Resolves one generated part against a kit.
- `BuildingPartPlacement` (interface): interface BuildingPartPlacement { id: string; buildingId: string; kind: BuildingPartKind; facade: BuildingFacade; position: Vec3; rotationY: number; scale: Vec3; kit: BuildingKitSlot; cell?: BuildingCellRef; tags?: readonly BuildingPartTag[] } — ⚠ undocumented
- `BuildingPartTag` (type): type BuildingPartTag = "ground" | "upper" | "open" | "closed" | "decor" | "structure" — ⚠ undocumented
- `BuildingProbabilities` (interface): interface BuildingProbabilities { window: number; openStore: number; awning: number; airConditioner: number; clothesline: number; storeSign: number; roofProp: number } — ⚠ undocumented · used by `BUILDING_STYLE_PROBABILITIES`: Facade part probabilities per style, so an industrial yard, a ruined block and a coastal strip differ in shape as well as colour.
- `BuildingSeed` (type): type BuildingSeed = number | string — ⚠ undocumented
- `BuildingStyle` (type): type BuildingStyle = | "generic" | "capital" | "village" | "desert" | "industrial" | "coastal" | "neon" | "ruin" | "frontier" | "aerial" — ⚠ undocumented · used by `BUILDING_STYLE_PROBABILITIES`: Facade part probabilities per style, so an industrial yard, a ruined block and a coastal strip differ in shape as well as colour.
- `BuildingSurface` (type): type BuildingSurface = string | BuildingSurfaceMaterial — What a building part kind is painted with: a hex colour, or a colour plus tiled PBR maps.
- `BuildingSurfaceMaps` (interface): interface BuildingSurfaceMaps — URLs of the PBR maps a building surface tiles; `buildMaterialCatalog(...).resolve(id)!.maps` fits directly.
- `BuildingSurfaceMaterial` (interface): interface BuildingSurfaceMaterial — A textured building surface: a base colour plus optional tiled PBR maps. With `maps`, `color` multiplies the albedo (leave it light to show the map as authored); without, it is the flat colour the part has always had.
- `BuildingVariantCounts` (interface): interface BuildingVariantCounts { wall: number; window: number; awning: number; airConditioner: number; clothesline: number; storefront: number; shutter: number; storeSign: number; roofProp: number } — ⚠ undocumented · used by `buildingKitVariantCounts` (@jgengine/core/world/buildingKit): The variant counts a kit actually supplies, shaped for `BuildingConfigInput.variants`.
- `DEFAULT_BUILDING_CONFIG` (const): const DEFAULT_BUILDING_CONFIG: BuildingConfig — ⚠ undocumented
- `DEFAULT_BUILDING_STYLE` (const): const DEFAULT_BUILDING_STYLE: BuildingStyle — ⚠ undocumented
- `GeneratedBuilding` (interface): interface GeneratedBuilding { id: string; seed: BuildingSeed; center: Vec2; footprint: Footprint; floors: number; floorHeight: number; bounds: Aabb; parts: readonly BuildingPartPlacement[]; rotationY?: number } — ⚠ undocumented · used by `generateBuilding`: Generate one building as a flat list of placed facade parts: bays × floors per facade, a ground row, corners, and a roof, with every decorat…
- `Vec3` (type): type Vec3 = readonly [number, number, number] — ⚠ undocumented · used by `coverPoints` (@jgengine/core/ai/tacticalQueries): Returns boundary locations that are hidden from a threat.
- `buildingSurfaceColor` (function): function buildingSurfaceColor(surface: BuildingSurface | undefined, fallback = "#808080"): string — The flat colour of a surface: the hex itself, or a material's `color`, else `fallback`.
- `createBuildingConfig` (function): function createBuildingConfig(input: BuildingConfigInput = {}): BuildingConfig — Fill a partial building description out to a complete {@link BuildingConfig}, clamping counts and probabilities. Use it to inspect or adjust the resolved shape before generating.
- `generateBuilding` (function): function generateBuilding(input: BuildingConfigInput = {}): GeneratedBuilding — Generate one building as a flat list of placed facade parts: bays × floors per facade, a ground row, corners, and a roof, with every decorative part rolled from `probabilities` and every part tagged with a `kit` slot the renderer binds to a model (see `world/buildingKit`). Deterministic from `seed`.
- `generateBuildingDistrict` (function): function generateBuildingDistrict(config: BuildingGridConfig): GeneratedBuilding[] — Generate a grid of buildings on lots sized by `lotSize` and separated by `streetWidth`, each with its floor count rolled from `floorRange`.
- `resolveBuildingProbabilities` (function): function resolveBuildingProbabilities(style: BuildingStyle = DEFAULT_BUILDING_STYLE, overrides?: Partial<BuildingProbabilities>): Partial<BuildingProbabilities> — Style facade probabilities with explicit overrides applied on top.
- `resolveBuildingSurface` (function): function resolveBuildingSurface(surface: BuildingSurface): BuildingSurfaceMaterial — Normalises a surface to its material form so a renderer reads one shape.

## @jgengine/core/world/captureCamera

- `CaptureCameraOverride` (interface): interface CaptureCameraOverride — Per-session capture-camera override — the harness counterpart of `?cam=`/`?look=`, and the same install-style seam as `world/spawnOverride`: the runner installs one, the shell reads it, nothing changes until one is installed.
- `clearCaptureCamera` (function): function clearCaptureCamera(): void — Clear any installed capture camera.
- `installCaptureCamera` (function): function installCaptureCamera(override: CaptureCameraOverride | null): void — Install (or, with `null`, clear) the capture camera. Idempotent; last write wins. It outranks the game's static camera config and any runtime `ctx.camera` rig selection, and it is never saved — it is a property of this capture session, not of the game.
- `readCaptureCamera` (function): function readCaptureCamera(): CaptureCameraOverride | null — The installed capture camera, or `null` when the game's own camera should render.

## @jgengine/core/world/carve

- `CarvableField` (class): class CarvableField implements TerrainField — A `TerrainField` you can write craters and mounds into at runtime — the height-field side of destructible terrain (Helldivers 2 explosion craters, engineer-deposited berms). Wraps a base field and layers smooth radial deformations on top, so `sampleHeight` (and therefore ground-snap, collision, and the shell's terrain mesh) all read the deformed surface. `carve` digs a bowl, `deposit` raises a mound.
- `CarveOp` (interface): interface CarveOp { center: readonly [number, number, number]; radius: number; toolStrength?: number } — ⚠ undocumented
- `CraterOp` (interface): interface CraterOp { x: number; z: number; radius: number; depth: number } — ⚠ undocumented
- `DepositOp` (interface): interface DepositOp { center: readonly [number, number, number]; radius: number; material: number } — ⚠ undocumented
- `EMPTY_VOXEL` (const): const EMPTY_VOXEL: 0 — ⚠ undocumented
- `MoundOp` (interface): interface MoundOp { x: number; z: number; radius: number; height: number } — ⚠ undocumented
- `VoxelMaterial` (interface): interface VoxelMaterial { id: number; name: string; strength: number; drop?: string } — ⚠ undocumented
- `VoxelMaterialTable` (type): type VoxelMaterialTable = Readonly<Record<number, VoxelMaterial>> — ⚠ undocumented
- `VoxelVolume` (class): class VoxelVolume — A runtime-editable dense voxel grid — the carve/deposit op behind destructible dig worlds (Deep Rock Galactic tunnels, Astroneer terrain). Cells hold a material id (0 = empty); `carve` clears a sphere of solid cells that a tool is strong enough to break and returns how many it removed (feed that to a loot roll), `deposit` fills a sphere with a material. World↔cell mapping is `origin`+`scale`.
- `VoxelVolumeConfig` (interface): interface VoxelVolumeConfig { dims: readonly [number, number, number]; origin?: readonly [number, number, number]; scale?: number; fill?: number; materials?: VoxelMaterialTable } — ⚠ undocumented
- `carvableTerrain` (function): function carvableTerrain(base: TerrainField): CarvableField — ⚠ undocumented

## @jgengine/core/world/catenary

- `Vec3` (type): type Vec3 = readonly [number, number, number] — A 3D point/vector as an `[x, y, z]` tuple — the engine's zero-allocation spatial primitive.
- `catenaryCurve` (function): function catenaryCurve(a: Vec3, b: Vec3, slack: number, segments: number): Vec3[] — True hyperbolic catenary between two anchors — the shape a uniform cable actually takes under gravity. `slack` is the extra length beyond the straight-line distance, as a fraction (0.1 = 10% longer than taut); larger slack droops deeper. Falls back to {@link sagCurve} for a near-taut cable. Returns `segments + 1` points. Anchors may differ in height; the curve interpolates the chord.
- `sagCurve` (function): function sagCurve(a: Vec3, b: Vec3, sag: number, segments: number): Vec3[] — Quadratic-Bézier sag between two anchors: the control point is pulled straight down so the mid-span lowest point droops by exactly `sag` meters below the chord. Cheap and stable; the go-to for cables where exact catenary physics don't matter. Returns `segments + 1` points.

## @jgengine/core/world/cellStates

- `CellRef` (interface): interface CellRef { col: number; row: number } — ⚠ undocumented
- `CellStateGrid` (interface): interface CellStateGrid<TState extends string> — A uniform world grid whose cells step through a discrete state ladder — pristine → cracked → burning → ruined — driven by whatever world events the game routes in (#284.8). Pure storage plus ladder mechanics; the game decides *when* to escalate, the grid guarantees ordered, clamped steps and cheap queries. `version()` bumps on every change for dirty-checked rendering.
- `CellStateGridConfig` (interface): interface CellStateGridConfig<TState extends string> { cols: number; rows: number; states: readonly TState[]; origin?: readonly [number, number]; cellSize?: number } — ⚠ undocumented
- `createCellStateGrid` (function): function createCellStateGrid<TState extends string>(config: CellStateGridConfig<TState>): CellStateGrid<TState> — ⚠ undocumented

## @jgengine/core/world/cityBlocks

- `BlockRings` (interface): interface BlockRings — A block's derived rings plus the sidewalk band (outer = curb line, inner = land line).
- `CityBlockKind` (type): type CityBlockKind = "buildable" | "park" | "plaza" | "field" | "buffer" — How a block (a face of the road graph) is used.
- `CityBlockLocal` (interface): interface CityBlockLocal — One closed block: a face of the road network, inset to its curb and land boundaries.
- `CityParcelFrontage` (interface): interface CityParcelFrontage — One street-frontage reference of a parcel.
- `CityParcelKind` (type): type CityParcelKind = "built" | "vacant" | "yard" — How a parcel is used after occupancy/fitting rolls.
- `CityParcelLocal` (interface): interface CityParcelLocal — One polygonal parcel subdivided out of a block's street frontage.
- `FabricParams` (interface): interface FabricParams — Everything block extraction needs from the district rules.
- `FabricStreet` (interface): interface FabricStreet — Minimal street shape the fabric needs (matches cityKind's LocalStreet).
- `GraphBlockEdge` (interface): interface GraphBlockEdge — One street-graph edge {@link extractGraphBlocks} traces block faces through.
- `GraphBlockNode` (interface): interface GraphBlockNode — Minimal node/edge shapes {@link extractGraphBlocks} needs (matches `StreetNetwork.nodes`/`edges`).
- `GraphBlockRings` (interface): interface GraphBlockRings — One block from {@link extractGraphBlocks}: the face polygon and its inset land ring.
- `GraphFace` (interface): interface GraphFace — One extracted face: closed centerline polygon + the street index along each polygon edge.
- `ParcelCut` (interface): interface ParcelCut — Inputs for one parcel strip cut from a block ring.
- `RingWalker` (class): class RingWalker — Arc-length station lookup along a closed ring.
- `buildablePolygon` (function): function buildablePolygon(parcel: readonly Vec2[], frontA: Vec2, frontB: Vec2, frontSetback: number, sideGap: number, rearMargin: number, depth: number): Vec2[] — Buildable polygon for a parcel: the parcel clipped by the front setback (a half-plane pushed in from the frontage chord), side gaps along both cut lines, and a rear margin. Works on any parcel polygon — no vertex correspondence needed.
- `carveCorridors` (function): function carveCorridors(poly: Vec2[], keep: Vec2, corridors: readonly { pts: readonly Vec2[]; width: number }[], margin: number): Vec2[] — Carve dead-end road corridors (cul-de-sac lanes pruned from the face graph) out of a polygon: for every corridor segment crossing it, keep the polygon piece on the side where `keep` lies.
- `conformPolygonToRing` (function): function conformPolygonToRing(poly: readonly Vec2[], ring: readonly Vec2[]): Vec2[] — Conform a polygon to a containing ring: sample every edge (a straight edge can bulge across a concave notch even when its endpoints hug the boundary), then pull each escaping point to its nearest boundary point. Callers re-run this after any operation that adds mid-edge vertices.
- `cutParcel` (function): function cutParcel(walker: RingWalker, blockRing: readonly Vec2[], cut: ParcelCut): Vec2[] | null — Cut one polygonal parcel out of a block land ring: the frontage arc between two stations, extruded inward along the station normals, clipped back to the block. Returns null when the strip collapses (over-tight corner, sliver arc).
- `extractBlocks` (function): function extractBlocks(streets: readonly FabricStreet[], hx: number, hz: number, params: FabricParams): { blocks: BlockRings[]; deadEnds: { pts: Vec2[]; width: number }[] } — Extract closed blocks from the street network: planar faces of the graph, each inset to its curb ring (pavement edge) and land ring (behind the sidewalk band). Faces that collapse under the inset come back with an empty `land` and are the caller's slivers/buffers.
- `extractGraphBlocks` (function): function extractGraphBlocks(nodes: readonly GraphBlockNode[], edges: readonly GraphBlockEdge[], params: { sidewalkBase: number; curbMargin: number }): { blocks: GraphBlockRings[]; deadEnds: { pts: Vec2[]; width: number; level: FabricStreet["level"]; street?: number }[] } — Extract closed blocks from an EXACT street graph — the `nodes`/`edges` a street network already carries — instead of re-deriving topology from welded polylines. Half-edges are ordered by true departure angle at each node, dangling chains are pruned first (returned as `deadEnds` for corridor carving), interior faces are traced through the rotation system, and each face is inset to its land ring by the bordering edges' half-widths (+ curb + sidewalk). Robust against wandered and arc-filleted centerlines, which defeat proximity welding. Pure bounded geometry.
- `isSliverBlock` (function): function isSliverBlock(land: readonly Vec2[], minArea: number, minWidth: number): boolean — Deterministic sliver verdict shared by classification and tests.
- `pointsInPolygon` (function): function pointsInPolygon(ring: readonly Vec2[], count: number, rng: () => number, margin = 1.5): Vec2[] — Sample deterministic points inside a polygon by seeded rejection over its bounds.
- `sidewalkWidthFor` (function): function sidewalkWidthFor(level: FabricStreet["level"], base: number): number — Sidewalk band width by street hierarchy (base = the district's street-level width).

## @jgengine/core/world/cityContent

- `CITY_FILLER_CLASSES` (const): const CITY_FILLER_CLASSES: readonly CityFillerClass[] — All filler classes, for validation and interior-pass allow-lists.
- `CITY_LANDMARK_CLASSES` (const): const CITY_LANDMARK_CLASSES: readonly CityLandmarkClass[] — All landmark classes, for schema hints, validation, and default allow-lists.
- `CITY_LOT_CLASSES` (const): const CITY_LOT_CLASSES: readonly CityLotClass[] — All classes, for schema hints and validation.
- `CITY_TREE_SPECIES` (const): const CITY_TREE_SPECIES: readonly CityTreeSpecies[] — All species, for schema hints and validation.
- `CityFillerClass` (type): type CityFillerClass = "garage" | "depot" — Filler classes used ONLY by the block-interior fill pass (`resolveCityLotContent` at a high `blockFill`). They are deliberately kept OUT of {@link CITY_LOT_CLASSES} so a zone mix can never weight them onto street frontage — they exist to pack the backs of Manhattan-style blocks with parking structures and warehouses/depots, mixed in with ordinary zone classes.
- `CityLandmarkClass` (type): type CityLandmarkClass = "hall" | "arena" | "market" | "campus" — A block-scale landmark class. Unlike {@link CityLotClass} these are never weighted into a zone mix — the landmark pass in `resolveCityLotContent` picks clusters of adjacent lots and stamps one of these over them. Each expresses with the same four piece shapes (box/gable/cylinder/dome) at a much larger footprint (~40–90 m).
- `CityLotClass` (type): type CityLotClass = | "tower" | "slab" | "shop" | "rowhouse" | "house" | "mansion" | "farmhouse" | "barn" | "silo" — A building class a zone mix can weight — drives lot size, floors, setback, and massing.
- `CityLotPiece` (interface): interface CityLotPiece — One massing piece in LOT-LOCAL space: x along frontage width, z into the block, y up from grade.
- `CityPieceRole` (type): type CityPieceRole = "wall" | "roof" | "trim" | "accent" — Palette role a piece colors from (wall/roof/trim/accent map onto the district's style palette).
- `CityPieceShape` (type): type CityPieceShape = "box" | "gable" | "cylinder" | "dome" — Primitive shapes massing pieces instance — the renderer keeps one InstancedMesh per shape.
- `CityTreeSpecies` (type): type CityTreeSpecies = "broadleaf" | "conifer" | "palm" | "cypress" — Tree species a district's tree mix can weight — the renderer keeps one canopy mesh per species.
- `CityZoneBand` (type): type CityZoneBand = "core" | "mid" | "edge" — Zone band a lot falls in: dense core, middle ring, or the district edge.
- `CityZoneProfile` (type): type CityZoneProfile = "core-out" | "inverted" | "uniform" — How the radial zone metric maps to bands.

## @jgengine/core/world/cityGenerator

- `CITY_PLOT_TIERS` (const): const CITY_PLOT_TIERS: readonly CityPlotTier[] — All plot tiers, for schema hints and validation.
- `CityContentOptions` (interface): interface CityContentOptions extends CityContentOverrides — Full options for {@link resolveCityLotContent}: the city geometry frame plus content overrides.
- `CityContentOverrides` (interface): interface CityContentOverrides — Tunable overrides for {@link resolveCityLotContent} (seed/halfExtents/laneFrontage are supplied).
- `CityGeneratorOptions` (interface): interface CityGeneratorOptions — Options for {@link generateCity}: a seed, street-dial overrides, and plot pass-through options.
- `CityLevelClassBias` (type): type CityLevelClassBias = Record<StreetLevel, Partial<Record<CityLotClass, number>>> — Per-street-level class weight multipliers applied to the band mix before the class pick, so towers and slabs bias toward wide boulevard/avenue frontage while houses bias toward lanes and quiet streets. A missing class ⇒ multiplier 1. Pure data modulating the weighted mixes.
- `CityPlot` (interface): interface CityPlot — One polygonal plot cut from a block's street frontage. Every plot fronts a street.
- `CityPlotFrontage` (interface): interface CityPlotFrontage — The street frontage a plot faces: which street, and the frontage chord along it.
- `CityPlotOptions` (interface): interface CityPlotOptions — Options for {@link deriveCityPlots}.
- `CityPlotResult` (interface): interface CityPlotResult — Output of {@link deriveCityPlots}: the plots plus whole-block park polygons.
- `CityPlotTier` (type): type CityPlotTier = "small" | "medium" | "large" | "grand" — Size tier a plot was cut at. `grand` is the block-scale tier that used to be a landmark pass.
- `CityZoneMixes` (interface): interface CityZoneMixes — Weighted building-class mix per zone band; the radial profile decides which band a lot falls in.
- `DEFAULT_BLOCK_FILL` (const): const DEFAULT_BLOCK_FILL: 0.45 — Default `blockFill`: gently gapped frontage — plots with breathing room, parks reserved.
- `DEFAULT_CITY_LEVEL_BIAS` (const): const DEFAULT_CITY_LEVEL_BIAS: CityLevelClassBias — Default street-level bias — boulevards favor big massing, lanes favor small/rural massing.
- `DEFAULT_CITY_ZONE_MIXES` (const): const DEFAULT_CITY_ZONE_MIXES: CityZoneMixes — Default zoned-metropolis mixes: towers/slabs downtown, slabs+rowhouses mid, houses at the edge.
- `DEFAULT_LANDMARK_SHARE` (const): const DEFAULT_LANDMARK_SHARE: 0.04 — Default grand-plot share dial — a handful of block-scale parcels per default city.
- `GeneratedCity` (interface): interface GeneratedCity — A generated city: streets, plots (with rect building lots as a compat view), and park blocks.
- `LANDMARK_HARD_CAP` (const): const LANDMARK_HARD_CAP: 12 — Hard cap on grand plots emitted regardless of dial/city size.
- `MassingFootprint` (interface): interface MassingFootprint — Axis-aligned massing extents (lot-local): full width along x and depth along z.
- `ResolvedCityLot` (interface): interface ResolvedCityLot — One plot enriched with its zone/class/floors/massing — the renderer instances `pieces` at `center`.
- `deriveCityPlots` (function): function deriveCityPlots(network: StreetNetwork, options: CityPlotOptions): CityPlotResult — Subdivide every buildable block's street frontage into size-tiered polygonal plots. Blocks come from the street network's planar faces ({@link extractBlocks}), so every plot fronts a real street; block interiors stay open (courtyards) and a seeded fraction of whole blocks becomes parks. Grand plots — the old "landmarks" — are just the biggest tier of the same pass. Deterministic per seed, bounded by `maxPlots` and per-block caps.
- `generateCity` (function): function generateCity(options: CityGeneratorOptions, hx: number, hz: number): GeneratedCity — Grow a street network inside the `hx`/`hz` half-extents, extract its blocks, and subdivide their frontage into plots. Deterministic: identical options ⇒ identical city.
- `resolveCityLotContent` (function): function resolveCityLotContent(city: Pick<GeneratedCity, "network" | "lots"> & Partial<Pick<GeneratedCity, "plots" | "parks">>, options: CityContentOptions): ResolvedCityLot[] — Enrich a generated city's plots into classed, massed buildings: each plot gets its zone band (radial position under a {@link CityZoneProfile}), a building class rolled from the band's weighted mix — biased by street level AND plot size, with grand plots rolling a landmark class — floors, and the deterministic massing pieces the class composes, sized to the plot's building rect. Deterministic per `seed` via {@link seededStreams}, bounded (one pass over `city.lots`), and pure. Same seed + city ⇒ identical resolved lots.

## @jgengine/core/world/cityGeometry

- `OrientedRect` (interface): interface OrientedRect — A rotated rectangle: center, half-extents, and yaw in the engine rotationY convention.
- `Vec2` (type): type Vec2 = readonly [number, number] — Deterministic 2D polygon math for the `city` studio's block/parcel pipeline: signed areas, point-in-polygon, half-plane clipping, per-edge inward insets (the curb → sidewalk → land and parcel → buildable transforms), simple-loop recovery after aggressive insets, and rotated-rect fitting inside arbitrary polygons. Pure functions over `[x, z]` tuples — no allocation-heavy classes, no rendering, no randomness — so every consumer from the resolver to the tests shares one geometric truth.
- `clipHalfPlane` (function): function clipHalfPlane(ring: readonly Vec2[], normal: Vec2, limit: number): Vec2[] — Clip a polygon to the half-plane `dot(p, normal) <= limit` (Sutherland–Hodgman step). Returns the surviving ring, possibly empty. The subject may be concave; the output of a single half-plane clip of a simple ring is always a valid (possibly pinched) ring.
- `dedupeRing` (function): function dedupeRing(ring: readonly Vec2[], epsilon = 1e-6): Vec2[] — Remove consecutive (near-)duplicate vertices; returns [] when fewer than 3 survive.
- `distanceToRing` (function): function distanceToRing(ring: readonly Vec2[], x: number, z: number): number — Distance from a point to the nearest boundary segment of a ring.
- `ensureCcw` (function): function ensureCcw(ring: readonly Vec2[]): Vec2[] — Ensure counter-clockwise winding (positive signed area) without mutating the input.
- `extractSimpleLoop` (function): function extractSimpleLoop(ring: readonly Vec2[], maxPasses = 6): Vec2[] — Recover the dominant simple loop from a lightly self-intersecting ring: whenever two edges cross, the smaller of the two loops the crossing pinches off is dropped. Bounded passes; rings that stay tangled after that return []. This is the cleanup net under aggressive insets — a concave block inset past a neck pinches into a bow-tie, and the bigger lobe is the block.
- `fitRectInPolygon` (function): function fitRectInPolygon(ring: readonly Vec2[], cx: number, cz: number, maxW: number, maxD: number, rotationY: number, minScale = 0.55): { w: number; d: number; cx: number; cz: number } | null — Fit the largest rect (up to `maxW`×`maxD`, oriented to `rotationY`, centered near `[cx, cz]`) inside a polygon by bounded bisection on a single scale factor. Deterministic; returns null when even `minScale` of the request does not fit after nudging the center inward.
- `insetRing` (function): function insetRing(ring: readonly Vec2[], edgeDistances: readonly number[]): Vec2[] — Inset a CCW ring inward with a PER-EDGE distance (edge i runs vertex i → i+1). True corners take the intersection of the two adjacent offset lines (so a street corner lands exactly where the two curb lines meet, even with different street widths); near-collinear vertices — polyline samples along a curve — fall back to the averaged-normal offset, which is exact in the limit. Returns [] when the inset collapses (sliver) or stays tangled after loop recovery.
- `insetRingUniform` (function): function insetRingUniform(ring: readonly Vec2[], distance: number): Vec2[] — Uniform-distance convenience over {@link insetRing}.
- `pointInPolygon` (function): function pointInPolygon(ring: readonly Vec2[], x: number, z: number): boolean — Even-odd point-in-polygon test.
- `polygonArea` (function): function polygonArea(ring: readonly Vec2[]): number — Absolute polygon area.
- `polygonCentroid` (function): function polygonCentroid(ring: readonly Vec2[]): Vec2 — Area centroid of a simple polygon (falls back to the vertex mean for degenerate rings).
- `polygonMeanWidth` (function): function polygonMeanWidth(ring: readonly Vec2[]): number — Mean "width" proxy for sliver detection: the diameter of the largest inscribed strip is approximated by 2·area / perimeter (exact for long rectangles, conservative elsewhere).
- `polygonPerimeter` (function): function polygonPerimeter(ring: readonly Vec2[]): number — Ring perimeter length.
- `polygonSignedArea` (function): function polygonSignedArea(ring: readonly Vec2[]): number — Signed area of a polygon ring (positive = counter-clockwise in XZ).
- `polygonsOverlap` (function): function polygonsOverlap(a: readonly Vec2[], b: readonly Vec2[], shrink = 0.05): boolean — Conservative polygon-overlap test: any vertex of one strictly inside the other, or any edges crossing.
- `rayDistanceToRing` (function): function rayDistanceToRing(ring: readonly Vec2[], origin: Vec2, dir: Vec2, minT = 0.6): number — Distance from `origin` along `dir` to the first ring-boundary crossing (ignoring hits closer than `minT`, e.g. the edge the origin sits on). Infinity when the ray never leaves — degenerate.
- `rectClearsPolyline` (function): function rectClearsPolyline(rect: OrientedRect, path: readonly Vec2[], clearance: number): boolean — True when a rotated rect stays at least `clearance` away from every segment of a polyline — the plot-contract test that keeps building plots off road corridors (pass the road half-width as the clearance). Exact segment-vs-expanded-rect intersection, not corner sampling.
- `rectCorners` (function): function rectCorners(cx: number, cz: number, hw: number, hd: number, rotationY: number): Vec2[] — All four corners of a rotated rect (center, half-extents, yaw in engine rotationY convention).
- `rectInsidePolygon` (function): function rectInsidePolygon(ring: readonly Vec2[], cx: number, cz: number, hw: number, hd: number, rotationY: number): boolean — True when the whole rotated rect (corners + edge midpoints) sits inside the ring.
- `rectsSeparated` (function): function rectsSeparated(a: OrientedRect, b: OrientedRect): boolean — Separating-axis test for two rotated rectangles: true when a gap exists (no overlap).
- `ringBounds` (function): function ringBounds(ring: readonly Vec2[]): { minX: number; minZ: number; maxX: number; maxZ: number } — Axis-aligned bounding box of a ring.
- `ringSelfIntersects` (function): function ringSelfIntersects(ring: readonly Vec2[]): boolean — True when any two non-adjacent edges of the ring properly cross. O(n²), fine for block-scale n.
- `splitByLine` (function): function splitByLine(ring: readonly Vec2[], normal: Vec2, limit: number): { below: Vec2[]; above: Vec2[] } — Split a polygon by the line `dot(p, normal) = limit` into the `<=` and `>=` sides.
- `triangulatePolygon` (function): function triangulatePolygon(ring: readonly Vec2[]): { positions: Vec2[]; indices: number[] } — Ear-clip a simple polygon into triangles. Returns the cleaned/CCW-oriented vertex ring plus flat index triples into it (so a draping consumer can sample a height per returned vertex). O(n²) — fine for block/park rings. A polygon that stays un-clippable (self-touching after dedupe) yields whatever ears were found before the guard trips; degenerate input returns no triangles.
- `triangulateRingBand` (function): function triangulateRingBand(outer: readonly Vec2[], inner: readonly Vec2[]): { positions: Vec2[]; indices: number[] } — Triangulate the band between two nested rings (an outer ring with an inner hole, e.g. a curb ring around a land ring — the sidewalk). Pairs the loops by cumulative arc-length fraction, aligning the inner start to the outer's first vertex, so it is robust to differing vertex counts and to a rotational offset between the rings. Returns the merged vertex list (outer, then the rotated inner) and index triples into it. Zero-area triangles — where the two rings coincide (a street edge with no sidewalk) — are dropped so `computeVertexNormals` never sees a degenerate face.

## @jgengine/core/world/cityKind

- `CITY_DEFAULTS` (const): const CITY_DEFAULTS: CityRules — City defaults: a zoned mixed metropolis — towers downtown, slabs mid-ring, houses at the edge.
- `CITY_KIND` (const): const CITY_KIND: "city" — The editor volume kind marking a box as a procedural city district.
- `CITY_SCHEMA` (const): const CITY_SCHEMA: ParamSchema — The city parameter schema — drives the inspector sliders and `meta` parse via the studio seam.
- `CITY_ZONE_KIND` (const): const CITY_ZONE_KIND: "cityzone" — The editor volume kind that locally overrides a city's zone band/mix — a district in a district.
- `CITY_ZONE_SCHEMA` (const): const CITY_ZONE_SCHEMA: ParamSchema — Zone-override schema for `cityzone` volumes: pin a band and optionally a bespoke class mix.
- `CityBlock` (interface): interface CityBlock — One closed city block: a face of the road graph, inset to curb and land boundaries.
- `CityBridge` (interface): interface CityBridge — One bridge deck spanning water: bank-to-bank polyline plus the silhouette style.
- `CityDriveway` (interface): interface CityDriveway — One driveway ribbon from a street to a lot.
- `CityHedge` (interface): interface CityHedge — One hedge run: a thin box strip (estate perimeter).
- `CityIntersection` (interface): interface CityIntersection — One crossing of two through streets: patch center/radius plus crosswalk arm directions.
- `CityLight` (interface): interface CityLight — One street light: curb position plus the yaw its arm faces (over the road).
- `CityLot` (interface): interface CityLot — One building lot: footprint, zone band, class, seeded floors, massing pieces, street anchor.
- `CityParcel` (interface): interface CityParcel — One polygonal parcel subdivided from a block's street frontage.
- `CityParcelFrontageOut` (interface): interface CityParcelFrontageOut — One street-frontage edge of a parcel.
- `CityPark` (interface): interface CityPark — One intentional open space: an unbuilt block, a block-interior courtyard, or a buffer sliver.
- `CityParking` (interface): interface CityParking — One parking pad behind a commercial lot.
- `CityRaceGridSlot` (interface): interface CityRaceGridSlot — One staggered spawn behind the start line.
- `CityRaceKerb` (interface): interface CityRaceKerb — One kerb strip hugging a corner's road edge, as a world-space polyline to stripe.
- `CityRaceSeal` (interface): interface CityRaceSeal — One street closed off where it leaves the race lap: world XZ, the yaw down the sealed street, and the width the barrier run spans.
- `CityRaceStart` (interface): interface CityRaceStart — The start/finish line: where it is, which way cars face, and the painted line across the road.
- `CityResolveContext` (interface): interface CityResolveContext extends SceneKindResolveContext — Extended resolve context: sibling `cityzone` volumes that override the band/mix locally.
- `CityRules` (interface): interface CityRules — Fully-defaulted city params parsed from a volume's `meta`.
- `CitySignal` (interface): interface CitySignal — One junction control on an approach arm: an arterial mast-arm signal, or a plain sign post.
- `CityStreet` (interface): interface CityStreet — One synthesized street: a world-space XZ polyline with width, hierarchy level, and surface.
- `CityTree` (interface): interface CityTree — One placed tree: world XZ, species, and seeded scale/color jitter.
- `CityTunnel` (interface): interface CityTunnel — One tunnel bore piercing a ridge: portal-to-portal polyline held at bank height.
- `CityVehicle` (interface): interface CityVehicle — One parked vehicle standing at a curb or nose-in inside a parking pad.
- `CityVehicleKind` (type): type CityVehicleKind = "car" | "van" | "truck" — Silhouette class of a parked vehicle — sizes the body the renderer instances.
- `ResolvedCity` (interface): interface ResolvedCity — A resolved city district: world-space network, zoned lots, parks, and furniture.
- `ResolvedRace` (interface): interface ResolvedRace — An instanced street race lifted out of the district's OWN streets: a closed lap through the city, with every side street leaving it sealed off. World space, like the rest of {@link ResolvedCity}.
- `citySolids` (function): function citySolids(city: ResolvedCity, sampleHeight: (x: number, z: number) => number = () => 0): WorldSolid[] — One solid per wall and roof piece of every lot, grounded the way the city renderer grounds it: grade at the highest lot corner, foundations down to half a metre under the lowest.
- `resolveCityObject` (function): function resolveCityObject(object: SceneKindObject, context?: CityResolveContext): ResolvedCity | null — Synthesize the deterministic city plan for one `city` volume: streets → bridges → parks → zoned frontage lots with massing pieces → furniture, all in the volume's local frame and then rotated/translated into world space. Same volume (id, footprint, meta) over the same terrain always resolves to the identical plan. When `context` provides a ground sampler, lots respect the `maxSlope` cliff rule — hillside and canyon districts keep their steep faces open. When `context.zoneOverrides` carries sibling `cityzone` volumes, lots inside them adopt the override band/mix. Returns null without a usable footprint.

## @jgengine/core/world/connectors

- `ConnectorPieceDef` (interface): interface ConnectorPieceDef { kind: string; sockets: readonly ConnectorSocket[] } — ⚠ undocumented
- `ConnectorRegistry` (type): type ConnectorRegistry = (kind: string) => ConnectorPieceDef | null — ⚠ undocumented
- `ConnectorSocket` (interface): interface ConnectorSocket { id: string; type: string; offset: ConnectorVec3; accepts?: readonly string[] } — ⚠ undocumented
- `ConnectorVec3` (type): type ConnectorVec3 = readonly [number, number, number] — ⚠ undocumented
- `PlacedPiece` (interface): interface PlacedPiece { id: string; kind: string; position: ConnectorVec3; rotationY: number } — ⚠ undocumented
- `SnapOptions` (interface): interface SnapOptions { snapDistance?: number; rotationY?: number } — ⚠ undocumented
- `SnapResult` (interface): interface SnapResult { socketId: string; targetPieceId: string; targetSocketId: string; position: ConnectorVec3; rotationY: number; distance: number } — ⚠ undocumented
- `WorldSocket` (interface): interface WorldSocket { pieceId: string; socket: ConnectorSocket; position: ConnectorVec3 } — ⚠ undocumented
- `collectWorldSockets` (function): function collectWorldSockets(registry: ConnectorRegistry, pieces: readonly PlacedPiece[]): WorldSocket[] — ⚠ undocumented
- `snapToNearest` (function): function snapToNearest(registry: ConnectorRegistry, placed: readonly PlacedPiece[], movingDef: ConnectorPieceDef, cursor: ConnectorVec3, options: SnapOptions = {}): SnapResult | null — ⚠ undocumented
- `socketWorldPosition` (function): function socketWorldPosition(socket: ConnectorSocket, origin: ConnectorVec3, rotationY: number): ConnectorVec3 — ⚠ undocumented
- `socketsCompatible` (function): function socketsCompatible(a: ConnectorSocket, b: ConnectorSocket): boolean — ⚠ undocumented
- `worldSockets` (function): function worldSockets(def: ConnectorPieceDef, piece: PlacedPiece): WorldSocket[] — ⚠ undocumented

## @jgengine/core/world/decalKind

- `DECAL_DEFAULTS` (const): const DECAL_DEFAULTS: DecalRules — Default decal rules: a small dirt smudge lying on the ground.
- `DECAL_KIND` (const): const DECAL_KIND: "decal" — The editor marker kind marking a surface decal.
- `DECAL_SCHEMA` (const): const DECAL_SCHEMA: ParamSchema — The decal parameter schema — drives the inspector and the `meta` parse.
- `DECAL_STYLES` (const): const DECAL_STYLES: readonly ["dirt", "cracks", "paint", "blood"] — The four authored decal looks; each has its own deterministic procedural texture.
- `DecalRules` (interface): interface DecalRules — Fully-defaulted decal params parsed from a marker's `meta`.
- `DecalStyle` (type): type DecalStyle = (typeof DECAL_STYLES)[number] — One of the four authored decal looks.
- `ResolvedDecal` (interface): interface ResolvedDecal — A resolved decal: its placed point/facing plus fully-defaulted rules.

## @jgengine/core/world/envField

- `EnvironmentField` (interface): interface EnvironmentField { sample(x: number, z: number, time: number, y?: number): EnvironmentSample; temperature(x: number, z: number, time: number, y?: number): number; wetness(x: number, z: number, time: number): number; lightExposure(x: number, z: number, time:… — ⚠ undocumented · used by `createEnvironmentField`: A sampleable environment field: read temperature, wetness, sun/sky exposure, and ambient light at any world position and time.
- `EnvironmentFieldConfig` (interface): interface EnvironmentFieldConfig { dayLength?: number; baseTemperature?: number; nightDrop?: number; altitudeLapse?: number; seaLevel?: number; terrain?: TerrainField; rain?: ScalarField; occluders?: ShadeProvider; heatSources?: readonly HeatSource[]; ambientFloor?: number… — ⚠ undocumented · used by `createEnvironmentField`: A sampleable environment field: read temperature, wetness, sun/sky exposure, and ambient light at any world position and time.
- `EnvironmentSample` (interface): interface EnvironmentSample { temperature: number; wetness: number; lightExposure: number; ambientLight: number; sheltered: boolean } — ⚠ undocumented · used by `resolveMaterialAppearance` (@jgengine/core/material/appearanceSignals): Resolve one surface from an immutable dry baseline, avoiding cumulative drift.
- `HeatSource` (interface): interface HeatSource — A localized warmth source — campfire, forge, geothermal vent.
- `OccluderRect` (interface): interface OccluderRect — A sky-occluding footprint — a roof, dense canopy, a cave mouth. `shade` 0..1 = fraction of sky blocked.
- `ScalarField` (type): type ScalarField = number | ((x: number, z: number, time: number) => number) — ⚠ undocumented
- `ShadeProvider` (type): type ShadeProvider = readonly OccluderRect[] | ((x: number, z: number) => number) — ⚠ undocumented
- `createEnvironmentField` (function): function createEnvironmentField(config: EnvironmentFieldConfig = {}): EnvironmentField — A sampleable environment field: read temperature, wetness, sun/sky exposure, and ambient light at any world position and time. Built on the same renderer-free footing as terrain/wind/water so meters, spawn gating, and damage-in-sunlight read the world the shell renders — no three.js. Instantaneous and pure (no accumulation); stateful build-up belongs to a decay meter reading this field.

## @jgengine/core/world/environmentForces

- `EnvironmentMotionTarget` (interface): interface EnvironmentMotionTarget — The game selects affected players, coupling, target bits and its acceleration limit.
- `installEnvironmentMotion` (function): function installEnvironmentMotion(ctx: GameContext, options: { targets: () => readonly EnvironmentMotionTarget[]; maxTargets?: number }): () => void — Inject authoritative spatial forces before existing movement consumes its motion intents.

## @jgengine/core/world/environmentSummary

- `EnvironmentCounts` (interface): interface EnvironmentCounts { terrain: number; islands: number; structureGroups: number; buildings: number; buildingParts: number; vegetationFields: number; waterBodies: number; weatherSystems: number; roads: number } — ⚠ undocumented
- `EnvironmentSummary` (interface): interface EnvironmentSummary { terrain?: TerrainSummary; islands: readonly IslandSummary[]; structures: readonly StructureSummary[]; vegetation: readonly VegetationSummary[]; water: readonly WaterSummary[]; weather: readonly WeatherSummary[]; roads: readonly RoadSummar… — ⚠ undocumented
- `IslandSummary` (interface): interface IslandSummary extends TerrainSummary { origin: readonly [number, number] } — ⚠ undocumented
- `RoadSummary` (interface): interface RoadSummary — One road descriptor's resolved footprint: vertex count, width, and total centerline length.
- `StructureSummary` (interface): interface StructureSummary { style: BuildingStyle; palette: BuildingPalette; requested: number; buildings: number; parts: number; bounds: Aabb } — ⚠ undocumented
- `TerrainHeightStats` (interface): interface TerrainHeightStats { min: number; max: number; mean: number; finite: boolean } — ⚠ undocumented
- `TerrainSummary` (interface): interface TerrainSummary { bounds: WorldBounds; height: TerrainHeightStats; palette: TerrainPalette; waterLevel?: number } — ⚠ undocumented
- `VegetationSummary` (interface): interface VegetationSummary { area: EnvironmentArea; density: number } — ⚠ undocumented
- `WaterSummary` (interface): interface WaterSummary { level: number; bounds: WorldBounds } — ⚠ undocumented
- `WeatherSummary` (interface): interface WeatherSummary { kind: "rain" | "snow"; area: EnvironmentArea; density: number } — ⚠ undocumented
- `resolveStructureBuildings` (function): function resolveStructureBuildings(descriptor: BuildingEnvironmentDescriptor): GeneratedBuilding[] — ⚠ undocumented
- `summarizeEnvironment` (function): function summarizeEnvironment(feature: EnvironmentWorldFeature): EnvironmentSummary — ⚠ undocumented

## @jgengine/core/world/fastTravel

- `FastTravelNetwork` (interface): interface FastTravelNetwork<TMeta = unknown> — A network of fast-travel points with per-player discovery + distance queries.
- `FastTravelOptions` (interface): interface FastTravelOptions<TMeta = unknown> — Options for {@link createFastTravelNetwork}.
- `FastTravelSnapshot` (interface): interface FastTravelSnapshot — Serializable discovery state.
- `TravelPointDef` (interface): interface TravelPointDef<TMeta = unknown> — A fast-travel destination the game defines. Discovery is tracked separately.
- `TravelPointView` (interface): interface TravelPointView<TMeta = unknown> extends TravelPointDef<TMeta> — A destination plus its discovery state (and distance from a query origin, when given).
- `createFastTravelNetwork` (function): function createFastTravelNetwork<TMeta = unknown>(options: FastTravelOptions<TMeta>): FastTravelNetwork<TMeta> — A fast-travel network: defined destinations plus per-player discovery, with distance-sorted queries, a `nearest` lookup, a `canTravel` gate, an `onDiscover` seam, and serializable `snapshot`/`restore`. Travel itself is a teleport the game applies to `TravelPointView.position`; this owns the unlock/where-can-I-go state. Points marked `initial` start discovered.

## @jgengine/core/world/features

- `BiomeBand` (interface): interface BiomeBand — A z-ordered ground palette zone — the linear-boundary counterpart to the radial `materialRegions`. Adjacent bands cross-fade into each other across a `fade`-wide window centered on the midpoint z between their centers, so a multi-biome world (vale → marsh → peaks along z) blends its ground color instead of hard-switching. Bands may also carry per-zone `fog`, `sky`, and `weather`. Order the list by ascending `z`.
- `BiomeFog` (interface): interface BiomeFog — Per-band fog override cross-faded along z by `createBiomeFogSampler`; unset fields fall through to the base sky fog.
- `BiomeSky` (interface): interface BiomeSky — Per-band sky/light override cross-faded along z by `createBiomeSkySampler`; unset fields fall through to the base sky.
- `BiomesWorldConfig` (interface): interface BiomesWorldConfig extends WorldGridConfig { map: string; zones: string; bounds?: WorldBounds } — ⚠ undocumented · used by `biomes`: Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain.
- `BuildingEnvironmentConfig` (interface): interface BuildingEnvironmentConfig { count?: number; position?: EnvironmentVec2; footprint?: WorldBounds; stories?: readonly [number, number]; storyHeight?: number; spacing?: number; style?: BuildingStyle; palette?: BuildingPaletteOverrides; probabilities?: Partial<BuildingP… — ⚠ undocumented · used by `building`: Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style.
- `BuildingEnvironmentDescriptor` (type): type BuildingEnvironmentDescriptor = { kind: "building" } & Required< Pick<BuildingEnvironmentConfig, "count" | "footprint" | "stories" | "storyHeight" | "spacing" | "style"> > & Pick<BuildingEnvironmentConfig, "seed" | "position" | "palette" | "probabilities" | "along" | "kit" | "solid"> — ⚠ undocumented · used by `building`: Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style.
- `BuildingFrontageConfig` (interface): interface BuildingFrontageConfig — Street-aware placement for `building()`: instead of a grid scattered around `position`, lots are stepped along each road's frontage, offset by a consistent setback (a curb + sidewalk strip), and turned so every building FRONT faces its road. `footprint` (`w` = frontage width, `d` = depth) and `spacing` (along-road gap) are shared with the grid mode. Deterministic and bounded by `maxLots`.
- `BuildingFrontageRoad` (interface): interface BuildingFrontageRoad — One road a `building({ along })` frontage lines with buildings: centerline + full width.
- `EnvironmentArea` (interface): interface EnvironmentArea extends WorldBounds { h?: number; position?: EnvironmentVec2 } — ⚠ undocumented
- `EnvironmentDescriptorList` (type): type EnvironmentDescriptorList<T> = T | readonly T[] — ⚠ undocumented
- `EnvironmentVec2` (type): type EnvironmentVec2 = readonly [number, number] — ⚠ undocumented
- `EnvironmentWorldConfig` (interface): interface EnvironmentWorldConfig { terrain?: TerrainEnvironmentDescriptor; islands?: readonly TerrainIslandDescriptor[]; sky?: SkyEnvironmentDescriptor; weather?: EnvironmentDescriptorList<WeatherEnvironmentDescriptor>; vegetation?: EnvironmentDescriptorList<VegetationEnvi… — ⚠ undocumented · used by `environment`: Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
- `EnvironmentWorldFeature` (interface): interface EnvironmentWorldFeature { kind: "environment"; terrain?: TerrainEnvironmentDescriptor; islands?: readonly TerrainIslandDescriptor[]; sky?: SkyEnvironmentDescriptor; weather?: readonly WeatherEnvironmentDescriptor[]; vegetation?: readonly VegetationEnvironmentDescr… — ⚠ undocumented · used by `environment`: Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
- `GrassEnvironmentConfig` (interface): interface GrassEnvironmentConfig { area?: EnvironmentArea; position?: EnvironmentVec2; density?: number; bladeHeight?: readonly [number, number]; bladeWidth?: number; windStrength?: number; colors?: readonly string[]; seed?: string; bladeBend?: readonly [number, number]; t… — ⚠ undocumented · used by `grass`: Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
- `GrassEnvironmentDescriptor` (type): type GrassEnvironmentDescriptor = { kind: "grass" } & Required< Pick<GrassEnvironmentConfig, "area" | "density" | "bladeHeight" | "bladeWidth" | "windStrength" | "colors"> > & Pick<GrassEnvironmentConfig, "seed" | "bladeBend" | "tuftRadius" | "colorVariation" | "normalLift" | "groundCover"> — ⚠ undocumented · used by `grass`: Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
- `OceanEnvironmentConfig` (interface): interface OceanEnvironmentConfig { bounds?: WorldBounds; position?: EnvironmentVec2; level?: number; levelAt?: (time: number) => number; waveHeight?: number; waveScale?: number; waveSpeed?: number; color?: string } — ⚠ undocumented · used by `ocean`: Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
- `OceanEnvironmentDescriptor` (type): type OceanEnvironmentDescriptor = { kind: "ocean" } & Required< Pick<OceanEnvironmentConfig, "bounds" | "level" | "waveHeight" | "waveScale" | "waveSpeed" | "color"> > & Pick<OceanEnvironmentConfig, "position" | "levelAt"> — ⚠ undocumented · used by `ocean`: Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
- `PadEnvironmentConfig` (interface): interface PadEnvironmentConfig { center: EnvironmentVec2; size: PadSize; height?: number; elevation?: number; color?: string; rotationY?: number } — ⚠ undocumented
- `PadEnvironmentDescriptor` (type): type PadEnvironmentDescriptor = { kind: "pad" } & Required< Pick<PadEnvironmentConfig, "center" | "size" | "height" | "color"> > & Pick<PadEnvironmentConfig, "rotationY" | "elevation"> — ⚠ undocumented · used by `padFlattenMasks`: Derives implicit `TerrainFlattenMask`s carving each pad's footprint into the terrain beneath it.
- `PadSize` (type): type PadSize = readonly [number, number] | { radius: number } — ⚠ undocumented
- `PlotsWorldConfig` (interface): interface PlotsWorldConfig extends WorldGridConfig { city?: string; interiors?: string } — ⚠ undocumented · used by `plots`: Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts.
- `RainEnvironmentConfig` (interface): interface RainEnvironmentConfig { area?: EnvironmentArea; position?: EnvironmentVec2; density?: number; speed?: number; dropLength?: number; wind?: EnvironmentVec2; color?: string; width?: number; opacity?: number } — ⚠ undocumented · used by `rain`: Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
- `RainEnvironmentDescriptor` (type): type RainEnvironmentDescriptor = { kind: "rain" } & Required< Pick<RainEnvironmentConfig, "area" | "density" | "speed" | "dropLength" | "wind" | "color" | "width" | "opacity"> > — ⚠ undocumented · used by `rain`: Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
- `RoadEnvironmentConfig` (interface): interface RoadEnvironmentConfig — Config for {@link road}: a flat asphalt ribbon draped over the terrain along a centerline.
- `RoadEnvironmentDescriptor` (type): type RoadEnvironmentDescriptor = { kind: "road" } & Required< Pick<RoadEnvironmentConfig, "path" | "width" | "color" | "markings" | "markingColor" | "elevation"> > & { /** Resolved sidewalk band, or `false` when the road has none. */ sidewalk: { width: number; color: string } | false; /** Procedural… — Resolved road descriptor produced by {@link road} and rendered by the shell environment scene.
- `SkyEnvironmentConfig` (interface): interface SkyEnvironmentConfig { preset?: "day" | "dusk" | "night"; timeOfDay?: boolean; horizonColor?: string; zenithColor?: string; sunIntensity?: number; ambientIntensity?: number; sunColor?: string; fogColor?: string; moonIntensity?: number; moonColor?: string; sun?:… — ⚠ undocumented · used by `CINEMATIC_SKY` (@jgengine/core/render/lookPreset): A static day sky: a real dome plus the shell's view-following shadow-casting sun and hemisphere fill.
- `SkyEnvironmentDescriptor` (type): type SkyEnvironmentDescriptor = { kind: "sky" } & Required< Pick<SkyEnvironmentConfig, "preset" | "timeOfDay"> > & Omit<SkyEnvironmentConfig, "preset" | "timeOfDay"> — ⚠ undocumented
- `SkySunConfig` (interface): interface SkySunConfig — Where the sun sits, as a compass bearing and a height above the horizon, both in degrees. `azimuth` 0 points toward -Z (north), 90 toward +X (east); `elevation` 90 is straight overhead.
- `SnowEnvironmentConfig` (interface): interface SnowEnvironmentConfig { area?: EnvironmentArea; position?: EnvironmentVec2; density?: number; speed?: number; flakeSize?: number; drift?: number; wind?: EnvironmentVec2; color?: string; opacity?: number } — ⚠ undocumented · used by `snow`: Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
- `SnowEnvironmentDescriptor` (type): type SnowEnvironmentDescriptor = { kind: "snow" } & Required< Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color" | "opacity"> > — ⚠ undocumented · used by `snow`: Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
- `StructureEnvironmentDescriptor` (type): type StructureEnvironmentDescriptor = BuildingEnvironmentDescriptor — ⚠ undocumented
- `TerrainCircleRegion` (interface): interface TerrainCircleRegion extends TerrainRegionStyle — A circular palette zone painted over the base terrain palette — snow caps, ash wastes, spawn circles.
- `TerrainColors` (interface): interface TerrainColors { low?: string; high?: string; waterline?: string } — ⚠ undocumented
- `TerrainDetailConfig` (interface): interface TerrainDetailConfig — Procedural detail-surface layer for terrain: a noise-driven shader that keeps the biome-tinted base ground (from `colors`/`biomeBands`) and blends distinct rock, sand, and snow over it by slope, height, and waterline — turning a flat vertex-colour surface into varied, textured-reading ground with no image assets.
- `TerrainDetailMaterialConfig` (interface): interface TerrainDetailMaterialConfig — Real PBR texture applied over the ground surface — the seam that lets a game put a `buildMaterialCatalog` material on terrain. Blends with, never replaces, the procedural detail shader: color/roughness/ao tile the maps by world position, `strength` fades them over the existing vertex-colour + noise look.
- `TerrainEnvironmentConfig` (interface): interface TerrainEnvironmentConfig { bounds?: WorldBounds; height?: number; heightMap?: string; heightField?: (x: number, z: number) => number; material?: TerrainMaterial; colors?: TerrainColors; materialRegions?: readonly TerrainMaterialRegion[]; biomeBands?: readonly Biome… — ⚠ undocumented · used by `terrain`: Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
- `TerrainEnvironmentDescriptor` (type): type TerrainEnvironmentDescriptor = { kind: "terrain" } & Required< Pick<TerrainEnvironmentConfig, "bounds" | "height"> > & Omit<TerrainEnvironmentConfig, "bounds" | "height"> — ⚠ undocumented · used by `terrain`: Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
- `TerrainFlattenMask` (interface): interface TerrainFlattenMask { center: EnvironmentVec2; radius: number; height?: number; falloff?: number } — ⚠ undocumented · used by `padFlattenMasks`: Derives implicit `TerrainFlattenMask`s carving each pad's footprint into the terrain beneath it.
- `TerrainIslandConfig` (interface): interface TerrainIslandConfig extends TerrainEnvironmentConfig — A bounded terrain patch floating at its own altitude — sky islands, arena platforms, split landmasses with void between.
- `TerrainIslandDescriptor` (type): type TerrainIslandDescriptor = Omit<TerrainEnvironmentDescriptor, "kind"> & { kind: "island"; origin: EnvironmentVec2; } — ⚠ undocumented
- `TerrainMaterial` (type): type TerrainMaterial = "grass" | "sand" | "snow" | "rock" | "ash" | "highland" | "slate" — ⚠ undocumented · used by `TERRAIN_MATERIALS` (@jgengine/core/editor): The default terrain paint palette (surface id → color) shared by the panel and the mesh.
- `TerrainMaterialMaps` (interface): interface TerrainMaterialMaps — PBR map URLs for a real ground texture — the same shape `libraryTerrainMaterial(name).maps` from `@jgengine/assets` returns. Kept dependency-free here so `core` never imports the assets package; any URLs (pulled maps, a CDN, a data URI) satisfy it. Omitted roughness keeps the terrain scalar; omitted AO skips occlusion sampling.
- `TerrainMaterialRegion` (type): type TerrainMaterialRegion = TerrainCircleRegion | TerrainPolylineRegion | TerrainRectRegion — A palette zone painted over the base terrain palette. Circle (the default when no `shape` is given), `polyline` ribbons for roads/rivers, and rotatable `rect` districts all paint fully inside their core and blend back across `falloff`; later regions in the list win overlaps.
- `TerrainPolylineRegion` (interface): interface TerrainPolylineRegion extends TerrainRegionStyle — A ribbon palette zone following a centerline — roads and rivers, instead of chaining overlapping circles.
- `TerrainRectRegion` (interface): interface TerrainRectRegion extends TerrainRegionStyle — A rectangular palette zone, optionally rotated about the world y axis — plazas, fields, districts.
- `TerrainRegionStyle` (interface): interface TerrainRegionStyle — Palette and blend fields shared by every `TerrainMaterialRegion` shape.
- `TilemapWorldConfig` (interface): interface TilemapWorldConfig extends WorldGridConfig { map: string; tileSet?: {atlas: SpriteAtlas; tiles: Record<string, string>}; sortingLayer?: string } — ⚠ undocumented · used by `tilemap`: Declares a 2D tilemap world from a map string.
- `VegetationEnvironmentDescriptor` (type): type VegetationEnvironmentDescriptor = GrassEnvironmentDescriptor — ⚠ undocumented
- `VoxelWorldConfig` (interface): interface VoxelWorldConfig extends WorldGridConfig { seed: string; generate?: string; streaming?: {radius: number} } — ⚠ undocumented · used by `voxel`: Declares a voxel-grid world for block-based games.
- `WaterEnvironmentDescriptor` (type): type WaterEnvironmentDescriptor = OceanEnvironmentDescriptor — ⚠ undocumented
- `WeatherEnvironmentDescriptor` (type): type WeatherEnvironmentDescriptor = RainEnvironmentDescriptor | SnowEnvironmentDescriptor — ⚠ undocumented
- `WorldBounds` (interface): interface WorldBounds { w: number; d: number } — ⚠ undocumented · used by `terrainBoundsFromDocument` (@jgengine/core/editor): The origin-centered terrain footprint that covers every authored object in a document, padded and floored to `minBounds`.
- `WorldFeature` (type): type WorldFeature = | PlaceWorldFeature | ({ kind: "biomes" } & BiomesWorldConfig) | ({ kind: "voxel" } & VoxelWorldConfig) | ({ kind: "plots" } & PlotsWorldConfig) | ({ kind: "tilemap" } & TilemapWorldConfig) | EnvironmentWorldFeature | { kind: "flat" } — A declared world shape passed to `defineGame`. The preferred model is the place feature from `world()` (`@jgengine/core/world/place`): substrate + laws, with all dressing authored in the editor. The remaining members — biomes, voxel grid, plots, tilemap, environment, flat — are the legacy code-declared shapes kept for existing games.
- `WorldGridCell` (interface): interface WorldGridCell { x: number; z: number; height?: number; color?: string } — ⚠ undocumented
- `WorldGridConfig` (interface): interface WorldGridConfig — Shared by `biomes()`/`voxel()`/`plots()`/`tilemap()` so the shell can render their declared content as instanced boxes without a hand-written renderer.
- `biomes` (function): function biomes(config: BiomesWorldConfig): WorldFeature — Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain.
- `building` (function): function building(config: BuildingEnvironmentConfig = {}): BuildingEnvironmentDescriptor — Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style. Pass `along` to line road frontage instead of gridding around `position`.
- `environment` (function): function environment(config: EnvironmentWorldConfig = {}): EnvironmentWorldFeature — Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
- `flat` (function): function flat(): WorldFeature — Declares an empty flat world — the minimal `WorldFeature` for games with no terrain of their own.
- `grass` (function): function grass(config: GrassEnvironmentConfig = {}): GrassEnvironmentDescriptor — Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
- `island` (function): function island(config: TerrainIslandConfig): TerrainIslandDescriptor — ⚠ undocumented
- `ocean` (function): function ocean(config: OceanEnvironmentConfig = {}): OceanEnvironmentDescriptor — Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
- `pad` (function): function pad(config: PadEnvironmentConfig): PadEnvironmentDescriptor — ⚠ undocumented
- `padFlattenMasks` (function): function padFlattenMasks(pads: readonly PadEnvironmentDescriptor[]): readonly TerrainFlattenMask[] — Derives implicit `TerrainFlattenMask`s carving each pad's footprint into the terrain beneath it. Elevated pads (absolute `elevation`) float free and carve nothing.
- `plots` (function): function plots(config: PlotsWorldConfig = {}): WorldFeature — Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts.
- `rain` (function): function rain(config: RainEnvironmentConfig = {}): RainEnvironmentDescriptor — Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
- `road` (function): function road(config: RoadEnvironmentConfig): RoadEnvironmentDescriptor — Declare a road ribbon for an `environment()` world; the shell drapes and renders it over the terrain.
- `sky` (function): function sky(config: SkyEnvironmentConfig = {}): SkyEnvironmentDescriptor — ⚠ undocumented
- `snow` (function): function snow(config: SnowEnvironmentConfig = {}): SnowEnvironmentDescriptor — Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
- `terrain` (function): function terrain(config: TerrainEnvironmentConfig = {}): TerrainEnvironmentDescriptor — Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
- `tilemap` (function): function tilemap(config: TilemapWorldConfig): WorldFeature — Declares a 2D tilemap world from a map string.
- `voxel` (function): function voxel(config: VoxelWorldConfig): WorldFeature — Declares a voxel-grid world for block-based games.

## @jgengine/core/world/fog

- `FogBounds` (interface): interface FogBounds { minX: number; minZ: number; maxX: number; maxZ: number } — ⚠ undocumented
- `FogCells` (interface): interface FogCells { cols: number; rows: number; minX: number; minZ: number; cellSize: number; revealed: readonly boolean[]; revealedCount: number } — ⚠ undocumented
- `FogConfig` (interface): interface FogConfig { bounds: FogBounds; cellSize: number; revealed?: readonly number[] } — ⚠ undocumented
- `FogField` (interface): interface FogField — Reveal-on-event fog of war over a fixed grid. Walking (`revealAlong`) and digging/acting (`reveal`) clear cells; once revealed a cell stays revealed. Pure and renderer-free — the shell/react map draws `cells()`.
- `createFogField` (function): function createFogField(config: FogConfig): FogField — ⚠ undocumented

## @jgengine/core/world/footprintGrid

- `AdjacentCell` (interface): interface AdjacentCell — One occupied neighbor cell reported by {@link boundaryNeighbors}.
- `FootprintGrid` (interface): interface FootprintGrid — Handle returned by {@link createFootprintGrid}.
- `FootprintGridOptions` (interface): interface FootprintGridOptions — Config for {@link createFootprintGrid}.
- `FootprintGridState` (interface): interface FootprintGridState — Plain JSON state of a {@link FootprintGrid}: live reservations in claim order.
- `FootprintRegion` (type): type FootprintRegion = RegionFootprint | MergedRegion — A standalone footprint or a pooled region carrying its original contributions.
- `FootprintReservation` (interface): interface FootprintReservation — A live claim on a {@link FootprintGrid}: which cells `id` (a `kind` tag for adjacency checks) holds.
- `GridCell` (interface): interface GridCell — One integer cell address on a {@link FootprintGrid}.
- `MergedRegion` (interface): interface MergedRegion extends RegionFootprint — Plain JSON pooled region. Contributions partition its cells and sum to its capacity.
- `RegionContribution` (interface): interface RegionContribution — Original footprint identity and capacity retained when regions pool.
- `RegionFootprint` (interface): interface RegionFootprint — Caller-owned logical footprint. Cells must be unique, safe integer addresses and cardinally connected.
- `RegionSplitIds` (interface): interface RegionSplitIds — Identities for split sides containing multiple contributions; singletons retain their original id.
- `RegionWorkBudget` (interface): interface RegionWorkBudget — Optional caller work limits, checked before cell traversal. Omitted limits follow input size.
- `boundaryNeighbors` (function): function boundaryNeighbors(grid: FootprintGrid, cells: readonly GridCell[]): AdjacentCell[] — Every occupied cell orthogonally touching `cells` but outside them — the connective-piece neighbor set.
- `canMerge` (function): function canMerge(a: FootprintRegion, b: FootprintRegion, budget: RegionWorkBudget = {}): boolean — Matching kind/tier, disjoint valid source identities/cells, and cardinal contact. Linear in input size.
- `createFootprintGrid` (function): function createFootprintGrid(options: FootprintGridOptions = {}): FootprintGrid — Multi-cell footprint occupancy/reservation on a shared build grid — `world/placementController` only owns the ghost preview; this is the persistent claim a committed placement holds so the next hover's `isFree` check (or another player's, in a shared world) sees it. Bridge into `world/placement`'s `PlacementRules.obstacles` with {@link footprintObstacles} instead of hand-rolling an occupancy map per game.
- `footprintObstacles` (function): function footprintObstacles(grid: FootprintGrid): PlacementObstacle[] — Bridges live reservations into `world/placement`'s `PlacementRules.obstacles` so `validatePlacement`/`createPlacementController` see the grid's committed footprints unchanged.
- `hasValidAdjacency` (function): function hasValidAdjacency(grid: FootprintGrid, cells: readonly GridCell[], accepts: (neighborKind: string) => boolean, requireConnection = false): boolean — Connective-piece adjacency validity: every occupied neighbor of `cells` must satisfy `accepts` (no incompatible piece touching), and when `requireConnection` is true at least one neighbor must (a road/pipe/belt segment placed with nothing to connect to is invalid). An empty-bordered footprint (no occupied neighbors at all) passes unless `requireConnection` demands one.
- `mergeFootprints` (function): function mergeFootprints(a: FootprintRegion, b: FootprintRegion, id: string, budget: RegionWorkBudget = {}): MergedRegion | null — Pool compatible footprints under caller-owned `id`, retaining original capacities and identities. Returns null for invalid data, kind/tier mismatch, overlap, no cardinal contact or exhausted budget. Does not mutate inputs or grid reservations; costs, merge width and upgrade policy remain caller-owned. Capacity is the ordered JavaScript-number sum of original contributions, independent of cell area.
- `splitRegion` (function): function splitRegion(region: MergedRegion, leftIds: readonly string[], ids: RegionSplitIds = {}, budget: RegionWorkBudget = {}): [FootprintRegion, FootprintRegion] | null — Partition whole original contributions by `leftIds`; both sides must remain cardinally connected. Singletons restore their original id and capacity; larger sides require explicit output identities. Returns null for invalid provenance/budget, unknown or duplicate ids, empty/disconnected sides, or conflicting output identities (including identities from the opposite side's contributions). An output may reuse its own side's source identity. Cell cuts/capacity repricing require caller policy. Both sides inherit the current region kind/tier. Inputs and grid reservations remain unchanged.

## @jgengine/core/world/geometry

- `Aabb` (interface): interface Aabb { minX: number; minZ: number; maxX: number; maxZ: number } — ⚠ undocumented · used by `polygonBounds` (@jgengine/core/world): Axis-aligned bounds of a polygon, or null if it has no points.
- `AvoidCorridor` (interface): interface AvoidCorridor — A clearance *corridor* along a polyline (a path/road): scatter is repelled within `halfWidth` of the centerline, feathered over the outer band. Clean straight edges — unlike approximating a corridor with a scalloped chain of discs.
- `AvoidMasks` (interface): interface AvoidMasks — A clearance region: point discs (spawns/plots) plus centerline corridors (paths).
- `AvoidZone` (interface): interface AvoidZone — A circular clearance around a gameplay spot (spawn, plot, path point, POI): scatter is repelled from it and terrain is flattened toward its center. `feather` (meters) is the soft outer band — full effect within `radius - feather`, ramping to zero at `radius`.
- `Ellipse` (interface): interface Ellipse — An axis-aligned ellipse: `center` with semi-axes `radiusX` and `radiusY`.
- `Footprint` (interface): interface Footprint { w: number; d: number } — ⚠ undocumented · used by `rotatedFootprint` (@jgengine/core/scene/assetSpace): The axis-aligned footprint extent after rotating a rectangular {@link Footprint} by `headingDegrees` — footprint-aware placement: a 90-degre…
- `MoveOptions` (interface): interface MoveOptions { bounds?: Aabb; radius?: number } — ⚠ undocumented
- `Vec2` (type): type Vec2 = readonly [number, number] — ⚠ undocumented · used by `assignFormationSlots` (@jgengine/core/movement/formation): Match `members` to `slots` by a deterministic greedy nearest assignment: every (member, slot) pair is ranked by squared travel distance (min…
- `Vec3` (type): type Vec3 = readonly [number, number, number] — A 3D point/vector as an `[x, y, z]` tuple — the engine's zero-allocation spatial primitive.

## @jgengine/core/world/grassKind

- `GRASS_DEFAULTS` (const): const GRASS_DEFAULTS: GrassRules — Grass defaults: a lush, lightly-swaying meadow.
- `GRASS_FIELD_KIND` (const): const GRASS_FIELD_KIND: "grass_field" — The editor volume kind marking a box as a GPU grass patch.
- `GRASS_SCHEMA` (const): const GRASS_SCHEMA: ParamSchema — The grass parameter schema — drives the inspector and `meta` parse via the studio seam.
- `GrassRules` (interface): interface GrassRules — Fully-defaulted grass params parsed from a volume's `meta`.
- `ResolvedGrass` (interface): interface ResolvedGrass — A resolved grass patch: world-space area center at ground height, footprint size (XZ), and rules.

## @jgengine/core/world/gridInstances

- `GridInstanceTransform` (interface): interface GridInstanceTransform { position: readonly [number, number, number]; scale: readonly [number, number, number]; color: string } — ⚠ undocumented
- `resolveGridCells` (function): function resolveGridCells(config: WorldGridConfig | GridWorldFeature): readonly WorldGridCell[] — ⚠ undocumented
- `resolveGridInstances` (function): function resolveGridInstances(config: WorldGridConfig | GridWorldFeature): readonly GridInstanceTransform[] — ⚠ undocumented

## @jgengine/core/world/grounded

- `grounded` (function): function grounded(ctx: Pick<GameContext, "world">, x: number, z: number): readonly [number, number, number] — Ground an XZ point onto the live world surface as `[x, groundY, z]`.

## @jgengine/core/world/interiors

- `EntityLocation` (interface): interface EntityLocation { space: SpaceRef; position: Vec2 } — ⚠ undocumented
- `Exterior` (interface): interface Exterior { bounds?: Aabb; obstacles?: readonly Aabb[] } — ⚠ undocumented
- `Interior` (interface): interface Interior { id: string; origin: Vec2; rotation?: number; bounds: Aabb; obstacles?: readonly Aabb[] } — ⚠ undocumented
- `Interiors` (interface): interface Interiors { move(location: EntityLocation, delta: Vec2): EntityLocation; enter(location: EntityLocation, id: string): EntityLocation | null; leave(location: EntityLocation): EntityLocation | null; toInterior(id: string, exterior: Vec2): Vec2 | null; … — ⚠ undocumented · used by `createInteriors`: Frame conversion and bounded movement across an exterior and its interiors; holds config only, no play state.
- `InteriorsConfig` (interface): interface InteriorsConfig { exterior?: Exterior; interiors?: readonly Interior[]; radius?: number } — ⚠ undocumented · used by `createInteriors`: Frame conversion and bounded movement across an exterior and its interiors; holds config only, no play state.
- `SpaceRef` (type): type SpaceRef = { kind: "exterior" } | { kind: "interior"; id: string } — ⚠ undocumented
- `createInteriors` (function): function createInteriors(config: InteriorsConfig = {}): Interiors — Frame conversion and bounded movement across an exterior and its interiors; holds config only, no play state.

## @jgengine/core/world/lod

- `LodBand` (interface): interface LodBand { maxDistance: number; interval: number } — ⚠ undocumented
- `LodScheduler` (interface): interface LodScheduler { bandIndex(distance: number): number; step(id: string, distance: number, dtSeconds: number): number; remove(id: string): void; clear(): void; size(): number; snapshot(): LodSchedulerState; restore(next: LodSchedulerState): void } — ⚠ undocumented
- `LodSchedulerConfig` (interface): interface LodSchedulerConfig { bands: readonly LodBand[]; beyondInterval?: number | null; stagger?: boolean } — ⚠ undocumented
- `LodSchedulerState` (interface): interface LodSchedulerState — Plain JSON state of a {@link LodScheduler}: each id's accumulated seconds.
- `createLodScheduler` (function): function createLodScheduler(config: LodSchedulerConfig): LodScheduler — ⚠ undocumented

## @jgengine/core/world/mapAnnotations

- `AnnotationLayer` (interface): interface AnnotationLayer — Player-drawn map annotation layer — strokes, shapes, and notes over caller-owned map data.
- `AnnotationLayerOptions` (interface): interface AnnotationLayerOptions — Options for {@link createAnnotationLayer}.
- `AnnotationSnapshot` (interface): interface AnnotationSnapshot — Whole serializable state of an annotation layer — drop into a save blob.
- `MapNote` (interface): interface MapNote — A text note pinned at a world point.
- `MapShapeAnnotation` (interface): interface MapShapeAnnotation — A drawn area annotation (circle/rect/polygon), reusing the map-zone shape vocabulary.
- `MapStroke` (interface): interface MapStroke — A freehand drawn line on the map — a world-XZ polyline.
- `createAnnotationLayer` (function): function createAnnotationLayer(options: AnnotationLayerOptions = {}): AnnotationLayer — Player-drawn map annotation layer: freehand `strokes`, area `shapes`, and pinned `notes`, all world-XZ and serializable. `routes()`/`zones()` project strokes/shapes into the exact shapes `Minimap`/`WorldMap`/`FullscreenMap` already render via their `routes`/`zones` props, so drawing needs no new renderer. State is plain data; `snapshot`/`restore` round-trip through a save.

## @jgengine/core/world/mapLayers

- `MAP_LAYER_TONE_COLORS` (const): const MAP_LAYER_TONE_COLORS: Record<MapLayerTone, string> — ⚠ undocumented
- `MapCellStates` (interface): interface MapCellStates { id: string; origin: MapXZ; cellSize: number; cells: readonly {col: number; row: number; tone: MapLayerTone; opacity?: number}[] } — ⚠ undocumented
- `MapLayerTone` (type): type MapLayerTone = "danger" | "warning" | "info" | "safe" | "neutral" — ⚠ undocumented
- `MapRoute` (interface): interface MapRoute { id: string; points: readonly MapXZ[]; tone?: MapLayerTone; forecast?: boolean; width?: number; closed?: boolean } — ⚠ undocumented
- `MapXZ` (type): type MapXZ = readonly [number, number] — ⚠ undocumented
- `MapZone` (interface): interface MapZone { id: string; shape: MapZoneShape; tone?: MapLayerTone; opacity?: number; forecast?: boolean; label?: string } — ⚠ undocumented
- `MapZoneShape` (type): type MapZoneShape = | { kind: "circle"; center: MapXZ; radius: number } | { kind: "rect"; center: MapXZ; w: number; d: number; rotate?: number } | { kind: "polygon"; points: readonly MapXZ[] } — ⚠ undocumented · used by `pointInMapZone`: Renderer-free overlay data for map surfaces (#285.1-2): zones with live + forecast states, route polylines, and per-cell status heatmaps.
- `mapLayerColor` (function): function mapLayerColor(tone: MapLayerTone | undefined): string — ⚠ undocumented
- `pointInMapZone` (function): function pointInMapZone(zone: MapZoneShape, x: number, z: number): boolean — Renderer-free overlay data for map surfaces (#285.1-2): zones with live + forecast states, route polylines, and per-cell status heatmaps. `@jgengine/react/map`'s `Minimap`/`WorldMap` take these straight in; `pointInMapZone` answers gameplay queries against the same data, so the HUD and the rules can never disagree about where the storm is.

## @jgengine/core/world/markers

- `DEFAULT_MARKER_KINDS` (const): const DEFAULT_MARKER_KINDS: Record<string, MarkerKindStyle> — ⚠ undocumented
- `MapMarker` (interface): interface MapMarker<TMeta = unknown> extends MarkerView<TMeta> — A marker owned by {@link MarkerSet}, including its lifecycle and query fields.
- `MarkerCollection` (type): type MarkerCollection<TMarker extends MarkerView = MarkerView> = | readonly TMarker[] | MarkerSource<TMarker> | MarkerSet — Marker data accepted by portable consumers: static views, an external source, or a native set.
- `MarkerInput` (interface): interface MarkerInput<TMeta = unknown> { id?: string; kind: string; position: MarkerPosition; label?: string; heading?: number; owner?: string; createdAt?: number; expiresAt?: number; meta?: TMeta } — ⚠ undocumented
- `MarkerKindStyle` (interface): interface MarkerKindStyle — Visual descriptor for a marker kind. Games supply their own palette; the engine ships `DEFAULT_MARKER_KINDS` as a content-agnostic starting set that the react minimap/compass read for colors and glyphs.
- `MarkerPosition` (type): type MarkerPosition = readonly [number, number, number] — ⚠ undocumented
- `MarkerQuery` (interface): interface MarkerQuery { kind?: string; owner?: string; near?: MarkerPosition; radius?: number } — ⚠ undocumented
- `MarkerSet` (interface): interface MarkerSet<TMeta = unknown> { add(marker: MarkerInput<TMeta>): string; remove(id: string): boolean; get(id: string): MapMarker<TMeta> | null; list(): readonly MapMarker<TMeta>[]; query(query: MarkerQuery): MapMarker<TMeta>[]; prune(now: number): number; clear(): void;… — ⚠ undocumented · used by `useLiveMarkers` (@jgengine/react): A self-ticking {@link MarkerSet} kept in sync with the live scene: on a heartbeat (default 100ms, and once immediately) it clears the set an…
- `MarkerSource` (interface): interface MarkerSource<TMarker extends MarkerView = MarkerView> — Observable marker snapshots owned by an external project. `getSnapshot` must return the same array identity until the source changes and calls its subscribers, matching React's external-store contract.
- `MarkerSourceOptions` (interface): interface MarkerSourceOptions<TEntity, TMarker extends MarkerView = MarkerView> — Configuration for projecting a caller-owned collection into display-only markers.
- `MarkerView` (interface): interface MarkerView<TMeta = unknown> — Small, display-only marker shape consumed by map renderers. Existing games can project their own entities to this view without adopting marker lifecycle storage or duplicating them into a {@link MarkerSet}.
- `createMarkerSet` (function): function createMarkerSet<TMeta = unknown>(now: () => number = Date.now): MarkerSet<TMeta> — ⚠ undocumented
- `createMarkerSource` (function): function createMarkerSource<TEntity, TMarker extends MarkerView = MarkerView>(options: MarkerSourceOptions<TEntity, TMarker>): MarkerSource<TMarker> — Adapt a caller-owned array/store to an observable marker source. Projection is cached between source changes, so React reads do not copy the collection per frame. The caller retains ownership of entities, updates, persistence, and subscription scheduling.
- `markerKindStyle` (function): function markerKindStyle(kind: string | undefined, styles: Record<string, MarkerKindStyle> = DEFAULT_MARKER_KINDS): MarkerKindStyle — ⚠ undocumented

## @jgengine/core/world/massing

- `MASSING_COMPOSITIONS` (const): const MASSING_COMPOSITIONS: readonly MassingComposition[] — ⚠ undocumented
- `MASSING_PROFILES` (const): const MASSING_PROFILES: readonly MassingProfile[] — ⚠ undocumented
- `MassingBody` (type): type MassingBody = { x: number; y: number; z: number; w: number; h: number; d: number; ry?: number; facade?: boolean; kind?: "box" | "capsule"; role?: MassingBodyRole; branch?: boolean; crown?: boolean; } — ⚠ undocumented
- `MassingBodyRole` (type): type MassingBodyRole = "mass" | "core" | "transfer" — ⚠ undocumented
- `MassingComposition` (type): type MassingComposition = | "bar" | "split" | "cluster" | "stack" | "court" | "bridge" | "ring" | "capsule" | "megastructure" — ⚠ undocumented
- `MassingProfile` (type): type MassingProfile = "straight" | "stepped" | "tapered" | "top-heavy" | "offset" | "twisted" — ⚠ undocumented
- `MassingSpec` (type): type MassingSpec = { seed: string; width: number; height: number; depth: number; floorHeight: number; baySpacing: number; pilotis: number; podiumHeight: number; cores: number; terraces: number; cantilever: number; voids: number; taper: number; articulation: number; crown: number; moduleDensity: numb… — ⚠ undocumented
- `composeMassing` (function): function composeMassing(b: MassingSpec): MassingBody[] — ⚠ undocumented
- `hashMassingSeed` (const): const hashMassingSeed: (text: string) => number — ⚠ undocumented
- `isVillageMassing` (const): const isVillageMassing: (spec: Pick<MassingSpec, "height" | "composition" | "articulation" | "moduleDensity">) => boolean — ⚠ undocumented
- `massingBase` (const): const massingBase: (spec: Pick<MassingSpec, "pilotis" | "height">, cap?: number) => number — ⚠ undocumented
- `massingFloorCount` (function): function massingFloorCount(spec: Pick<MassingSpec, "pilotis" | "height" | "floorHeight">): number — ⚠ undocumented

## @jgengine/core/world/minimap

- `Cardinal` (type): type Cardinal = "N" | "NE" | "E" | "SE" | "S" | "SW" | "W" | "NW" — ⚠ undocumented
- `MinimapPoint` (interface): interface MinimapPoint { x: number; y: number; distance: number; inside: boolean } — ⚠ undocumented · used by `clampToMinimapEdge`: Clamp a projected point to the minimap edge, preserving direction (edge markers).
- `MinimapView` (interface): interface MinimapView { center: WorldXZ; worldRadius: number; size: number; rotate?: number } — ⚠ undocumented · used by `projectToMinimap`: Project a world XZ (or XYZ) point into minimap pixel space.
- `WorldXZ` (type): type WorldXZ = readonly [number, number] — ⚠ undocumented · used by `compassBearing`: Compass bearing (radians, 0 = map north = −Z, increasing clockwise toward +X = east) from one world XZ point to another.
- `bearingToCardinal` (function): function bearingToCardinal(bearing: number): Cardinal — ⚠ undocumented
- `clampToMinimapEdge` (function): function clampToMinimapEdge(point: MinimapPoint, size: number): { x: number; y: number } — Clamp a projected point to the minimap edge, preserving direction (edge markers).
- `compassBearing` (function): function compassBearing(from: WorldXZ, to: WorldXZ): number — Compass bearing (radians, 0 = map north = −Z, increasing clockwise toward +X = east) from one world XZ point to another. Feeds both the minimap direction and the compass strip.
- `headingToBearing` (function): function headingToBearing(yaw: number): number — Bearing of an entity facing direction given its `rotationY` (yaw) in radians.
- `projectToMinimap` (function): function projectToMinimap(world: WorldXZ | readonly [number, number, number], view: MinimapView): MinimapPoint — Project a world XZ (or XYZ) point into minimap pixel space. Origin is the top-left of the `size×size` box; north (−Z) maps to −Y (up). Pass `view.rotate` to spin the map under a fixed north-up player arrow.
- `relativeBearing` (function): function relativeBearing(bearing: number, reference: number): number — Signed offset of `bearing` from `reference`, wrapped into (−π, π].
- `unprojectFromMinimap` (function): function unprojectFromMinimap(point: { x: number; y: number }, view: MinimapView): WorldXZ — Invert `projectToMinimap` (#285.6): minimap pixel → world XZ, rotate-aware — click-to-pin, tap-to-ping, drag-to-set-waypoint map interactions.

## @jgengine/core/world/minimapBake

- `DEFAULT_MINIMAP_PALETTE` (const): const DEFAULT_MINIMAP_PALETTE: MinimapBakePalette — The built-in height→color ramp and water color a bake uses when no palette override is given.
- `MinimapBake` (interface): interface MinimapBake — A baked minimap image: RGBA pixels plus the world bounds they span.
- `MinimapBakeBounds` (interface): interface MinimapBakeBounds — Deterministic minimap terrain bake (#1036): rasterize an authored world's terrain (plus optional biome zones and water) into a top-down RGBA image and a matching world-bounds rectangle, then encode it as a PNG data URI. The editor runs this as a bake action and stores the result on the scene document; runtime feeds it straight into the existing `Minimap` / `WorldMap` `background` + `mapBounds` props — no new runtime render path, and the same authored world always bakes the same image (safe for verify/CI). Pure: no canvas, no DOM, `core` still imports nothing external.
- `MinimapBakeOptions` (interface): interface MinimapBakeOptions — Options for {@link bakeMinimapImage}.
- `MinimapBakePalette` (interface): interface MinimapBakePalette — The height→color ramp and water color used by the bake.
- `MinimapBakeSource` (interface): interface MinimapBakeSource — The authored world a bake reads — a height sampler, its bounds, and optional zones/water.
- `MinimapBakeZone` (interface): interface MinimapBakeZone — One biome/region tint painted over the terrain shade where the ground falls inside its polygon.
- `bakeMinimapBackground` (function): function bakeMinimapBackground(source: MinimapBakeSource, options: MinimapBakeOptions = {}): { background: string; mapBounds: MinimapBakeBounds } — One-call convenience: rasterize a source and return `{ background, mapBounds }` for a minimap.
- `bakeMinimapImage` (function): function bakeMinimapImage(source: MinimapBakeSource, options: MinimapBakeOptions = {}): MinimapBake — Rasterizes a top-down terrain image: height maps onto a low→high color ramp (normalized over the sampled height range), slope darkens the shade, water fills below `waterLevel`, and each zone polygon tints the ground it covers. Deterministic for a fixed source. The bounds are preserved so a player-centered minimap pans the image correctly.
- `encodeBakePng` (function): function encodeBakePng(bake: MinimapBake): Uint8Array — Encodes an RGBA bake to raw PNG bytes (pure; stored DEFLATE, valid for any decoder).
- `minimapBakeToPngDataUri` (function): function minimapBakeToPngDataUri(bake: MinimapBake): string — Encodes a bake as a `data:image/png;base64,...` URI — the exact string the `Minimap` / `WorldMap` `background` prop takes. Deterministic for a fixed bake.

## @jgengine/core/world/minimapTrack

- `TrackAxis` (interface): interface TrackAxis — A world-space segment defining a linear "track" minimap — points are projected onto the `from`→`to` axis.
- `trackFraction` (function): function trackFraction(point: WorldXZ | readonly [number, number, number], axis: TrackAxis): number — Project a world point onto the `from`→`to` segment of `axis` and return the clamped 0..1 fraction of how far along the track it lies (0 at `from`, 1 at `to`). The linear analogue of `projectToMinimap` — feeds a horizontal corridor/route progress rail. Accepts XZ (`[x, z]`) or XYZ (`[x, y, z]`) points (index 0 = x, index 2 when length 3 else index 1 = z). A zero-length axis returns 0.

## @jgengine/core/world/pathInstances

- `PathInstance` (interface): interface PathInstance — One placed transform along a path: grounded position, facing yaw, and its ordinal + arc distance.
- `PlaceAlongPathOptions` (interface): interface PlaceAlongPathOptions — Options for {@link placeAlongPath}.
- `placeAlongPath` (function): function placeAlongPath(points: readonly { x: number; z: number }[], options: PlaceAlongPathOptions): PathInstance[] — Evenly place transforms along `points` (XZ polyline). The run length is divided into the whole number of equal spans closest to `spacing`, so instances always land on both endpoints and stay evenly distributed. Returns `spans + 1` instances. Empty for fewer than 2 points.

## @jgengine/core/world/pathTerrain

- `PathHeightPolicy` (type): type PathHeightPolicy = | { readonly kind: "sample" } | { readonly kind: "fixed"; readonly height: number } | { readonly kind: "grade"; readonly start: number; readonly end: number } — Where a path corridor drives its centerline height: - `sample` — follow the base terrain under the centerline, so the corridor drapes level across its width while still tracking the hills the path crosses (the natural policy for a road or trail). - `fixed` — hold one constant height for the whole corridor (a level causeway, runway, or dam crest). - `grade` — interpolate linearly from `start` to `end` height along the path's arc length, a constant-slope ramp between two anchors (a switchback, a graded rail bed, an accessibility ramp).
- `PathRetaining` (interface): interface PathRetaining — Retaining behavior for a path corridor's shoulders. A wall rises only where the corridor already cuts or fills into the surrounding ground by at least `threshold` — gentle stretches stay open — so a road through a canyon gets held banks while the same profile on flat ground does not. The wall fades in smoothly across `taper` above the threshold so it never steps on or off between adjacent samples.
- `TerrainPathProfile` (interface): interface TerrainPathProfile — A serializable path-driven terrain modifier. The `points` centerline reshapes the heightfield across a corridor of `width`, feathering back to the surrounding ground across `shoulder`. `height` sets the centerline target (sample / fixed / grade); `depth` carves a channel below it (deepest at the centerline, easing to zero at the core edge — rivers and trenches); `retaining` raises walls where the cut/fill exceeds a threshold; `maxCut`/`maxFill` cap how far the ground may move from its base height. All fields are plain data (numbers, string enums, point arrays) so a profile round-trips through the scene document and evaluates identically at author time and runtime.
- `withPathProfiles` (function): function withPathProfiles(base: (x: number, z: number) => number, profiles: readonly TerrainPathProfile[]): (x: number, z: number) => number — Wraps a height sampler so each authored `TerrainPathProfile` reshapes it. Profiles apply in list order (later profiles compose over earlier ones, so an intersection's last profile wins its core); each reads the running height as its surrounding ground and the original `base` for `sample` centerline heights. The returned sampler is pure and deterministic. Degenerate profiles (fewer than two points, non-positive width or length) are skipped; with no usable profile the original `base` is returned unchanged.

## @jgengine/core/world/place

- `BoardGround` (interface): interface BoardGround — A 2D surface you look at — grid games, solitaire, tabletop. Physics is often zero-gravity or omitted; the game owns the face it draws on the board.
- `BoardGroundSize` (interface): interface BoardGroundSize — Size of a `board` ground: a 2D surface you look at, in cells or layout units.
- `FlatGround` (interface): interface FlatGround — A 3D walkable plane/slab. `Infinity` axes are unbounded; no separate "infinite" mode exists.
- `FlatGroundSize` (interface): interface FlatGroundSize — Size of a `flat` ground: extents in world units. `Infinity` on an axis means unbounded — an endless plain needs no bounds number invented for it. `y` optionally bounds vertical play space.
- `GroundConfig` (type): type GroundConfig = FlatGround | RoundGround | VoxelGround | BoardGround — The substrate of a place, discriminated by `mode` — TS rejects a `radius` on `flat` and `x`/`z` on `round`.
- `GroundGenerator` (interface): interface GroundGenerator — Serializable algorithm parameters for a procedural ground generator. Never a genre kit.
- `GroundMode` (type): type GroundMode = "flat" | "round" | "voxel" | "board" — Canonical ground modes after normalization (`stage` → `board`).
- `PlaceConfig` (interface): interface PlaceConfig — Input to {@link world}: place identity, substrate, and the laws of this place.
- `PlaceWorldFeature` (interface): interface PlaceWorldFeature — A declared place — the `world()` result carried on `GameDefinition.world`.
- `ResolvedBoardGround` (type): type ResolvedBoardGround = Omit<BoardGround, "mode"> & { mode: "board" } — {@link BoardGround} with the `stage` alias resolved away.
- `ResolvedGround` (type): type ResolvedGround = FlatGround | RoundGround | VoxelGround | ResolvedBoardGround — A place's ground after `world()` normalization.
- `RoundGround` (interface): interface RoundGround — A planet/sphere you play on the outside of. Sized by `radius` only.
- `RoundGroundSize` (interface): interface RoundGroundSize — Size of a `round` ground: the planet/sphere radius in world units. Nothing else.
- `SurfaceLaws` (interface): interface SurfaceLaws — The place model: a world is the place you play in — substrate (ground) plus laws (physics, surface) — never a dressed diorama. Sky look, foliage scatter, props, and sculpt are content: they are authored in the editor (or by a content preset that writes into the scene document) and consumed through the authored-scene seams, not declared on the world.
- `VoxelGround` (interface): interface VoxelGround — A procedural volume of blocks. `size` is the generator domain; `generator` is algorithm params only.
- `VoxelGroundSize` (interface): interface VoxelGroundSize — Size of a `voxel` ground: the generator's domain per axis; axes may be `Infinity` for streaming volumes.
- `isPlaceWorld` (function): function isPlaceWorld(worldFeature: { kind: string } | undefined): worldFeature is PlaceWorldFeature — Type guard for the place-model world feature.
- `resolveWorldPhysics` (function): function resolveWorldPhysics(worldFeature: { kind: string; physics?: PhysicsConfig } | undefined, base: PhysicsConfig | undefined): PhysicsConfig | undefined — Resolves the physics laws in effect for the active world: a place world's own `physics` wins field-by-field over the game-level default. Non-place worlds (and games with no world) keep the game-level config unchanged.
- `seedForPlace` (function): function seedForPlace(worldId: string, runSeed = ""): string — The engine-side seed derivation for a place: a stable string from the world `id` plus the save/run seed. Generators and scatter receive this — never a `seed` field in the world definition — so a save replays its world deterministically and a fresh run can vary by `runSeed` alone.
- `world` (function): function world(config: PlaceConfig): PlaceWorldFeature — Declares the place a game is played in: substrate (`ground`) + laws (`physics`, `ground.surface`). The thin default start — `flat` with `Infinity` axes and default physics, `board` for 2D — is a complete world; dressing it (sky, foliage, props, sculpt) is editor-authored scene content. Multiple worlds per game are first-class: declare one `world()` per place, each with its own id, ground, and physics. Games that are not a spatial place (pure UI/rules) omit `world` entirely.

## @jgengine/core/world/placeAsset

- `PlaceAssetFromCommitOptions` (interface): interface PlaceAssetFromCommitOptions — Optional catalog/label overrides for {@link placeAssetFromCommit}.
- `PlaceAssetResult` (interface): interface PlaceAssetResult — Shared place-asset verb: one resolved payload for editor `place_asset` and in-game build-mode commits. Convert with {@link toStructureInput} / {@link toEditorMarker}.
- `PlaceAssetVec3` (type): type PlaceAssetVec3 = { x: number; y: number; z: number } — World-space point shared by structure stores and editor markers.
- `ResolvePlaceAssetInput` (interface): interface ResolvePlaceAssetInput — Inputs to {@link resolvePlaceAsset}: asset id, pose, and optional catalog/known fields.
- `placeAssetFromCommit` (function): function placeAssetFromCommit(commit: PlacementCommit, assetId: string, options: PlaceAssetFromCommitOptions = {}): PlaceAssetResult — Bridge a {@link PlacementCommit} into the shared place-asset verb.
- `resolvePlaceAsset` (function): function resolvePlaceAsset(input: ResolvePlaceAssetInput): PlaceAssetResult — Resolve a place-asset intent into a shared payload (editor + games, one verb).
- `toEditorMarker` (function): function toEditorMarker(result: PlaceAssetResult): { id: string; kind: string; position: PlaceAssetVec3; rotationY: number; label: string; color: string; meta: Record<string, unknown>; } — Scene-document form: feed editor `addMarker` / `place_asset` path.
- `toStructureInput` (function): function toStructureInput(result: PlaceAssetResult): AddStructureInput — Game-state form: feed {@link createPlacedStructureStore}.add.

## @jgengine/core/world/placedStructureStore

- `AddStructureInput` (interface): interface AddStructureInput { id?: string; catalogId: string; position: StructureVec3; rotationY?: number; plotId?: string; data?: Readonly<Record<string, unknown>> } — ⚠ undocumented · used by `toStructureInput` (@jgengine/core/world): Game-state form: feed {@link createPlacedStructureStore}.add.
- `PlacedStructure` (interface): interface PlacedStructure { id: string; catalogId: string; position: StructureVec3; rotationY: number; plotId?: string; data?: Readonly<Record<string, unknown>> } — ⚠ undocumented
- `PlacedStructureSnapshot` (interface): interface PlacedStructureSnapshot { structures: readonly PlacedStructure[] } — ⚠ undocumented
- `PlacedStructureStore` (interface): interface PlacedStructureStore { add(input: AddStructureInput): PlacedStructure; move(id: string, position: StructureVec3): boolean; rotate(id: string, rotationY: number): boolean; remove(id: string): boolean; get(id: string): PlacedStructure | null; list(filter?: Struct… — ⚠ undocumented
- `StructureFilter` (interface): interface StructureFilter { plotId?: string; catalogId?: string } — ⚠ undocumented
- `StructureVec3` (type): type StructureVec3 = readonly [number, number, number] — ⚠ undocumented
- `createPlacedStructureStore` (function): function createPlacedStructureStore(): PlacedStructureStore — ⚠ undocumented

## @jgengine/core/world/placement

- `PlacementObstacle` (interface): interface PlacementObstacle { aabb: Aabb; id?: string } — ⚠ undocumented · used by `footprintObstacles` (@jgengine/core/world): Bridges live reservations into `world/placement`'s `PlacementRules.obstacles` so `validatePlacement`/`createPlacementController` see the gri…
- `PlacementRequest` (interface): interface PlacementRequest { center: Vec2; footprint: Footprint; quarterTurns?: number } — ⚠ undocumented · used by `validatePlacement`: Footprint validity: bounds + obstacle overlap after optional grid snap.
- `PlacementResult` (type): type PlacementResult = | { status: "ok"; center: Vec2; aabb: Aabb } | { status: "rejected"; reason: "out-of-bounds" } | { status: "rejected"; reason: "territory.blocked" } | { status: "rejected"; reason: "overlap"; obstacle: PlacementObstacle; index: number } — ⚠ undocumented · used by `validatePlacement`: Footprint validity: bounds + obstacle overlap after optional grid snap.
- `PlacementRules` (interface): interface PlacementRules { bounds?: Aabb; obstacles?: readonly PlacementObstacle[]; snap?: number; territory?: (aabb: Aabb) => {ok: boolean} } — ⚠ undocumented · used by `validatePlacement`: Footprint validity: bounds + obstacle overlap after optional grid snap.
- `footprintObstacle` (function): function footprintObstacle(request: PlacementRequest, id?: string): PlacementObstacle — ⚠ undocumented
- `validatePlacement` (function): function validatePlacement(request: PlacementRequest, rules: PlacementRules = {}): PlacementResult — Footprint validity: bounds + obstacle overlap after optional grid snap.

## @jgengine/core/world/placementController

- `PlacementCommit` (interface): interface PlacementCommit { center: Vec2; y: number; rotationY: number; quarterTurns: number; footprint: Footprint; aabb: Aabb; slotId?: string } — ⚠ undocumented · used by `placeAssetFromCommit` (@jgengine/core/world): Bridge a {@link PlacementCommit} into the shared place-asset verb.
- `PlacementController` (interface): interface PlacementController { hover(hit: PlacementHit): PlacementPreview; current(): PlacementPreview | null; rotate(steps?: number): PlacementPreview | null; setSnapMode(mode: SnapMode): PlacementPreview | null; cycleSnapMode(): SnapMode; setFootprint(footprint: Foot… — ⚠ undocumented · used by `createPlacementController`: Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit.
- `PlacementControllerConfig` (interface): interface PlacementControllerConfig { footprint: Footprint; rules?: PlacementRules; snapMode?: SnapMode; grid?: number; quarterTurns?: number; slots?: readonly PlacementSlot[]; slotRadius?: number } — ⚠ undocumented · used by `createPlacementController`: Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit.
- `PlacementHit` (interface): interface PlacementHit { point: PlacementVec3; normal: PlacementVec3 } — ⚠ undocumented
- `PlacementPreview` (interface): interface PlacementPreview { center: Vec2; y: number; quarterTurns: number; footprint: Footprint; aabb: Aabb; valid: boolean; reason?: "out-of-bounds" | "overlap" | "no-slot" | "territory.blocked"; snapMode: SnapMode; normal: PlacementVec3; slotId?: string } — ⚠ undocumented
- `PlacementSlot` (interface): interface PlacementSlot — A fixed buildable slot the placement controller snaps to instead of grid/free positioning.
- `PlacementVec3` (type): type PlacementVec3 = readonly [number, number, number] — ⚠ undocumented
- `SnapMode` (type): type SnapMode = "grid" | "free" | "surface" — ⚠ undocumented
- `createPlacementController` (function): function createPlacementController(config: PlacementControllerConfig): PlacementController — Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit. Pair with `@jgengine/shell/structures` `PlacementGhost` and {@link placeAssetFromCommit}.
- `quarterTurnsToRotationY` (function): function quarterTurnsToRotationY(quarterTurns: number): number — Maps 0–3 quarter turns onto radians for ghost/commit rotation.

## @jgengine/core/world/poleLineKind

- `Cable` (interface): interface Cable — One resolved cable span: a point string to loft into a tube, plus its radius.
- `POLE_LINE_KIND` (const): const POLE_LINE_KIND: "pole_line" — The editor path kind marking a polyline as a pole/cable run.
- `POLE_LINE_SCHEMA` (const): const POLE_LINE_SCHEMA: ParamSchema — The pole-line parameter schema — drives the inspector and `meta` parse via the studio seam.
- `Pole` (interface): interface Pole — One placed pole: grounded base position plus facing yaw along the run.
- `ResolvedPoleLine` (interface): interface ResolvedPoleLine — The renderable payload the resolver returns and the shell renderer consumes.
- `resolvePoleLine` (function): function resolvePoleLine(object: SceneKindObject, params: ParsedParams, context?: SceneKindResolveContext): ResolvedPoleLine — Resolve poles + cables from a document object's points and parsed params. Poles come from the generic `placeAlongPath` sampler; between each consecutive pair, `wireCount` parallel cables are strung with lateral offset and quadratic-Bézier `sag` (deeper on longer spans). Pure data.

## @jgengine/core/world/polyline

- `Polyline` (interface): interface Polyline — A polyline prepared for repeated distance/fraction sampling, with cumulative arc-length precomputed.
- `PolylineHit` (interface): interface PolylineHit — The closest point on a polyline to a query point, with where it lands along the line.

## @jgengine/core/world/raceCircuit

- `CIRCUIT_ROUTE_DEFAULTS` (const): const CIRCUIT_ROUTE_DEFAULTS: CircuitRouteRules — Defaults: a ~2.4 km arterial street lap with 12 gates, 3 laps, and barriered side streets.
- `CircuitCorner` (interface): interface CircuitCorner — One analyzed corner: where the lap turns, how hard, and which way.
- `CircuitGate` (interface): interface CircuitGate — One checkpoint trigger volume, shaped to hand straight to `raceTrack({ checkpoints })`.
- `CircuitGridSlot` (interface): interface CircuitGridSlot — One grid slot: a staggered spawn behind the start line.
- `CircuitKerb` (interface): interface CircuitKerb — One kerb strip on the outside or inside of a corner, as an offset polyline to stripe.
- `CircuitKerbOptions` (interface): interface CircuitKerbOptions — Kerb strips on the outside and inside of every real corner.
- `CircuitRoute` (interface): interface CircuitRoute — A closed race lap lifted out of a street network, with everything a race needs hung off it.
- `CircuitRouteRules` (interface): interface CircuitRouteRules — Fully-defaulted sliders the route search answers to.
- `CircuitSeal` (interface): interface CircuitSeal — One street closed off where it leaves the lap — the thing that turns public roads into an instanced event. Stands just off the junction, spanning the sealed street's full width.
- `CircuitSealKind` (type): type CircuitSealKind = "barrier" | "cones" | "fence" — How a sealed-off side street is closed: hard barriers, a cone line, or temporary fencing.
- `CircuitStart` (interface): interface CircuitStart — The start/finish line: where it is, which way cars face, and the painted line across the road.
- `circuitKerbs` (function): function circuitKerbs(route: CircuitRoute, options: CircuitKerbOptions = {}): CircuitKerb[] — Red/white kerb strips hugging both road edges through each corner. Returns the polylines and stripe pitch as data; the renderer owns the mesh and the colors.
- `extractCircuitRoute` (function): function extractCircuitRoute(network: StreetNetwork, rules: Partial<CircuitRouteRules> = {}): CircuitRoute | null — Lift a closed, sealed-off race lap out of an existing street network. Returns `null` when the network has no drivable cycle (a pure tree of dead-end streets), so callers can fall back or warn rather than render a broken race.

## @jgengine/core/world/realm

- `ComposedRealm` (interface): interface ComposedRealm { params: RealmEnvironmentParams; weather: WeatherState; spawnTable: Record<string, number>; aesthetics: readonly string[]; cards: readonly RealmCard[]; environmentField(extra?: Omit<EnvironmentFieldConfig, "baseTemperature" | "nightDrop" |… — ⚠ undocumented · used by `composeRealm`: Assemble a played realm instance at runtime from a deck of modifier cards — the Nightingale "realm card" model.
- `DEFAULT_REALM_ENVIRONMENT` (const): const DEFAULT_REALM_ENVIRONMENT: RealmEnvironmentParams — ⚠ undocumented
- `RealmBase` (interface): interface RealmBase { environment?: Partial<RealmEnvironmentParams>; weather?: WeatherState; spawn?: Record<string, number> } — ⚠ undocumented · used by `composeRealm`: Assemble a played realm instance at runtime from a deck of modifier cards — the Nightingale "realm card" model.
- `RealmCard` (interface): interface RealmCard { id: string; kind: "major" | "minor"; environment?: Partial<RealmEnvironmentParams>; weather?: Partial<WeatherState>; spawn?: SpawnTableOverride; aesthetic?: string } — ⚠ undocumented · used by `composeRealm`: Assemble a played realm instance at runtime from a deck of modifier cards — the Nightingale "realm card" model.
- `RealmEnvironmentParams` (interface): interface RealmEnvironmentParams — The recomposable environment parameters a realm card can override.
- `SpawnTableOverride` (interface): interface SpawnTableOverride — Spawn-table edits a card layers on: replace weights, add/scale, or remove ids.
- `composeRealm` (function): function composeRealm(base: RealmBase, cards: readonly RealmCard[]): ComposedRealm — Assemble a played realm instance at runtime from a deck of modifier cards — the Nightingale "realm card" model. A major card is the biome base; minor cards layer weather, day length, and spawn edits. The result recomposes both the environment (into a sampleable field via `environmentField()`) and the spawn table, and it depends on the weather hooks in this group (#92) to turn its `weather` into gameplay modifiers. Cards apply in array order; sort your deck (majors first) before composing.

## @jgengine/core/world/regions

- `ColorInput` (type): type ColorInput = string | Rgb — ⚠ undocumented
- `RegionDef` (interface): interface RegionDef<T = unknown> — A content-agnostic region. The engine blends `height` and the visual/physical knobs (`tint`, `water`, `fog`, `speedMultiplier`, …) across region borders and selects the dominant region by nearest center in `selector` space. `data` is an opaque payload the engine never inspects — games hang their own content off it (spawn tables, prop palettes, structure ids, names, …).
- `RegionField` (interface): interface RegionField<T = unknown> extends TerrainField { sampleRegion(x: number, z: number): RegionSample<T>; readonly regions: readonly RegionDef<T>[]; readonly seaLevel: number; readonly seed: number } — ⚠ undocumented · used by `scatterItems` (@jgengine/core/world): Deterministically place opaque items across `area`, grounded on a region field.
- `RegionFieldConfig` (interface): interface RegionFieldConfig<T = unknown> { regions: readonly RegionDef<T>[]; seed?: number; bounds?: WorldBounds; seaLevel?: number; selectorFrequencies?: readonly number[]; axisWeights?: readonly number[]; sharpness?: number; warp?: number } — ⚠ undocumented
- `RegionHeight` (interface): interface RegionHeight { baseHeight: number; amplitude: number; frequency: number; octaves?: number; lacunarity?: number; persistence?: number; ridged?: boolean } — ⚠ undocumented
- `RegionSample` (interface): interface RegionSample<T = unknown> { region: RegionDef<T>; weight: number; selector: readonly number[]; tint: Rgb; steepTint: Rgb; water: Rgb | null; fog: Rgb | null; fogDensity: number; speedMultiplier: number; data: T | undefined } — ⚠ undocumented · used by `scatterItems` (@jgengine/core/world): Deterministically place opaque items across `area`, grounded on a region field.
- `Rgb` (type): type Rgb = readonly [number, number, number] — ⚠ undocumented
- `createRegionField` (function): function createRegionField<T = unknown>(config: RegionFieldConfig<T>): RegionField<T> — ⚠ undocumented
- `isRegionField` (function): function isRegionField(field: TerrainField): field is RegionField — ⚠ undocumented

## @jgengine/core/world/resourceNode

- `HarvestOptions` (interface): interface HarvestOptions — Options for a single harvest.
- `HarvestResult` (interface): interface HarvestResult — Outcome of one harvest attempt.
- `Quantity` (type): type Quantity = number | readonly [number, number] — A quantity that is either fixed or a uniformly sampled `[min, max]` range resolved by the field rng.
- `ResourceGrant` (interface): interface ResourceGrant — One resource kind granted by a harvest and its resolved amount.
- `ResourceNodeDef` (interface): interface ResourceNodeDef — A harvestable node definition: a finite budget, the resources it yields, and how it respawns.
- `ResourceNodeField` (interface): interface ResourceNodeField — A set of harvestable nodes: harvest with tool profiles, tick respawn timers, snapshot/hydrate for save-load.
- `ResourceNodeFieldConfig` (interface): interface ResourceNodeFieldConfig — Construction options for {@link createResourceNodeField}: node definitions and an optional RNG/suppression hook.
- `ResourceNodeState` (interface): interface ResourceNodeState — Serializable per-node runtime state — round-trips through save/load and multiplayer sync.
- `ResourceYield` (interface): interface ResourceYield — One resource kind a node can yield and its base per-harvest amount (before tool bias and harvester multiplier).
- `ToolProfile` (interface): interface ToolProfile — How a tool extracts from a node — its per-hit power and per-resource yield bias. Two profiles over the same multi-resource node return different resources and amounts: the generic pick-vs-hatchet mechanic.
- `createResourceNodeField` (function): function createResourceNodeField(config: ResourceNodeFieldConfig): ResourceNodeField — A field of depletable, respawning harvest nodes with tool-dependent yields — the generic rock / tree / bush / vein / corpse. Each node holds a finite budget across one or more resource kinds. A harvest applies a {@link ToolProfile} whose per-resource biases decide *which* resources and *how much* the same node returns (pick favors ore, hatchet favors wood), scaled by a creature/harvester multiplier and optional deterministic rng variance; the budget drops by the tool's power. When a node empties it starts a respawn timer that `tick(dt)` counts down and refills — unless respawn is suppressed by the per-node flag or the injected predicate (a structure claimed the spot). All state is plain and serializable for save-load and multiplayer sync via {@link snapshot}/{@link hydrate}.

## @jgengine/core/world/roads

- `BandTrimOptions` (interface): interface BandTrimOptions extends JunctionGeometryOptions — Options for {@link trimBandAtJunctions} — junction geometry tunables plus a band-specific clearance.
- `DashExclusion` (interface): interface DashExclusion — A circular exclusion zone: dashes whose midpoint falls inside are dropped (e.g. junction patches).
- `GROUND_DECAL_LAYERS` (const): const GROUND_DECAL_LAYERS: { readonly road: 0.06; readonly junction: 0.06; readonly marking: 0.11; readonly glow: 0.14; } — The single owning table of ground-decal Y offsets, in world units above the sampled terrain.
- `IntersectionMarkingIntent` (interface): interface IntersectionMarkingIntent — Paint intent carried through trimming without renderer inference.
- `IntersectionMarkingLine` (interface): interface IntersectionMarkingLine — One longitudinal lane-marking ribbon, offset left (+) or right (-) from the authored centerline.
- `IntersectionMarkingOptions` (interface): interface IntersectionMarkingOptions — Tunables for {@link buildIntersectionMarkings}.
- `IntersectionSidewalkWidths` (interface): interface IntersectionSidewalkWidths — Widths of renderer-neutral sidewalk bands on each authored side of a street.
- `IntersectionStreet` (interface): interface IntersectionStreet — One street to trim + mesh through {@link buildTrimmedIntersections}.
- `JunctionApproach` (interface): interface JunctionApproach — One approach feeding {@link buildJunctionSurface}: the exact draped corner vertices a ribbon ends at.
- `JunctionGeometryOptions` (interface): interface JunctionGeometryOptions — Tunables shared by {@link trimPathAtJunctions}, {@link buildJunctionSurface}, and {@link buildTrimmedIntersections}.
- `RoadCut` (interface): interface RoadCut — One trim of a ribbon end back to a junction boundary — the seam the welded surface attaches to.
- `RoadJunctionInput` (interface): interface RoadJunctionInput — The minimal junction shape this geometry needs — a node position plus its outgoing arms. Matches the structural subset of `StreetJunction` (streetGenerator) so a network's `junctions` can be fed straight in. Arm `angle` follows the generator convention `atan2(dx, dz)`, i.e. the outward unit direction of an arm is `[sin(angle), cos(angle)]`.
- `RoadPoint` (type): type RoadPoint = readonly [number, number] — A road centerline vertex in world XZ.
- `RoadRibbon` (interface): interface RoadRibbon — Renderer-ready triangle ribbon: flat position triples plus triangle indices.
- `RoadRibbonOptions` (interface): interface RoadRibbonOptions — Options for {@link buildRoadRibbon}.
- `RoadSample` (interface): interface RoadSample — Result of {@link nearestOnPath}: closest point on the centerline plus distance and tangent.
- `TrimmedIntersections` (interface): interface TrimmedIntersections — Renderer-ready output of {@link buildTrimmedIntersections}: trimmed ribbons + welded junction surfaces.
- `TrimmedRoad` (interface): interface TrimmedRoad — A street sub-path after trimming, plus the cuts (0–2) that shortened it. Feed `path` to {@link buildRoadRibbon}.
- `buildIntersectionMarkings` (function): function buildIntersectionMarkings(intersections: TrimmedIntersections, sampleHeight: (x: number, z: number) => number, options: IntersectionMarkingOptions = {}): RoadRibbon[] — Mesh the paint declared on streets passed to {@link buildTrimmedIntersections}. Longitudinal ribbons follow the trimmed road paths. At degree-2 nodes corresponding lines are joined by a tangent-continuous cubic (signed offsets are preserved); at multi-arm nodes lines deliberately stop short of the mouth and optional transverse stop lines make that termination readable.
- `buildJunctionConnector` (function): function buildJunctionConnector(junction: { x: number; z: number }, approaches: readonly JunctionApproach[], segments = 8): RoadPoint[] | null — Build a tangent-continuous centerline through a two-arm junction. This is the shared path for paint, medians, curbs, or other linear dressing that should follow a bend but stop at crossings. Returns `null` for anything other than exactly two approaches.
- `buildJunctionPatch` (function): function buildJunctionPatch(center: RoadPoint, radius: number, sampleHeight: (x: number, z: number) => number, options: { elevation?: number; segments?: number } = {}): RoadRibbon — Build a flat, ground-draped disc patch centered on `center` — a triangle fan of `segments` sides (default 16), every vertex draped at `sampleHeight + elevation`.
- `buildJunctionSurface` (function): function buildJunctionSurface(junction: { x: number; z: number }, approaches: readonly JunctionApproach[], sampleHeight: (x: number, z: number) => number, options: JunctionGeometryOptions = {}): RoadRibbon — Weld one triangulated junction surface onto the corner vertices its incident ribbons END at (from {@link trimPathAtJunctions}). Corners are grouped by approach (so unequal widths cannot interleave a neighbour between a mouth pair), ordered around the node, and bridged as follows:
- `buildRoadRibbon` (function): function buildRoadRibbon(path: readonly RoadPoint[], width: number, sampleHeight: (x: number, z: number) => number, options: RoadRibbonOptions = {}): RoadRibbon — Triangulate a road centerline into a ground-draped ribbon mesh: the polyline is subdivided, each vertex is offset half a `width` along the local perpendicular, and every vertex sits at `sampleHeight(x, z) + elevation`. Pure geometry — the shell (or any renderer) turns the result into a mesh, and tests can assert on it directly.
- `buildTrimmedIntersections` (function): function buildTrimmedIntersections(streets: readonly IntersectionStreet[], junctions: readonly RoadJunctionInput[], sampleHeight: (x: number, z: number) => number, options: JunctionGeometryOptions = {}): TrimmedIntersections — Trim a set of streets against a set of junctions and weld the crossing surfaces in one call — the ergonomic entry the shell/playground consume for meshing.
- `dashSegments` (function): function dashSegments(path: readonly RoadPoint[], dashLength = 3, gapLength = 3, exclude: readonly DashExclusion[] = []): readonly (readonly RoadPoint[])[] — Split a centerline into dash sub-polylines for lane markings: `dashLength` of painted line, `gapLength` of asphalt, repeated along the path's arc length. Feed each returned sub-path back through {@link buildRoadRibbon} with a thin width to mesh the dashes. Pass `exclude` circles (junction patches) to interrupt the center line through intersections — any dash whose midpoint lands inside an exclusion is dropped.
- `isOnRoad` (function): function isOnRoad(path: readonly RoadPoint[], width: number, x: number, z: number): boolean — True when the query point lies within half the road `width` of the centerline.
- `nearestOnPath` (function): function nearestOnPath(path: readonly RoadPoint[], x: number, z: number): RoadSample | null — Closest-point query against a road centerline — the seam traffic AI, spawn placement, and "am I on the road" checks share. Returns null for a degenerate path.
- `pathLength` (function): function pathLength(path: readonly RoadPoint[]): number — Total arc length of a centerline in world units.
- `trimBandAtJunctions` (function): function trimBandAtJunctions(bandPath: readonly RoadPoint[], bandWidth: number, junctions: readonly RoadJunctionInput[], options: BandTrimOptions = {}): RoadPoint[][] — Cut an offset band (a polyline running PARALLEL to a street — e.g. a sidewalk from `Street.sidewalks.{left,right}`) out of every junction's apron, so the band stops at the crossing instead of sailing straight through it. Unlike {@link trimPathAtJunctions} the band never passes through a node, so it is clipped by DISTANCE: each junction contributes a circular apron of radius `max arm half-width + apronMargin + bandWidth/2 + clearance` (plus a small curb-return allowance), and any part of the band inside any apron circle is removed, splitting the band into the sub-paths that survive outside. Entry/exit points land exactly on the apron boundary. A band that never enters an apron passes through as a single untouched copy.
- `trimPathAtJunctions` (function): function trimPathAtJunctions(path: readonly RoadPoint[], width: number, junctions: readonly RoadJunctionInput[], options: JunctionGeometryOptions = {}): TrimmedRoad[] — Cut a street centerline back from the junctions it passes through so its ribbon ENDS at the junction boundary instead of ploughing through the node. Junctions are matched to path vertices within `nodeEpsilon` (endpoints and interior vertices alike); a junction sitting on an interior vertex SPLITS the path into two independently-trimmed sub-paths. Each cut records the exact boundary point and the road's left/right edge corners there, so {@link buildJunctionSurface} can weld its polygon onto the identical vertices with no overlap.

## @jgengine/core/world/scatter

- `ScatterArea` (interface): interface ScatterArea { w: number; d: number; center?: Vec2 } — ⚠ undocumented
- `ScatterConfig` (interface): interface ScatterConfig { area: ScatterArea | Aabb; count?: number; density?: number; seed?: string | number; minDistance?: number; avoid?: readonly Aabb[]; avoidMargin?: number; jitter?: number; maxAttempts?: number } — ⚠ undocumented
- `ScatterPoint` (interface): interface ScatterPoint { x: number; z: number; index: number } — ⚠ undocumented
- `scatter` (function): function scatter(config: ScatterConfig): ScatterPoint[] — ⚠ undocumented
- `scatterAabb` (function): function scatterAabb(area: ScatterArea | Aabb): Aabb — ⚠ undocumented

## @jgengine/core/world/scatterCoverage

- `CITY_BUILDING_BUDGET` (const): const CITY_BUILDING_BUDGET: 2600 — Max buildings a single `city` district generates — the block/parcel pipeline's bounded lot cap.
- `SCATTER_COVERAGE_SPECS` (const): const SCATTER_COVERAGE_SPECS: Record<ScatterCoverageKind, ScatterCoverageSpec> — The coverage spec per scatterable kind — the single source for its unit + budget.
- `SCATTER_INSTANCE_BUDGET` (const): const SCATTER_INSTANCE_BUDGET: 250000 — Max blade/placement instances a single `grass_field` or `scatter` patch places. Mirrors the grass renderer's instance-buffer ceiling; the scatter resolver truncates to it too, so a patch never renders more than this many placements regardless of density × area.
- `ScatterCoverage` (interface): interface ScatterCoverage — A resolved coverage readout: how many instances an authored patch WANTS (`requested`, when it can be computed cheaply from geometry × density), how many it will actually place after the budget clamp (`count`), the `budget` ceiling, and whether the request hit it (`capped`). `requested` is `null` for kinds whose pre-cap ask is not knowable without running the generator (city, where the count comes from the resolved street fabric).
- `ScatterCoverageKind` (type): type ScatterCoverageKind = "grass_field" | "scatter" | "city" — The shared "how much stuff grows here" contract for scatterable scene kinds (`grass_field` / `scatter` / `city`). Every scatterable kind fills an authored AREA with instances at a DENSITY, and every kind caps the placed count at a bounded BUDGET so a huge or dense request can never generate unbounded work. Before this module each kind hand-rolled its own readout and clamp story (grass silently capped in the renderer, scatter never capped, city had no budget note); this is the one place that
- `ScatterCoverageSpec` (interface): interface ScatterCoverageSpec — Per-kind coverage descriptor: the unit noun, whether density is per-m², and the placement budget.
- `budgetWarning` (function): function budgetWarning(coverage: ScatterCoverage): string — The shared clamp-and-warn clause every scatterable kind appends, worded identically: `""` when under budget, else ` · requested N, capped at M (budget)` when the pre-cap ask is known, or ` · capped at M (budget)` when only the ceiling is (city). This is the "surfaced, never silent" budget signal from #1112.
- `densityCoverage` (function): function densityCoverage(kind: "grass_field" | "scatter", area: number, density: number): ScatterCoverage — Coverage for a per-m² kind (`grass_field` / `scatter`): `requested = floor(density × area)`, clamped to the kind's budget. `capped` is true when the request exceeds the budget.
- `describeScatterCoverage` (function): function describeScatterCoverage(coverage: ScatterCoverage): string — The full one-line coverage readout: `≈ N unit · A m²` plus the {@link budgetWarning} when capped.
- `placedCoverage` (function): function placedCoverage(kind: ScatterCoverageKind, area: number, placed: number): ScatterCoverage — Coverage for a kind whose placed `count` is already known from its generator (city, from its resolved lots). No pre-cap `requested` is available — the generator stops at the budget — so `capped` is inferred from the placed count reaching the ceiling.
- `scatterCoverageSpec` (function): function scatterCoverageSpec(kind: string): ScatterCoverageSpec | null — The coverage spec for a scatterable kind, or `null` when the kind is not scatterable.
- `scatterFootprintArea` (function): function scatterFootprintArea(object: { points?: readonly { x: number; z: number }[]; halfExtents?: { x: number; z: number }; radius?: number; }): number — Footprint area (m²) of a scatterable object: a closed path polygon (shoelace), a volume box (`halfExtents`), or a disc (`radius`). Structural so it accepts a `SceneKindObject`, an editor volume, or a scatter path without a hard type dependency.

## @jgengine/core/world/scatterItems

- `ScatterInstance` (interface): interface ScatterInstance { id: string; item: string; x: number; z: number; y: number; scale: number; rotation: number; regionId: string } — ⚠ undocumented · used by `scatterItems`: Deterministically place opaque items across `area`, grounded on a region field.
- `ScatterLayer` (interface): interface ScatterLayer — One placeable class. `item` is an opaque id the caller maps to a mesh/entity.
- `pickWeighted` (function): function pickWeighted<T>(entries: readonly { value: T; weight: number }[], roll: number): T | null — Weighted pick from opaque entries; `roll` in [0, 1). Returns null when empty.
- `scatterItems` (function): function scatterItems<T>(field: RegionField<T>, area: Aabb, layersFor: (sample: RegionSample<T>) => readonly ScatterLayer[], options: { cell?: number; max?: number; saltKey?: number } = {}): ScatterInstance[] — Deterministically place opaque items across `area`, grounded on a region field. For each grid cell it asks `layersFor` which items may appear in that region and rolls one against their densities. The engine never interprets `item` — a game maps it to a mesh or entity. Content scatter (region-driven density) as opposed to `scatter` in `./scatter`, which is renderer-free geometric point distribution.

## @jgengine/core/world/scatterRegion

- `ClearanceOptions` (interface): interface ClearanceOptions — Controls which gameplay objects auto-repel scatter (and, for markers, flatten terrain).
- `DEFAULT_CLEARANCE_KINDS` (const): const DEFAULT_CLEARANCE_KINDS: readonly string[] — Marker/volume kinds that repel scatter and flatten terrain by default (spawns, objectives, vendors).
- `DEFAULT_MARKER_CLEARANCE` (const): const DEFAULT_MARKER_CLEARANCE: 3.5 — Default clearance radius (m) for an auto-avoided gameplay marker with no explicit `meta.clearance`.
- `ResolveScatterOptions` (interface): interface ResolveScatterOptions extends ClearanceOptions — Extra inputs for {@link resolveScatter}: manual discs plus the auto-clearance toggle/scoping.
- `SCATTER_DEFAULTS` (const): const SCATTER_DEFAULTS: ScatterRegionRules — Defaults a bare scatter region fills with: sparse grass, lightly spaced.
- `SCATTER_PATH_KIND` (const): const SCATTER_PATH_KIND: "scatter" — The editor path kind that marks a closed polyline as a foliage/scatter region.
- `ScatterChunk` (interface): interface ScatterChunk — A spatial bucket of scatter instances — one draw unit the renderer can frustum-cull as a whole.
- `ScatterInstance` (interface): interface ScatterInstance — A single placed scatter instance — grounded world position plus per-instance variation.
- `ScatterPaletteEntry` (interface): interface ScatterPaletteEntry — One species/prop in a scatter region's palette, with a relative spawn weight.
- `ScatterRegion` (interface): interface ScatterRegion — A resolvable scatter region: a closed polygon footprint plus its fill rules.
- `ScatterRegionRules` (interface): interface ScatterRegionRules — How a scatter region fills its polygon: density, spacing, variation, and masking rules.
- `ScatterTerrain` (interface): interface ScatterTerrain — Ground sampler a scatter resolve reads height/normal from (the sculpt terrain or the game's ground).
- `clearanceZonesFrom` (function): function clearanceZonesFrom(doc: SceneDocumentLike, options: ClearanceOptions = {}): AvoidZone[] — Point-pad clearance **discs** from a document's markers/volumes — the terrain-flatten set (spawns, plots, POIs get a level pad). A marker/volume contributes a disc when it carries `meta.clearance` or its kind is in `kinds`. Paths are *not* included (they render draped, never flattened — see {@link clearanceMasksFrom} for their foliage corridor). Pass `ids`/`kinds` to scope it.
- `distanceToPolygonEdge` (function): function distanceToPolygonEdge(point: Vec2, polygon: readonly Vec2[]): number — Shortest distance from a point to a polygon's boundary.
- `isScatterPath` (function): function isScatterPath(path: ScenePathLike): boolean — True when an editor path is a foliage/scatter region.
- `pointInPolygon` (function): function pointInPolygon(point: Vec2, polygon: readonly Vec2[]): boolean — Ray-casting point-in-polygon test on the XZ plane.
- `polygonArea` (function): function polygonArea(polygon: readonly Vec2[]): number — Shoelace area of a polygon (always non-negative), in square meters.
- `polygonBounds` (function): function polygonBounds(polygon: readonly Vec2[]): Aabb | null — Axis-aligned bounds of a polygon, or null if it has no points.
- `readScatterPalette` (function): function readScatterPalette(meta: Record<string, unknown> | undefined): ScatterPaletteEntry[] — Parses a scatter region's palette from meta: a weighted `palette` array, else a single `item`.
- `readScatterRules` (function): function readScatterRules(path: ScenePathLike): ScatterRegionRules | null — The path's scatter rules with defaults filled in; null for non-scatter paths.
- `resolveScatter` (function): function resolveScatter(doc: SceneDocumentLike, terrain?: ScatterTerrain, options: ResolveScatterOptions = {}): ScatterInstance[] — Every scatter region's placements across a document, grounded on `terrain` when provided. Regions honor clearance masks: their own manual `avoid` discs, plus (when the region's `autoAvoid` is on and `options.autoAvoid !== false`) the document-wide discs + path corridors from {@link clearanceMasksFrom} — so foliage auto-clears spawns, plots, and paths without hand-carving the polygon.
- `resolveScatterRegion` (function): function resolveScatterRegion(region: ScatterRegion, terrain?: ScatterTerrain, avoid?: AvoidMasks): ScatterInstance[] — Deterministic placements for one scatter region: scatter its polygon footprint at `density` items/m² (respecting `minSpacing`), clip to the polygon, thin near the edge, drop placements outside the slope/height mask, and derive item/scale/yaw from the region id + seed — so the same saved region always grows the same field. Grounds each instance on `terrain` when provided.
- `scatterRegionEstimate` (function): function scatterRegionEstimate(path: ScenePathLike): { area: number; count: number } — Estimated placement count for a scatter path — density × polygon area, for a live UI readout.
- `scatterRegionFromPath` (function): function scatterRegionFromPath(path: ScenePathLike): ScatterRegion | null — Builds a resolvable {@link ScatterRegion} from a scatter path (XZ polygon + rules), or null.

## @jgengine/core/world/sceneShapes

- `SceneDocumentLike` (interface): interface SceneDocumentLike — The minimal document shape scatter/vegetation resolve against — markers, volumes, and paths only. Any `EditorDocument` satisfies it structurally; this module never imports the editor domain, so world stays the one-directional dependency editor already builds on.
- `SceneMarkerLike` (interface): interface SceneMarkerLike — The minimal point-object shape clearance reads from a document's markers; any `EditorMarker` satisfies it.
- `ScenePathLike` (interface): interface ScenePathLike — The minimal polyline shape {@link resolveScatterRegion} et al. read; any `EditorPath` satisfies it.
- `ScenePoint3` (interface): interface ScenePoint3 — A world-space point — structurally compatible with the editor's `EditorVec3`.
- `SceneVolumeLike` (interface): interface SceneVolumeLike — The minimal volume shape vegetation/clearance/triggers read; any `EditorVolume` satisfies it.

## @jgengine/core/world/segment

- `CircleSegmentHit` (interface): interface CircleSegmentHit — A resolved circle-vs-segment contact.
- `ClosestOnSegment` (interface): interface ClosestOnSegment — Closest point on segment `a`→`b` to `p`, and the clamped parameter `t` in [0,1] where it lies.
- `circleVsSegment` (function): function circleVsSegment(center: Vec2, radius: number, a: Vec2, b: Vec2, thickness = 0): CircleSegmentHit | null — Circle (center + `radius`) against a capsule segment `a`→`b` of half-thickness `thickness` (0 for a thin wall). Returns the contact — surface normal, penetration depth, contact point, and the separated center — or `null` when they do not overlap. Endpoints are rounded (the segment is a capsule), so a ball never catches on a corner. Reflect the velocity across `normal` for the bounce; the pure geometry every 2D ball game (pinball, breakout, air hockey) reimplemented per wall, bumper, and paddle.
- `closestPointOnSegment` (function): function closestPointOnSegment(p: Vec2, a: Vec2, b: Vec2): ClosestOnSegment — Closest point on the segment `a`→`b` to point `p`, with the clamped parameter `t` (0 at `a`, 1 at `b`).

## @jgengine/core/world/sharedAnnotations

- `ANNOTATION_FEED_ACTION` (const): const ANNOTATION_FEED_ACTION: "map.annotation" — Feed action shared drawings ride by default (pair with the party feed, like pings).
- `AnnotationBroadcast` (type): type AnnotationBroadcast = | { op: "stroke"; from: string; id: string; points: readonly WorldXZ[]; tone?: MapLayerTone; width?: number } | { op: "shape"; from: string; id: string; shape: MapZoneShape; tone?: MapLayerTone; label?: string } | { op: "note"; from: string; id: string; position: WorldXZ; … — A serializable map-annotation edit broadcast to other players.
- `AnnotationFeedSink` (interface): interface AnnotationFeedSink — The feed sink shared annotations push to — an alias of the ping/feed `push` seam.
- `SharedAnnotations` (interface): interface SharedAnnotations — Local annotation edits that also broadcast, plus `apply` for inbound edits. `add*`/`remove`/`clear` mirror {@link AnnotationLayer} but return globally-unique ids so two clients never collide.
- `SharedAnnotationsDeps` (interface): interface SharedAnnotationsDeps — Construction options for {@link createSharedAnnotations}.
- `createSharedAnnotations` (function): function createSharedAnnotations(deps: SharedAnnotationsDeps): SharedAnnotations — Make a map annotation layer collaborative: local `addStroke`/`addShape`/ `addNote`/`remove`/`clear` apply then broadcast a serializable edit over the party feed (the same seam `createPingSystem` uses), and `apply` mirrors inbound edits from other players — dropping our own echoes. Ids are globally unique per client so two players' strokes never collide. Transport-agnostic: wire `feed` to any replicated feed and route received entries into `apply`.

## @jgengine/core/world/soilKind

- `ResolvedSoil` (interface): interface ResolvedSoil — A resolved soil patch: world-space area center at ground height, footprint size (XZ), and rules.
- `SOIL_DEFAULTS` (const): const SOIL_DEFAULTS: SoilRules — Soil defaults: sun-cracked dirt with light moss creep.
- `SOIL_KIND` (const): const SOIL_KIND: "soil" — The editor volume kind marking a box as a soil crack/moss patch.
- `SOIL_SCHEMA` (const): const SOIL_SCHEMA: ParamSchema — The soil parameter schema — drives the inspector and `meta` parse via the studio seam.
- `SoilRules` (interface): interface SoilRules — Fully-defaulted soil params parsed from a volume's `meta`.

## @jgengine/core/world/spatialSample

- `AreaDistribution` (type): type AreaDistribution = "uniform" | "edge" — Fill policy for a rect/box: `"uniform"` = even coverage; `"edge"` = biased to a boundary band.
- `FallbackPolicy` (type): type FallbackPolicy<P extends SamplePoint = SamplePoint> = | "none" | "last-candidate" | { readonly point: P } — What to return when the attempt budget is exhausted. `"none"` yields no point (honest failure); `"last-candidate"` returns the final rejected draw (post-projection); `{ point }` returns a caller fixed fallback (a hand-placed safe spot). Explicit, so a caller never mistakes a fallback for a hit.
- `Point3` (type): type Point3 = readonly [number, number, number] — Deterministic spatial sampling — draw one or many positions from a geometric region under explicit constraints, with an injected RNG, bounded attempts, and a structured pass/fail result.
- `RadialDistribution` (type): type RadialDistribution = "area" | "radial" — Fill policy for a circle/ring: `"area"` = area-uniform (even density); `"radial"` = radius-uniform (clumps toward center).
- `SampleBatchOptions` (interface): interface SampleBatchOptions<P extends SamplePoint = SamplePoint> — Inputs for a {@link sampleBatch} draw of many spaced points.
- `SampleBatchResult` (interface): interface SampleBatchResult<P extends SamplePoint = SamplePoint> — Structured batch outcome: the placed points plus whether the full count was met.
- `SampleConstraints` (interface): interface SampleConstraints<P extends SamplePoint = SamplePoint> — Post-draw gates a candidate must clear. All are optional; an empty constraint set accepts every in-region draw. `exclude` discs/spheres are the keep-out distance primitive ("no closer than R to this center"); `accept` is a free-form caller predicate (biome, slope, ownership); `project` snaps a candidate onto a surface/navmesh before validation and may reject by returning `null`.
- `SamplePoint` (type): type SamplePoint = readonly number[] — A sampled point: 2D `[x, z]` or 3D `[x, y, z]`. Every point in one run shares its dimensionality.
- `SamplePointOptions` (interface): interface SamplePointOptions<P extends SamplePoint = SamplePoint> — Inputs for a single {@link samplePoint} draw.
- `SampleReason` (type): type SampleReason = "accepted" | "exhausted" | "empty-region" — Why a sample ended: a clean hit, budget exhausted, or the region was degenerate.
- `SampleRegion` (interface): interface SampleRegion<P extends SamplePoint = SamplePoint> — A geometric region a sampler can draw from. Built-ins cover point sets, rect/box, circle/sphere, annulus/shell, polygon, and weighted composites; {@link customRegion} wraps a caller-defined sampler + bounds. `sample` draws one raw candidate under the region's own distribution policy; `contains` is the membership test reused for include/exclude constraints and rejection.
- `SampleResult` (interface): interface SampleResult<P extends SamplePoint = SamplePoint> — Structured single-sample outcome — never a bare point, so failure and fallback are visible.
- `StratifiedOptions` (interface): interface StratifiedOptions — Inputs for {@link sampleStratified}: a grid over `area` with one jittered point per cell.
- `VolumeDistribution` (type): type VolumeDistribution = "volume" | "radial" — Fill policy for a sphere/shell: `"volume"` = volume-uniform (even density); `"radial"` = radius-uniform.
- `WeightedRegionEntry` (interface): interface WeightedRegionEntry<P extends SamplePoint = SamplePoint> — A weighted member of a {@link weightedRegion} composite.
- `annulusRegion` (function): function annulusRegion(center: Vec2, innerRadius: number, outerRadius: number, options: { distribution?: RadialDistribution } = {}): SampleRegion<Vec2> — A ring (annulus) between `innerRadius` and `outerRadius`. `"area"` fills the band with even density; `"radial"` spreads uniformly in radius. Angle first, then radius.
- `boxRegion` (function): function boxRegion(min: Point3, max: Point3): SampleRegion<Point3> — An axis-aligned box `[min..max]` in 3D. Uniform density; draws x, y, z in order.
- `customRegion` (function): function customRegion<P extends SamplePoint>(spec: { dimensions: 2 | 3; sample: (rng: () => number) => P; contains: (point: P) => boolean; isEmpty?: boolean; }): SampleRegion<P> — Wrap a caller-defined sampler and bounds test as a {@link SampleRegion} — the escape hatch for regions the built-ins do not cover (a navmesh cell, a heightfield mask, a spline tube).
- `discRegion` (function): function discRegion(center: Vec2, radius: number, options: { distribution?: RadialDistribution } = {}): SampleRegion<Vec2> — A filled circle. `"area"` is area-uniform (√-corrected radius, even density); `"radial"` is radius-uniform (clumps toward the center). Angle is drawn first, then radius — matching the common `angle = rng()·2π; r = rng()·R` idiom so migrations keep their stream.
- `pointSetRegion` (function): function pointSetRegion(points: readonly Vec2[], options: { weights?: readonly number[] } = {}): SampleRegion<Vec2> — A fixed set of candidate points sampled by (optionally weighted) selection — the "spawn point table" region. `contains` is exact membership. Empty when the set is empty.
- `polygonRegion` (function): function polygonRegion(polygon: readonly Vec2[]): SampleRegion<Vec2> — An arbitrary closed polygon on the XZ plane. Candidates are drawn uniformly from the polygon's bounding box and gated by point-in-polygon `contains`, so a run's draw count stays fixed (the sampler's attempt budget bounds the rejection, not a hidden inner loop).
- `rectRegion` (function): function rectRegion(area: Aabb, options: { distribution?: AreaDistribution; edgeThickness?: number } = {}): SampleRegion<Vec2> — An axis-aligned rectangle on the XZ plane. `"uniform"` spreads evenly (draws x then z); `"edge"` biases onto a boundary band of `edgeThickness` meters (perimeter-weighted side, then inward depth) — the two are never conflated, the caller opts in.
- `sampleBatch` (function): function sampleBatch<P extends SamplePoint>(options: SampleBatchOptions<P>): SampleBatchResult<P> — Place up to `count` points from `region`, each clearing the shared constraints and honoring `minSeparation` against every point already placed in this batch (via a spatial hash, not an O(n²) scan). Order is deterministic for a given `rng` stream. Batches never silently under-fill: the result reports `placed`, `complete`, and the total attempt count.
- `samplePoint` (function): function samplePoint<P extends SamplePoint>(options: SamplePointOptions<P>): SampleResult<P> — Draw one point from `region` that clears every constraint, retrying up to `maxAttempts` times with the injected `rng`, then apply the `fallback` policy. Returns a structured {@link SampleResult} — a clean hit is `ok: true`; exhaustion or a degenerate region is reported with the attempt count and an explicit fallback flag, never a silently-accepted bad point.
- `sampleStratified` (function): function sampleStratified(options: StratifiedOptions): Vec2[] — Stratified 2D sampling: one jittered point per grid cell over `area`, in deterministic row-major order. Unlike pure rejection sampling this guarantees even coverage (no clumps, no gaps) — the distinct "stratified" distribution policy, kept separate from area-uniform draws.
- `shellRegion` (function): function shellRegion(center: Point3, innerRadius: number, outerRadius: number, options: { distribution?: VolumeDistribution } = {}): SampleRegion<Point3> — A spherical shell between `innerRadius` and `outerRadius`. `"volume"` fills the shell with even density; `"radial"` spreads uniformly in radius. Direction first, then radius.
- `sphereRegion` (function): function sphereRegion(center: Point3, radius: number, options: { distribution?: VolumeDistribution } = {}): SampleRegion<Point3> — A filled ball. `"volume"` is volume-uniform (∛-corrected radius); `"radial"` is radius-uniform. Direction is drawn first (two draws), then radius.
- `weightedRegion` (function): function weightedRegion<P extends SamplePoint>(entries: readonly WeightedRegionEntry<P>[]): SampleRegion<P> — A composite that first picks one member by weight, then delegates to its sampler — the "weighted subregions" distribution policy. `contains` is true when any member contains the point.

## @jgengine/core/world/spawnOverride

- `SpawnOverride` (interface): interface SpawnOverride — Per-session player-spawn override — a capture-harness ergonomics seam that lets a single screenshot or drive run place the player somewhere other than the authored `player_spawn` marker *without mutating `editor.scene.json`*. The runner installs one from the `?spawn=` URL overlay (mirroring `?cam=`); {@link authoredSpawnPosition} consults it for the default player-spawn resolution only, so authored content is untouched and the override evaporates the moment the page reloads without the param.
- `clearSpawnOverride` (function): function clearSpawnOverride(): void — Clear any installed player-spawn override.
- `installSpawnOverride` (function): function installSpawnOverride(override: SpawnOverride | null): void — Install (or, with `null`, clear) the active player-spawn override. Idempotent; last write wins.
- `parseSpawnOverride` (function): function parseSpawnOverride(raw: string | null | undefined): SpawnOverride | null — Parse a `?spawn=` / `--spawn` value into a {@link SpawnOverride}, or `null` when it is absent or malformed. Accepts `"x,y,z"` and `"x,y,z,yaw"` (yaw in radians); whitespace around components is tolerated. A non-finite or short tuple yields `null` so a typo never silently teleports the player to `NaN`.
- `readSpawnOverride` (function): function readSpawnOverride(): SpawnOverride | null — The currently installed player-spawn override, or `null` when none is active.

## @jgengine/core/world/streetGenerator

- `Street` (interface): interface Street — One chained through-street: a maximal run of edges through degree-2 nodes, for rendering + furniture.
- `StreetDeadEnd` (interface): interface StreetDeadEnd — One dangling street end kept as a cul-de-sac: node position plus the heading pointing off the road.
- `StreetEdge` (interface): interface StreetEdge — One atomic node-to-node edge — the fabric graph consumes these (welds at shared node coords).
- `StreetFeature` (interface): interface StreetFeature — A resolved path feature in world-of-the-volume space: a bridge deck or tunnel bore centerline.
- `StreetFeatureKind` (type): type StreetFeatureKind = "bridge" | "tunnel" — A path feature spanning part of an edge/street: a bridge deck over a gap or a tunnel bore under a ridge.
- `StreetFeatureSpan` (interface): interface StreetFeatureSpan — A feature span carried by a street: a `[from, to]` index window into the street's `points`.
- `StreetJunction` (interface): interface StreetJunction — One crossing of three or more streets: patch center/radius plus outgoing arm directions.
- `StreetLevel` (type): type StreetLevel = "boulevard" | "avenue" | "street" | "lane" — Road hierarchy, widest to narrowest — shared by the city fabric and the renderer.
- `StreetNetwork` (interface): interface StreetNetwork — The fully-resolved network in volume-local coords.
- `StreetNetworkContext` (interface): interface StreetNetworkContext — Ground sampler + feature toggles enabling bridges/tunnels; omit for a flat, feature-free network.
- `StreetNetworkMode` (type): type StreetNetworkMode = "net" | "circuit" — The generator's chosen topology family: an open street `net`, or a closed `circuit` loop.
- `StreetNetworkRules` (interface): interface StreetNetworkRules — Fully-defaulted slider set the generator reads.
- `StreetNode` (interface): interface StreetNode — One graph node: a junction, a dead end, or a mid-street bend, with its connection count.
- `StreetSidewalks` (interface): interface StreetSidewalks — Left/right pedestrian bands flanking a street's asphalt, as offset polylines.
- `StreetVec2` (type): type StreetVec2 = readonly [number, number] — A path vertex in the volume-local XZ frame.
- `generateStreets` (function): function generateStreets(rules: StreetNetworkRules, hx: number, hz: number, context: StreetNetworkContext = {}): StreetNetwork — Resolve a full path network from its rules inside a volume of half-extents `hx`×`hz`. Deterministic per `(rules.seed, hx, hz, context)`. Pass a {@link StreetNetworkContext} with a ground sampler to turn water gaps into bridges and ridges into tunnels. Coordinates are volume-local; the caller maps to world space.

## @jgengine/core/world/streets

- `FurnitureSpot` (interface): interface FurnitureSpot — A placement anchor on the curb line: position, outward-facing heading, and which side it sits on.
- `FurnitureSpotOptions` (interface): interface FurnitureSpotOptions — Options for {@link furnitureSpots}.
- `JunctionMarkingOptions` (interface): interface JunctionMarkingOptions — Options for {@link junctionMarkings}.
- `JunctionMarkings` (interface): interface JunctionMarkings — Thin marking polylines for a junction: stop-line bars and crosswalk bars, ready for {@link buildRoadRibbon}.
- `ParkingSpot` (interface): interface ParkingSpot — A curbside parking anchor: position at the road edge and a heading parallel to the street.
- `ParkingSpotOptions` (interface): interface ParkingSpotOptions — Options for {@link parkingSpots}.
- `RoadApproach` (interface): interface RoadApproach — A single arm of a junction: the road width plus the outward direction the road leaves the center.
- `RoadJunction` (interface): interface RoadJunction — A welded road intersection: a patch center/radius plus the arms that feed it.
- `RoadJunctionOptions` (interface): interface RoadJunctionOptions — Options for {@link findRoadJunctions}.
- `RoadSurfaceOptions` (interface): interface RoadSurfaceOptions — Grip levels and blend width for {@link roadSurfaceSampler}; each field is optional and defaulted.
- `StreetLane` (interface): interface StreetLane — A directed lane derived from a road: an offset centerline plus its direction of travel.
- `curbPaths` (function): function curbPaths(road: RoadEnvironmentDescriptor, inset = 0): readonly [readonly RoadPoint[], readonly RoadPoint[]] — The two curb lines of a road — offset polylines running along the outer edge of the asphalt on each side. Mesh these with a thin darker ribbon to give the road a curb/edge strip instead of a hard asphalt-to-terrain seam. `inset` (default 0) nudges the line inward off the raw edge so the strip straddles the border.
- `distanceToRoadEdge` (function): function distanceToRoadEdge(roads: readonly RoadEnvironmentDescriptor[], x: number, z: number): number — Signed planar distance from `(x, z)` to the nearest road *surface edge* across every segment of every road (#1051): negative inside the asphalt (magnitude = how far in from the closest edge, so `-width/2` on the centerline), `~0` right at the curb, and positive off the road (the gap to the nearest edge). Point-to-segment distance minus the road's half width, minimised over all segments — the "am I on the road, and by how much" seam driving grip, tyre audio, and off-road penalties.
- `findRoadJunctions` (function): function findRoadJunctions(roads: readonly RoadEnvironmentDescriptor[], options: RoadJunctionOptions = {}): readonly RoadJunction[] — Detect welded intersections across a set of roads: wherever two road centerlines cross (or a road terminates on another) within the same elevation band, emit a {@link RoadJunction} whose patch covers the crossing ribbons. Nearby crossings merge into one junction. Deterministic and bounded — O(roads² · segments²) with a `maxJunctions` cap — so a scene builds its intersections once.
- `furnitureSpots` (function): function furnitureSpots(road: RoadEnvironmentDescriptor, options: FurnitureSpotOptions = {}): readonly FurnitureSpot[] — Evenly spaced street-furniture anchors along a road's curb lines — streetlights, palms, signs, hydrants, benches. Each spot sits just outside the asphalt (plus `outset`), faces away from the street, and alternates sides by default so lights stagger like a real avenue. This is the answer to "where do I put it": furniture is an asset of the street, never a hand-typed coordinate.
- `junctionExclusions` (function): function junctionExclusions(junctions: readonly RoadJunction[], pad = 0.5): readonly DashExclusion[] — Circular marking-exclusion zones for the junctions, sized to hide the center line under each patch.
- `junctionMarkings` (function): function junctionMarkings(junction: RoadJunction, options: JunctionMarkingOptions = {}): JunctionMarkings — Data-driven junction entry markings: a stop-line bar across each approach and a band of crosswalk bars just outside the welded patch. Each returned polyline is a thin centerline meant to be meshed with {@link buildRoadRibbon} at a small width. Fully skippable per-feature via the options.
- `laneCenters` (function): function laneCenters(road: RoadEnvironmentDescriptor): readonly [StreetLane, StreetLane] — Two right-hand-traffic lane centerlines for a road — each offset a quarter of the drivable width from the center and ordered in its direction of travel. Feed a lane's `path` straight into `nav/pathFollow` for traffic AI, or use its endpoints as directed car spawn points.
- `offsetPath` (function): function offsetPath(path: readonly RoadPoint[], offset: number): readonly RoadPoint[] — Offset a centerline sideways by a signed distance along its local perpendicular — the building block for lanes, curb lines, and sidewalk paths. Positive offsets fall on the left of the direction of travel, negative on the right.
- `parkingSpots` (function): function parkingSpots(road: RoadEnvironmentDescriptor, options: ParkingSpotOptions = {}): readonly ParkingSpot[] — Curbside parking anchors along a road: hugging the edge of the asphalt, headed parallel to the street in that side's direction of travel. Spawn parked vehicles here instead of eyeballing coordinates in the middle of the carriageway.
- `roadSurfaceSampler` (function): function roadSurfaceSampler(roads: readonly RoadEnvironmentDescriptor[], options: RoadSurfaceOptions = {}): (x: number, z: number) => number — A `surfaceFriction`-compatible sampler (the `(x, z) => grip` hook a kinematic car reads each tick) that turns road geometry into grip (#1051): full `onRoad` grip on the asphalt, a monotonic linear ramp down across a `shoulder`-wide band at the curb, and flat `offRoad` grip beyond it — so a car that clips onto the grass loses bite progressively instead of snapping. Closes over {@link distanceToRoadEdge}, so the returned sampler is itself allocation-free per call.
- `sidewalkPaths` (function): function sidewalkPaths(road: RoadEnvironmentDescriptor): readonly (readonly RoadPoint[])[] — The two sidewalk walking paths of a road — offset polylines running down the middle of each sidewalk band. Pedestrians spawn and route along these instead of the asphalt.
- `sidewalkPoint` (function): function sidewalkPoint(road: RoadEnvironmentDescriptor, side: "left" | "right", fraction: number): RoadPoint | null — A deterministic point on one of a road's sidewalks at a normalized position — `side` picks the band, `fraction` (0..1) picks how far along. The canonical pedestrian spawn helper.
- `sidewalkWidthOf` (function): function sidewalkWidthOf(road: RoadEnvironmentDescriptor): number — Resolved sidewalk band widths for a road; zero when the road declares no sidewalk.

## @jgengine/core/world/support

- `DebrisOptions` (interface): interface DebrisOptions { scatter?: number; seed?: number } — ⚠ undocumented
- `SupportConfig` (interface): interface SupportConfig { maxDistance?: number } — ⚠ undocumented
- `SupportLink` (interface): interface SupportLink { a: string; b: string } — ⚠ undocumented
- `SupportPiece` (interface): interface SupportPiece { id: string; grounded?: boolean; position?: ConnectorVec3; halfExtents?: ConnectorVec3; mass?: number } — ⚠ undocumented
- `SupportResult` (interface): interface SupportResult { supported: readonly string[]; unsupported: readonly string[]; distance: Readonly<Record<string, number>> } — ⚠ undocumented
- `solveSupport` (function): function solveSupport(pieces: readonly SupportPiece[], links: readonly SupportLink[], config: SupportConfig = {}): SupportResult — ⚠ undocumented
- `toDebrisBodies` (function): function toDebrisBodies(pieces: readonly SupportPiece[], collapsedIds: readonly string[], options: DebrisOptions = {}): AddBodyOptions[] — ⚠ undocumented

## @jgengine/core/world/terraform

- `BlendStroke` (interface): interface BlendStroke — Accumulates a whole blend-paint drag into one compact {@link WeightDelta}. Keeps each weight slot's first `before` and latest `after`, so undo replays the blend as a single step.
- `EditableTerrain` (interface): interface EditableTerrain extends TerrainField { readonly cols: number; readonly rows: number; readonly cellSize: number; readonly gridBounds: Aabb; apply(edit: TerraformEdit): number; applyRecording(edit: TerraformEdit, record: TerraformDeltaRecorder): number; editDelta(edit: Terraform… — ⚠ undocumented · used by `beginSurfaceStroke`: Opens a paint-stroke recorder over `terrain`; stamp paint edits into it, then read one net delta.
- `EditableTerrainConfig` (interface): interface EditableTerrainConfig { bounds: Aabb; base?: TerrainField; cellSize?: number } — ⚠ undocumented · used by `createTerrainSnapshot`: A fresh, unedited terrain snapshot sized to `bounds`/`cellSize` — the seed for a new sculpt document.
- `SurfaceDelta` (interface): interface SurfaceDelta — A compact record of the surface-material cells a paint stroke touched: parallel `indices`/`before`/`after` arrays into the per-cell surface grid. One per stroke keeps paint undo history small.
- `SurfaceDeltaRecorder` (type): type SurfaceDeltaRecorder = (index: number, before: string | null, after: string | null) => void — Reports each changed cell during a recorded paint: grid index, prior surface id, new surface id.
- `SurfaceStroke` (interface): interface SurfaceStroke — Accumulates a whole paint drag — many surface stamps — into one compact {@link SurfaceDelta}. Keeps each cell's first `before` and latest `after`, so undo replays the paint as a single step.
- `TerraformBrush` (interface): interface TerraformBrush { raise(center: Vec2): number; lower(center: Vec2): number; flatten(center: Vec2, target?: number): number; paint(center: Vec2, surface?: string): number; setRadius(radius: number): void; setStrength(strength: number): void; config(): Requi… — ⚠ undocumented
- `TerraformBrushConfig` (interface): interface TerraformBrushConfig { radius?: number; strength?: number; falloff?: TerraformFalloff; surface?: string } — ⚠ undocumented
- `TerraformBrushState` (interface): interface TerraformBrushState — Plain JSON state of a {@link TerraformBrush}.
- `TerraformDelta` (interface): interface TerraformDelta — A compact record of the vertices a sculpt stroke touched: parallel `indices`/`before`/`after` arrays into the offset grid. Storing one of these per stroke keeps undo history small — the whole terrain document is never copied.
- `TerraformDeltaRecorder` (type): type TerraformDeltaRecorder = (index: number, before: number, after: number) => void — Reports each changed vertex during a recorded edit: grid index, prior offset, new offset.
- `TerraformEdit` (interface): interface TerraformEdit — A single sculpt stamp: which brush, where, and its shaping parameters.
- `TerraformFalloff` (type): type TerraformFalloff = "smooth" | "linear" | "none" — How a brush's strength fades from its center to its rim.
- `TerraformHeightLimit` (interface): interface TerraformHeightLimit — Clamp bounds applied to the resulting terrain height after a heightfield edit.
- `TerraformMode` (type): type TerraformMode = "raise" | "lower" | "smooth" | "flatten" | "noise" | "ramp" | "paint" — A sculpt operation kind: heightfield brushes plus the surface-paint brush.
- `TerraformShape` (type): type TerraformShape = "circle" | "square" — A brush footprint: a round disc or an axis-aligned square.
- `TerraformSnapshot` (interface): interface TerraformSnapshot { bounds: Aabb; cellSize: number; cols: number; rows: number; offsets: readonly number[]; surfaces: readonly (string | null)[]; layers?: readonly TerrainMaterialLayer[]; weights?: readonly number[] } — ⚠ undocumented · used by `applyDeltaToSnapshot`: Returns a new snapshot with a delta's `after` offsets applied (copy-on-write — inputs untouched).
- `TerraformStroke` (interface): interface TerraformStroke — Accumulates a whole drag — many brush stamps — into one compact {@link TerraformDelta}. Keeps each vertex's first `before` and latest `after`, so undo replays the stroke as a single step even though the pointer fired dozens of moves.
- `TerrainMaterialLayer` (interface): interface TerrainMaterialLayer — One material layer in a terrain's reorderable stack: a palette `surface` id (drives the base color) plus its render parameters. Array order is the stack order — lower index paints under higher. `roughness`/`tiling`/`triplanar`/`tint`/`opacity` are carried as data so a runtime game reads them straight off the snapshot.
- `TerrainSurfaceRule` (interface): interface TerrainSurfaceRule — A height/slope predicate for auto-painting a surface layer (e.g. rock on steep slopes, snow up high).
- `WeightDelta` (interface): interface WeightDelta — A compact record of the blend weights a blend-paint stroke touched: parallel `indices`/`before`/ `after` arrays into the flat `weights` grid (`cell*layerCount + layer`). `layerCount` guards the delta against being replayed after the layer stack changed shape.
- `WeightDeltaRecorder` (type): type WeightDeltaRecorder = (index: number, before: number, after: number) => void — Reports each changed weight slot during a recorded blend: flat index, prior weight, new weight.
- `applyDeltaToSnapshot` (function): function applyDeltaToSnapshot(snapshot: TerraformSnapshot, delta: TerraformDelta): TerraformSnapshot — Returns a new snapshot with a delta's `after` offsets applied (copy-on-write — inputs untouched).
- `applySurfaceDeltaToSnapshot` (function): function applySurfaceDeltaToSnapshot(snapshot: TerraformSnapshot, delta: SurfaceDelta): TerraformSnapshot — Returns a new snapshot with a surface delta's `after` ids applied (copy-on-write).
- `beginSurfaceStroke` (function): function beginSurfaceStroke(terrain: Pick<EditableTerrain, "paintRecording">): SurfaceStroke — Opens a paint-stroke recorder over `terrain`; stamp paint edits into it, then read one net delta.
- `beginTerraformStroke` (function): function beginTerraformStroke(terrain: Pick<EditableTerrain, "applyRecording">): TerraformStroke — Opens a stroke recorder over `terrain`; stamp edits into it, then read one net delta.
- `brushWeight` (function): function brushWeight(distance: number, radius: number, falloff: TerraformFalloff): number — Smooth/linear/hard brush weight for a sample `distance` from the brush center.
- `createEditableTerrain` (function): function createEditableTerrain(config: EditableTerrainConfig): EditableTerrain — ⚠ undocumented
- `createTerraformBrush` (function): function createTerraformBrush(terrain: Pick<EditableTerrain, "apply">, config: TerraformBrushConfig = {}): TerraformBrush — ⚠ undocumented
- `createTerrainSnapshot` (function): function createTerrainSnapshot(config: EditableTerrainConfig): TerraformSnapshot — A fresh, unedited terrain snapshot sized to `bounds`/`cellSize` — the seed for a new sculpt document.
- `editableTerrainFromSnapshot` (function): function editableTerrainFromSnapshot(snapshot: TerraformSnapshot, base?: TerrainField): EditableTerrain — Rebuilds a live {@link EditableTerrain} from a snapshot, layered over `base` ground.
- `migrateTerrainSnapshot` (function): function migrateTerrainSnapshot(snapshot: TerraformSnapshot): TerraformSnapshot — Upgrades a pre-2.0 snapshot in place-safe (copy-on-write) form: derives a {@link TerrainMaterialLayer} stack from the distinct painted surfaces (first-seen order, default params) when none exists. Leaves the lazy `weights` buffer absent — a single-layer terrain stays compact until blended. Idempotent: a snapshot that already carries `layers` is returned unchanged.
- `revertDeltaFromSnapshot` (function): function revertDeltaFromSnapshot(snapshot: TerraformSnapshot, delta: TerraformDelta): TerraformSnapshot — Returns a new snapshot with a delta's `before` offsets restored (copy-on-write undo).
- `revertSurfaceDeltaFromSnapshot` (function): function revertSurfaceDeltaFromSnapshot(snapshot: TerraformSnapshot, delta: SurfaceDelta): TerraformSnapshot — Returns a new snapshot with a surface delta's `before` ids restored (copy-on-write undo).

## @jgengine/core/world/terrain

- `ARENA_WATER_LEVEL` (const): const ARENA_WATER_LEVEL: -0.9 — ⚠ undocumented
- `ArenaFieldConfig` (interface): interface ArenaFieldConfig { seed?: string | number; bounds?: WorldBounds } — ⚠ undocumented
- `BiomeFogValue` (interface): interface BiomeFogValue — A concrete fog look — the shape `createBiomeFogSampler` resolves per z from a band's `fog` over the base fog.
- `BiomeSkyValue` (interface): interface BiomeSkyValue — A concrete sky look — the shape `createBiomeSkySampler` resolves per z from a band's `sky` over the base sky.
- `DEFAULT_MAX_WALK_SLOPE` (const): const DEFAULT_MAX_WALK_SLOPE: 0.6 — ⚠ undocumented
- `DEFAULT_TERRAIN_MATERIAL` (const): const DEFAULT_TERRAIN_MATERIAL: TerrainMaterial — ⚠ undocumented
- `FLAT_FIELD` (const): const FLAT_FIELD: TerrainField — ⚠ undocumented
- `FractalNoiseConfig` (interface): interface FractalNoiseConfig — Octave settings for {@link fractalNoise}: frequency, layering, and optional ridged shaping.
- `GroundSnapEntityStore` (interface): interface GroundSnapEntityStore { get(id: string): GroundSnapTarget | null; setPose(id: string, pose: {position?: readonly [number, number, number]}): boolean } — ⚠ undocumented
- `GroundSnapTarget` (interface): interface GroundSnapTarget { position: readonly [number, number, number] } — ⚠ undocumented
- `HeightFieldRayBounds` (interface): interface HeightFieldRayBounds — XZ region a {@link raycastHeightField} march is clipped to.
- `HeightFieldRayHit` (interface): interface HeightFieldRayHit — Where a {@link raycastHeightField} march crossed the surface.
- `HeightFieldRaycastOptions` (interface): interface HeightFieldRaycastOptions — Tuning for {@link raycastHeightField}: march resolution and refinement depth.
- `HeightMapFieldConfig` (interface): interface HeightMapFieldConfig { columns: number; rows: number; samples: ArrayLike<number>; bounds?: WorldBounds; heightScale?: number; baseHeight?: number; waterLevel?: number } — ⚠ undocumented
- `ISLAND_VOID_HEIGHT` (const): const ISLAND_VOID_HEIGHT: -256 — Ground height between islands when no base terrain exists — deep enough to read as a fall into the void, finite so physics stays sane.
- `NoiseFieldConfig` (interface): interface NoiseFieldConfig — Configuration for {@link noiseField}: seed, amplitude, and fractal noise shaping.
- `ResolvedTerrainDetail` (type): type ResolvedTerrainDetail = Required<Omit<TerrainDetailConfig, "waterLevel" | "material" | "sweeps">> & { waterLevel: number; material?: ResolvedTerrainDetailMaterial; sweeps: { dry: readonly [number, number, number]; wet: readonly [number, number, number] }; } — A {@link TerrainDetailConfig} with every field resolved to a concrete value — the shape the shell's detail material consumes.
- `ResolvedTerrainDetailMaterial` (interface): interface ResolvedTerrainDetailMaterial — A resolved {@link TerrainDetailMaterialConfig} — `repeat`/`strength` filled with defaults, `maps` passed through.
- `RollingFieldConfig` (interface): interface RollingFieldConfig { seed?: string | number; amplitude?: number; frequency?: number; bounds?: WorldBounds } — ⚠ undocumented
- `TERRAIN_MATERIAL_PALETTES` (const): const TERRAIN_MATERIAL_PALETTES: Record<TerrainMaterial, TerrainPalette> — ⚠ undocumented
- `TerrainField` (interface): interface TerrainField — A sampleable ground surface: height and normal at any x/z, with optional bounds and water level.
- `TerrainNormal` (type): type TerrainNormal = readonly [number, number, number] — A surface normal vector at a terrain sample point.
- `TerrainPalette` (interface): interface TerrainPalette { low: string; high: string; waterline: string } — ⚠ undocumented
- `TerrainSlopeSample` (interface): interface TerrainSlopeSample { downhill: readonly [number, number]; steepness: number } — ⚠ undocumented
- `applyPathProfiles` (function): function applyPathProfiles(field: TerrainField, profiles: readonly TerrainPathProfile[]): TerrainField — Composes authored path profiles onto a field — the shared seam that turns a scene road/river/ramp path into flattened, graded, carved, or retained ground. Applies after `flatten` masks in `resolveTerrainField` so a corridor grades over already-leveled pads; call it directly to layer profiles onto any field a game builds by hand. Returns the field unchanged when no profile is given.
- `raycastHeightField` (function): function raycastHeightField(sampleHeight: (x: number, z: number) => number, origin: readonly [number, number, number], direction: readonly [number, number, number], options: HeightFieldRaycastOptions): HeightFieldRayHit | null — Intersects a ray with a `sampleHeight` field by fixed-step raymarching plus bisection — the O(steps) editor/gameplay picking seam that replaces brute-force triangle raycasts against a tessellated ground mesh (tens of thousands of triangle tests per pick on a sculpt-sized grid). The ray is clipped to `bounds` on XZ first, marched at `step`, and the first above→below crossing is bisected. An origin already under the surface hits immediately at entry. Returns null when the clipped ray never crosses the surface.

## @jgengine/core/world/terrainGuides

- `ContourLine` (interface): interface ContourLine — A single iso-elevation contour traced across a region as a flat list of XZ line segments.
- `ContourOptions` (interface): interface ContourOptions — Shaping for {@link extractContours}: region, vertical spacing, emphasis cadence, and sample budget.
- `DrapeOptions` (interface): interface DrapeOptions — Shaping for surface draping: subdivision spacing and a lift to keep the line off the ground.
- `ElevationReadout` (interface): interface ElevationReadout — Measurable elevation readout at a single world point — the cursor/hover feedback value.
- `ElevationSummary` (interface): interface ElevationSummary — Aggregate elevation statistics over a region — the selection min/max/mean and legend range.
- `GroundPoint` (type): type GroundPoint = readonly [number, number] — A world-space point on the ground plane as an `[x, z]` pair.
- `GuideRegion` (interface): interface GuideRegion — An axis-aligned XZ rectangle to generate terrain-readability guides within.
- `HeightSampler` (type): type HeightSampler = (x: number, z: number) => number — A height sampler over the ground: world elevation at any `x`/`z`.
- `SurfaceGridLine` (interface): interface SurfaceGridLine — One draped grid line from {@link surfaceGridLines}: its axis, emphasis, and draped vertices.
- `SurfaceGridOptions` (interface): interface SurfaceGridOptions — Shaping for {@link surfaceGridLines}: region, spacing, emphasis cadence, and draping.
- `chooseContourInterval` (function): function chooseContourInterval(range: number, targetLines = 12): number — Picks a human-friendly contour interval — a `1/2/2.5/5 × 10ⁿ` step — so an elevation `range` splits into roughly `targetLines` bands. Drives adaptive contour density: a tall terrain gets a coarse interval, a shallow one a fine interval, without the author choosing a number. Returns `0` when the range is non-positive (nothing to contour).
- `drapePolyline` (function): function drapePolyline(sampleHeight: HeightSampler, points: readonly GroundPoint[], options: DrapeOptions = {}): number[] — Drapes an XZ polyline onto the surface: subdivides each span to at most `spacing` and lifts every vertex to `sampleHeight + offset`, returning flat `[x, y, z, ...]` world triples. The reusable seam behind surface-following placement guides and grid lines — a straight guide bends to follow terrain.
- `extractContours` (function): function extractContours(sampleHeight: HeightSampler, options: ContourOptions): ContourLine[] — Traces surface-following contour lines from a height field via marching squares: samples a bounded grid over the region, then for every multiple of `interval` strictly inside the sampled height range emits the iso-line as XZ segments (saddle cells disambiguated by the cell-center average). Because a contour is exact constant elevation, drawing each segment at `y = level` makes it hug the terrain — the readable, scale-bearing overlay a flat ground grid cannot give. Pure math, renderer-agnostic.
- `sampleElevation` (function): function sampleElevation(sampleHeight: HeightSampler, x: number, z: number, reference = 0): ElevationReadout — Reads the ground elevation under a world point and its signed delta from a reference plane — the measurable cursor/hover feedback ("+3.4 above the pad") an author needs to judge sculpted height.
- `summarizeElevation` (function): function summarizeElevation(sampleHeight: HeightSampler, region: GuideRegion, resolution = 64, maxSamples = 256): ElevationSummary — Summarises elevation across a region on a bounded sample grid: min, max, mean, relief range, and the world points of the extremes — the selection min/max and legend feedback the readability overlay reports, and the input to {@link chooseContourInterval}. Pure math, renderer-agnostic.
- `surfaceGridLines` (function): function surfaceGridLines(sampleHeight: HeightSampler, options: SurfaceGridOptions): SurfaceGridLine[] — Builds a surface-following major/minor grid over a region: constant-`x` and constant-`z` lines at `spacing`, each draped onto the terrain so the reference grid climbs sculpted surfaces instead of being occluded by them (the flat `y = 0` grid's core failure). Draping subdivides to `drape.spacing`. Pure math, renderer-agnostic.
- `surfaceRing` (function): function surfaceRing(sampleHeight: HeightSampler, center: GroundPoint, radius: number, segments = 48, options: DrapeOptions = {}): number[] — A closed circle draped on the surface — the surface-following placement guide ring under a cursor or a selected object. Returns flat `[x, y, z, ...]` world triples forming a loop (last vertex repeats the first). `segments` sets the smoothness of the ring.
- `terrainContourGuides` (function): function terrainContourGuides(field: Pick<TerrainField, "sampleHeight">, region: GuideRegion, targetLines = 12, resolution = 128): { interval: number; summary: ElevationSummary; contours: ContourLine[] } — Convenience over {@link extractContours} that auto-picks the interval from the field's own relief: summarises the region, chooses a readable interval for `targetLines` bands, and traces the contours — the one call the editor overlay makes to turn a `TerrainField` into ready-to-draw guides. Returns an empty list for flat ground.

## @jgengine/core/world/territory

- `Territory` (type): type Territory = ReturnType<typeof createTerritory> — Snapshot-backed claim, release, owner and starter-grant operations.
- `TerritoryCell` (type): type TerritoryCell = { x: number; z: number } — Integer cell coordinates used for ownership on the ground plane.
- `TerritoryPlan` (type): type TerritoryPlan = { ok: true; cells: TerritoryCell[]; cost: number } | { ok: false; reason: "territory.blocked" | "territory.unaffordable" } — Read-only footprint quote or a blocked/insufficient-balance rejection.
- `TerritoryPolicy` (type): type TerritoryPolicy = { gapCells?: number; cellSize?: number; chunkSize?: number; currency?: string; price?: (ownedCount: number) => number; starterBlock?: number; nowMs?: number; } — Cell size, foreign-owner gap, growth price, currency and starter-grant policy.
- `TerritoryResult` (type): type TerritoryResult = { ok: true; snapshot: GameRuntimeSnapshot; cost: number } | { ok: false; reason: "territory.blocked" | "territory.unaffordable" } — Atomic claim outcome with the replacement snapshot and total charge.
- `TerritoryStorage` (interface): interface TerritoryStorage — Host-owned snapshot access used by the territory facade.
- `claimTerritory` (function): function claimTerritory(snapshot: GameRuntimeSnapshot, userId: string, cells: readonly TerritoryCell[], policy: TerritoryPolicy = {}): TerritoryResult — Atomically buy every unowned footprint cell, leaving the input untouched on failure.
- `createTerritory` (function): function createTerritory(storage: TerritoryStorage, policy: () => TerritoryPolicy = () => ({})): { snapshot: () => GameRuntimeSnapshot; restore: (snapshot: GameRuntimeSnapshot) => void; ownerOf: (cell: TerritoryCell) => string | null; canUse: (userId: string, cell: TerritoryCell) => boolean; claim(u… — Snapshot-backed territory facade with host-owned storage and live policy.
- `placeWithTerritory` (function): function placeWithTerritory(snapshot: GameRuntimeSnapshot, userId: string, bounds: Aabb, policy: TerritoryPolicy, place: (snapshot: GameRuntimeSnapshot) => { ok: true; snapshot: GameRuntimeSnapshot } | { ok: false; reason: string }): { ok: true; snapshot: GameRuntimeSnapshot; cost: number } | { ok: … — Placement transaction: rejected object placement also rolls back territory and its charge.
- `planFootprintClaims` (function): function planFootprintClaims(snapshot: GameRuntimeSnapshot, userId: string, footprint: readonly TerritoryCell[], policy: TerritoryPolicy = {}): TerritoryPlan — Price and validate a footprint without mutating or charging; reuse for placement previews.
- `territoryChunkKey` (function): function territoryChunkKey(cell: TerritoryCell, policy: TerritoryPolicy = {}): string — Persisted chunk key containing one territory cell.
- `territoryChunkKeys` (function): function territoryChunkKeys(cells: readonly TerritoryCell[], policy: TerritoryPolicy = {}): string[] — Exact chunks needed to validate a footprint and its foreign-owner gap.
- `territoryFootprintCells` (function): function territoryFootprintCells(bounds: Aabb, cellSize = 1): TerritoryCell[] — Cells touched by a placement, excluding cells that only touch its outer edge.
- `territoryOwnerOf` (function): function territoryOwnerOf(snapshot: GameRuntimeSnapshot, cell: TerritoryCell, policy: TerritoryPolicy = {}): string | null — Owner of a loaded cell; hosts load the target and gap neighborhood before evaluating claims.

## @jgengine/core/world/vegetation

- `VEGETATION_DEFAULTS` (const): const VEGETATION_DEFAULTS: VegetationSettings — Defaults a bare `kind: "vegetation"` volume grows with: grass at 4 blades/m².
- `VEGETATION_VOLUME_KIND` (const): const VEGETATION_VOLUME_KIND: "vegetation" — The editor volume kind that marks an area as vegetation fill.
- `VegetationPlacement` (interface): interface VegetationPlacement — One placed vegetation instance — position on the ground plane plus per-instance variation.
- `VegetationSettings` (interface): interface VegetationSettings — How a vegetation volume fills its area, read from the volume's `meta`. `density` is items per square meter — the one slider number: grass blades, trees, bushes, rocks all scale with it. Every field has a default, so a freshly placed `kind: "vegetation"` volume already grows grass.

## @jgengine/core/world/visibilityField

- `VISIBILITY_HIDDEN` (const): const VISIBILITY_HIDDEN: 0 — Numeric code for a cell no group member has seen, or has fully forgotten.
- `VISIBILITY_OBSERVED` (const): const VISIBILITY_OBSERVED: 2 — Numeric code for a cell a group currently observes.
- `VISIBILITY_REMEMBERED` (const): const VISIBILITY_REMEMBERED: 1 — Numeric code for a cell seen before but not currently in view (last-known).
- `VisibilityCells` (interface): interface VisibilityCells — Dense per-cell readout for one group, shaped for minimap/overlay drawing.
- `VisibilityDelta` (interface): interface VisibilityDelta — The cells that changed state for one group in a single {@link VisibilityField.observe} call — a pure incremental readout for rendering, minimaps, AI, UI, and authoritative replication. Never lists unchanged cells, so it stays bounded by how much the group's view actually moved.
- `VisibilityField` (interface): interface VisibilityField — A gameplay (fog-of-war) knowledge field: per viewer group, every grid cell is hidden, remembered, or observed. Distinct from render culling in `core/visibility` — this models what a team KNOWS, not what a camera can draw. It generalizes `world/fog`'s single-group reveal-once model to many groups with configurable terrain memory, and keeps each group's knowledge isolated so one group's hidden state can never be derived from another's.
- `VisibilityFieldConfig` (interface): interface VisibilityFieldConfig — Construction options for {@link createVisibilityField}.
- `VisibilityFieldState` (interface): interface VisibilityFieldState — Serializable snapshot of a whole field — JSON round-trips losslessly.
- `VisibilityGroupState` (interface): interface VisibilityGroupState — Sparse serialized knowledge for one group — only non-hidden cells are stored.
- `VisibilityMemory` (type): type VisibilityMemory = | { readonly kind: "permanent" } | { readonly kind: "none" } | { readonly kind: "decay"; readonly updates: number } — How a cell decays after a group stops observing it — the terrain-memory policy. `permanent` keeps last-known terrain forever (RTS explored map); `none` drops it straight back to hidden the moment it leaves view (pure line-of-sight stealth); `decay` remembers it for `updates` observe cycles, then hides it. Day/night, height, sensor, and stealth rules are NOT encoded here — the caller bakes those into which cells it reports as observed each update.
- `VisibilityState` (type): type VisibilityState = "hidden" | "remembered" | "observed" — One viewer group's knowledge of a cell: never/forgotten, last-known, or live.
- `createVisibilityField` (function): function createVisibilityField(config: VisibilityFieldConfig): VisibilityField — Build a per-group gameplay visibility field. First adopters: an RTS/stealth team whose scout observes terrain (which stays remembered after it leaves) while enemy units re-hide once no scout observes their cell, and any authoritative host that must filter hidden entities out of a client's replica.

## @jgengine/core/world/volumetricClouds

- `VOLUMETRIC_CLOUDS_DEFAULTS` (const): const VOLUMETRIC_CLOUDS_DEFAULTS: VolumetricCloudsRules — Volumetric cloud defaults: a moderate, drifting cumulus layer.
- `VolumetricCloudsConfig` (interface): interface VolumetricCloudsConfig — Volumetric cloud layer config for `sky()` — a raymarched cloud slab mounted from the environment `sky` seam. Pure config + defaulting here; the raymarch shader lives in the `shell` renderer (`environment/VolumetricClouds.tsx`), mounted alongside `SkyDome` whenever a sky descriptor carries this field. Off by default — omit `volumetricClouds` on `sky({...})` and no layer mounts.
- `VolumetricCloudsRules` (interface): interface VolumetricCloudsRules — Fully-defaulted volumetric cloud params, resolved from a `VolumetricCloudsConfig`.

## @jgengine/core/world/voxelField

- `VOXEL_FACES` (const): const VOXEL_FACES: readonly VoxelFace[] — ⚠ undocumented
- `VOXEL_FACE_NORMALS` (const): const VOXEL_FACE_NORMALS: Record<VoxelFace, VoxelCoord> — ⚠ undocumented
- `VoxelBounds` (interface): interface VoxelBounds { min: VoxelCoord; max: VoxelCoord } — ⚠ undocumented
- `VoxelCell` (interface): interface VoxelCell<T extends string = string> { x: number; y: number; z: number; type: T } — ⚠ undocumented
- `VoxelCoord` (type): type VoxelCoord = readonly [number, number, number] — ⚠ undocumented
- `VoxelFace` (type): type VoxelFace = "px" | "nx" | "py" | "ny" | "pz" | "nz" — ⚠ undocumented
- `VoxelField` (interface): interface VoxelField<T extends string = string> { set(x: number, y: number, z: number, type: T): boolean; remove(x: number, y: number, z: number): boolean; get(x: number, y: number, z: number): T | null; has(x: number, y: number, z: number): boolean; fill(min: VoxelCoord, max: VoxelCoord… — ⚠ undocumented
- `VoxelFieldConfig` (interface): interface VoxelFieldConfig { chunkSize?: number } — ⚠ undocumented
- `VoxelFieldSummary` (interface): interface VoxelFieldSummary<T extends string = string> { blocks: number; types: Record<T, number>; bounds: VoxelBounds | null } — ⚠ undocumented
- `VoxelHit` (interface): interface VoxelHit<T extends string = string> { x: number; y: number; z: number; type: T; face: VoxelFace; adjacent: VoxelCoord; distance: number } — ⚠ undocumented
- `createVoxelField` (function): function createVoxelField<T extends string = string>(config?: VoxelFieldConfig): VoxelField<T> — ⚠ undocumented

## @jgengine/core/world/walls

- `EnclosedFootprint` (interface): interface EnclosedFootprint { polygon: readonly Vec2[]; aabb: Aabb; area: number; perimeter: number; closed: boolean } — ⚠ undocumented
- `PaintTarget` (type): type PaintTarget = "floor" | "wall" — ⚠ undocumented
- `RoofConfig` (interface): interface RoofConfig { style?: RoofStyle; eaveHeight?: number; pitch?: number; overhang?: number } — ⚠ undocumented
- `RoofPlan` (interface): interface RoofPlan { style: RoofStyle; ridge: readonly [Vec2, Vec2]; apexHeight: number; eaveHeight: number; faces: readonly (readonly WallVec3[])[] } — ⚠ undocumented
- `RoofStyle` (type): type RoofStyle = "hip" | "gable" | "flat" — ⚠ undocumented
- `SurfacePaintStore` (interface): interface SurfacePaintStore { paint(target: PaintTarget, key: string, surface: string): void; clear(target: PaintTarget, key: string): void; get(target: PaintTarget, key: string): string | null; entries(target: PaintTarget): readonly (readonly [string, string])[]; sna… — ⚠ undocumented
- `WallDrawTool` (interface): interface WallDrawTool { addPoint(point: Vec2, snap?: number): Vec2; undo(): void; close(): void; clear(): void; points(): readonly Vec2[]; segments(): WallSegment[]; isClosed(): boolean; footprint(): EnclosedFootprint | null; roof(config?: RoofConfig): RoofPlan … — ⚠ undocumented
- `WallDrawToolState` (interface): interface WallDrawToolState — Plain JSON state of a {@link WallDrawTool}: the drawn points and whether the loop is closed.
- `WallSegment` (interface): interface WallSegment { from: Vec2; to: Vec2; length: number; angle: number } — ⚠ undocumented · used by `wallSolids` (@jgengine/core/world/worldSolids): One oriented solid per wall segment (see `wallSegments` in `world/walls`).
- `WallVec3` (type): type WallVec3 = readonly [number, number, number] — ⚠ undocumented

## @jgengine/core/world/water

- `GerstnerWave` (interface): interface GerstnerWave { direction: readonly [number, number]; wavelength: number; amplitude: number; steepness: number; speed: number } — ⚠ undocumented
- `WaterNormal` (type): type WaterNormal = readonly [number, number, number] — ⚠ undocumented
- `WaterSurface` (interface): interface WaterSurface { readonly level: number; readonly waves: readonly GerstnerWave[]; height(x: number, z: number, time: number): number; normal(x: number, z: number, time: number): WaterNormal; displace(x: number, z: number, time: number): readonly [number, … — ⚠ undocumented
- `WaterSurfaceConfig` (interface): interface WaterSurfaceConfig { level?: number; levelAt?: (time: number) => number; waveHeight?: number; waveScale?: number; waveSpeed?: number; waves?: number; choppiness?: number } — ⚠ undocumented
- `synthesizeWaves` (function): function synthesizeWaves(config: WaterSurfaceConfig = {}): GerstnerWave[] — ⚠ undocumented
- `waterSurface` (function): function waterSurface(config: WaterSurfaceConfig = {}): WaterSurface — ⚠ undocumented
- `waterSurfaceFromDescriptor` (function): function waterSurfaceFromDescriptor(descriptor: OceanEnvironmentDescriptor, waves?: number): WaterSurface — ⚠ undocumented

## @jgengine/core/world/waterKind

- `ResolvedWater` (interface): interface ResolvedWater — A resolved water surface: world-space plane center/size (XZ) at surface height `y`, plus its params.
- `WATER_DEFAULTS` (const): const WATER_DEFAULTS: WaterRules — Water defaults: a calm blue-green pond with a soft foam edge.
- `WATER_SCHEMA` (const): const WATER_SCHEMA: ParamSchema — The water parameter schema — drives the inspector and `meta` parse via the studio seam.
- `WATER_VOLUME_KIND` (const): const WATER_VOLUME_KIND: "water" — The editor volume kind marking a box as a water surface.
- `WaterRules` (interface): interface WaterRules — Fully-defaulted water surface params parsed from a volume's `meta`.

## @jgengine/core/world/waypoints

- `WaypointEntry` (interface): interface WaypointEntry — A single player-placed waypoint. World-XZ only — serializable and renderer-free.
- `WaypointGuidance` (interface): interface WaypointGuidance — Direction/range to the tracked waypoint, for an on-screen guide arrow.
- `WaypointSnapshot` (interface): interface WaypointSnapshot — Whole serializable state of a {@link WaypointStore} — drop into a save blob.
- `WaypointStore` (interface): interface WaypointStore — Player-owned waypoint layer — place/track/clear pins, mirror to a `MarkerSet`, and read guide-arrow data.
- `WaypointStoreDeps` (interface): interface WaypointStoreDeps — Construction options for {@link createWaypointStore}.
- `createWaypointStore` (function): function createWaypointStore(deps: WaypointStoreDeps = {}): WaypointStore — Player-owned waypoint layer: place/track/clear pins, mirror them into a shared `MarkerSet` (so `Minimap`/`WorldMap`/`Compass` render them for free), and read bearing/distance guidance for an on-screen arrow to the tracked one. State is plain data — `snapshot()`/`restore()` round-trip through any save blob.

## @jgengine/core/world/weather

- `FireCell` (interface): interface FireCell { fuel: number; heat: number; state: FireCellState } — ⚠ undocumented
- `FireCellState` (type): type FireCellState = "unburnt" | "burning" | "burnt" — ⚠ undocumented
- `FireGrid` (interface): interface FireGrid { readonly cols: number; readonly rows: number; readonly cellSize: number; readonly origin: readonly [number, number]; step(dt: number, options?: FireStepOptions): void; igniteCell(col: number, row: number): void; extinguishCell(col: number… — ⚠ undocumented
- `FireGridConfig` (interface): interface FireGridConfig { cols: number; rows: number; cellSize: number; origin?: readonly [number, number]; fuelAt?: (col: number, row: number) => number; ignitionThreshold?: number; spreadRate?: number; burnRate?: number; wind?: WindVector; windBias?: number; max… — ⚠ undocumented
- `FireGridTuning` (type): type FireGridTuning = Pick<FireGridConfig, "ignitionThreshold" | "spreadRate" | "burnRate" | "wind" | "windBias"> — Live fire ignition, spread, consumption and wind policies; grid geometry stays fixed.
- `FireStepOptions` (interface): interface FireStepOptions { spread?: number; wind?: WindVector; windAt?: (x: number, z: number) => WindVector; wetnessAt?: (col: number, row: number) => number; extinguishRate?: number } — ⚠ undocumented
- `ResolvedWeather` (interface): interface ResolvedWeather { grip: number; visibility: number; structureDamage: number; chill: number; ignition: number; spread: number } — ⚠ undocumented
- `WeatherKind` (type): type WeatherKind = string — ⚠ undocumented
- `WeatherKindOf` (type): type WeatherKindOf<TTable extends WeatherModifierTable> = Extract<keyof TTable, string> — ⚠ undocumented
- `WeatherModifier` (interface): interface WeatherModifier { grip?: number; visibility?: number; structureDamage?: number; chill?: number; ignition?: number; spread?: number } — ⚠ undocumented
- `WeatherModifierTable` (type): type WeatherModifierTable<K extends string = string> = Record<K, WeatherModifier> — ⚠ undocumented
- `WeatherState` (interface): interface WeatherState { kind: WeatherKind; intensity: number; wind?: WindVector } — ⚠ undocumented
- `createFireGrid` (function): function createFireGrid(config: FireGridConfig): FireGrid — ⚠ undocumented
- `resolveWeather` (function): function resolveWeather<TTable extends WeatherModifierTable>(state: WeatherState, table: TTable): ResolvedWeather — ⚠ undocumented

## @jgengine/core/world/wind

- `WindField` (interface): interface WindField { readonly direction: WindVector; readonly speed: number; at(time: number): WindVector; atPoint(x: number, z: number, time: number): WindVector; strengthAt(x: number, z: number, time: number): number } — ⚠ undocumented
- `WindFieldConfig` (interface): interface WindFieldConfig { direction?: WindVector; speed?: number; gust?: number; gustFrequency?: number; turbulence?: number; seed?: string | number } — ⚠ undocumented
- `WindVector` (type): type WindVector = readonly [number, number] — ⚠ undocumented
- `windField` (function): function windField(config: WindFieldConfig = {}): WindField — ⚠ undocumented

## @jgengine/core/world/windZones

- `WindShiftForecast` (interface): interface WindShiftForecast { zoneId: string; at: number; inSeconds: number; next: WindZoneState } — ⚠ undocumented
- `WindZoneConfig` (interface): interface WindZoneConfig { id: string; center: readonly [number, number]; radius: number; phases: readonly SchedulePhase<WindZoneState>[]; offsetSeconds?: number } — ⚠ undocumented
- `WindZoneState` (interface): interface WindZoneState { direction: WindVector; speed: number; label?: string } — ⚠ undocumented
- `WindZones` (interface): interface WindZones — Named, discrete wind zones over an ambient field — each zone runs a deterministic `StateSchedule` of wind states, so games get scheduled shifts with advance announcement (`forecastShift` drives the "gale in 12s" countdown) instead of one continuous field.
- `WindZonesConfig` (interface): interface WindZonesConfig { zones: readonly WindZoneConfig[]; ambient?: WindField } — ⚠ undocumented
- `createWindZones` (function): function createWindZones(config: WindZonesConfig): WindZones — ⚠ undocumented

## @jgengine/core/world/worldSolids

- `WallSolidOptions` (interface): interface WallSolidOptions — Wall height, thickness and base for {@link wallSolids}.
- `WorldSolid` (interface): interface WorldSolid — One solid box in world space: the collision half of generated or authored world geometry.
- `WorldSolidRayWork` (interface): interface WorldSolidRayWork — Caller-owned work counters, reset by each world-solid ray candidate query.
- `WorldSolids` (interface): interface WorldSolids — Static collision for world geometry that is not a scene object: generated buildings, studio volumes like `city`, wall runs. Solids live in named layers so a feature can replace or drop its own set without touching the rest. `solidObstaclesNear` (player and NPC movement), `syncWorldColliders` (physics backends) and `populateNavGridFromSolids` all read this one store.
- `WorldSolidsState` (interface): interface WorldSolidsState — Serializable contents of a {@link WorldSolids}: every layer's solids by layer id.
- `buildingSolids` (function): function buildingSolids(buildings: readonly GeneratedBuilding[], groundHeight: (x: number, z: number) => number = () => 0): WorldSolid[] — One solid per generated building: its `bounds` footprint turned by `rotationY` about `center`, from the ground under its center up through its floors. `groundHeight` defaults to flat `0`.
- `createWorldSolids` (function): function createWorldSolids(options: { cellSize?: number } = {}): WorldSolids — A store of static world solids in named layers.
- `structureSolids` (function): function structureSolids(world: EnvironmentWorldFeature, groundHeight?: (x: number, z: number) => number): WorldSolid[] — Solids for every `structures` descriptor on an environment feature, skipping any marked `solid: false`.
- `wallSolids` (function): function wallSolids(segments: readonly WallSegment[], options: WallSolidOptions): WorldSolid[] — One oriented solid per wall segment (see `wallSegments` in `world/walls`).
- `worldSolidBounds` (function): function worldSolidBounds(solid: WorldSolid): { min: [number, number, number]; max: [number, number, number]; } — Yaw-expanded world AABB of an oriented solid box.
- `worldSolidFootprint` (function): function worldSolidFootprint(solid: WorldSolid): Aabb — XZ footprint of a solid's world AABB, for 2D consumers such as nav grids.

## @jgengine/navbake

- `BakeNavMeshOptions` (interface): interface BakeNavMeshOptions — Walkable geometry and agent dimensions for {@link bakeNavMesh}.
- `bakeNavMesh` (function): function bakeNavMesh(options: BakeNavMeshOptions): NavMeshData — Voxelize indexed triangles with recast and return the walkable surface as convex polygons in the engine's serializable nav-mesh format: eroded by `agentRadius`, cut where clearance is under `agentHeight`, and split at slopes over `maxSlope` or steps over `maxClimb`. Requires {@link initNavBake}.
- `initNavBake` (function): function initNavBake(): Promise<void> — Load the recast WebAssembly module once; await before the first {@link bakeNavMesh}.
- `navBakeReady` (function): function navBakeReady(): boolean — Whether {@link initNavBake} has finished and {@link bakeNavMesh} can run synchronously.

## @jgengine/rapier

- `RapierBackendOptions` (interface): interface RapierBackendOptions extends PhysicsBackendConfig — Construction options for the Rapier-backed {@link PhysicsBackend}.
- `createRapierBackend` (function): function createRapierBackend(options: RapierBackendOptions = {}): Promise<PhysicsBackend> — Create a Rapier-backed {@link PhysicsBackend}; initialization loads Rapier's WASM module asynchronously.

## @jgengine/rapier/rapierBackend

- `RapierBackendOptions` (interface): interface RapierBackendOptions extends PhysicsBackendConfig — Construction options for the Rapier-backed {@link PhysicsBackend}.
- `createRapierBackend` (function): function createRapierBackend(options: RapierBackendOptions = {}): Promise<PhysicsBackend> — Create a Rapier-backed {@link PhysicsBackend}; initialization loads Rapier's WASM module asynchronously.
