@jgengine/shell 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/CombatPresentation.d.ts +5 -0
  5. package/dist/CombatPresentation.js +8 -0
  6. package/dist/GameHost.d.ts +25 -1
  7. package/dist/GameHost.js +60 -4
  8. package/dist/GamePhaseStamp.d.ts +1 -0
  9. package/dist/GamePhaseStamp.js +9 -0
  10. package/dist/GamePlayer.d.ts +5 -0
  11. package/dist/GamePlayer.js +5 -0
  12. package/dist/GamePlayerShell.d.ts +5 -12
  13. package/dist/GamePlayerShell.js +67 -1332
  14. package/dist/GameUiPreview.js +3 -2
  15. package/dist/Shell3dPresentation.d.ts +63 -0
  16. package/dist/Shell3dPresentation.js +302 -0
  17. package/dist/ShellChrome.d.ts +51 -0
  18. package/dist/ShellChrome.js +51 -0
  19. package/dist/ShellHudPresentation.d.ts +41 -0
  20. package/dist/ShellHudPresentation.js +22 -0
  21. package/dist/audio/audioEngine.d.ts +4 -0
  22. package/dist/audio/audioEngine.js +128 -21
  23. package/dist/audio/audioWire.d.ts +40 -0
  24. package/dist/audio/audioWire.js +62 -0
  25. package/dist/audio/loopParams.d.ts +20 -0
  26. package/dist/audio/loopParams.js +28 -0
  27. package/dist/behaviour.d.ts +2 -1
  28. package/dist/behaviour.js +2 -1
  29. package/dist/behaviourAttach.d.ts +1 -0
  30. package/dist/behaviourAttach.js +1 -0
  31. package/dist/behaviourDriver.d.ts +1 -0
  32. package/dist/behaviourDriver.js +1 -0
  33. package/dist/boundActionDispatch.d.ts +13 -0
  34. package/dist/boundActionDispatch.js +37 -0
  35. package/dist/camera/GameCameraRig.d.ts +5 -2
  36. package/dist/camera/GameCameraRig.js +8 -3
  37. package/dist/camera/GameFirstPersonCamera.d.ts +9 -2
  38. package/dist/camera/GameFirstPersonCamera.js +8 -3
  39. package/dist/camera/GameInspectionCamera.d.ts +1 -1
  40. package/dist/camera/GameInspectionCamera.js +2 -2
  41. package/dist/camera/GameOrbitCamera.js +24 -9
  42. package/dist/camera/cameraBlendMath.d.ts +3 -0
  43. package/dist/camera/cameraBlendMath.js +3 -0
  44. package/dist/camera/cameraRigs.d.ts +3 -1
  45. package/dist/camera/cameraRigs.js +21 -3
  46. package/dist/camera/fovPreference.d.ts +6 -1
  47. package/dist/camera/fovPreference.js +6 -1
  48. package/dist/camera/index.d.ts +4 -7
  49. package/dist/camera/index.js +4 -7
  50. package/dist/camera/inspectionCameraMath.d.ts +7 -2
  51. package/dist/camera/inspectionCameraMath.js +7 -2
  52. package/dist/camera/orbitCameraMath.d.ts +36 -6
  53. package/dist/camera/orbitCameraMath.js +56 -6
  54. package/dist/camera/rigMath.d.ts +114 -24
  55. package/dist/camera/rigMath.js +129 -24
  56. package/dist/camera/rigResolve.d.ts +4 -2
  57. package/dist/camera/rigResolve.js +4 -2
  58. package/dist/camera/shakeChannel.d.ts +6 -2
  59. package/dist/camera/shakeChannel.js +6 -2
  60. package/dist/camera/shakeChannelMath.d.ts +1 -0
  61. package/dist/camera/shakeChannelMath.js +1 -0
  62. package/dist/commandSink.d.ts +8 -3
  63. package/dist/commandSink.js +8 -3
  64. package/dist/defineGame.d.ts +15 -1
  65. package/dist/defineGame.js +50 -9
  66. package/dist/devtools/ColPanel.d.ts +1 -0
  67. package/dist/devtools/ColPanel.js +14 -0
  68. package/dist/devtools/DevtoolsOverlay.d.ts +11 -7
  69. package/dist/devtools/DevtoolsOverlay.js +47 -462
  70. package/dist/devtools/KeysPanel.d.ts +4 -0
  71. package/dist/devtools/KeysPanel.js +31 -0
  72. package/dist/devtools/LogsPanel.d.ts +1 -0
  73. package/dist/devtools/LogsPanel.js +12 -0
  74. package/dist/devtools/NetPanel.d.ts +4 -0
  75. package/dist/devtools/NetPanel.js +10 -0
  76. package/dist/devtools/PerfPanel.d.ts +4 -0
  77. package/dist/devtools/PerfPanel.js +53 -0
  78. package/dist/devtools/TunePanel.d.ts +3 -0
  79. package/dist/devtools/TunePanel.js +309 -0
  80. package/dist/devtools/agentBridge.d.ts +41 -0
  81. package/dist/devtools/agentBridge.js +266 -0
  82. package/dist/devtools/collisionDebug.d.ts +6 -0
  83. package/dist/devtools/collisionDebug.js +6 -0
  84. package/dist/devtools/collisionDebugMath.d.ts +8 -2
  85. package/dist/devtools/collisionDebugMath.js +24 -5
  86. package/dist/devtools/devtoolsOverrides.d.ts +6 -0
  87. package/dist/devtools/devtoolsOverrides.js +48 -0
  88. package/dist/devtools/panelAtoms.d.ts +9 -0
  89. package/dist/devtools/panelAtoms.js +10 -0
  90. package/dist/devtools/perfDiagnose.d.ts +2 -0
  91. package/dist/devtools/perfDiagnose.js +43 -0
  92. package/dist/diagnostics/RuntimeDiagnostics.d.ts +36 -0
  93. package/dist/diagnostics/RuntimeDiagnostics.js +80 -0
  94. package/dist/drivers/FrameDriver.d.ts +37 -0
  95. package/dist/drivers/FrameDriver.js +232 -0
  96. package/dist/drivers/HudOnlyDriver.d.ts +16 -0
  97. package/dist/drivers/HudOnlyDriver.js +60 -0
  98. package/dist/environment/Daylight.d.ts +23 -7
  99. package/dist/environment/Daylight.js +106 -13
  100. package/dist/environment/EnvironmentScene.js +44 -9
  101. package/dist/environment/VolumetricClouds.d.ts +17 -0
  102. package/dist/environment/VolumetricClouds.js +202 -0
  103. package/dist/environment/daylightCycle.d.ts +3 -1
  104. package/dist/environment/daylightCycle.js +3 -1
  105. package/dist/environment/groundPadMath.d.ts +3 -0
  106. package/dist/environment/groundPadMath.js +3 -0
  107. package/dist/environment/index.d.ts +1 -0
  108. package/dist/environment/index.js +1 -0
  109. package/dist/environment/skyLightingPolicy.d.ts +2 -0
  110. package/dist/environment/skyLightingPolicy.js +2 -0
  111. package/dist/environment/terrainGroundColor.d.ts +9 -0
  112. package/dist/environment/terrainGroundColor.js +22 -0
  113. package/dist/gameKit.d.ts +27 -0
  114. package/dist/gameKit.js +29 -0
  115. package/dist/hotbarActions.d.ts +26 -0
  116. package/dist/hotbarActions.js +27 -0
  117. package/dist/inputSink.d.ts +16 -4
  118. package/dist/inputSink.js +57 -7
  119. package/dist/map/MapMarkerBeacons.d.ts +3 -2
  120. package/dist/materialOverride.d.ts +10 -0
  121. package/dist/materialOverride.js +15 -3
  122. package/dist/multiplayer.js +8 -2
  123. package/dist/postfx/PostProcessing.d.ts +9 -1
  124. package/dist/postfx/PostProcessing.js +56 -11
  125. package/dist/postfx/gradeShader.js +9 -1
  126. package/dist/presentationResolve.d.ts +35 -0
  127. package/dist/presentationResolve.js +51 -0
  128. package/dist/registry.d.ts +4 -2
  129. package/dist/render/EnvironmentLighting.d.ts +10 -0
  130. package/dist/render/EnvironmentLighting.js +34 -0
  131. package/dist/render/SceneLighting.d.ts +7 -0
  132. package/dist/render/SceneLighting.js +18 -0
  133. package/dist/render/SceneModels.d.ts +14 -0
  134. package/dist/render/SceneModels.js +337 -0
  135. package/dist/render/assetBase.d.ts +17 -0
  136. package/dist/render/assetBase.js +35 -0
  137. package/dist/render/defaultSurface.d.ts +29 -0
  138. package/dist/render/defaultSurface.js +101 -0
  139. package/dist/render/modelLoad.d.ts +24 -0
  140. package/dist/render/modelLoad.js +76 -0
  141. package/dist/render/modelRender.d.ts +11 -0
  142. package/dist/render/modelRender.js +15 -0
  143. package/dist/render/resolveModel.d.ts +54 -3
  144. package/dist/render/resolveModel.js +116 -4
  145. package/dist/render/useEntityRenderCues.d.ts +13 -0
  146. package/dist/render/useEntityRenderCues.js +62 -0
  147. package/dist/scatter/InstancedScatter.d.ts +24 -0
  148. package/dist/scatter/InstancedScatter.js +135 -0
  149. package/dist/scatter/scatterModels.d.ts +25 -0
  150. package/dist/scatter/scatterModels.js +61 -0
  151. package/dist/scatter/scatterProxies.d.ts +6 -0
  152. package/dist/scatter/scatterProxies.js +118 -0
  153. package/dist/scatter.d.ts +1 -0
  154. package/dist/scatter.js +1 -0
  155. package/dist/scene/AuthoredScene.d.ts +84 -0
  156. package/dist/scene/AuthoredScene.js +178 -0
  157. package/dist/scene/CityRenderer.d.ts +2 -0
  158. package/dist/scene/CityRenderer.js +1031 -0
  159. package/dist/scene/GeneratedAssetRenderer.d.ts +14 -0
  160. package/dist/scene/GeneratedAssetRenderer.js +59 -0
  161. package/dist/scene/GrassFieldRenderer.d.ts +2 -0
  162. package/dist/scene/GrassFieldRenderer.js +73 -0
  163. package/dist/scene/PoleLineRenderer.d.ts +2 -0
  164. package/dist/scene/PoleLineRenderer.js +287 -0
  165. package/dist/scene/SoilPatchRenderer.d.ts +2 -0
  166. package/dist/scene/SoilPatchRenderer.js +84 -0
  167. package/dist/scene/StudioStage.d.ts +37 -0
  168. package/dist/scene/StudioStage.js +42 -0
  169. package/dist/scene/WaterRenderer.d.ts +2 -0
  170. package/dist/scene/WaterRenderer.js +61 -0
  171. package/dist/scene/builtinSceneKindRenderers.d.ts +2 -0
  172. package/dist/scene/builtinSceneKindRenderers.js +26 -0
  173. package/dist/scene/cityWindowMaterial.d.ts +16 -0
  174. package/dist/scene/cityWindowMaterial.js +81 -0
  175. package/dist/scene/sceneKindRenderers.d.ts +30 -0
  176. package/dist/scene/sceneKindRenderers.js +17 -0
  177. package/dist/scene.d.ts +1 -0
  178. package/dist/scene.js +1 -0
  179. package/dist/settings/appliedSettings.d.ts +7 -1
  180. package/dist/settings/appliedSettings.js +13 -2
  181. package/dist/settings/settingsController.d.ts +2 -0
  182. package/dist/settings/settingsController.js +22 -1
  183. package/dist/shellConstants.d.ts +4 -0
  184. package/dist/shellConstants.js +4 -0
  185. package/dist/shellMovement.d.ts +8 -0
  186. package/dist/shellMovement.js +11 -0
  187. package/dist/shellPointer.d.ts +20 -0
  188. package/dist/shellPointer.js +28 -0
  189. package/dist/structures/PlacementGhost.d.ts +4 -0
  190. package/dist/structures/PlacementGhost.js +4 -0
  191. package/dist/structures/TransformGizmo.d.ts +53 -0
  192. package/dist/structures/TransformGizmo.js +59 -0
  193. package/dist/structures/index.d.ts +1 -0
  194. package/dist/structures/index.js +1 -0
  195. package/dist/terrain/GrassField.d.ts +11 -3
  196. package/dist/terrain/GrassField.js +16 -6
  197. package/dist/terrain/TerraformBrushCursor.js +3 -0
  198. package/dist/terrain/grassBudget.d.ts +11 -2
  199. package/dist/terrain/grassBudget.js +20 -4
  200. package/dist/terrain/grassGeometry.d.ts +35 -0
  201. package/dist/terrain/grassGeometry.js +85 -20
  202. package/dist/terrain/grassMaterial.d.ts +20 -0
  203. package/dist/terrain/grassMaterial.js +68 -13
  204. package/dist/terrain/heightfieldGeometry.d.ts +34 -0
  205. package/dist/terrain/heightfieldGeometry.js +109 -0
  206. package/dist/terrain/index.d.ts +1 -0
  207. package/dist/terrain/index.js +1 -0
  208. package/dist/terrain/random.d.ts +3 -0
  209. package/dist/terrain/random.js +3 -0
  210. package/dist/terrain/soilPatchMaterial.d.ts +23 -0
  211. package/dist/terrain/soilPatchMaterial.js +147 -0
  212. package/dist/terrain/terrainDetailMaterial.d.ts +19 -2
  213. package/dist/terrain/terrainDetailMaterial.js +87 -7
  214. package/dist/terrain/terrainMath.d.ts +8 -1
  215. package/dist/terrain/terrainMath.js +8 -1
  216. package/dist/touch/TouchControlsOverlay.d.ts +9 -5
  217. package/dist/touch/TouchControlsOverlay.js +201 -22
  218. package/dist/useShellMultiplayerSync.d.ts +9 -0
  219. package/dist/useShellMultiplayerSync.js +98 -0
  220. package/dist/visibility/CullingProvider.js +1 -1
  221. package/dist/water/Ocean.d.ts +7 -1
  222. package/dist/water/Ocean.js +16 -3
  223. package/dist/water/OceanConfig.d.ts +11 -0
  224. package/dist/water/OceanConfig.js +8 -0
  225. package/dist/water/OceanMaterial.d.ts +12 -0
  226. package/dist/water/OceanMaterial.js +9 -0
  227. package/dist/water/OceanShader.d.ts +2 -2
  228. package/dist/water/OceanShader.js +78 -10
  229. package/dist/weather/fireSpreadPose.d.ts +1 -0
  230. package/dist/weather/fireSpreadPose.js +1 -0
  231. package/dist/weather/weatherGeometry.d.ts +1 -0
  232. package/dist/weather/weatherGeometry.js +1 -0
  233. package/dist/weather/weatherMath.d.ts +3 -0
  234. package/dist/weather/weatherMath.js +3 -0
  235. package/dist/weather/weatherUniforms.d.ts +3 -0
  236. package/dist/weather/weatherUniforms.js +3 -0
  237. package/dist/world/PlaceScene.d.ts +11 -0
  238. package/dist/world/PlaceScene.js +27 -0
  239. package/dist/world/RetainedVfx.d.ts +10 -0
  240. package/dist/world/RetainedVfx.js +136 -0
  241. package/dist/world/WorldHud.d.ts +49 -2
  242. package/dist/world/WorldHud.js +87 -2
  243. package/dist/world/WorldScene.d.ts +21 -0
  244. package/dist/world/WorldScene.js +186 -0
  245. package/dist/world/WorldVfx.d.ts +9 -0
  246. package/dist/world/WorldVfx.js +184 -0
  247. package/dist/world/entityPose.d.ts +2 -0
  248. package/dist/world/entityPose.js +2 -0
  249. package/dist/world/floatTextStyle.d.ts +1 -0
  250. package/dist/world/floatTextStyle.js +1 -0
  251. package/dist/world/telegraphPulse.d.ts +1 -0
  252. package/dist/world/telegraphPulse.js +1 -0
  253. package/dist/world/worldBarSamples.d.ts +25 -0
  254. package/dist/world/worldBarSamples.js +38 -0
  255. package/dist/worldSky.d.ts +11 -0
  256. package/dist/worldSky.js +21 -0
  257. package/dist/worldSync.d.ts +2 -1
  258. package/dist/worldSync.js +2 -1
  259. package/package.json +6 -6
  260. package/skills/game-design/SKILL.md +28 -0
  261. package/skills/game-design/agents/openai.yaml +4 -0
  262. package/skills/game-design/references/application-playbook.md +170 -0
  263. package/skills/game-design/references/field-guide.md +288 -0
  264. package/skills/jgengine/SKILL.md +54 -0
  265. package/skills/jgengine/api.md +527 -0
  266. package/skills/jgengine/capabilities.md +131 -0
  267. package/skills/jgengine/recipes/minimal-game.md +88 -0
  268. package/skills/jgengine-ui/SKILL.md +41 -0
  269. package/skills/jgengine-ui/api.md +2007 -0
  270. package/skills/jgengine-ui/capabilities.md +211 -0
  271. package/skills/jgengine-ui/recipes/portable-minimap.md +150 -0
  272. package/skills/jgengine-ui/reference.md +513 -0
  273. package/skills/jgengine-ui/references/visual-scorecard.md +73 -0
  274. package/skills/jgengine-world/SKILL.md +51 -0
  275. package/skills/jgengine-world/api.md +3056 -0
  276. package/skills/jgengine-world/capabilities.md +476 -0
  277. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  278. package/skills/jgengine-world/reference.md +261 -0
  279. package/skills/level-design/SKILL.md +54 -0
  280. package/skills/level-design/agents/openai.yaml +4 -0
  281. package/skills/level-design/references/application-playbook.md +192 -0
  282. package/skills/level-design/references/field-guide.md +337 -0
  283. package/skills/level-design/references/live-editor-loop.md +179 -0
  284. package/dist/cartridge.d.ts +0 -145
  285. package/dist/cartridge.js +0 -246
  286. package/llms.txt +0 -2761
@@ -0,0 +1,3056 @@
1
+ <!-- GENERATED by scripts/gen-skill-api.ts — do not edit. Regenerate: bun run gen:skill-api -->
2
+
3
+ # jgengine-world — exported API surface
4
+
5
+ ## @jgengine/core/ai/crowd
6
+
7
+ - `CrowdField` (interface): interface CrowdField — ⚠ undocumented
8
+ - `FlowField` (interface): interface FlowField — ⚠ undocumented
9
+ - `FlowFieldOptions` (interface): interface FlowFieldOptions — ⚠ undocumented
10
+ - `Poi` (interface): interface Poi — ⚠ undocumented
11
+ - `SelectPoiOptions` (interface): interface SelectPoiOptions — ⚠ undocumented
12
+ - `VisitorLoop` (interface): interface VisitorLoop — Handle returned by {@link createVisitorLoop}: per-agent seek/travel/dwell/depart state machine.
13
+ - `VisitorLoopOptions` (interface): interface VisitorLoopOptions — Config for {@link createVisitorLoop}: the POI catalog, dwell duration, and exit point every agent shares.
14
+ - `VisitorPhase` (type): type VisitorPhase = "seeking" | "traveling" | "dwelling" | "departing" | "done" — A many-agent visitor's current step of the seek→travel→arrive→dwell→depart loop.
15
+ - `VisitorStep` (interface): interface VisitorStep — One tick's result from a {@link VisitorLoop}: current phase, where to steer, and which POI it concerns.
16
+
17
+ ## @jgengine/core/ai/flock
18
+
19
+ - `FlockAgent` (interface): interface FlockAgent — ⚠ undocumented
20
+ - `FlockConfig` (interface): interface FlockConfig — ⚠ undocumented
21
+ - `FlockStepAgent` (interface): interface FlockStepAgent — ⚠ undocumented
22
+ - `FlockVec3` (type): type FlockVec3 = readonly [number, number, number] — ⚠ undocumented
23
+
24
+ ## @jgengine/core/ai/groupAssist
25
+
26
+ - `AssistMember` (interface): interface AssistMember — ⚠ undocumented
27
+ - `AssistNetwork` (interface): interface AssistNetwork — ⚠ undocumented
28
+ - `AssistNetworkConfig` (interface): interface AssistNetworkConfig — ⚠ undocumented
29
+
30
+ ## @jgengine/core/ai/heatSystem
31
+
32
+ - `HeatConfig` (interface): interface HeatConfig — Tuning for {@link createHeatState}/{@link advanceHeat} — levels, decay, and pursuit-spawn ring.
33
+ - `HeatGain` (interface): interface HeatGain — One crime tick's contribution — only `witnessed` gains raise heat (unseen crimes are free, GTA-style).
34
+ - `HeatLevelDef` (interface): interface HeatLevelDef — One escalation tier — the heat threshold it begins at and the pursuer count it wants active.
35
+ - `HeatPoint` (type): type HeatPoint = readonly [number, number] — A world-space `[x, z]` used for the heat system's spawn ring and witness proximity checks.
36
+ - `HeatState` (interface): interface HeatState — Serializable heat-system state — round-trips through `createHeatState`/`advanceHeat` each tick.
37
+ - `HeatStep` (interface): interface HeatStep — One `advanceHeat` tick's result — updated state plus what the caller should spawn/despawn.
38
+ - `HeatTickContext` (interface): interface HeatTickContext — Per-tick world facts {@link advanceHeat} needs but can't derive itself — witness proximity, pursuer count, origin.
39
+
40
+ ## @jgengine/core/ai/interestScheduler
41
+
42
+ - `InterestCensus` (interface): interface InterestCensus — Aggregate counts of active vs dormant gates — the metric the issue asks a scheduler to expose.
43
+ - `InterestCensusAccumulator` (interface): interface InterestCensusAccumulator — A running census accumulator; call `record` inside the caller's existing tick loop (no extra pass).
44
+ - `InterestGateInput` (interface): interface InterestGateInput — Per-tick input the caller supplies to a gate.
45
+ - `InterestGateState` (interface): interface InterestGateState — Per-agent serializable gate state. Round-trip the whole object; never read fields to drive logic.
46
+ - `InterestGateStep` (interface): interface InterestGateStep — Per-tick output that tells the caller whether to run expensive work.
47
+ - `InterestSchedulerConfig` (interface): interface InterestSchedulerConfig — Static configuration shared by every gate of one behavior class.
48
+ - `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.
49
+ - `InterestTier` (interface): interface InterestTier — A distance-keyed cadence tier: nearer agents tick faster, farther-but-awake agents tick slower.
50
+ - `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.
51
+ - `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.
52
+ - `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.
53
+ - `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}.
54
+
55
+ ## @jgengine/core/ai/jobBoard
56
+
57
+ - `Job` (interface): interface Job — ⚠ undocumented
58
+ - `JobBoard` (interface): interface JobBoard — ⚠ undocumented
59
+ - `JobDef` (interface): interface JobDef — ⚠ undocumented
60
+ - `JobPhase` (type): type JobPhase = "idle" | "travelling" | "working" | "done" — ⚠ undocumented
61
+ - `JobReport` (interface): interface JobReport — ⚠ undocumented
62
+ - `JobTickContext` (interface): interface JobTickContext — ⚠ undocumented
63
+ - `WorkerState` (interface): interface WorkerState — ⚠ undocumented
64
+
65
+ ## @jgengine/core/ai/laneSelect
66
+
67
+ - `LaneCandidate` (interface): interface LaneCandidate<TId extends string = string> — ⚠ undocumented
68
+ - `PickLaneOptions` (interface): interface PickLaneOptions<TId extends string = string> — ⚠ undocumented
69
+
70
+ ## @jgengine/core/ai/mobBrain
71
+
72
+ - `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.
73
+ - `MobBrainConfig` (interface): interface MobBrainConfig — ⚠ undocumented
74
+ - `MobBrainDeps` (interface): interface MobBrainDeps — ⚠ undocumented
75
+ - `MobBrainMode` (type): type MobBrainMode = "idle" | "wander" | "chase" | "engage" | "evade" — ⚠ undocumented
76
+ - `MobBrainStep` (interface): interface MobBrainStep — ⚠ undocumented
77
+ - `MobVec3` (type): type MobVec3 = readonly [number, number, number] — ⚠ undocumented
78
+ - `MobWanderConfig` (interface): interface MobWanderConfig — ⚠ undocumented
79
+
80
+ ## @jgengine/core/ai/populationDirector
81
+
82
+ - `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.
83
+ - `PopulationDirector` (interface): interface PopulationDirector — Stateful ambient population manager for one world; drive it with `tick` and lifecycle notifications.
84
+ - `PopulationDirectorConfig` (interface): interface PopulationDirectorConfig — Full ambient-population configuration: per-region species budgets plus global refill limits and PRNG seed.
85
+ - `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.
86
+ - `PopulationRegionConfig` (interface): interface PopulationRegionConfig — Ambient population budget for a single region: its species ceilings, refill timing, and spawn geometry.
87
+ - `PopulationSpawnRequest` (interface): interface PopulationSpawnRequest — A single ambient spawn the game should realise, refilling a region toward its species caps.
88
+ - `PopulationSpeciesEntry` (interface): interface PopulationSpeciesEntry — One species that ambiently populates a region: how heavily it is favoured and its alive ceiling.
89
+ - `PopulationTickContext` (interface): interface PopulationTickContext — Per-call spawn-point selection hook, letting a game apply bias (distance from players, etc.) at tick time.
90
+ - `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`.
91
+
92
+ ## @jgengine/core/ai/pursuit
93
+
94
+ - `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.
95
+ - `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.
96
+ - `PursuitState` (interface): interface PursuitState — Per-entity cooldown state owned by the primitive. One serializable number; no methods.
97
+ - `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:
98
+ - `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"`.
99
+ - `createPursuitState` (function): function createPursuitState(attackCooldown = 0): PursuitState — A fresh pursuit state, ready to attack immediately (`attackCooldown` at `0`).
100
+
101
+ ## @jgengine/core/ai/spawnDirector
102
+
103
+ - `DirectorContext` (interface): interface DirectorContext — ⚠ undocumented
104
+ - `DirectorStep` (interface): interface DirectorStep — ⚠ undocumented
105
+ - `SpawnDirectorConfig` (interface): interface SpawnDirectorConfig — ⚠ undocumented
106
+ - `SpawnDirectorState` (interface): interface SpawnDirectorState — ⚠ undocumented
107
+ - `SpawnEntry` (interface): interface SpawnEntry — ⚠ undocumented
108
+ - `SpawnPointBiasStrength` (type): type SpawnPointBiasStrength = "subtle" | "moderate" | "strong" — How strongly `distanceBias` weights candidates by distance from `avoid` — a named intent, not a weighting exponent.
109
+ - `SpawnPointDistanceBias` (type): type SpawnPointDistanceBias = "near" | "far" | "none" — Preference for picking a spawn point relative to `avoid` positions: closer, farther, or unweighted.
110
+ - `SpawnPointSelectionOptions` (interface): interface SpawnPointSelectionOptions — Semantic options for selecting a spawn point without exposing weighting internals.
111
+ - `SpawnRequest` (interface): interface SpawnRequest — ⚠ undocumented
112
+ - `WaveManifest` (interface): interface WaveManifest — ⚠ undocumented
113
+ - `advanceSpawnDirector` (function): function advanceSpawnDirector(config: SpawnDirectorConfig, state: SpawnDirectorState, dt: number, ctx: DirectorContext): DirectorStep — ⚠ undocumented
114
+ - `advanceWave` (function): function advanceWave(config: SpawnDirectorConfig, state: SpawnDirectorState): SpawnDirectorState — ⚠ undocumented
115
+ - `createSpawnDirectorState` (function): function createSpawnDirectorState(config: SpawnDirectorConfig): SpawnDirectorState — ⚠ undocumented
116
+ - `pickSpawnPoint` (function): function pickSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null — Selects a candidate spawn point using a semantic distance preference and caller-supplied randomness.
117
+ - `raiseAlert` (function): function raiseAlert(state: SpawnDirectorState, amount: number): SpawnDirectorState — ⚠ undocumented
118
+
119
+ ## @jgengine/core/ai/spawnPoint
120
+
121
+ - `SpawnPointDistanceBias` (type): type SpawnPointDistanceBias = "near" | "far" | "none" — Preference for picking a spawn point relative to `avoid` positions: closer, farther, or unweighted.
122
+ - `SpawnPointSelectionOptions` (interface): interface SpawnPointSelectionOptions — Semantic options for selecting a spawn point without exposing weighting internals.
123
+
124
+ ## @jgengine/core/ai/targetAcquisition
125
+
126
+ - `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.
127
+ - `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.
128
+ - `AcquisitionResult` (interface): interface AcquisitionResult — Outcome of one acquisition pass.
129
+ - `AcquisitionRetention` (interface): interface AcquisitionRetention — Retention hysteresis that keeps an already-held target from flickering under churn.
130
+ - `TargetAcquirer` (interface): interface TargetAcquirer — A stateful acquirer that holds the current target across passes — sugar over {@link acquireTarget}.
131
+ - `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.
132
+ - `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}.
133
+
134
+ ## @jgengine/core/ai/threat
135
+
136
+ - `HighestThreatOptions` (interface): interface HighestThreatOptions — ⚠ undocumented
137
+ - `ThreatEntry` (interface): interface ThreatEntry — ⚠ undocumented
138
+ - `ThreatTable` (interface): interface ThreatTable — ⚠ undocumented
139
+ - `ThreatTableConfig` (interface): interface ThreatTableConfig — ⚠ undocumented
140
+ - `createThreatTable` (function): function createThreatTable(config: ThreatTableConfig = {}): ThreatTable — ⚠ undocumented
141
+
142
+ ## @jgengine/core/anim/easing
143
+
144
+ - `Easing` (type): type Easing = (t: number) => number — ⚠ undocumented
145
+
146
+ ## @jgengine/core/area/areaEffectField
147
+
148
+ - `AreaEffectEvent` (interface): interface AreaEffectEvent<P> — One membership edge emitted by `step`, `removeSource`, or `clear`.
149
+ - `AreaEffectField` (interface): interface AreaEffectField<P> — Runtime handle tracking continuous area membership across ticks.
150
+ - `AreaEventKind` (type): type AreaEventKind = "enter" | "refresh" | "leave" — The three membership edges a step can emit.
151
+ - `AreaFieldState` (interface): interface AreaFieldState<P> — Serialized field state: source descriptors (minus their transient shape) and per-member refresh phase.
152
+ - `AreaLeaveReason` (type): type AreaLeaveReason = "exit" | "source-removed" | "disabled" | "cleared" — Why a `leave` edge fired.
153
+ - `AreaMembership` (interface): interface AreaMembership<P> — One active (source, receiver) membership — feed a receiver's list to a stacking policy.
154
+ - `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.
155
+ - `AreaSourceSpec` (interface): interface AreaSourceSpec<P> — Descriptor for one continuous area source; re-supplied each tick so its shape follows the emitter.
156
+ - `AreaStepInput` (interface): interface AreaStepInput — Per-tick inputs the field needs to reconcile membership without scanning the world.
157
+ - `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.
158
+
159
+ ## @jgengine/core/area/stackPolicy
160
+
161
+ - `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.
162
+ - `MagnitudeOf` (type): type MagnitudeOf<P> = (membership: AreaMembership<P>) => number — Read a comparable magnitude from a membership (e.g. buff strength, damage per tick).
163
+ - `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.
164
+ - `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.
165
+ - `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.
166
+ - `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.
167
+ - `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.
168
+
169
+ ## @jgengine/core/audio/audioFalloff
170
+
171
+ - `AudioBusDef` (interface): interface AudioBusDef — ⚠ undocumented
172
+ - `AudioBusId` (type): type AudioBusId = string — ⚠ undocumented
173
+ - `AudioFalloffConfig` (interface): interface AudioFalloffConfig — ⚠ undocumented
174
+ - `FalloffCurve` (type): type FalloffCurve = "linear" | "inverse" | "none" — ⚠ undocumented
175
+ - `SoundDef` (interface): interface SoundDef — ⚠ undocumented
176
+ - `computeFalloffGain` (function): function computeFalloffGain(distance: number, config: AudioFalloffConfig = {}): number — ⚠ undocumented
177
+ - `distance3` (function): function distance3(a: { x: number; y: number; z: number }, b: { x: number; y: number; z: number }): number — ⚠ undocumented
178
+ - `resolveEmitterGain` (function): function resolveEmitterGain(distance: number, sound: Pick<SoundDef, "gain" | "positional" | "falloff">, busGain: number): number — ⚠ undocumented
179
+
180
+ ## @jgengine/core/audio/music
181
+
182
+ - `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.
183
+ - `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.
184
+ - `NoteEvent` (interface): interface NoteEvent — One scheduled note in a theme, positioned on the loop's quarter-note grid.
185
+ - `ScheduledNote` (interface): interface ScheduledNote — A resolved note occurrence: the source note plus its absolute onset in seconds.
186
+ - `mtof` (function): function mtof(midi: number): number — Standard equal-temperament MIDI-to-frequency (A4 = 440 Hz at MIDI 69).
187
+ - `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.
188
+ - `themeLoopSeconds` (function): function themeLoopSeconds(theme: MusicTheme): number — Loop length of a theme in seconds.
189
+
190
+ ## @jgengine/core/audio/synth
191
+
192
+ - `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`.
193
+ - `SynthFilter` (type): type SynthFilter = "lowpass" | "highpass" | "bandpass" — Biquad filter shape a noise voice is coloured through.
194
+ - `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`.
195
+ - `SynthVoice` (type): type SynthVoice = ToneVoice | NoiseVoice — One layered voice of a synth cue.
196
+ - `SynthWave` (type): type SynthWave = "sine" | "square" | "sawtooth" | "triangle" — Oscillator waveform available to a pitched synth voice.
197
+ - `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`.
198
+ - `patchDuration` (function): function patchDuration(patch: SynthPatch): number — Total wall-clock length of a patch in seconds — the latest voice end across all voices.
199
+
200
+ ## @jgengine/core/faction/factions
201
+
202
+ - `FactionDef` (interface): interface FactionDef — ⚠ undocumented
203
+ - `FactionGraph` (interface): interface FactionGraph — ⚠ undocumented
204
+ - `FactionGraphConfig` (interface): interface FactionGraphConfig — ⚠ undocumented
205
+ - `FactionRelation` (type): type FactionRelation = "hostile" | "neutral" | "friendly" — ⚠ undocumented
206
+ - `FactionRoster` (interface): interface FactionRoster — ⚠ undocumented
207
+ - `createFactionGraph` (function): function createFactionGraph(config: FactionGraphConfig): FactionGraph — ⚠ undocumented
208
+ - `createFactionRoster` (function): function createFactionRoster(graph: FactionGraph): FactionRoster — ⚠ undocumented
209
+
210
+ ## @jgengine/core/faction/reputation
211
+
212
+ - `DEFAULT_REPUTATION_TIERS` (const): const DEFAULT_REPUTATION_TIERS: readonly ReputationTier[] — ⚠ undocumented
213
+ - `EffectiveRelationInput` (interface): interface EffectiveRelationInput — ⚠ undocumented
214
+ - `ReputationLedger` (interface): interface ReputationLedger — ⚠ undocumented
215
+ - `ReputationLedgerConfig` (interface): interface ReputationLedgerConfig — ⚠ undocumented
216
+ - `ReputationTier` (interface): interface ReputationTier — ⚠ undocumented
217
+ - `createReputationLedger` (function): function createReputationLedger(config: ReputationLedgerConfig = {}): ReputationLedger — ⚠ undocumented
218
+ - `effectiveRelation` (function): function effectiveRelation(input: EffectiveRelationInput): FactionRelation — ⚠ undocumented
219
+ - `tierForStanding` (function): function tierForStanding(tiers: readonly ReputationTier[], standing: number): ReputationTier — Map a faction standing value to its named reputation tier.
220
+
221
+ ## @jgengine/core/input/actionBindings
222
+
223
+ - `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.
224
+ - `ActionBindingConfig` (type): type ActionBindingConfig<TCode extends string = string> = ActionBinding<TCode>[] | ActionBindingModes<TCode> — ⚠ undocumented
225
+ - `ActionBindingMap` (type): type ActionBindingMap<TAction extends string, TCode extends string = string> = Record< TAction, ActionBinding<TCode> > — ⚠ undocumented
226
+ - `ActionBindingModes` (interface): interface ActionBindingModes<TCode extends string = string> — ⚠ undocumented
227
+ - `ActionCodes` (type): type ActionCodes<TCode extends string = string> = | readonly TCode[] | { hold?: readonly TCode[]; toggle?: readonly TCode[]; repeatMs?: number } — ⚠ undocumented
228
+ - `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.
229
+ - `ActionStateBindingMap` (type): type ActionStateBindingMap<TAction extends string, TCode extends string = string> = Record< TAction, ActionBindingConfig<TCode> > — ⚠ undocumented
230
+ - `ActionStateTracker` (interface): interface ActionStateTracker<TAction extends string> — ⚠ undocumented
231
+ - `ShouldDispatchActionInput` (interface): interface ShouldDispatchActionInput — ⚠ undocumented
232
+
233
+ ## @jgengine/core/input/axisInput
234
+
235
+ - `AXIS_RANGE` (const): const AXIS_RANGE: Record<AxisName, AxisRange> — ⚠ undocumented
236
+ - `AxisBinding` (interface): interface AxisBinding — ⚠ undocumented
237
+ - `AxisBindingMap` (type): type AxisBindingMap = Record<AxisName, AxisBinding> — ⚠ undocumented
238
+ - `AxisChannelConfig` (interface): interface AxisChannelConfig — ⚠ undocumented
239
+ - `AxisInput` (interface): interface AxisInput — ⚠ undocumented
240
+ - `AxisName` (type): type AxisName = keyof AxisInput — ⚠ undocumented
241
+ - `AxisRange` (interface): interface AxisRange — ⚠ undocumented
242
+ - `DRIVE_AXIS_BINDINGS` (const): const DRIVE_AXIS_BINDINGS: AxisBindingMap — ⚠ undocumented
243
+ - `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.
244
+ - `GenericAxisConfig` (interface): interface GenericAxisConfig<TAxes extends string> — ⚠ undocumented
245
+ - `NEUTRAL_AXIS` (const): const NEUTRAL_AXIS: AxisInput — ⚠ undocumented
246
+
247
+ ## @jgengine/core/input/bindingOverrides
248
+
249
+ - `BINDING_OVERRIDES_STORAGE_PREFIX` (const): const BINDING_OVERRIDES_STORAGE_PREFIX: "jgengine:keybinds:" — ⚠ undocumented
250
+ - `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.
251
+ - `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.
252
+ - `bindingOverridesStorageKey` (function): function bindingOverridesStorageKey(gameId: string): string — ⚠ undocumented
253
+ - `clearAllBindingOverrides` (function): function clearAllBindingOverrides(gameId: string, storage: Pick<WebStorageLike, "removeItem"> | null | undefined = defaultStorage()): void — ⚠ undocumented
254
+ - `clearBindingOverride` (function): function clearBindingOverride(gameId: string, action: string, storage: Pick<WebStorageLike, "getItem" | "setItem" | "removeItem"> | null | undefined = defaultStorage()): BindingOverrides — ⚠ undocumented
255
+ - `loadBindingOverrides` (function): function loadBindingOverrides(gameId: string, storage: Pick<WebStorageLike, "getItem"> | null | undefined = defaultStorage()): BindingOverrides — ⚠ undocumented
256
+ - `saveBindingOverride` (function): function saveBindingOverride(gameId: string, action: string, codes: ActionCodes, storage: Pick<WebStorageLike, "getItem" | "setItem" | "removeItem"> | null | undefined = defaultStorage()): BindingOverrides — ⚠ undocumented
257
+
258
+ ## @jgengine/core/input/controlGroups
259
+
260
+ - `ControlGroupInput` (interface): interface ControlGroupInput — A decoded control-group key press plus the memory needed to detect a double-tap.
261
+ - `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.
262
+ - `ControlGroupOptions` (interface): interface ControlGroupOptions — Tuning for the control-group idiom: the double-tap focus window and the bookmark-key namespace.
263
+ - `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}.
264
+ - `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.
265
+
266
+ ## @jgengine/core/input/gestureSurface
267
+
268
+ - `DEFAULT_GESTURE_TUNING` (const): const DEFAULT_GESTURE_TUNING: GestureSurfaceTuning — ⚠ undocumented
269
+ - `GestureSurfaceTracker` (interface): interface GestureSurfaceTracker — ⚠ undocumented
270
+ - `GestureSurfaceTuning` (interface): interface GestureSurfaceTuning — ⚠ undocumented
271
+ - `createGestureSurfaceTracker` (function): function createGestureSurfaceTracker(bindings: TouchGestureBindings, tuning: GestureSurfaceTuning = DEFAULT_GESTURE_TUNING): GestureSurfaceTracker — ⚠ undocumented
272
+
273
+ ## @jgengine/core/input/lookChannel
274
+
275
+ - `LookChannel` (interface): interface LookChannel — ⚠ undocumented
276
+ - `LookChannelOptions` (interface): interface LookChannelOptions — ⚠ undocumented
277
+ - `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.
278
+ - `createLookChannel` (function): function createLookChannel({ sensitivity, maxVerticalOffset = Infinity }: LookChannelOptions): LookChannel — ⚠ undocumented
279
+
280
+ ## @jgengine/core/input/pointer
281
+
282
+ - `DragCapture` (interface): interface DragCapture — Renderer-agnostic drag-capture / pull-vector state machine for slingshot-style aiming, drawback abilities, and similar gestures.
283
+ - `DragCaptureConfig` (interface): interface DragCaptureConfig — ⚠ undocumented
284
+ - `DragResult` (type): type DragResult = DragState — ⚠ undocumented
285
+ - `DragState` (interface): interface DragState — Snapshot of an in-progress or just-released drag: origin/current cursor points plus the clamped pull vector.
286
+ - `PointerButton` (type): type PointerButton = "primary" | "secondary" | "middle" — ⚠ undocumented
287
+ - `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.
288
+ - `PointerVec3` (type): type PointerVec3 = readonly [number, number, number] — ⚠ undocumented
289
+ - `aimToPoint` (function): function aimToPoint(origin: PointerVec3, point: PointerVec3): Aim — Build an `origin → point` aim for `item.use` / projectiles, firing toward the cursor.
290
+ - `createDragCapture` (function): function createDragCapture(config: DragCaptureConfig = {}): DragCapture — ⚠ undocumented
291
+ - `groundOf` (function): function groundOf(hit: PointerHit): readonly [number, number] — Project a pointer hit onto the XZ plane for navmesh routing (`findPath` takes `[x, z]`).
292
+ - `moveTargetFromHit` (function): function moveTargetFromHit(hit: PointerHit): PointerVec3 — The move-to target of a pointer hit — sugar over `hit.point`.
293
+
294
+ ## @jgengine/core/input/pointerAxis
295
+
296
+ - `PointerAxisBinding` (interface): interface PointerAxisBinding — Maps one pointer axis onto an analog axis target — the pointer-backed counterpart of an `AxisBinding`'s key lists.
297
+ - `PointerAxisState` (interface): interface PointerAxisState — ⚠ undocumented
298
+ - `PointerSurfaceRect` (interface): interface PointerSurfaceRect — ⚠ undocumented
299
+ - `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.
300
+ - `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]`.
301
+
302
+ ## @jgengine/core/input/touchGestures
303
+
304
+ - `TouchGestureEnd` (type): type TouchGestureEnd = "tap" | "hold-end" | null — ⚠ undocumented
305
+ - `TouchGestureTracker` (interface): interface TouchGestureTracker — ⚠ undocumented
306
+ - `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.
307
+ - `createTouchGestureTracker` (function): function createTouchGestureTracker(tuning: TouchGestureTuning): TouchGestureTracker — ⚠ undocumented
308
+
309
+ ## @jgengine/core/input/touchScheme
310
+
311
+ - `DEFAULT_TOUCH_STYLE` (const): const DEFAULT_TOUCH_STYLE: TouchStyle — Skin used when neither the game nor the player picks one.
312
+ - `DeriveTouchSchemeOptions` (interface): interface DeriveTouchSchemeOptions — ⚠ undocumented
313
+ - `ResolvedTouchLayout` (interface): interface ResolvedTouchLayout — The dock zone each cluster resolved to, after applying game config over the bottom-layout defaults.
314
+ - `TOUCH_CODE_PREFIX` (const): const TOUCH_CODE_PREFIX: "touch:" — ⚠ undocumented
315
+ - `TOUCH_STYLES` (const): const TOUCH_STYLES: readonly TouchStyle[] — Every touch skin id, in menu order.
316
+ - `TOUCH_STYLE_OPTIONS` (const): const TOUCH_STYLE_OPTIONS: readonly { value: TouchStyle; label: string }[] — Touch skins as `{ value, label }` rows for the Settings → Controls selector.
317
+ - `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.
318
+ - `TouchButton` (interface): interface TouchButton — ⚠ undocumented
319
+ - `TouchButtonKind` (type): type TouchButtonKind = "primary" | "utility" — ⚠ undocumented
320
+ - `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.
321
+ - `TouchButtonSpec` (interface): interface TouchButtonSpec — ⚠ undocumented
322
+ - `TouchControlsConfig` (interface): interface TouchControlsConfig — ⚠ undocumented
323
+ - `TouchDragBinding` (interface): interface TouchDragBinding — ⚠ undocumented
324
+ - `TouchGestureBindings` (interface): interface TouchGestureBindings — ⚠ undocumented
325
+ - `TouchJoystick` (interface): interface TouchJoystick — ⚠ undocumented
326
+ - `TouchLayoutConfig` (interface): interface TouchLayoutConfig — Where each touch cluster docks; unset falls back to the classic bottom layout.
327
+ - `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.
328
+ - `TouchScheme` (interface): interface TouchScheme — ⚠ undocumented
329
+ - `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.
330
+ - `deriveTouchScheme` (function): function deriveTouchScheme(input: ActionCodesMap | undefined, { reserved, firstPerson, config }: DeriveTouchSchemeOptions): TouchScheme | null — Null means "render no touch controls" — either the game opted out or there is nothing to synthesize.
331
+ - `touchActionLabel` (function): function touchActionLabel(action: string): string — ⚠ undocumented
332
+ - `touchButtonKind` (function): function touchButtonKind(action: string): TouchButtonKind — ⚠ undocumented
333
+ - `touchButtonShape` (function): function touchButtonShape(action: string): TouchButtonShape — Default silhouette for an action; `circle` when nothing more specific fits.
334
+ - `touchCode` (function): function touchCode(action: string): string — ⚠ undocumented
335
+ - `withTouchCodes` (function): function withTouchCodes(map: ActionCodesMap | undefined): ActionCodesMap — Every action gains a synthetic touch code alongside its physical codes.
336
+
337
+ ## @jgengine/core/interaction/contextMenu
338
+
339
+ - `BuildContextMenuInput` (interface): interface BuildContextMenuInput — ⚠ undocumented
340
+ - `ContextMenu` (interface): interface ContextMenu — ⚠ undocumented
341
+ - `ContextTargetKind` (type): type ContextTargetKind = "entity" | "object" — ⚠ undocumented
342
+ - `ContextVerb` (interface): interface ContextVerb — One right-click verb: a label plus the command it dispatches (walk-then-act supported by args).
343
+ - `buildContextMenu` (function): function buildContextMenu(input: BuildContextMenuInput): ContextMenu | null — Assemble a menu from a target's catalog verbs; null when the target lists none.
344
+ - `contextVerb` (function): function contextVerb(label: string, command: string, args?: Record<string, unknown>): ContextVerb — Builds a {@link ContextVerb} for a right-click menu entry.
345
+ - `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.
346
+
347
+ ## @jgengine/core/interaction/lockpick
348
+
349
+ - `LOCK_ACTIONS` (const): const LOCK_ACTIONS: readonly LockAction[] — The five pick actions, in display order (shallow → deep).
350
+ - `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.
351
+ - `LockAction` (type): type LockAction = "hardSet" | "set" | "steady" | "ease" | "drop" — One discrete pick move: how far the pick drives into the lock this step.
352
+ - `LockCell` (interface): interface LockCell — One cell inside the fogged {@link visibleCells} window: its board position and kind.
353
+ - `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.
354
+ - `LockSpec` (interface): interface LockSpec — A generated lock board. `open[col]` holds every enterable row in that column.
355
+ - `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.
356
+ - `LockTierSpec` (interface): interface LockTierSpec — Difficulty dials for one lock: board size, forgiveness band, gates, fog window, traps.
357
+ - `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.
358
+ - `solveLock` (function): function solveLock(spec: LockSpec): boolean — Whether the board has a path from the start row to the bolt seat at all.
359
+ - `solveLockPath` (function): function solveLockPath(spec: LockSpec): number[] | null — Return a concrete row-per-column solution, or null if the board is unsolvable.
360
+ - `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.
361
+ - `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.
362
+
363
+ ## @jgengine/core/interaction/proximityPrompt
364
+
365
+ - `GaugePromptDisplay` (interface): interface GaugePromptDisplay — ⚠ undocumented
366
+ - `KeybindPromptDisplay` (interface): interface KeybindPromptDisplay — ⚠ undocumented
367
+ - `LabelPromptDisplay` (interface): interface LabelPromptDisplay — ⚠ undocumented
368
+ - `PositionedPrompt` (interface): interface PositionedPrompt — ⚠ undocumented
369
+ - `PromptCommand` (interface): interface PromptCommand — ⚠ undocumented
370
+ - `PromptPoint` (interface): interface PromptPoint — ⚠ undocumented
371
+ - `ProximityPrompt` (interface): interface ProximityPrompt — ⚠ undocumented
372
+ - `ProximityPromptConfig` (interface): interface ProximityPromptConfig — ⚠ undocumented
373
+ - `ProximityPromptDisplay` (type): type ProximityPromptDisplay = KeybindPromptDisplay | GaugePromptDisplay | LabelPromptDisplay — ⚠ undocumented
374
+ - `command` (function): function command(name: string, input?: unknown): PromptCommand — ⚠ undocumented
375
+ - `gauge` (function): function gauge(gaugeId: string): GaugePromptDisplay — ⚠ undocumented
376
+ - `keybind` (function): function keybind(actionId: string, label?: string): KeybindPromptDisplay — ⚠ undocumented
377
+ - `label` (function): function label(text: string): LabelPromptDisplay — ⚠ undocumented
378
+ - `positionedPromptsEqual` (function): function positionedPromptsEqual(a: PositionedPrompt, b: PositionedPrompt): boolean — ⚠ undocumented
379
+ - `promptCommandsEqual` (function): function promptCommandsEqual(a: PromptCommand | null, b: PromptCommand | null): boolean — ⚠ undocumented
380
+ - `promptDisplaysEqual` (function): function promptDisplaysEqual(a: ProximityPromptDisplay, b: ProximityPromptDisplay): boolean — ⚠ undocumented
381
+ - `proximityPrompt` (function): function proximityPrompt({ radius, display, invoke = null }: ProximityPromptConfig): ProximityPrompt — ⚠ undocumented
382
+ - `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.
383
+
384
+ ## @jgengine/core/interaction/qte
385
+
386
+ - `QteInputEvent` (interface): interface QteInputEvent — ⚠ undocumented
387
+ - `QteOutcome` (type): type QteOutcome = | { status: "success" } | { status: "fail"; atStep: string; reason: "missed-window" | "wrong-action" | "too-early" } — ⚠ undocumented
388
+ - `QteStep` (interface): interface QteStep — ⚠ undocumented
389
+ - `evaluateQteSequence` (function): function evaluateQteSequence(steps: readonly QteStep[], inputs: readonly QteInputEvent[]): QteOutcome — Evaluate a quick-time-event input sequence against timed hit windows.
390
+ - `pendingQteStep` (function): function pendingQteStep(steps: readonly QteStep[], elapsedSeconds: number): QteStep | null — ⚠ undocumented
391
+ - `qteProgress` (function): function qteProgress(steps: readonly QteStep[], elapsedSeconds: number): number — ⚠ undocumented
392
+
393
+ ## @jgengine/core/interaction/skillCheck
394
+
395
+ - `SkillCheckConfig` (interface): interface SkillCheckConfig — ⚠ undocumented
396
+ - `SkillCheckResult` (interface): interface SkillCheckResult — ⚠ undocumented
397
+ - `SkillCheckZone` (interface): interface SkillCheckZone — ⚠ undocumented
398
+ - `evaluateSkillCheck` (function): function evaluateSkillCheck(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckResult — ⚠ undocumented
399
+ - `skillCheckMarkerPosition` (function): function skillCheckMarkerPosition(config: SkillCheckConfig, elapsedSeconds: number): number — ⚠ undocumented
400
+ - `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.
401
+
402
+ ## @jgengine/core/movement/avatarGait
403
+
404
+ - `DEFAULT_GAIT_TUNING` (const): const DEFAULT_GAIT_TUNING: GaitTuning — ⚠ undocumented
405
+ - `GaitTuning` (interface): interface GaitTuning — ⚠ undocumented
406
+ - `advanceGaitPhase` (function): function advanceGaitPhase(phase: number, speedUnitsPerSec: number, dtSec: number, tuning: GaitTuning = DEFAULT_GAIT_TUNING): number — ⚠ undocumented
407
+ - `gaitBobOffset` (function): function gaitBobOffset(phase: number, speedUnitsPerSec: number, tuning: GaitTuning = DEFAULT_GAIT_TUNING): number — Vertical hop per footfall — two peaks per stride cycle.
408
+ - `gaitSwayAngle` (function): function gaitSwayAngle(phase: number, speedUnitsPerSec: number, tuning: GaitTuning = DEFAULT_GAIT_TUNING): number — Signed side-to-side lean alternating with each footfall.
409
+
410
+ ## @jgengine/core/movement/avoidance
411
+
412
+ - `AvoidanceAgent` (interface): interface AvoidanceAgent — A circular agent that avoidance may push on the XZ plane.
413
+ - `LocalAvoidanceOptions` (interface): interface LocalAvoidanceOptions — Tuning for {@link resolveLocalAvoidance}.
414
+ - `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.
415
+
416
+ ## @jgengine/core/movement/cameraRig
417
+
418
+ - `CAMERA_PITCH_LIMIT` (const): const CAMERA_PITCH_LIMIT: 1.45 — ⚠ undocumented
419
+
420
+ ## @jgengine/core/movement/dash
421
+
422
+ - `DashBurst` (interface): interface DashBurst — ⚠ undocumented
423
+ - `DashConfig` (interface): interface DashConfig — ⚠ undocumented
424
+ - `DashDirection` (interface): interface DashDirection — ⚠ undocumented
425
+ - `DashRejection` (type): type DashRejection = { reason: "no-stamina" | "cooldown" | "dashing" } — ⚠ undocumented
426
+ - `DashState` (interface): interface DashState — ⚠ undocumented
427
+
428
+ ## @jgengine/core/movement/formation
429
+
430
+ - `BoxFormationOptions` (interface): interface BoxFormationOptions — Options for {@link boxFormation}.
431
+ - `CircleFormationOptions` (interface): interface CircleFormationOptions — Options for {@link circleFormation}.
432
+ - `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.
433
+ - `LineFormationOptions` (interface): interface LineFormationOptions — Options for {@link lineFormation}.
434
+ - `SlotAssignmentOptions` (interface): interface SlotAssignmentOptions — Tuning for {@link assignFormationSlots}' stable, low-churn matching.
435
+ - `Vec2` (type): type Vec2 = readonly [number, number] — A point or offset on the XZ ground plane: `[x, z]`.
436
+ - `WedgeFormationOptions` (interface): interface WedgeFormationOptions — Options for {@link wedgeFormation}.
437
+ - `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.
438
+ - `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.
439
+ - `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.
440
+ - `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.
441
+ - `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.
442
+ - `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.
443
+ - `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.
444
+
445
+ ## @jgengine/core/movement/glideModel
446
+
447
+ - `GlideInput` (interface): interface GlideInput — ⚠ undocumented
448
+ - `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.
449
+ - `GlideModelConfig` (interface): interface GlideModelConfig — ⚠ undocumented
450
+ - `GlideStep` (interface): interface GlideStep — ⚠ undocumented
451
+ - `GlideVec3` (type): type GlideVec3 = readonly [number, number, number] — ⚠ undocumented
452
+ - `createGlideModel` (function): function createGlideModel(config: GlideModelConfig = {}): GlideModel — Gliding/wingsuit descent control — lift, drag, and steering from a launch.
453
+
454
+ ## @jgengine/core/movement/grappleSwing
455
+
456
+ - `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.
457
+ - `GrappleSwingConfig` (interface): interface GrappleSwingConfig — ⚠ undocumented
458
+ - `GrappleSwingState` (interface): interface GrappleSwingState — ⚠ undocumented
459
+ - `GrappleSwingStep` (interface): interface GrappleSwingStep — ⚠ undocumented
460
+ - `SwingVec3` (type): type SwingVec3 = readonly [number, number, number] — ⚠ undocumented
461
+ - `createGrappleSwing` (function): function createGrappleSwing(config: GrappleSwingConfig = {}): GrappleSwing — Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.
462
+
463
+ ## @jgengine/core/movement/leaderTrail
464
+
465
+ - `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.
466
+ - `LeaderTrailConfig` (interface): interface LeaderTrailConfig — ⚠ undocumented
467
+ - `TrailPoint` (type): type TrailPoint = readonly [number, number, number] — ⚠ undocumented
468
+ - `TrailPose` (interface): interface TrailPose — ⚠ undocumented
469
+ - `createLeaderTrail` (function): function createLeaderTrail(config: LeaderTrailConfig): LeaderTrail — A trailing follower formation that chases a leader along its past path — snake/convoy trails.
470
+
471
+ ## @jgengine/core/movement/movementModel
472
+
473
+ - `CollisionObstacle` (interface): interface CollisionObstacle — A placed scene object the walking player collides against as a circle-vs-AABB obstacle.
474
+ - `MAX_JUMP_OFFSET` (const): const MAX_JUMP_OFFSET: 1.15 — Peak jump height from MOVEMENT_TUNING.jumpVelocity + gravity, with small buffer.
475
+ - `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.
476
+ - `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.
477
+ - `MovementFrameStep` (interface): interface MovementFrameStep — Horizontal step (world units) the avatar should commit this frame.
478
+ - `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.
479
+ - `MovementKey` (type): type MovementKey = "w" | "a" | "s" | "d" | "shift" | "control" | "c" | "space" — Movement core (pure model).
480
+ - `MovementKeysState` (type): type MovementKeysState = Record<MovementKey, boolean> — ⚠ undocumented
481
+ - `MovementTuningOverrides` (interface): interface MovementTuningOverrides — Per-game overrides for the gravity/jump feel, sourced from `GameDefinition.physics`. Omitted fields fall back to {@link MOVEMENT_TUNING}.
482
+ - `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.
483
+
484
+ ## @jgengine/core/movement/playerMovement
485
+
486
+ - `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.
487
+ - `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.
488
+ - `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.
489
+ - `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.
490
+ - `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}.
491
+ - `stepPlayerMovement` (function): function stepPlayerMovement(ctx: GameContext, userId: string, input: InputFrame, dt: number, tuning: PlayerMovementTuning, heading?: 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.
492
+
493
+ ## @jgengine/core/movement/poseState
494
+
495
+ - `AimMode` (type): type AimMode = "hip" | "ads" — ⚠ undocumented
496
+ - `MovementPose` (type): type MovementPose = "standing" | "crouch" | "prone" | "running" — ⚠ undocumented
497
+ - `POSE_HITBOX` (const): const POSE_HITBOX: Record<MovementPose, PoseHitbox> — ⚠ undocumented
498
+ - `PoseAllowedStates` (interface): interface PoseAllowedStates — ⚠ undocumented
499
+ - `PoseHitbox` (interface): interface PoseHitbox — ⚠ undocumented
500
+ - `PoseRejection` (interface): interface PoseRejection — ⚠ undocumented
501
+ - `PoseSnapshot` (interface): interface PoseSnapshot — ⚠ undocumented
502
+ - `PoseState` (interface): interface PoseState — ⚠ undocumented
503
+ - `createPoseState` (function): function createPoseState(resolveAllowed: (instanceId: string) => PoseAllowedStates | null | undefined): PoseState — Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.
504
+
505
+ ## @jgengine/core/movement/steering
506
+
507
+ - `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.
508
+ - `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.
509
+ - `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.
510
+ - `yawForward` (function): function yawForward(yaw: number): YawVectorXZ — XZ forward direction of a yaw (`rotationY`): `(sin yaw, cos yaw)`.
511
+ - `yawRight` (function): function yawRight(yaw: number): YawVectorXZ — XZ screen-right of a yaw — `forward × up` with up = +Y: `(-cos yaw, sin yaw)`.
512
+
513
+ ## @jgengine/core/movement/voxelController
514
+
515
+ - `DEFAULT_VOXEL_DIMS` (const): const DEFAULT_VOXEL_DIMS: VoxelPlayerDims — ⚠ undocumented
516
+ - `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.
517
+ - `SolidQuery` (type): type SolidQuery = (x: number, y: number, z: number) => boolean — ⚠ undocumented
518
+ - `VoxelPlayerBody` (interface): interface VoxelPlayerBody — Mutable kinematic state carried between frames by the voxel controller.
519
+ - `VoxelPlayerDims` (interface): interface VoxelPlayerDims — Footprint + height of the player box, in world units.
520
+ - `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): void — Advance one frame of voxel-collided player kinematics. Mutates `body` (position, velocity, grounded) in place.
521
+ - `createVoxelPlayerBody` (function): function createVoxelPlayerBody(x: number, y: number, z: number): VoxelPlayerBody — ⚠ undocumented
522
+
523
+ ## @jgengine/core/nav/corridors
524
+
525
+ - `CorridorEdge` (interface): interface CorridorEdge — ⚠ undocumented
526
+ - `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.
527
+ - `CorridorPoint` (type): type CorridorPoint = readonly [number, number] — ⚠ undocumented
528
+ - `CorridorSample` (interface): interface CorridorSample — ⚠ undocumented
529
+ - `createCorridorField` (function): function createCorridorField(edges: readonly CorridorEdge[]): CorridorField — ⚠ undocumented
530
+
531
+ ## @jgengine/core/nav/navConstrain
532
+
533
+ - `NavConstrainEntity` (interface): interface NavConstrainEntity — ⚠ undocumented
534
+ - `NavConstrainOptions` (interface): interface NavConstrainOptions — ⚠ undocumented
535
+ - `NavConstrainProposed` (interface): interface NavConstrainProposed — ⚠ undocumented
536
+ - `constrainToNavGrid` (function): function constrainToNavGrid(grid: NavGrid, options?: NavConstrainOptions): (proposed: NavConstrainProposed, entity: NavConstrainEntity) => NavConstrainProposed | null — ⚠ undocumented
537
+
538
+ ## @jgengine/core/nav/navFromEnvironment
539
+
540
+ - `NavObstacleGrid` (interface): interface NavObstacleGrid — ⚠ undocumented
541
+ - `populateNavGridFromEnvironment` (function): function populateNavGridFromEnvironment(grid: NavObstacleGrid, world: EnvironmentWorldFeature): number — Expands every structure descriptor on an environment world feature into its generated buildings and blocks their footprints on `grid`. Returns the number of buildings blocked.
542
+
543
+ ## @jgengine/core/nav/navGrid
544
+
545
+ - `FindPathOptions` (interface): interface FindPathOptions — ⚠ undocumented
546
+ - `NavCell` (interface): interface NavCell — ⚠ undocumented
547
+ - `NavGrid` (interface): interface NavGrid — ⚠ undocumented
548
+ - `NavGridConfig` (interface): interface NavGridConfig — ⚠ undocumented
549
+ - `NavPoint` (type): type NavPoint = readonly [number, number] — ⚠ undocumented
550
+ - `createNavGrid` (function): function createNavGrid(config: NavGridConfig): NavGrid — ⚠ undocumented
551
+ - `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.
552
+ - `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.
553
+ - `smoothPath` (function): function smoothPath(grid: NavGrid, points: readonly NavPoint[]): NavPoint[] — Remove waypoints the mover can skip because it has clear line-of-sight past them.
554
+
555
+ ## @jgengine/core/nav/pathFollow
556
+
557
+ - `HeightSampler` (interface): interface HeightSampler — ⚠ undocumented
558
+ - `PathFollowConfig` (interface): interface PathFollowConfig — ⚠ undocumented
559
+ - `PathFollowProgress` (interface): interface PathFollowProgress — Read-only progress readout for inspection/debug tooling, produced by {@link pathFollowProgress}.
560
+ - `PathFollowState` (interface): interface PathFollowState — ⚠ undocumented
561
+ - `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.
562
+ - `Waypoint` (type): type Waypoint = readonly [number, number, number] — ⚠ undocumented
563
+ - `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).
564
+ - `createPathFollow` (function): function createPathFollow(config: PathFollowConfig): PathFollowState — ⚠ undocumented
565
+ - `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.
566
+ - `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.
567
+ - `pathFromNav` (function): function pathFromNav(points: readonly NavPoint[], elevation: number | HeightSampler = 0, offset = 0): Waypoint[] — ⚠ undocumented
568
+ - `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.
569
+
570
+ ## @jgengine/core/nav/railGraph
571
+
572
+ - `RailEdge` (interface): interface RailEdge — ⚠ undocumented
573
+ - `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.
574
+ - `RailGraphConfig` (interface): interface RailGraphConfig — ⚠ undocumented
575
+ - `RailNode` (interface): interface RailNode — ⚠ undocumented
576
+ - `RailRider` (interface): interface RailRider — ⚠ undocumented
577
+ - `RailRiderConfig` (interface): interface RailRiderConfig — ⚠ undocumented
578
+ - `RailRiderPose` (interface): interface RailRiderPose — ⚠ undocumented
579
+ - `ResolvedRailEdge` (interface): interface ResolvedRailEdge — ⚠ undocumented
580
+ - `createRailGraph` (function): function createRailGraph(config: RailGraphConfig): RailGraph — ⚠ undocumented
581
+ - `createRailRider` (function): function createRailRider(graph: RailGraph, config: RailRiderConfig): RailRider — ⚠ undocumented
582
+
583
+ ## @jgengine/core/nav/timetable
584
+
585
+ - `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.
586
+ - `RouteTimetableConfig` (interface): interface RouteTimetableConfig — ⚠ undocumented
587
+ - `TimetablePose` (interface): interface TimetablePose — ⚠ undocumented
588
+ - `TimetableStop` (interface): interface TimetableStop — ⚠ undocumented
589
+ - `createRouteTimetable` (function): function createRouteTimetable(config: RouteTimetableConfig): RouteTimetable — ⚠ undocumented
590
+
591
+ ## @jgengine/core/orders/orderKinds
592
+
593
+ - `AttackMoveOrderPayload` (interface): interface AttackMoveOrderPayload — Payload for an attack-move: advance toward `point`, engaging hostiles encountered en route.
594
+ - `EmptyOrderPayload` (type): type EmptyOrderPayload = Record<string, never> — Payload for stop/hold orders — no data; the verb is the intent.
595
+ - `EngagementKindConfig` (interface): interface EngagementKindConfig extends OrderKindConfig — Move + engagement config carrying the default radii the payload may override.
596
+ - `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.
597
+ - `MoveOrderPayload` (interface): interface MoveOrderPayload — Payload for a move order: go to a point and complete on arrival.
598
+ - `OrderKindConfig` (interface): interface OrderKindConfig — Shared factory config: override the verb key so a game can register the composition under its own name.
599
+ - `OrderMoveResult` (interface): interface OrderMoveResult — Result of one movement step, from the game's motion adapter.
600
+ - `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.
601
+ - `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.
602
+ - `PatrolOrderPayload` (interface): interface PatrolOrderPayload — Payload for a patrol: walk a waypoint route, optionally looping forever.
603
+ - `PatrolOrderState` (interface): interface PatrolOrderState — Serializable patrol progress.
604
+ - `TargetedOrderPayload` (interface): interface TargetedOrderPayload — Payload for a targeted action: pursue one target until in range, holding within a leash.
605
+ - `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.
606
+ - `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.
607
+ - `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`.
608
+ - `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`.
609
+ - `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.
610
+ - `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.
611
+
612
+ ## @jgengine/core/orders/orderQueue
613
+
614
+ - `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`.
615
+ - `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`.
616
+ - `OrderEvent` (interface): interface OrderEvent — A lifecycle event emitted synchronously as orders move through the queue.
617
+ - `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).
618
+ - `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.
619
+ - `OrderOutcome` (interface): interface OrderOutcome — Terminal outcome handed to a kind's `finish` cleanup hook.
620
+ - `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.
621
+ - `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.
622
+ - `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.
623
+ - `OrderQueueOptions` (interface): interface OrderQueueOptions<TPayload = unknown> — Construction options for a queue.
624
+ - `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.
625
+ - `OrderQueueState` (interface): interface OrderQueueState<TPayload = unknown> — Serializable snapshot of a queue: the active order plus the pending list, in order.
626
+ - `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.
627
+ - `OrderRejection` (interface): interface OrderRejection — A kind's refusal of a payload (from `validate`) — surfaced to the issuer as a rejection reason.
628
+ - `OrderRequest` (interface): interface OrderRequest<TPayload = unknown> — A request to issue an order; `policy` defaults to `replace`, `id` is generated when omitted.
629
+ - `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`.
630
+ - `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.
631
+ - `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.
632
+ - `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.
633
+ - `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.
634
+
635
+ ## @jgengine/core/physics/ballisticSweep
636
+
637
+ - `BallisticSweep` (type): type BallisticSweep = ( origin: readonly [number, number, number], velocity: readonly [number, number, number], gravity: number, maxTime: number, ) => BallisticSweepHit | null — ⚠ undocumented
638
+ - `BallisticSweepHit` (interface): interface BallisticSweepHit — ⚠ undocumented
639
+ - `BallisticSweepOptions` (interface): interface BallisticSweepOptions — ⚠ undocumented
640
+ - `createBallisticSweep` (function): function createBallisticSweep(world: PhysicsWorld, options: BallisticSweepOptions = {}): BallisticSweep — Marches the closed-form arc (constant gravity, straight lateral) through `world` and reports the first sample inside any live body's AABB — sleeping bodies included — refined by one bisection between the last clear sample and the hit sample. Returns `null` when the whole arc is clear.
641
+
642
+ ## @jgengine/core/physics/buoyancy
643
+
644
+ - `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)`.
645
+ - `BuoyantBodyConfig` (interface): interface BuoyantBodyConfig — ⚠ undocumented
646
+ - `createBuoyantBody` (function): function createBuoyantBody(world: PhysicsWorld, config: BuoyantBodyConfig): BuoyantBody — ⚠ undocumented
647
+
648
+ ## @jgengine/core/physics/carryable
649
+
650
+ - `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.
651
+ - `CarryableConfig` (interface): interface CarryableConfig — ⚠ undocumented
652
+ - `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.).
653
+
654
+ ## @jgengine/core/physics/damageZones
655
+
656
+ - `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.
657
+ - `DamageModelConfig` (interface): interface DamageModelConfig — ⚠ undocumented
658
+ - `DamageTransition` (interface): interface DamageTransition — ⚠ undocumented
659
+ - `DamageZoneDef` (interface): interface DamageZoneDef — ⚠ undocumented
660
+ - `DamageZoneState` (interface): interface DamageZoneState — ⚠ undocumented
661
+ - `createDamageModel` (function): function createDamageModel(config: DamageModelConfig): DamageModel — ⚠ undocumented
662
+
663
+ ## @jgengine/core/physics/drivableVehicle
664
+
665
+ - `DrivableVehicleOptions` (interface): interface DrivableVehicleOptions — Options for {@link tickDrivableVehicle} — ground snapping and per-tick tuning modifiers.
666
+ - `DrivableVehiclePose` (interface): interface DrivableVehiclePose — A `setPose`-ready patch — spread straight into `entities.setPose(vehicleId, drive.pose)`.
667
+ - `DrivableVehiclePosition` (type): type DrivableVehiclePosition = readonly [number, number, number] — World-space `[x, y, z]` for a drivable vehicle's resolved pose.
668
+ - `DrivableVehicleStep` (interface): interface DrivableVehicleStep — {@link tickDrivableVehicle}'s result — the ready-to-apply pose patch plus the raw sim step for HUD/telemetry reads.
669
+ - `tickDrivableVehicle` (function): function tickDrivableVehicle(vehicle: KinematicVehicle, dt: number, axis: AxisInput, options: DrivableVehicleOptions = {}): DrivableVehicleStep — Connects an `AxisInput` sample straight through a {@link KinematicVehicle} 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.
670
+
671
+ ## @jgengine/core/physics/flightDynamics
672
+
673
+ - `AircraftDynamics` (interface): interface AircraftDynamics — Stateful six-degree-of-freedom aircraft simulation.
674
+ - `AircraftKind` (type): type AircraftKind = "fixedWing" | "rotorcraft" | "vtol" — Supported aerodynamic/propulsion families.
675
+ - `AircraftOptions` (interface): interface AircraftOptions — Spawn state and injectable world-field samplers for an aircraft instance.
676
+ - `AircraftStep` (interface): interface AircraftStep — Pose and aerodynamic telemetry returned after one flight tick.
677
+ - `AircraftTuning` (interface): interface AircraftTuning — Data-first physical tuning shared by all aircraft instances of one catalog type.
678
+ - `FlightControlInput` (interface): interface FlightControlInput — Normalized pilot inputs for one flight-simulation tick.
679
+ - `FlightControlRates` (interface): interface FlightControlRates — Angular authority, response, damping, and self-leveling configuration.
680
+ - `FlightVector` (type): type FlightVector = readonly [number, number, number] — Three-dimensional world-space vector used by the flight model.
681
+ - `createAircraftDynamics` (function): function createAircraftDynamics(tuning: AircraftTuning, options: AircraftOptions = {}): AircraftDynamics — Six-degree-of-freedom arcade flight model for fixed-wing, helicopter, and VTOL aircraft.
682
+
683
+ ## @jgengine/core/physics/flowTube
684
+
685
+ - `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).
686
+ - `FlowTubeConfig` (interface): interface FlowTubeConfig — ⚠ undocumented
687
+ - `FlowVec3` (type): type FlowVec3 = readonly [number, number, number] — ⚠ undocumented
688
+ - `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.
689
+ - `createFlowTube` (function): function createFlowTube(config: FlowTubeConfig): FlowTube — ⚠ undocumented
690
+
691
+ ## @jgengine/core/physics/forceVolume
692
+
693
+ - `ForceMode` (type): type ForceMode = "impulse" | "velocity" | "accelerate" — ⚠ undocumented
694
+ - `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.
695
+ - `ForceVolumeConfig` (interface): interface ForceVolumeConfig — ⚠ undocumented
696
+ - `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.
697
+ - `PlatformCarryConfig` (interface): interface PlatformCarryConfig — ⚠ undocumented
698
+ - `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.
699
+ - `VolumeTriggerConfig` (interface): interface VolumeTriggerConfig — ⚠ undocumented
700
+ - `VolumeTriggerStep` (interface): interface VolumeTriggerStep<TId> — ⚠ undocumented
701
+ - `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.
702
+ - `createVolumeTrigger` (function): function createVolumeTrigger<TId = string>(config: VolumeTriggerConfig): VolumeTrigger<TId> — ⚠ undocumented
703
+
704
+ ## @jgengine/core/physics/gravityField
705
+
706
+ - `GravityField` (interface): interface GravityField — Position-dependent gravity source used by movement and vehicle simulations.
707
+ - `GravityVector` (type): type GravityVector = readonly [number, number, number] — Three-dimensional acceleration vector sampled from a gravity field.
708
+ - `PointGravityOptions` (interface): interface PointGravityOptions — Center, strength, and falloff for radial gravity.
709
+ - `combineGravity` (function): function combineGravity(fields: readonly GravityField[]): GravityField — Adds several gravity sources into one field.
710
+ - `pointGravity` (function): function pointGravity(options: PointGravityOptions): GravityField — Radial gravity toward one center, with optional inverse-square falloff for planetary worlds.
711
+ - `uniformGravity` (function): function uniformGravity(vector: GravityVector = [0, -9.81, 0]): GravityField — Constant vector gravity for ordinary worlds, space stations, and sideways-gravity levels.
712
+
713
+ ## @jgengine/core/physics/kinematicVehicle
714
+
715
+ - `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.
716
+ - `KinematicDynamicsTuning` (interface): interface KinematicDynamicsTuning — Aerodynamic and electronic-assist settings layered over tire grip.
717
+ - `KinematicPowertrainTuning` (interface): interface KinematicPowertrainTuning — Data-first gearbox and torque-curve tuning for a kinematic ground vehicle.
718
+ - `KinematicSteeringTuning` (interface): interface KinematicSteeringTuning — Bicycle-model steering settings; all angles are radians.
719
+ - `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.
720
+ - `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.
721
+ - `KinematicVehicleOptions` (interface): interface KinematicVehicleOptions — ⚠ undocumented
722
+ - `KinematicVehicleStep` (interface): interface KinematicVehicleStep — ⚠ undocumented
723
+ - `KinematicVehicleTuning` (interface): interface KinematicVehicleTuning — ⚠ undocumented
724
+ - `createKinematicVehicle` (function): function createKinematicVehicle(tuning: KinematicVehicleTuning, options: KinematicVehicleOptions = {}): KinematicVehicle — ⚠ undocumented
725
+
726
+ ## @jgengine/core/physics/physicsWorld
727
+
728
+ - `AddBodyOptions` (type): type AddBodyOptions = BoxBodyOptions | SphereBodyOptions — ⚠ undocumented
729
+ - `BodyCommonOptions` (interface): interface BodyCommonOptions — ⚠ undocumented
730
+ - `BoxBodyOptions` (interface): interface BoxBodyOptions extends BodyCommonOptions — ⚠ undocumented
731
+ - `CollisionEvent` (interface): interface CollisionEvent — A contact reported to `onCollision`. The object is reused each call — read/copy, never retain.
732
+ - `JOINT_DISTANCE` (const): const JOINT_DISTANCE: 2 — ⚠ undocumented
733
+ - `JOINT_FIXED` (const): const JOINT_FIXED: 0 — ⚠ undocumented
734
+ - `JOINT_HINGE` (const): const JOINT_HINGE: 1 — ⚠ undocumented
735
+ - `JOINT_SPRING` (const): const JOINT_SPRING: 3 — ⚠ undocumented
736
+ - `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`.
737
+ - `JointOptions` (interface): interface JointOptions — ⚠ undocumented
738
+ - `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()`.
739
+ - `PhysicsBounds` (interface): interface PhysicsBounds — ⚠ undocumented
740
+ - `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.
741
+ - `PhysicsStats` (interface): interface PhysicsStats — ⚠ undocumented
742
+ - `PhysicsWorld` (class): class PhysicsWorld — ⚠ undocumented
743
+ - `PhysicsWorldConfig` (interface): interface PhysicsWorldConfig — ⚠ undocumented
744
+ - `SHAPE_BOX` (const): const SHAPE_BOX: 0 — ⚠ undocumented
745
+ - `SHAPE_SPHERE` (const): const SHAPE_SPHERE: 1 — ⚠ undocumented
746
+ - `SphereBodyOptions` (interface): interface SphereBodyOptions extends BodyCommonOptions — The radius fills all three half-extent columns, so broadphase and bounds see the sphere's enclosing AABB.
747
+ - `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.
748
+ - `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.
749
+
750
+ ## @jgengine/core/physics/radialImpulse
751
+
752
+ - `RadialFalloff` (type): type RadialFalloff = "linear" | "quadratic" | "none" — How a radial impulse fades from the blast center to its edge.
753
+ - `RadialImpulse` (interface): interface RadialImpulse — A radial push: the impulse vector plus the 0..1 falloff sampled at the target.
754
+ - `RadialImpulseOptions` (interface): interface RadialImpulseOptions — Options for {@link radialImpulse}.
755
+ - `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.
756
+
757
+ ## @jgengine/core/physics/ragdoll
758
+
759
+ - `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.
760
+ - `RagdollBalanceConfig` (interface): interface RagdollBalanceConfig — ⚠ undocumented
761
+ - `RagdollBoneSpec` (interface): interface RagdollBoneSpec — ⚠ undocumented
762
+ - `RagdollConfig` (interface): interface RagdollConfig — ⚠ undocumented
763
+ - `RagdollLinkSpec` (interface): interface RagdollLinkSpec — ⚠ undocumented
764
+ - `createRagdoll` (function): function createRagdoll(world: PhysicsWorld, config: RagdollConfig): Ragdoll — ⚠ undocumented
765
+
766
+ ## @jgengine/core/physics/spatialGrid
767
+
768
+ - `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.
769
+ - `SpatialGridConfig` (interface): interface SpatialGridConfig — ⚠ undocumented
770
+
771
+ ## @jgengine/core/physics/structure
772
+
773
+ - `CollapseEvent` (interface): interface CollapseEvent — ⚠ undocumented
774
+ - `DebrisConfig` (interface): interface DebrisConfig — ⚠ undocumented
775
+ - `StructureEdgeSpec` (interface): interface StructureEdgeSpec — ⚠ undocumented
776
+ - `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.
777
+ - `StructureMaterial` (interface): interface StructureMaterial — ⚠ undocumented
778
+ - `StructureMaterialTable` (type): type StructureMaterialTable = Readonly<Record<string, StructureMaterial>> — ⚠ undocumented
779
+ - `StructureNodeSpec` (interface): interface StructureNodeSpec — ⚠ undocumented
780
+
781
+ ## @jgengine/core/physics/traversal
782
+
783
+ - `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.
784
+ - `GlideConfig` (interface): interface GlideConfig — ⚠ undocumented
785
+ - `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.
786
+ - `GrappleConfig` (interface): interface GrappleConfig — ⚠ undocumented
787
+
788
+ ## @jgengine/core/physics/vehicleBody
789
+
790
+ - `DEFAULT_GRIP_CURVE` (const): const DEFAULT_GRIP_CURVE: GripCurve — ⚠ undocumented
791
+ - `GripCurve` (interface): interface GripCurve — ⚠ undocumented
792
+ - `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)`.
793
+ - `VehicleBodyConfig` (interface): interface VehicleBodyConfig — ⚠ undocumented
794
+ - `WheelSpec` (interface): interface WheelSpec — ⚠ undocumented
795
+ - `WheelState` (interface): interface WheelState — ⚠ undocumented
796
+ - `createVehicleBody` (function): function createVehicleBody(world: PhysicsWorld, config: VehicleBodyConfig): VehicleBody — ⚠ undocumented
797
+ - `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.
798
+
799
+ ## @jgengine/core/physics/vehicleObstacles
800
+
801
+ - `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}.
802
+ - `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.
803
+ - `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}).
804
+
805
+ ## @jgengine/core/procedural
806
+
807
+ - `DecayMeterSet` (interface): interface DecayMeterSet — Set of named survival meters (hunger/thirst/…) that drain and refill over game time.
808
+ - `Moodle` (interface): interface Moodle — One survival moodle (status icon) — severity, source, and label for HUD chips.
809
+ - `MoodleStack` (interface): interface MoodleStack — Ordered stack of active moodles derived from meters/ailments/buffs.
810
+ - `MultiRegionHealth` (interface): interface MultiRegionHealth — Per-limb / per-region health track with treat/damage/heal APIs.
811
+ - `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`.
812
+ - `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.
813
+ - `createMultiRegionHealth` (function): function createMultiRegionHealth(config: MultiRegionHealthConfig): MultiRegionHealth — Per-region/limb health tracked separately, so each body part takes and heals damage on its own.
814
+ - `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.
815
+
816
+ ## @jgengine/core/scene/assetCatalog
817
+
818
+ - `AssetCatalog` (interface): interface AssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef> — ⚠ undocumented
819
+ - `AssetRef` (type): type AssetRef = ModelAssetRef | GeneratorAssetRef — A catalog entry: a static GLB model, or a parametric generator.
820
+ - `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.
821
+ - `ModelAssetRef` (interface): interface ModelAssetRef — ⚠ undocumented
822
+ - `ModelDims` (interface): interface ModelDims — Measured horizontal footprint, footprint center, and lowest Y of a model in model space.
823
+ - `createAssetCatalog` (function): function createAssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef>(): AssetCatalog<TMeta> — ⚠ undocumented
824
+
825
+ ## @jgengine/core/scene/assetDiagnostics
826
+
827
+ - `AssetLoadDiagnosis` (interface): interface AssetLoadDiagnosis — The verdict for one model-asset fetch: its {@link AssetLoadKind} plus a ready-to-log message.
828
+ - `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.
829
+ - `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.
830
+ - `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).
831
+ - `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.
832
+
833
+ ## @jgengine/core/scene/assetGenerator
834
+
835
+ - `AssetGeneratorDefinition` (interface): interface AssetGeneratorDefinition — A registered asset generator — schema drives the inspector; `generate` is a pure seeded function.
836
+ - `GeneratedAsset` (interface): interface GeneratedAsset — A resolved generator asset: its parts plus the overall local-space bounds (min/max corners).
837
+ - `GeneratedPart` (interface): interface GeneratedPart — One generated primitive part — a box/panel placed in the asset's local space.
838
+ - `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.
839
+ - `registerAssetGenerator` (function): function registerAssetGenerator(definition: AssetGeneratorDefinition): void — Register a parametric asset generator. Idempotent per id (last wins); call at module load.
840
+
841
+ ## @jgengine/core/scene/assetPreload
842
+
843
+ - `SceneAssetFetcher` (type): type SceneAssetFetcher = (url: string) => void — ⚠ undocumented
844
+ - `createSceneAssetPreloader` (function): function createSceneAssetPreloader(fetcher: SceneAssetFetcher): { preloadUrl(url: string): void; preloadUrls(urls: readonly string[]): void; hasPreloaded(url: string): boolean; reset(): void; } — ⚠ undocumented
845
+
846
+ ## @jgengine/core/scene/assetSpace
847
+
848
+ - `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]`.
849
+ - `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.
850
+ - `AssetSpaceIssue` (interface): interface AssetSpaceIssue — One problem found by {@link validateAssetSpace}: which metadata field and why it is invalid.
851
+ - `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.
852
+ - `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.
853
+ - `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.
854
+ - `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.
855
+ - `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.
856
+ - `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.
857
+ - `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.
858
+ - `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`.
859
+ - `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.
860
+ - `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.
861
+ - `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}.
862
+ - `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).
863
+ - `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.
864
+
865
+ ## @jgengine/core/scene/authoredTriggers
866
+
867
+ - `AuthoredTrigger` (interface): interface AuthoredTrigger — One resolved trigger binding from a document object.
868
+ - `AuthoredTriggerRuntime` (interface): interface AuthoredTriggerRuntime — Runtime handle that watches authored triggers against moving actors each tick.
869
+ - `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}.
870
+ - `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.
871
+ - `TriggerDispatchEvent` (interface): interface TriggerDispatchEvent — Fired when a watched actor trips an authored trigger edge.
872
+ - `TriggerEvent` (type): type TriggerEvent = "enter" | "exit" | "interact" — Event edge that can fire an authored trigger.
873
+ - `TriggerHandlers` (type): type TriggerHandlers = Readonly<Record<string, (event: TriggerDispatchEvent) => void>> — Handler map keyed by action id — unknown actions are skipped unless `onDispatch` is set.
874
+ - `TriggerOutcome` (interface): interface TriggerOutcome — Serializable read-model the built-in trigger actions write — the HUD/game reads it each frame.
875
+ - `TriggerOutcomeStore` (interface): interface TriggerOutcomeStore — Outcome store: the built-in action handlers plus a subscribable snapshot of what they produced.
876
+ - `TriggerSourceKind` (type): type TriggerSourceKind = "marker" | "volume" — Document collection a trigger source lives on.
877
+ - `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.
878
+ - `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.
879
+ - `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.
880
+ - `getTriggerAction` (function): function getTriggerAction(id: string): TriggerActionDefinition | undefined — Registered definition for an action id, or undefined when the game never declared it.
881
+ - `listTriggerActions` (function): function listTriggerActions(target?: TriggerSourceKind): TriggerActionDefinition[] — Every registered action, optionally filtered by target collection.
882
+ - `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.
883
+ - `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).
884
+ - `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.
885
+
886
+ ## @jgengine/core/scene/autoTarget
887
+
888
+ - `AutoTargetDeps` (interface): interface AutoTargetDeps — ⚠ undocumented
889
+ - `AutoTargetPolicy` (type): type AutoTargetPolicy = | "nearest" | "farthest" | "random" | "strongest" | "weakest" | "first" | "last" — ⚠ undocumented
890
+ - `AutoTargeter` (interface): interface AutoTargeter — ⚠ undocumented
891
+ - `createAutoTargeter` (function): function createAutoTargeter(policy: AutoTargetPolicy, deps: AutoTargetDeps): AutoTargeter — ⚠ undocumented
892
+ - `selectAutoTarget` (function): function selectAutoTarget(policy: AutoTargetPolicy, fromId: string, deps: AutoTargetDeps): string | null — ⚠ undocumented
893
+
894
+ ## @jgengine/core/scene/behaviorRuntime
895
+
896
+ - `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}.
897
+ - `BehaviorInspection` (interface): interface BehaviorInspection — Inspection readout for editor/debug tooling, from {@link BehaviorControl.inspect}/{@link BehaviorControl.list}.
898
+ - `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 treats it as `freeze`.
899
+ - `BehaviorSnapshot` (type): type BehaviorSnapshot = | { readonly kind: "patrol"; readonly state: PathFollowState } | { readonly kind: "wander"; readonly origin: Waypoint; readonly target: Waypoint | null } — Serializable snapshot of one behavior instance — round-trips exactly through {@link BehaviorControl.serialize}/{@link BehaviorControl.restore}.
900
+ - `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`).
901
+ - `advanceBehaviors` (function): function advanceBehaviors(ctx: GameContext, dt: number): void — Advance every spawned entity carrying a `patrol` or `wander` {@link BehaviorDescriptor} 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.
902
+ - `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.
903
+
904
+ ## @jgengine/core/scene/behaviors
905
+
906
+ - `BehaviorDescriptor` (type): type BehaviorDescriptor = | WanderBehavior | PatrolBehavior | PromptableBehavior | PlayerBehavior — ⚠ undocumented
907
+ - `PatrolBehavior` (interface): interface PatrolBehavior — ⚠ undocumented
908
+ - `PlayerBehavior` (interface): interface PlayerBehavior — ⚠ undocumented
909
+ - `PromptableBehavior` (interface): interface PromptableBehavior — ⚠ undocumented
910
+ - `WanderBehavior` (interface): interface WanderBehavior — ⚠ undocumented
911
+ - `patrol` (function): function patrol({ waypoints, speed, loop = true, startProgress, groundClamp, }: { waypoints: readonly Waypoint[]; speed: number; loop?: boolean; startProgress?: PathProgress; groundClamp?: boolean; }): PatrolBehavior — ⚠ undocumented
912
+ - `player` (function): function player(): PlayerBehavior — ⚠ undocumented
913
+ - `promptable` (function): function promptable(prompt: ProximityPrompt): PromptableBehavior — ⚠ undocumented
914
+ - `talkable` (function): function talkable(dialogueId: string): PromptableBehavior — ⚠ undocumented
915
+ - `wander` (function): function wander({ radius }: { radius: number }): WanderBehavior — ⚠ undocumented
916
+
917
+ ## @jgengine/core/scene/bodyBind
918
+
919
+ - `BodyBind` (interface): interface BodyBind — The lazily-keyed handle `ctx.scene.entity.bind(key)` returns.
920
+ - `BodyBindDeps` (interface): interface BodyBindDeps — Structural entity-store seam a {@link BodyBind} mirrors onto — satisfied by `ctx.scene.entity` itself.
921
+ - `BodyBindPose` (interface): interface BodyBindPose — The pose a {@link BodyBindDeps.setPose} call receives for an id already bound.
922
+ - `BodyBindSpawnInput` (interface): interface BodyBindSpawnInput — The options a {@link BodyBindDeps.spawn} call receives for an id seen for the first time.
923
+ - `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).
924
+ - `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.
925
+
926
+ ## @jgengine/core/scene/builtinSceneKinds
927
+
928
+ - `SCATTER_SCHEMA` (const): const SCATTER_SCHEMA: ParamSchema — The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`.
929
+
930
+ ## @jgengine/core/scene/captureCheck
931
+
932
+ - `CaptureCheckInput` (interface): interface CaptureCheckInput — ⚠ undocumented
933
+ - `captureChance` (function): function captureChance(input: CaptureCheckInput): number — ⚠ undocumented
934
+ - `rollCapture` (function): function rollCapture(input: CaptureCheckInput, rng: () => number = Math.random): boolean — ⚠ undocumented
935
+
936
+ ## @jgengine/core/scene/colliders
937
+
938
+ - `ColliderDef` (interface): interface ColliderDef — ⚠ undocumented
939
+ - `ColliderPurpose` (type): type ColliderPurpose = "physical" | "damage" — ⚠ undocumented
940
+ - `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`.
941
+ - `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).
942
+ - `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).
943
+ - `DEFAULT_ENTITY_HIT_RADIUS` (const): const DEFAULT_ENTITY_HIT_RADIUS: 0.5 — ⚠ undocumented
944
+ - `DEFAULT_OBJECT_HALF_EXTENTS` (const): const DEFAULT_OBJECT_HALF_EXTENTS: EntityPosition — ⚠ undocumented
945
+ - `EntityColliderSet` (interface): interface EntityColliderSet — ⚠ undocumented
946
+ - `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.
947
+ - `ResolvedCollider` (interface): interface ResolvedCollider — ⚠ undocumented
948
+
949
+ ## @jgengine/core/scene/collisionMesh
950
+
951
+ - `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.
952
+ - `CollisionMeshHit` (interface): interface CollisionMeshHit — Nearest triangle impact from {@link raycastCollisionMesh}: world distance along the ray and the world-space geometric normal facing the ray.
953
+ - `CollisionMeshSource` (interface): interface CollisionMeshSource — Raw triangle soup for {@link encodeCollisionMesh}: model-space xyz triples plus triangle indices.
954
+ - `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.
955
+ - `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.
956
+ - `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.
957
+ - `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.
958
+
959
+ ## @jgengine/core/scene/companion
960
+
961
+ - `CompanionAdoptOptions` (interface): interface CompanionAdoptOptions — Options for {@link CompanionRoster.adopt}.
962
+ - `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.
963
+ - `CompanionConfig` (interface): interface CompanionConfig — Per-companion configuration shared by every companion the roster mints.
964
+ - `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.
965
+ - `CompanionIntentContext` (interface): interface CompanionIntentContext — Per-tick world context the game supplies so a command resolves into a concrete intent.
966
+ - `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.
967
+ - `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.
968
+ - `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.
969
+ - `CompanionStatUpgrade` (interface): interface CompanionStatUpgrade — Rule for turning one spent level-point into a stat gain. Absent from config ⇒ the stat can't be upgraded.
970
+ - `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.
971
+ - `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.
972
+
973
+ ## @jgengine/core/scene/entityStats
974
+
975
+ - `EntityStatsApi` (interface): interface EntityStatsApi extends StatPoolAccess — Native entity-stat adapter over the portable {@link StatPoolAccess} contract.
976
+ - `PoolDeltaResult` (type): type PoolDeltaResult = | { status: "ok"; map: StatValueMap; stat: StatValue; hitMin: boolean; hitMax: boolean } | { status: "rejected"; reason: string } — ⚠ undocumented
977
+ - `StatCatalog` (type): type StatCatalog = Record<string, { max: number; min?: number; current?: number }> — ⚠ undocumented
978
+ - `StatValue` (interface): interface StatValue extends StatPool — Native entity-stat name retained as a compatibility bridge to the portable pool model.
979
+ - `StatValueMap` (type): type StatValueMap = Record<string, StatValue> — ⚠ undocumented
980
+ - `StatValuePatch` (interface): interface StatValuePatch extends StatPoolPatch — Native entity-stat patch retained as a compatibility bridge.
981
+
982
+ ## @jgengine/core/scene/entityStore
983
+
984
+ - `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.
985
+ - `EntityMovement` (interface): interface EntityMovement — ⚠ undocumented
986
+ - `EntityPose` (interface): interface EntityPose — ⚠ undocumented
987
+ - `EntityPosition` (type): type EntityPosition = readonly [number, number, number] — ⚠ undocumented
988
+ - `EntityRole` (type): type EntityRole = "player" | "npc" | "prop" — ⚠ undocumented
989
+ - `EntityStore` (interface): interface EntityStore<TMeta = unknown> — ⚠ undocumented
990
+ - `EntityUpdatePatch` (type): type EntityUpdatePatch<TMeta = unknown> = Partial< Pick<SceneEntity<TMeta>, "name" | "rotationY" | "rotationX" | "rotationZ" | "role" | "movement" | "behaviors" | "meta"> > & { /** Accepts the same friendly shapes as `spawn`/`setPose` (#286.13). Raw patch semantics — velocity is not derived; use `se… — ⚠ undocumented
991
+ - `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.
992
+ - `PoseConstraintFrame` (interface): interface PoseConstraintFrame — ⚠ undocumented
993
+ - `SceneEntity` (interface): interface SceneEntity<TMeta = unknown> — ⚠ undocumented
994
+ - `SpawnOptions` (interface): interface SpawnOptions<TMeta = unknown> — ⚠ undocumented
995
+ - `SpawnPose` (interface): interface SpawnPose — ⚠ undocumented
996
+ - `SpawnPositionInput` (type): type SpawnPositionInput = EntityPosition | { x: number; y: number; z: number } — ⚠ undocumented
997
+ - `createEntityStore` (function): function createEntityStore<TMeta = unknown>(): EntityStore<TMeta> — ⚠ undocumented
998
+ - `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.
999
+ - `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.
1000
+ - `movedWhileFrozen` (function): function movedWhileFrozen(entity: SceneEntity<unknown>, threshold = DEFAULT_FROZEN_MOVE_THRESHOLD): boolean — ⚠ undocumented
1001
+
1002
+ ## @jgengine/core/scene/facing
1003
+
1004
+ - `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.
1005
+
1006
+ ## @jgengine/core/scene/form
1007
+
1008
+ - `FormChangedEvent` (interface): interface FormChangedEvent — ⚠ undocumented
1009
+ - `FormDef` (interface): interface FormDef — ⚠ undocumented
1010
+ - `FormEntities` (interface): interface FormEntities — ⚠ undocumented
1011
+ - `FormEvents` (interface): interface FormEvents — ⚠ undocumented
1012
+ - `FormTime` (interface): interface FormTime — ⚠ undocumented
1013
+ - `Forms` (interface): interface Forms — ⚠ undocumented
1014
+ - `FormsDeps` (interface): interface FormsDeps — ⚠ undocumented
1015
+ - `createForms` (function): function createForms(deps: FormsDeps): Forms — ⚠ undocumented
1016
+
1017
+ ## @jgengine/core/scene/modelSockets
1018
+
1019
+ - `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.
1020
+ - `ModelSocket` (interface): interface ModelSocket — One resolved socket: its node name and local-space offset from the model origin.
1021
+ - `SOCKET_PATTERN` (const): const SOCKET_PATTERN: RegExp — Default socket-name matcher: "socket", "wire", "attach", "anchor", "mount", "hardpoint" (any case).
1022
+ - `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.
1023
+
1024
+ ## @jgengine/core/scene/mount
1025
+
1026
+ - `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.
1027
+ - `MountKind` (type): type MountKind = "ground" | "boat" | "flying" | "swimming" — ⚠ undocumented
1028
+ - `MountKit` (interface): interface MountKit — ⚠ undocumented
1029
+ - `MountResult` (type): type MountResult = { ok: true; seat: MountSeat } | { ok: false; reason: string } — ⚠ undocumented
1030
+ - `MountSeat` (interface): interface MountSeat — ⚠ undocumented
1031
+ - `Occupant` (interface): interface Occupant — ⚠ undocumented
1032
+ - `RideableConfig` (interface): interface RideableConfig — ⚠ undocumented
1033
+ - `SeatRef` (interface): interface SeatRef — ⚠ undocumented
1034
+ - `createMountController` (function): function createMountController(): MountController — ⚠ undocumented
1035
+
1036
+ ## @jgengine/core/scene/movementSpeed
1037
+
1038
+ - `MovementSpeedConfig` (interface): interface MovementSpeedConfig — ⚠ undocumented
1039
+ - `MovementSpeedDeps` (interface): interface MovementSpeedDeps — ⚠ undocumented
1040
+ - `MovementSpeedModifiers` (interface): interface MovementSpeedModifiers — ⚠ undocumented
1041
+ - `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.
1042
+ - `deriveWalkSpeed` (function): function deriveWalkSpeed(base: number, modifiers: MovementSpeedModifiers): number — `base * (multiplier ?? 1) + (flatBonus ?? 0)`, clamped to never go negative.
1043
+
1044
+ ## @jgengine/core/scene/objectQuery
1045
+
1046
+ - `ObjectQueryBroadphase` (interface): interface ObjectQueryBroadphase — Optional broadphase for large object sets — typically `ObjectStore.inBox`.
1047
+ - `ObjectRaycastHit` (interface): interface ObjectRaycastHit — ⚠ undocumented
1048
+ - `ObjectRaycastInput` (interface): interface ObjectRaycastInput — ⚠ undocumented
1049
+ - `ObjectRaycastSource` (type): type ObjectRaycastSource = readonly SceneObject[] | ObjectQueryBroadphase — ⚠ undocumented
1050
+ - `intersectAabb` (function): function intersectAabb(origin: EntityPosition, direction: EntityPosition, min: EntityPosition, max: EntityPosition, maxDistance: number): { distance: number; normal: EntityPosition } | null — ⚠ undocumented
1051
+ - `normalizeDirection` (function): function normalizeDirection(direction: EntityPosition): EntityPosition — ⚠ undocumented
1052
+
1053
+ ## @jgengine/core/scene/objectStore
1054
+
1055
+ - `ObjectListFilter` (interface): interface ObjectListFilter — ⚠ undocumented
1056
+ - `ObjectStore` (interface): interface ObjectStore — ⚠ undocumented
1057
+ - `ObjectVisual` (interface): interface ObjectVisual — ⚠ undocumented
1058
+ - `PlaceOptions` (interface): interface PlaceOptions — ⚠ undocumented
1059
+ - `SceneObject` (interface): interface SceneObject — ⚠ undocumented
1060
+ - `createObjectStore` (function): function createObjectStore(): ObjectStore — ⚠ undocumented
1061
+ - `objectVisualScale` (function): function objectVisualScale(visual: ObjectVisual | undefined): readonly [number, number, number] — ⚠ undocumented
1062
+
1063
+ ## @jgengine/core/scene/paintLayer
1064
+
1065
+ - `PaintLayer` (interface): interface PaintLayer — ⚠ undocumented
1066
+ - `PaintStroke` (interface): interface PaintStroke — ⚠ undocumented
1067
+ - `createPaintLayer` (function): function createPaintLayer(): PaintLayer — ⚠ undocumented
1068
+
1069
+ ## @jgengine/core/scene/possession
1070
+
1071
+ - `Possession` (interface): interface Possession — ⚠ undocumented
1072
+ - `PossessionDeps` (interface): interface PossessionDeps — ⚠ undocumented
1073
+ - `PossessionEntities` (interface): interface PossessionEntities — ⚠ undocumented
1074
+ - `PossessionEvents` (interface): interface PossessionEvents — ⚠ undocumented
1075
+ - `PossessionSnapshot` (interface): interface PossessionSnapshot — ⚠ undocumented
1076
+ - `PossessionSwappedEvent` (interface): interface PossessionSwappedEvent — ⚠ undocumented
1077
+ - `createPossession` (function): function createPossession(deps: PossessionDeps): Possession — ⚠ undocumented
1078
+
1079
+ ## @jgengine/core/scene/roster
1080
+
1081
+ - `Roster` (interface): interface Roster — ⚠ undocumented
1082
+ - `RosterCaptureOptions` (interface): interface RosterCaptureOptions — ⚠ undocumented
1083
+ - `RosterDeps` (interface): interface RosterDeps — ⚠ undocumented
1084
+ - `RosterEntry` (interface): interface RosterEntry — ⚠ undocumented
1085
+ - `createRoster` (function): function createRoster(deps: RosterDeps = {}): Roster — ⚠ undocumented
1086
+
1087
+ ## @jgengine/core/scene/sceneKinds
1088
+
1089
+ - `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.
1090
+ - `BoolParamField` (interface): interface BoolParamField — A checkbox.
1091
+ - `ColorParamField` (interface): interface ColorParamField — A hex color picker.
1092
+ - `NumberParamField` (interface): interface NumberParamField — A free numeric input, optionally clamped.
1093
+ - `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.
1094
+ - `ParamGroup` (interface): interface ParamGroup — A named, optionally-collapsed section the inspector groups fields under (by `field.group === id`).
1095
+ - `ParamIssue` (interface): interface ParamIssue — One validation problem found by {@link validateParams}: which field and why.
1096
+ - `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.
1097
+ - `ParamSchema` (interface): interface ParamSchema — A kind's full parameter surface: an ordered list of fields the inspector renders top-to-bottom.
1098
+ - `ParsedParams` (type): type ParsedParams = Record<string, number | boolean | string | WeightedParamEntry[]> — Parsed params after `parseParams`: every schema field present with a validated, defaulted value.
1099
+ - `RangeParamField` (interface): interface RangeParamField — A numeric slider row: bounded range with a live readout.
1100
+ - `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.
1101
+ - `SceneKindObject` (interface): interface SceneKindObject — The raw document object a resolver receives — shape shared by markers, volumes, and paths.
1102
+ - `SceneKindResolveContext` (interface): interface SceneKindResolveContext — Ground sampler + options a resolver may read (terrain height/normal snap).
1103
+ - `SceneKindTarget` (type): type SceneKindTarget = "path" | "marker" | "volume" — The parametric-studio seam: a registry that maps an editor object `kind` to a typed parameter schema (drives the inspector + `meta` parse/validation), an optional pure-data `resolve` (turns a document object into renderable data), and `+ Add` menu metadata. Registering a kind lets a third party ship a new authorable "studio" (pole line, water, bookcase) — schema + resolver here, a matching renderer in `shell` — without editing editor or engine files. Scatter is the proof adopter.
1104
+ - `ScenePathShape` (type): type ScenePathShape = "area" | "line" — A closed-polygon area vs an open polyline, for path-target kinds. Ignored for marker/volume kinds.
1105
+ - `SeedParamField` (interface): interface SeedParamField — A seed string with a reroll button — same seed reproduces the same generated result.
1106
+ - `SelectParamField` (interface): interface SelectParamField — A dropdown of fixed string options.
1107
+ - `TextParamField` (interface): interface TextParamField — A free string input.
1108
+ - `WeightedListParamField` (interface): interface WeightedListParamField — A repeatable list of weighted `{ item, weight }` rows (species palette, book set, …).
1109
+ - `WeightedParamEntry` (interface): interface WeightedParamEntry — One weighted entry in a `weightedList` param — an item id and its relative spawn weight.
1110
+ - `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.
1111
+ - `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.
1112
+ - `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.
1113
+
1114
+ ## @jgengine/core/scene/sceneRaycast
1115
+
1116
+ - `SceneEntityQuerySource` (interface): interface SceneEntityQuerySource — ⚠ undocumented
1117
+ - `SceneObjectQuerySource` (interface): interface SceneObjectQuerySource — ⚠ undocumented
1118
+ - `SceneRaycastApi` (interface): interface SceneRaycastApi — ⚠ undocumented
1119
+ - `SceneRaycastDeps` (interface): interface SceneRaycastDeps — ⚠ undocumented
1120
+ - `SceneRaycastFilter` (interface): interface SceneRaycastFilter — ⚠ undocumented
1121
+ - `SceneRaycastHit` (interface): interface SceneRaycastHit — ⚠ undocumented
1122
+ - `SceneRaycastInput` (interface): interface SceneRaycastInput — ⚠ undocumented
1123
+ - `SceneRaycastTargetKind` (type): type SceneRaycastTargetKind = "entity" | "object" | "terrain" | "wall" — ⚠ undocumented
1124
+ - `TerrainRaycastSource` (interface): interface TerrainRaycastSource — ⚠ undocumented
1125
+ - `WallSegment` (interface): interface WallSegment — ⚠ undocumented
1126
+ - `createSceneRaycast` (function): function createSceneRaycast(deps: SceneRaycastDeps): SceneRaycastApi — ⚠ undocumented
1127
+ - `firstImpact` (function): function firstImpact(hits: readonly SceneRaycastHit[]): SceneRaycastHit | null — First impact: nearest hit that blocks, or nearest hit if none block.
1128
+ - `hitsUntilBlocked` (function): function hitsUntilBlocked(hits: readonly SceneRaycastHit[]): SceneRaycastHit[] — Hits up to and including the first blocking collider (damage hitboxes before a wall stay).
1129
+
1130
+ ## @jgengine/core/scene/selection
1131
+
1132
+ - `ScreenPoint` (interface): interface ScreenPoint — ⚠ undocumented
1133
+ - `ScreenRect` (interface): interface ScreenRect — ⚠ undocumented
1134
+ - `SelectionSet` (interface): interface SelectionSet — ⚠ undocumented
1135
+ - `createSelectionSet` (function): function createSelectionSet(initial?: Iterable<string>): SelectionSet — An ordered, deduplicated set of selected instance ids for RTS unit-command routing.
1136
+ - `isMarquee` (function): function isMarquee(rect: ScreenRect, thresholdPx = 4): boolean — True when the drag is large enough to be a marquee rather than a click.
1137
+ - `rectContainsPoint` (function): function rectContainsPoint(rect: ScreenRect, x: number, y: number): boolean — ⚠ undocumented
1138
+ - `screenRect` (function): function screenRect(ax: number, ay: number, bx: number, by: number): ScreenRect — Normalize two drag corners (in any order) into a rectangle.
1139
+ - `selectWithinRect` (function): function selectWithinRect(candidates: readonly ScreenPoint[], rect: ScreenRect): string[] — Ids of the projected candidates whose screen point falls inside the marquee.
1140
+
1141
+ ## @jgengine/core/scene/selectionBookmarks
1142
+
1143
+ - `BookmarkRecallMode` (type): type BookmarkRecallMode = "replace" | "merge" — How a recalled bookmark folds into the active selection.
1144
+ - `RecallBookmarkOptions` (interface): interface RecallBookmarkOptions — Caller hooks for {@link recallSelectionBookmark} — kept out of the store so focus and validity stay genre-owned.
1145
+ - `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.
1146
+ - `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.
1147
+ - `SelectionPruneResult` (interface): interface SelectionPruneResult — Outcome of a {@link SelectionBookmarks.prune} pass — what the validity predicate removed.
1148
+ - `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.
1149
+ - `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.
1150
+
1151
+ ## @jgengine/core/scene/spatial
1152
+
1153
+ - `Aim` (type): type Aim = | { origin: EntityPosition; direction: EntityPosition } | { yaw: number; pitch: number; spread?: number } — ⚠ undocumented
1154
+ - `MoveTowardOptions` (interface): interface MoveTowardOptions — ⚠ undocumented
1155
+ - `QueryArcOptions` (interface): interface QueryArcOptions — ⚠ undocumented
1156
+ - `SpatialApi` (interface): interface SpatialApi — ⚠ undocumented
1157
+ - `SpatialApiOptions` (interface): interface SpatialApiOptions — ⚠ undocumented
1158
+ - `SpatialGridOptions` (interface): interface SpatialGridOptions — ⚠ undocumented
1159
+ - `createSpatialApi` (function): function createSpatialApi(options: SpatialApiOptions): SpatialApi — ⚠ undocumented
1160
+ - `distanceBetween` (function): function distanceBetween(a: EntityPosition, b: EntityPosition): number — ⚠ undocumented
1161
+
1162
+ ## @jgengine/core/scene/stationClaim
1163
+
1164
+ - `ClaimResult` (type): type ClaimResult = | { ok: true; station: Station } | { ok: false; reason: "unknown_vehicle" | "unknown_facet" | "station_taken" | "vehicle_full" } — ⚠ undocumented
1165
+ - `SharedVehicleConfig` (interface): interface SharedVehicleConfig — ⚠ undocumented
1166
+ - `Station` (interface): interface Station — ⚠ undocumented
1167
+ - `StationClaim` (class): class StationClaim — ⚠ undocumented
1168
+ - `createStationClaim` (function): function createStationClaim(controller?: MountController): StationClaim — ⚠ undocumented
1169
+
1170
+ ## @jgengine/core/scene/targeting
1171
+
1172
+ - `CycleTargetOptions` (interface): interface CycleTargetOptions — ⚠ undocumented
1173
+ - `TargetFilter` (type): type TargetFilter = TargetRelation | "any" — ⚠ undocumented
1174
+ - `TargetRelation` (type): type TargetRelation = "hostile" | "friendly" — ⚠ undocumented
1175
+ - `Targeting` (interface): interface Targeting — ⚠ undocumented
1176
+ - `TargetingOptions` (interface): interface TargetingOptions — ⚠ undocumented
1177
+ - `createTargeting` (function): function createTargeting(options: TargetingOptions): Targeting — ⚠ undocumented
1178
+
1179
+ ## @jgengine/core/scene/vehicleSeat
1180
+
1181
+ - `DismountOffset` (interface): interface DismountOffset — Where {@link VehicleSeats.exit} steps the rider out, relative to the vehicle's heading.
1182
+ - `EnterVehicleOptions` (interface): interface EnterVehicleOptions — Options for {@link VehicleSeats.enter}.
1183
+ - `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.
1184
+ - `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" } — Result of {@link VehicleSeats.exit} — the side-door placement plus the camera/movement patches to apply.
1185
+ - `RiderMovementPatch` (interface): interface RiderMovementPatch — Movement-lock patch for `entities.update(riderId, { movement: { ...current, ...patch } })` (#286.gameplay `movement.frozen`).
1186
+ - `VehiclePose` (interface): interface VehiclePose — A vehicle's world-space position and heading, used for {@link VehicleSeats.exit}'s dismount placement math.
1187
+ - `VehiclePosition` (type): type VehiclePosition = readonly [number, number, number] — World-space `[x, y, z]` for a vehicle's current position.
1188
+ - `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`.
1189
+ - `createVehicleSeats` (function): function createVehicleSeats(controller?: MountController): VehicleSeats — Builds a {@link VehicleSeats}, optionally over an existing `MountController` to share its occupancy.
1190
+
1191
+ ## @jgengine/core/sensor/concealment
1192
+
1193
+ - `ColorHex` (type): type ColorHex = string — ⚠ undocumented
1194
+ - `ConcealmentSample` (interface): interface ConcealmentSample — ⚠ undocumented
1195
+ - `ConcealmentSensor` (interface): interface ConcealmentSensor — ⚠ undocumented
1196
+ - `ConcealmentTarget` (interface): interface ConcealmentTarget — ⚠ undocumented
1197
+
1198
+ ## @jgengine/core/sensor/freezeMonitor
1199
+
1200
+ - `FreezeMonitor` (interface): interface FreezeMonitor — ⚠ undocumented
1201
+ - `FreezeSubject` (interface): interface FreezeSubject — ⚠ undocumented
1202
+ - `FreezeViolation` (interface): interface FreezeViolation — ⚠ undocumented
1203
+
1204
+ ## @jgengine/core/sensor/frustumSensor
1205
+
1206
+ - `FramingConfig` (interface): interface FramingConfig — ⚠ undocumented
1207
+ - `FrustumCamera` (interface): interface FrustumCamera — ⚠ undocumented
1208
+ - `FrustumProjection` (interface): interface FrustumProjection — ⚠ undocumented
1209
+ - `FrustumSample` (interface): interface FrustumSample — ⚠ undocumented
1210
+ - `FrustumSensor` (interface): interface FrustumSensor — ⚠ undocumented
1211
+ - `FrustumTarget` (interface): interface FrustumTarget — ⚠ undocumented
1212
+
1213
+ ## @jgengine/core/sensor/hiddenStateProbe
1214
+
1215
+ - `HiddenStateSource` (interface): interface HiddenStateSource — ⚠ undocumented
1216
+ - `HiddenStateValue` (type): type HiddenStateValue = number | string | boolean — ⚠ undocumented
1217
+ - `SensorProbeOptions` (interface): interface SensorProbeOptions — ⚠ undocumented
1218
+ - `SensorReading` (interface): interface SensorReading — ⚠ undocumented
1219
+
1220
+ ## @jgengine/core/sensor/recordingBuffer
1221
+
1222
+ - `RecordingBuffer` (interface): interface RecordingBuffer<T> — ⚠ undocumented
1223
+ - `RecordingBufferOptions` (interface): interface RecordingBufferOptions — ⚠ undocumented
1224
+ - `RecordingFrame` (interface): interface RecordingFrame<T> — ⚠ undocumented
1225
+ - `RecordingPair` (interface): interface RecordingPair<T> — ⚠ undocumented
1226
+
1227
+ ## @jgengine/core/sensor/replayLoop
1228
+
1229
+ - `RecordedPoseLike` (interface): interface RecordedPoseLike — ⚠ undocumented
1230
+ - `ReplayEntityDeps` (interface): interface ReplayEntityDeps — ⚠ undocumented
1231
+ - `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".
1232
+ - `ReplayLoopOptions` (interface): interface ReplayLoopOptions<T> — ⚠ undocumented
1233
+
1234
+ ## @jgengine/core/sensor/revealQuery
1235
+
1236
+ - `RevealHit` (interface): interface RevealHit — ⚠ undocumented
1237
+ - `RevealQuery` (interface): interface RevealQuery — ⚠ undocumented
1238
+ - `RevealQueryOptions` (interface): interface RevealQueryOptions — ⚠ undocumented
1239
+
1240
+ ## @jgengine/core/sensor/visionCone
1241
+
1242
+ - `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.
1243
+ - `VisionConeConfig` (interface): interface VisionConeConfig — ⚠ undocumented
1244
+ - `VisionPoint` (type): type VisionPoint = readonly [number, number] — ⚠ undocumented
1245
+ - `VisionTarget` (interface): interface VisionTarget<TId extends string = string> — ⚠ undocumented
1246
+ - `VisionWall` (interface): interface VisionWall — Structurally matches `world/walls` `WallSegment` — pass those straight in as occluders.
1247
+
1248
+ ## @jgengine/core/time/beatClock
1249
+
1250
+ - `BeatAccuracyTier` (interface): interface BeatAccuracyTier — ⚠ undocumented
1251
+ - `BeatClock` (interface): interface BeatClock — ⚠ undocumented
1252
+ - `BeatClockConfig` (interface): interface BeatClockConfig — ⚠ undocumented
1253
+ - `BeatInputBuffer` (interface): interface BeatInputBuffer<T> — ⚠ undocumented
1254
+ - `BeatJudgement` (interface): interface BeatJudgement — ⚠ undocumented
1255
+ - `BeatSnapshot` (interface): interface BeatSnapshot — ⚠ undocumented
1256
+ - `BufferedAction` (interface): interface BufferedAction<T> — ⚠ undocumented
1257
+ - `DEFAULT_BEAT_TIERS` (const): const DEFAULT_BEAT_TIERS: readonly BeatAccuracyTier[] — ⚠ undocumented
1258
+
1259
+ ## @jgengine/core/time/calendarClock
1260
+
1261
+ - `GameTime` (interface): interface GameTime — ⚠ undocumented
1262
+
1263
+ ## @jgengine/core/time/gameClock
1264
+
1265
+ - `DEFAULT_TIME_SCALE` (const): const DEFAULT_TIME_SCALE: 24 — Simulation clock: real time scaled into game time, plus the derived game-day counter.
1266
+ - `SECONDS_PER_GAME_DAY` (const): const SECONDS_PER_GAME_DAY: number — ⚠ undocumented
1267
+ - `computeGameDay` (function): function computeGameDay(createdAt: number, now: number = Date.now(), timeScale?: number | null): number — ⚠ undocumented
1268
+ - `getCurrentGameTimestamp` (function): function getCurrentGameTimestamp(createdAt: number, now: number, timeScale?: number | null): number — ⚠ undocumented
1269
+ - `getScaledElapsedMs` (function): function getScaledElapsedMs(createdAt: number, now: number, timeScale?: number | null): number — ⚠ undocumented
1270
+ - `sanitizeGameTimeScale` (function): function sanitizeGameTimeScale(timeScale?: number | null): number — ⚠ undocumented
1271
+
1272
+ ## @jgengine/core/time/idleProgress
1273
+
1274
+ - `ExponentialCatchUpInput` (interface): interface ExponentialCatchUpInput — ⚠ undocumented
1275
+ - `IdleWindow` (interface): interface IdleWindow — ⚠ undocumented
1276
+ - `IdleWindowConfig` (interface): interface IdleWindowConfig — ⚠ undocumented
1277
+ - `LinearCatchUpInput` (interface): interface LinearCatchUpInput — ⚠ undocumented
1278
+ - `SteppedCatchUpResult` (interface): interface SteppedCatchUpResult — ⚠ undocumented
1279
+
1280
+ ## @jgengine/core/time/serverTick
1281
+
1282
+ - `PlanServerTickOptions` (type): type PlanServerTickOptions = { /** Cap catch-up runs per system per heartbeat to avoid spiral-of-death. Default 3. */ maxCatchUp?: number; } — ⚠ undocumented
1283
+ - `ServerTickPlan` (interface): interface ServerTickPlan<TSystemId extends string = string> — ⚠ undocumented
1284
+ - `TickAnchors` (type): type TickAnchors = Record<string, number> — Last-run timestamp per system id.
1285
+ - `TickSystemDefinition` (interface): interface TickSystemDefinition<TSystemId extends string = string> — ⚠ undocumented
1286
+ - `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 id is repeated (bounded by maxCatchUp). Excess lag past the bound resyncs the anchor to `now`. Returned anchors carry only systems present in the pipeline, so removed systems clean up.
1287
+
1288
+ ## @jgengine/core/time/simClock
1289
+
1290
+ - `CalendarTime` (interface): interface CalendarTime — ⚠ undocumented
1291
+ - `ClockSnapshot` (interface): interface ClockSnapshot — ⚠ undocumented
1292
+ - `SimClock` (interface): interface SimClock — ⚠ undocumented
1293
+ - `SimClockOptions` (interface): interface SimClockOptions — ⚠ undocumented
1294
+ - `TimeConfig` (interface): interface TimeConfig — ⚠ undocumented
1295
+ - `createSimClock` (function): function createSimClock(options: SimClockOptions = {}): SimClock — ⚠ undocumented
1296
+
1297
+ ## @jgengine/core/time/stateSchedule
1298
+
1299
+ - `ClearWindowScan` (interface): interface ClearWindowScan — ⚠ undocumented
1300
+ - `SchedulePhase` (interface): interface SchedulePhase<T> — ⚠ undocumented
1301
+ - `ScheduleSample` (interface): interface ScheduleSample<T> — ⚠ undocumented
1302
+ - `ScheduleWindow` (interface): interface ScheduleWindow — ⚠ undocumented
1303
+ - `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.
1304
+ - `StateScheduleConfig` (interface): interface StateScheduleConfig<T> — ⚠ undocumented
1305
+ - `createStateSchedule` (function): function createStateSchedule<T>(config: StateScheduleConfig<T>): StateSchedule<T> — ⚠ undocumented
1306
+ - `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.
1307
+
1308
+ ## @jgengine/core/visibility/assetStreaming
1309
+
1310
+ - `AssetLoadResult` (interface): interface AssetLoadResult — ⚠ undocumented
1311
+ - `AssetLoadState` (type): type AssetLoadState = "queued" | "loading" | "loaded" | "unloaded" | "error" — ⚠ undocumented
1312
+ - `AssetRecord` (interface): interface AssetRecord — ⚠ undocumented
1313
+ - `AssetStreamingOptions` (interface): interface AssetStreamingOptions — ⚠ undocumented
1314
+ - `AssetStreamingSystem` (interface): interface AssetStreamingSystem — ⚠ undocumented
1315
+ - `CancelSignal` (interface): interface CancelSignal — ⚠ undocumented
1316
+ - `StreamingStats` (interface): interface StreamingStats — ⚠ undocumented
1317
+ - `createAssetStreamingSystem` (function): function createAssetStreamingSystem(options: AssetStreamingOptions): AssetStreamingSystem — ⚠ undocumented
1318
+
1319
+ ## @jgengine/core/visibility/bounds
1320
+
1321
+ - `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.
1322
+ - `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).
1323
+ - `DEFAULT_BOUNDS` (const): const DEFAULT_BOUNDS: BoundsSpec — Conservative default: a unit sphere. Objects without explicit bounds cull as a small volume, never a point.
1324
+ - `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.
1325
+ - `Vec3` (type): type Vec3 = EntityPosition — ⚠ undocumented
1326
+
1327
+ ## @jgengine/core/visibility/camera
1328
+
1329
+ - `CameraKind` (type): type CameraKind = "main" | "splitScreen" | "renderToTexture" | "editor" | "minimap" — ⚠ undocumented
1330
+ - `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`.
1331
+ - `cameraInfluencesStreaming` (function): function cameraInfluencesStreaming(context: CameraVisibilityContext): boolean — ⚠ undocumented
1332
+
1333
+ ## @jgengine/core/visibility/config
1334
+
1335
+ - `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).
1336
+
1337
+ ## @jgengine/core/visibility/diagnostics
1338
+
1339
+ - `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.
1340
+ - `createVisibilityStats` (function): function createVisibilityStats(): VisibilityStats — ⚠ undocumented
1341
+ - `nowMs` (function): function nowMs(): number — High-resolution clock that degrades to a monotonic-ish fallback when `performance` is absent.
1342
+ - `resetCullingStats` (function): function resetCullingStats(stats: VisibilityStats): void — ⚠ undocumented
1343
+
1344
+ ## @jgengine/core/visibility/distance
1345
+
1346
+ - `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.
1347
+ - `distance` (function): function distance(a: Vec3, b: Vec3): number — ⚠ undocumented
1348
+ - `distanceSquared` (function): function distanceSquared(ax: number, ay: number, az: number, bx: number, by: number, bz: number): number — ⚠ undocumented
1349
+
1350
+ ## @jgengine/core/visibility/frustum
1351
+
1352
+ - `CameraView` (type): type CameraView = PerspectiveView | OrthographicView — ⚠ undocumented
1353
+ - `Frustum` (interface): interface Frustum — ⚠ undocumented
1354
+ - `OrthographicView` (interface): interface OrthographicView — 2D / orthographic camera (top-down, side-scroller, minimap).
1355
+ - `PerspectiveView` (interface): interface PerspectiveView — 3D perspective camera (the default game camera).
1356
+
1357
+ ## @jgengine/core/visibility/occlusion
1358
+
1359
+ - `AxisOccluderOptions` (interface): interface AxisOccluderOptions — ⚠ undocumented
1360
+ - `OcclusionInput` (interface): interface OcclusionInput — ⚠ undocumented
1361
+ - `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.
1362
+ - `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.
1363
+ - `noOcclusion` (const): const noOcclusion: OcclusionTester — The safe default: never occludes anything.
1364
+
1365
+ ## @jgengine/core/visibility/settings
1366
+
1367
+ - `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.
1368
+ - `DEFAULT_CULLING_SETTINGS` (const): const DEFAULT_CULLING_SETTINGS: CullingSettings — ⚠ undocumented
1369
+ - `DEFAULT_STREAMING_SETTINGS` (const): const DEFAULT_STREAMING_SETTINGS: StreamingSettings — ⚠ undocumented
1370
+ - `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.
1371
+ - `ResolvedOverrides` (interface): interface ResolvedOverrides — ⚠ undocumented
1372
+ - `StreamingSettings` (interface): interface StreamingSettings — ⚠ undocumented
1373
+ - `mergeCullingSettings` (function): function mergeCullingSettings(base: CullingSettings, patch: Partial<CullingSettings>): CullingSettings — ⚠ undocumented
1374
+ - `mergeStreamingSettings` (function): function mergeStreamingSettings(base: StreamingSettings, patch: Partial<StreamingSettings>): StreamingSettings — ⚠ undocumented
1375
+ - `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.
1376
+
1377
+ ## @jgengine/core/visibility/simulationCulling
1378
+
1379
+ - `SimulationCuller` (interface): interface SimulationCuller — ⚠ undocumented
1380
+ - `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.
1381
+ - `SimulationDecision` (interface): interface SimulationDecision — ⚠ undocumented
1382
+ - `createSimulationCuller` (function): function createSimulationCuller(options: SimulationCullingOptions = {}): SimulationCuller — ⚠ undocumented
1383
+
1384
+ ## @jgengine/core/visibility/spatialIndex
1385
+
1386
+ - `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.
1387
+ - `SpatialIndexOptions` (interface): interface SpatialIndexOptions — ⚠ undocumented
1388
+ - `createSpatialIndex` (function): function createSpatialIndex(options: SpatialIndexOptions = {}): SpatialIndex — ⚠ undocumented
1389
+
1390
+ ## @jgengine/core/visibility/visibilitySystem
1391
+
1392
+ - `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.
1393
+ - `VisibilityDebugSnapshot` (interface): interface VisibilityDebugSnapshot — ⚠ undocumented
1394
+ - `VisibilityResult` (interface): interface VisibilityResult — ⚠ undocumented
1395
+ - `VisibilitySystem` (interface): interface VisibilitySystem — ⚠ undocumented
1396
+ - `VisibilitySystemOptions` (interface): interface VisibilitySystemOptions — ⚠ undocumented
1397
+ - `createVisibilitySystem` (function): function createVisibilitySystem(options: VisibilitySystemOptions): VisibilitySystem — ⚠ undocumented
1398
+
1399
+ ## @jgengine/core/world
1400
+
1401
+ - `Aabb` (interface): interface Aabb — ⚠ undocumented
1402
+ - `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.
1403
+ - `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.
1404
+ - `AcquisitionResult` (interface): interface AcquisitionResult — Outcome of one acquisition pass.
1405
+ - `AcquisitionRetention` (interface): interface AcquisitionRetention — Retention hysteresis that keeps an already-held target from flickering under churn.
1406
+ - `AddBodyOptions` (type): type AddBodyOptions = BoxBodyOptions | SphereBodyOptions — ⚠ undocumented
1407
+ - `Aim` (type): type Aim = | { origin: EntityPosition; direction: EntityPosition } | { yaw: number; pitch: number; spread?: number } — ⚠ undocumented
1408
+ - `AircraftDynamics` (interface): interface AircraftDynamics — Stateful six-degree-of-freedom aircraft simulation.
1409
+ - `AircraftKind` (type): type AircraftKind = "fixedWing" | "rotorcraft" | "vtol" — Supported aerodynamic/propulsion families.
1410
+ - `AircraftOptions` (interface): interface AircraftOptions — Spawn state and injectable world-field samplers for an aircraft instance.
1411
+ - `AircraftStep` (interface): interface AircraftStep — Pose and aerodynamic telemetry returned after one flight tick.
1412
+ - `AircraftTuning` (interface): interface AircraftTuning — Data-first physical tuning shared by all aircraft instances of one catalog type.
1413
+ - `AreaDistribution` (type): type AreaDistribution = "uniform" | "edge" — Fill policy for a rect/box: `"uniform"` = even coverage; `"edge"` = biased to a boundary band.
1414
+ - `AreaEffectEvent` (interface): interface AreaEffectEvent<P> — One membership edge emitted by `step`, `removeSource`, or `clear`.
1415
+ - `AreaEffectField` (interface): interface AreaEffectField<P> — Runtime handle tracking continuous area membership across ticks.
1416
+ - `AreaEventKind` (type): type AreaEventKind = "enter" | "refresh" | "leave" — The three membership edges a step can emit.
1417
+ - `AreaFieldState` (interface): interface AreaFieldState<P> — Serialized field state: source descriptors (minus their transient shape) and per-member refresh phase.
1418
+ - `AreaLeaveReason` (type): type AreaLeaveReason = "exit" | "source-removed" | "disabled" | "cleared" — Why a `leave` edge fired.
1419
+ - `AreaMembership` (interface): interface AreaMembership<P> — One active (source, receiver) membership — feed a receiver's list to a stacking policy.
1420
+ - `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.
1421
+ - `AreaSourceSpec` (interface): interface AreaSourceSpec<P> — Descriptor for one continuous area source; re-supplied each tick so its shape follows the emitter.
1422
+ - `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.
1423
+ - `AreaStepInput` (interface): interface AreaStepInput — Per-tick inputs the field needs to reconcile membership without scanning the world.
1424
+ - `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]`.
1425
+ - `AssetCatalog` (interface): interface AssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef> — ⚠ undocumented
1426
+ - `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.
1427
+ - `AssetSpaceIssue` (interface): interface AssetSpaceIssue — One problem found by {@link validateAssetSpace}: which metadata field and why it is invalid.
1428
+ - `AttackMoveOrderPayload` (interface): interface AttackMoveOrderPayload — Payload for an attack-move: advance toward `point`, engaging hostiles encountered en route.
1429
+ - `AudioBusDef` (interface): interface AudioBusDef — ⚠ undocumented
1430
+ - `AudioFalloffConfig` (interface): interface AudioFalloffConfig — ⚠ undocumented
1431
+ - `AuthoredTrigger` (interface): interface AuthoredTrigger — One resolved trigger binding from a document object.
1432
+ - `AuthoredTriggerRuntime` (interface): interface AuthoredTriggerRuntime — Runtime handle that watches authored triggers against moving actors each tick.
1433
+ - `AutoTargetPolicy` (type): type AutoTargetPolicy = | "nearest" | "farthest" | "random" | "strongest" | "weakest" | "first" | "last" — ⚠ undocumented
1434
+ - `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`.
1435
+ - `AvoidanceAgent` (interface): interface AvoidanceAgent — A circular agent that avoidance may push on the XZ plane.
1436
+ - `BallisticSweep` (type): type BallisticSweep = ( origin: readonly [number, number, number], velocity: readonly [number, number, number], gravity: number, maxTime: number, ) => BallisticSweepHit | null — ⚠ undocumented
1437
+ - `BallisticSweepHit` (interface): interface BallisticSweepHit — ⚠ undocumented
1438
+ - `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}.
1439
+ - `BehaviorDescriptor` (type): type BehaviorDescriptor = | WanderBehavior | PatrolBehavior | PromptableBehavior | PlayerBehavior — ⚠ undocumented
1440
+ - `BehaviorInspection` (interface): interface BehaviorInspection — Inspection readout for editor/debug tooling, from {@link BehaviorControl.inspect}/{@link BehaviorControl.list}.
1441
+ - `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 treats it as `freeze`.
1442
+ - `BehaviorSnapshot` (type): type BehaviorSnapshot = | { readonly kind: "patrol"; readonly state: PathFollowState } | { readonly kind: "wander"; readonly origin: Waypoint; readonly target: Waypoint | null } — Serializable snapshot of one behavior instance — round-trips exactly through {@link BehaviorControl.serialize}/{@link BehaviorControl.restore}.
1443
+ - `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`).
1444
+ - `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`.
1445
+ - `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.
1446
+ - `BoardGroundSize` (interface): interface BoardGroundSize — Size of a `board` ground: a 2D surface you look at, in cells or layout units.
1447
+ - `BookmarkRecallMode` (type): type BookmarkRecallMode = "replace" | "merge" — How a recalled bookmark folds into the active selection.
1448
+ - `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).
1449
+ - `BoxFormationOptions` (interface): interface BoxFormationOptions — Options for {@link boxFormation}.
1450
+ - `BuildRole` (type): type BuildRole = "owner" | "editor" | "viewer" — ⚠ undocumented
1451
+ - `BuildingEnvironmentDescriptor` (type): type BuildingEnvironmentDescriptor = { kind: "building" } & Required< Pick<BuildingEnvironmentConfig, "count" | "footprint" | "stories" | "storyHeight" | "spacing" | "style"> > & Pick<BuildingEnvironmentConfig, "seed" | "position" | "palette"> — ⚠ undocumented
1452
+ - `BuildingIndex` (interface): interface BuildingIndex — ⚠ undocumented
1453
+ - `BuildingPaletteOverrides` (type): type BuildingPaletteOverrides = Partial<BuildingPalette> — ⚠ undocumented
1454
+ - `BuildingStyle` (type): type BuildingStyle = | "generic" | "capital" | "village" | "desert" | "industrial" | "coastal" | "neon" | "ruin" | "frontier" | "aerial" — ⚠ undocumented
1455
+ - `CITY_DEFAULTS` (const): const CITY_DEFAULTS: CityRules — City defaults: a zoned mixed metropolis — towers downtown, slabs mid-ring, houses at the edge.
1456
+ - `CITY_KIND` (const): const CITY_KIND: "city" — The editor volume kind marking a box as a procedural city district.
1457
+ - `CITY_LOT_CLASSES` (const): const CITY_LOT_CLASSES: readonly CityLotClass[] — All classes, for schema hints and validation.
1458
+ - `CITY_SCHEMA` (const): const CITY_SCHEMA: ParamSchema — The city parameter schema — drives the inspector sliders and `meta` parse via the studio seam.
1459
+ - `CITY_TREE_SPECIES` (const): const CITY_TREE_SPECIES: readonly CityTreeSpecies[] — All species, for schema hints and validation.
1460
+ - `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.
1461
+ - `CITY_ZONE_SCHEMA` (const): const CITY_ZONE_SCHEMA: ParamSchema — Zone-override schema for `cityzone` volumes: pin a band and optionally a bespoke class mix.
1462
+ - `CameraView` (type): type CameraView = PerspectiveView | OrthographicView — ⚠ undocumented
1463
+ - `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`.
1464
+ - `Cardinal` (type): type Cardinal = "N" | "NE" | "E" | "SE" | "S" | "SW" | "W" | "NW" — ⚠ undocumented
1465
+ - `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.
1466
+ - `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.
1467
+ - `CircleFormationOptions` (interface): interface CircleFormationOptions — Options for {@link circleFormation}.
1468
+ - `CityBlock` (interface): interface CityBlock — One closed city block: a face of the road graph, inset to curb and land boundaries.
1469
+ - `CityBlockKind` (type): type CityBlockKind = "buildable" | "park" | "plaza" | "field" | "buffer" — How a block (a face of the road graph) is used.
1470
+ - `CityBridge` (interface): interface CityBridge — One bridge deck spanning water: bank-to-bank polyline plus the silhouette style.
1471
+ - `CityDriveway` (interface): interface CityDriveway — One driveway ribbon from a street to a lot.
1472
+ - `CityHedge` (interface): interface CityHedge — One hedge run: a thin box strip (estate perimeter).
1473
+ - `CityIntersection` (interface): interface CityIntersection — One crossing of two through streets: patch center/radius plus crosswalk arm directions.
1474
+ - `CityLight` (interface): interface CityLight — One street light: curb position plus the yaw its arm faces (over the road).
1475
+ - `CityLot` (interface): interface CityLot — One building lot: footprint, zone band, class, seeded floors, massing pieces, street anchor.
1476
+ - `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.
1477
+ - `CityLotPiece` (interface): interface CityLotPiece — One massing piece in LOT-LOCAL space: x along frontage width, z into the block, y up from grade.
1478
+ - `CityParcel` (interface): interface CityParcel — One polygonal parcel subdivided from a block's street frontage.
1479
+ - `CityParcelFrontageOut` (interface): interface CityParcelFrontageOut — One street-frontage edge of a parcel.
1480
+ - `CityPark` (interface): interface CityPark — One intentional open space: an unbuilt block, a block-interior courtyard, or a buffer sliver.
1481
+ - `CityParking` (interface): interface CityParking — One parking pad behind a commercial lot.
1482
+ - `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).
1483
+ - `CityPieceShape` (type): type CityPieceShape = "box" | "gable" | "cylinder" | "dome" — Primitive shapes massing pieces instance — the renderer keeps one InstancedMesh per shape.
1484
+ - `CityResolveContext` (interface): interface CityResolveContext extends SceneKindResolveContext — Extended resolve context: sibling `cityzone` volumes that override the band/mix locally.
1485
+ - `CityRules` (interface): interface CityRules — Fully-defaulted city params parsed from a volume's `meta`.
1486
+ - `CityStreet` (interface): interface CityStreet — One synthesized street: a world-space XZ polyline with width, hierarchy level, and surface.
1487
+ - `CityTree` (interface): interface CityTree — One placed tree: world XZ, species, and seeded scale/color jitter.
1488
+ - `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.
1489
+ - `CityZoneBand` (type): type CityZoneBand = "core" | "mid" | "edge" — Zone band a lot falls in: dense core, middle ring, or the district edge.
1490
+ - `CityZoneProfile` (type): type CityZoneProfile = "core-out" | "inverted" | "uniform" — How the radial zone metric maps to bands.
1491
+ - `ClockSnapshot` (interface): interface ClockSnapshot — ⚠ undocumented
1492
+ - `CollapseEvent` (interface): interface CollapseEvent — ⚠ undocumented
1493
+ - `ColliderPurpose` (type): type ColliderPurpose = "physical" | "damage" — ⚠ undocumented
1494
+ - `CollisionEvent` (interface): interface CollisionEvent — A contact reported to `onCollision`. The object is reused each call — read/copy, never retain.
1495
+ - `CollisionObstacle` (interface): interface CollisionObstacle — A placed scene object the walking player collides against as a circle-vs-AABB obstacle.
1496
+ - `ConcealmentSensor` (interface): interface ConcealmentSensor — ⚠ undocumented
1497
+ - `ContextMenu` (interface): interface ContextMenu — ⚠ undocumented
1498
+ - `ContextVerb` (interface): interface ContextVerb — One right-click verb: a label plus the command it dispatches (walk-then-act supported by args).
1499
+ - `ContourLine` (interface): interface ContourLine — A single iso-elevation contour traced across a region as a flat list of XZ line segments.
1500
+ - `ContourOptions` (interface): interface ContourOptions — Shaping for {@link extractContours}: region, vertical spacing, emphasis cadence, and sample budget.
1501
+ - `ControlGroupInput` (interface): interface ControlGroupInput — A decoded control-group key press plus the memory needed to detect a double-tap.
1502
+ - `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.
1503
+ - `ControlGroupOptions` (interface): interface ControlGroupOptions — Tuning for the control-group idiom: the double-tap focus window and the bookmark-key namespace.
1504
+ - `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.
1505
+ - `DEFAULT_GRIP_CURVE` (const): const DEFAULT_GRIP_CURVE: GripCurve — ⚠ undocumented
1506
+ - `DEFAULT_MARKER_KINDS` (const): const DEFAULT_MARKER_KINDS: Record<string, MarkerKindStyle> — ⚠ undocumented
1507
+ - `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.
1508
+ - `DEFAULT_REPUTATION_TIERS` (const): const DEFAULT_REPUTATION_TIERS: readonly ReputationTier[] — ⚠ undocumented
1509
+ - `DrapeOptions` (interface): interface DrapeOptions — Shaping for surface draping: subdivision spacing and a lift to keep the line off the ground.
1510
+ - `EditableTerrain` (interface): interface EditableTerrain extends TerrainField — ⚠ undocumented
1511
+ - `ElevationReadout` (interface): interface ElevationReadout — Measurable elevation readout at a single world point — the cursor/hover feedback value.
1512
+ - `ElevationSummary` (interface): interface ElevationSummary — Aggregate elevation statistics over a region — the selection min/max/mean and legend range.
1513
+ - `EmptyOrderPayload` (type): type EmptyOrderPayload = Record<string, never> — Payload for stop/hold orders — no data; the verb is the intent.
1514
+ - `EnclosedFootprint` (interface): interface EnclosedFootprint — ⚠ undocumented
1515
+ - `EngagementKindConfig` (interface): interface EngagementKindConfig extends OrderKindConfig — Move + engagement config carrying the default radii the payload may override.
1516
+ - `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.
1517
+ - `EntityColliderSet` (interface): interface EntityColliderSet — ⚠ undocumented
1518
+ - `EntityPosition` (type): type EntityPosition = readonly [number, number, number] — ⚠ undocumented
1519
+ - `EnvironmentField` (interface): interface EnvironmentField — ⚠ undocumented
1520
+ - `EnvironmentWorldFeature` (interface): interface EnvironmentWorldFeature — ⚠ undocumented
1521
+ - `FactionDef` (interface): interface FactionDef — ⚠ undocumented
1522
+ - `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.
1523
+ - `FireGrid` (interface): interface FireGrid — ⚠ undocumented
1524
+ - `FlatGround` (interface): interface FlatGround — A 3D walkable plane/slab. `Infinity` axes are unbounded; no separate "infinite" mode exists.
1525
+ - `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.
1526
+ - `FlightControlInput` (interface): interface FlightControlInput — Normalized pilot inputs for one flight-simulation tick.
1527
+ - `FlightControlRates` (interface): interface FlightControlRates — Angular authority, response, damping, and self-leveling configuration.
1528
+ - `FlightVector` (type): type FlightVector = readonly [number, number, number] — Three-dimensional world-space vector used by the flight model.
1529
+ - `FogCells` (interface): interface FogCells — ⚠ undocumented
1530
+ - `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()`.
1531
+ - `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.
1532
+ - `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.
1533
+ - `FramingConfig` (interface): interface FramingConfig — ⚠ undocumented
1534
+ - `FreezeMonitor` (interface): interface FreezeMonitor — ⚠ undocumented
1535
+ - `FreezeViolation` (interface): interface FreezeViolation — ⚠ undocumented
1536
+ - `Frustum` (interface): interface Frustum — ⚠ undocumented
1537
+ - `FrustumProjection` (interface): interface FrustumProjection — ⚠ undocumented
1538
+ - `FrustumSample` (interface): interface FrustumSample — ⚠ undocumented
1539
+ - `FrustumSensor` (interface): interface FrustumSensor — ⚠ undocumented
1540
+ - `FrustumTarget` (interface): interface FrustumTarget — ⚠ undocumented
1541
+ - `GRASS_SCHEMA` (const): const GRASS_SCHEMA: ParamSchema — The grass parameter schema — drives the inspector and `meta` parse via the studio seam.
1542
+ - `GeneratedAsset` (interface): interface GeneratedAsset — A resolved generator asset: its parts plus the overall local-space bounds (min/max corners).
1543
+ - `GeneratedPart` (interface): interface GeneratedPart — One generated primitive part — a box/panel placed in the asset's local space.
1544
+ - `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.
1545
+ - `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.
1546
+ - `GrassEnvironmentDescriptor` (type): type GrassEnvironmentDescriptor = { kind: "grass" } & Required< Pick<GrassEnvironmentConfig, "area" | "density" | "bladeHeight" | "bladeWidth" | "windStrength" | "colors"> > & Pick<GrassEnvironmentConfig, "seed"> — ⚠ undocumented
1547
+ - `GravityField` (interface): interface GravityField — Position-dependent gravity source used by movement and vehicle simulations.
1548
+ - `GravityVector` (type): type GravityVector = readonly [number, number, number] — Three-dimensional acceleration vector sampled from a gravity field.
1549
+ - `GripCurve` (interface): interface GripCurve — ⚠ undocumented
1550
+ - `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`.
1551
+ - `GroundGenerator` (interface): interface GroundGenerator — Serializable algorithm parameters for a procedural ground generator. Never a genre kit.
1552
+ - `GroundMode` (type): type GroundMode = "flat" | "round" | "voxel" | "board" — Canonical ground modes after normalization (`stage` → `board`).
1553
+ - `GroundPoint` (type): type GroundPoint = readonly [number, number] — A world-space point on the ground plane as an `[x, z]` pair.
1554
+ - `GuideRegion` (interface): interface GuideRegion — An axis-aligned XZ rectangle to generate terrain-readability guides within.
1555
+ - `HeatConfig` (interface): interface HeatConfig — Tuning for {@link createHeatState}/{@link advanceHeat} — levels, decay, and pursuit-spawn ring.
1556
+ - `HeatGain` (interface): interface HeatGain — One crime tick's contribution — only `witnessed` gains raise heat (unseen crimes are free, GTA-style).
1557
+ - `HeatLevelDef` (interface): interface HeatLevelDef — One escalation tier — the heat threshold it begins at and the pursuer count it wants active.
1558
+ - `HeatSource` (interface): interface HeatSource — A localized warmth source — campfire, forge, geothermal vent.
1559
+ - `HeatState` (interface): interface HeatState — Serializable heat-system state — round-trips through `createHeatState`/`advanceHeat` each tick.
1560
+ - `HeightSampler` (type): type HeightSampler = (x: number, z: number) => number — A height sampler over the ground: world elevation at any `x`/`z`.
1561
+ - `HiddenStateSource` (interface): interface HiddenStateSource — ⚠ undocumented
1562
+ - `InterestCensus` (interface): interface InterestCensus — Aggregate counts of active vs dormant gates — the metric the issue asks a scheduler to expose.
1563
+ - `InterestCensusAccumulator` (interface): interface InterestCensusAccumulator — A running census accumulator; call `record` inside the caller's existing tick loop (no extra pass).
1564
+ - `InterestGateInput` (interface): interface InterestGateInput — Per-tick input the caller supplies to a gate.
1565
+ - `InterestGateState` (interface): interface InterestGateState — Per-agent serializable gate state. Round-trip the whole object; never read fields to drive logic.
1566
+ - `InterestGateStep` (interface): interface InterestGateStep — Per-tick output that tells the caller whether to run expensive work.
1567
+ - `InterestSchedulerConfig` (interface): interface InterestSchedulerConfig — Static configuration shared by every gate of one behavior class.
1568
+ - `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.
1569
+ - `InterestTier` (interface): interface InterestTier — A distance-keyed cadence tier: nearer agents tick faster, farther-but-awake agents tick slower.
1570
+ - `Job` (interface): interface Job — ⚠ undocumented
1571
+ - `JobDef` (interface): interface JobDef — ⚠ undocumented
1572
+ - `JobReport` (interface): interface JobReport — ⚠ undocumented
1573
+ - `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.
1574
+ - `KinematicDynamicsTuning` (interface): interface KinematicDynamicsTuning — Aerodynamic and electronic-assist settings layered over tire grip.
1575
+ - `KinematicPowertrainTuning` (interface): interface KinematicPowertrainTuning — Data-first gearbox and torque-curve tuning for a kinematic ground vehicle.
1576
+ - `KinematicSteeringTuning` (interface): interface KinematicSteeringTuning — Bicycle-model steering settings; all angles are radians.
1577
+ - `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.
1578
+ - `KinematicVehicleStep` (interface): interface KinematicVehicleStep — ⚠ undocumented
1579
+ - `KinematicVehicleTuning` (interface): interface KinematicVehicleTuning — ⚠ undocumented
1580
+ - `LOCK_ACTIONS` (const): const LOCK_ACTIONS: readonly LockAction[] — The five pick actions, in display order (shallow → deep).
1581
+ - `LineFormationOptions` (interface): interface LineFormationOptions — Options for {@link lineFormation}.
1582
+ - `LocalAvoidanceOptions` (interface): interface LocalAvoidanceOptions — Tuning for {@link resolveLocalAvoidance}.
1583
+ - `LockAction` (type): type LockAction = "hardSet" | "set" | "steady" | "ease" | "drop" — One discrete pick move: how far the pick drives into the lock this step.
1584
+ - `LockCell` (interface): interface LockCell — One cell inside the fogged {@link visibleCells} window: its board position and kind.
1585
+ - `LockSpec` (interface): interface LockSpec — A generated lock board. `open[col]` holds every enterable row in that column.
1586
+ - `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.
1587
+ - `LockTierSpec` (interface): interface LockTierSpec — Difficulty dials for one lock: board size, forgiveness band, gates, fog window, traps.
1588
+ - `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.
1589
+ - `MagnitudeOf` (type): type MagnitudeOf<P> = (membership: AreaMembership<P>) => number — Read a comparable magnitude from a membership (e.g. buff strength, damage per tick).
1590
+ - `MapCellStates` (interface): interface MapCellStates — ⚠ undocumented
1591
+ - `MapMarker` (interface): interface MapMarker<TMeta = unknown> extends MarkerView<TMeta> — A marker owned by {@link MarkerSet}, including its lifecycle and query fields.
1592
+ - `MapRoute` (interface): interface MapRoute — ⚠ undocumented
1593
+ - `MapZone` (interface): interface MapZone — ⚠ undocumented
1594
+ - `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.
1595
+ - `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.
1596
+ - `MarkerSet` (interface): interface MarkerSet<TMeta = unknown> — ⚠ undocumented
1597
+ - `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.
1598
+ - `MarkerSourceOptions` (interface): interface MarkerSourceOptions<TEntity, TMarker extends MarkerView = MarkerView> — Configuration for projecting a caller-owned collection into display-only markers.
1599
+ - `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}.
1600
+ - `MinimapBake` (interface): interface MinimapBake — A baked minimap image: RGBA pixels plus the world bounds they span.
1601
+ - `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.
1602
+ - `MinimapBakeOptions` (interface): interface MinimapBakeOptions — Options for {@link bakeMinimapImage}.
1603
+ - `MinimapBakePalette` (interface): interface MinimapBakePalette — The height→color ramp and water color used by the bake.
1604
+ - `MinimapBakeSource` (interface): interface MinimapBakeSource — The authored world a bake reads — a height sampler, its bounds, and optional zones/water.
1605
+ - `MinimapBakeZone` (interface): interface MinimapBakeZone — One biome/region tint painted over the terrain shade where the ground falls inside its polygon.
1606
+ - `MinimapView` (interface): interface MinimapView — ⚠ undocumented
1607
+ - `ModelAssetRef` (interface): interface ModelAssetRef — ⚠ undocumented
1608
+ - `ModelDims` (interface): interface ModelDims — Measured horizontal footprint, footprint center, and lowest Y of a model in model space.
1609
+ - `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.
1610
+ - `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.
1611
+ - `MoveOrderPayload` (interface): interface MoveOrderPayload — Payload for a move order: go to a point and complete on arrival.
1612
+ - `MovementPose` (type): type MovementPose = "standing" | "crouch" | "prone" | "running" — ⚠ undocumented
1613
+ - `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.
1614
+ - `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.
1615
+ - `NavGrid` (interface): interface NavGrid — ⚠ undocumented
1616
+ - `NavPoint` (type): type NavPoint = readonly [number, number] — ⚠ undocumented
1617
+ - `NoiseFieldConfig` (interface): interface NoiseFieldConfig — Configuration for {@link noiseField}: seed, amplitude, and fractal noise shaping.
1618
+ - `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`.
1619
+ - `NoteEvent` (interface): interface NoteEvent — One scheduled note in a theme, positioned on the loop's quarter-note grid.
1620
+ - `ObjectVisual` (interface): interface ObjectVisual — ⚠ undocumented
1621
+ - `OceanEnvironmentDescriptor` (type): type OceanEnvironmentDescriptor = { kind: "ocean" } & Required< Pick<OceanEnvironmentConfig, "bounds" | "level" | "waveHeight" | "waveScale" | "waveSpeed" | "color"> > & Pick<OceanEnvironmentConfig, "position" | "levelAt"> — ⚠ undocumented
1622
+ - `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`.
1623
+ - `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`.
1624
+ - `OrderEvent` (interface): interface OrderEvent — A lifecycle event emitted synchronously as orders move through the queue.
1625
+ - `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).
1626
+ - `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.
1627
+ - `OrderKindConfig` (interface): interface OrderKindConfig — Shared factory config: override the verb key so a game can register the composition under its own name.
1628
+ - `OrderMoveResult` (interface): interface OrderMoveResult — Result of one movement step, from the game's motion adapter.
1629
+ - `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.
1630
+ - `OrderOutcome` (interface): interface OrderOutcome — Terminal outcome handed to a kind's `finish` cleanup hook.
1631
+ - `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.
1632
+ - `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.
1633
+ - `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.
1634
+ - `OrderQueueOptions` (interface): interface OrderQueueOptions<TPayload = unknown> — Construction options for a queue.
1635
+ - `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.
1636
+ - `OrderQueueState` (interface): interface OrderQueueState<TPayload = unknown> — Serializable snapshot of a queue: the active order plus the pending list, in order.
1637
+ - `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.
1638
+ - `OrderRejection` (interface): interface OrderRejection — A kind's refusal of a payload (from `validate`) — surfaced to the issuer as a rejection reason.
1639
+ - `OrderRequest` (interface): interface OrderRequest<TPayload = unknown> — A request to issue an order; `policy` defaults to `replace`, `id` is generated when omitted.
1640
+ - `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`.
1641
+ - `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.
1642
+ - `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.
1643
+ - `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.
1644
+ - `POLE_LINE_SCHEMA` (const): const POLE_LINE_SCHEMA: ParamSchema — The pole-line parameter schema — drives the inspector and `meta` parse via the studio seam.
1645
+ - `POSE_HITBOX` (const): const POSE_HITBOX: Record<MovementPose, PoseHitbox> — ⚠ undocumented
1646
+ - `PadEnvironmentDescriptor` (type): type PadEnvironmentDescriptor = { kind: "pad" } & Required< Pick<PadEnvironmentConfig, "center" | "size" | "height" | "color"> > & Pick<PadEnvironmentConfig, "rotationY" | "elevation"> — ⚠ undocumented
1647
+ - `PadSize` (type): type PadSize = readonly [number, number] | { radius: number } — ⚠ undocumented
1648
+ - `PaintStroke` (interface): interface PaintStroke — ⚠ undocumented
1649
+ - `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.
1650
+ - `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.
1651
+ - `ParamSchema` (interface): interface ParamSchema — A kind's full parameter surface: an ordered list of fields the inspector renders top-to-bottom.
1652
+ - `ParsedParams` (type): type ParsedParams = Record<string, number | boolean | string | WeightedParamEntry[]> — Parsed params after `parseParams`: every schema field present with a validated, defaulted value.
1653
+ - `PathFollowConfig` (interface): interface PathFollowConfig — ⚠ undocumented
1654
+ - `PathFollowProgress` (interface): interface PathFollowProgress — Read-only progress readout for inspection/debug tooling, produced by {@link pathFollowProgress}.
1655
+ - `PathFollowState` (interface): interface PathFollowState — ⚠ undocumented
1656
+ - `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).
1657
+ - `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.
1658
+ - `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.
1659
+ - `PatrolOrderPayload` (interface): interface PatrolOrderPayload — Payload for a patrol: walk a waypoint route, optionally looping forever.
1660
+ - `PatrolOrderState` (interface): interface PatrolOrderState — Serializable patrol progress.
1661
+ - `PhysicsStats` (interface): interface PhysicsStats — ⚠ undocumented
1662
+ - `PhysicsWorld` (class): class PhysicsWorld — ⚠ undocumented
1663
+ - `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}.
1664
+ - `PlaceConfig` (interface): interface PlaceConfig — Input to {@link world}: place identity, substrate, and the laws of this place.
1665
+ - `PlaceWorldFeature` (interface): interface PlaceWorldFeature — A declared place — the `world()` result carried on `GameDefinition.world`.
1666
+ - `PlacedStructure` (interface): interface PlacedStructure — ⚠ undocumented
1667
+ - `PlacementCommit` (interface): interface PlacementCommit — ⚠ undocumented
1668
+ - `PlacementController` (interface): interface PlacementController — ⚠ undocumented
1669
+ - `PlacementPreview` (interface): interface PlacementPreview — ⚠ undocumented
1670
+ - `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.
1671
+ - `PlacementRules` (interface): interface PlacementRules — ⚠ undocumented
1672
+ - `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.
1673
+ - `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.
1674
+ - `PointGravityOptions` (interface): interface PointGravityOptions — Center, strength, and falloff for radial gravity.
1675
+ - `PositionedPrompt` (interface): interface PositionedPrompt — ⚠ undocumented
1676
+ - `ProximityPrompt` (interface): interface ProximityPrompt — ⚠ undocumented
1677
+ - `QteStep` (interface): interface QteStep — ⚠ undocumented
1678
+ - `RadialDistribution` (type): type RadialDistribution = "area" | "radial" — Fill policy for a circle/ring: `"area"` = area-uniform (even density); `"radial"` = radius-uniform (clumps toward center).
1679
+ - `RainEnvironmentDescriptor` (type): type RainEnvironmentDescriptor = { kind: "rain" } & Required< Pick<RainEnvironmentConfig, "area" | "density" | "speed" | "dropLength" | "wind" | "color" | "width" | "opacity"> > — ⚠ undocumented
1680
+ - `RecallBookmarkOptions` (interface): interface RecallBookmarkOptions — Caller hooks for {@link recallSelectionBookmark} — kept out of the store so focus and validity stay genre-owned.
1681
+ - `RecordingBuffer` (interface): interface RecordingBuffer<T> — ⚠ undocumented
1682
+ - `RecordingBufferOptions` (interface): interface RecordingBufferOptions — ⚠ undocumented
1683
+ - `RegionField` (interface): interface RegionField<T = unknown> extends TerrainField — ⚠ undocumented
1684
+ - `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.
1685
+ - `ResolvedCity` (interface): interface ResolvedCity — A resolved city district: world-space network, zoned lots, parks, and furniture.
1686
+ - `ResolvedCollider` (interface): interface ResolvedCollider — ⚠ undocumented
1687
+ - `ResolvedGround` (type): type ResolvedGround = FlatGround | RoundGround | VoxelGround | ResolvedBoardGround — A place's ground after `world()` normalization.
1688
+ - `ResolvedPoleLine` (interface): interface ResolvedPoleLine — The renderable payload the resolver returns and the shell renderer consumes.
1689
+ - `ResolvedTerrainDetail` (type): type ResolvedTerrainDetail = Required<Omit<TerrainDetailConfig, "waterLevel" | "material">> & { waterLevel: number; material?: ResolvedTerrainDetailMaterial; } — A {@link TerrainDetailConfig} with every field resolved to a concrete value — the shape the shell's detail material consumes.
1690
+ - `ResolvedWeather` (interface): interface ResolvedWeather — ⚠ undocumented
1691
+ - `RevealHit` (interface): interface RevealHit — ⚠ undocumented
1692
+ - `RevealQuery` (interface): interface RevealQuery — ⚠ undocumented
1693
+ - `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; } — Resolved road descriptor produced by {@link road} and rendered by the shell environment scene.
1694
+ - `RoadSurfaceOptions` (interface): interface RoadSurfaceOptions — Grip levels and blend width for {@link roadSurfaceSampler}; each field is optional and defaulted.
1695
+ - `RoofPlan` (interface): interface RoofPlan — ⚠ undocumented
1696
+ - `RosterEntry` (interface): interface RosterEntry — ⚠ undocumented
1697
+ - `RoundGround` (interface): interface RoundGround — A planet/sphere you play on the outside of. Sized by `radius` only.
1698
+ - `RoundGroundSize` (interface): interface RoundGroundSize — Size of a `round` ground: the planet/sphere radius in world units. Nothing else.
1699
+ - `SCATTER_PATH_KIND` (const): const SCATTER_PATH_KIND: "scatter" — The editor path kind that marks a closed polyline as a foliage/scatter region.
1700
+ - `SHAPE_BOX` (const): const SHAPE_BOX: 0 — ⚠ undocumented
1701
+ - `SHAPE_SPHERE` (const): const SHAPE_SPHERE: 1 — ⚠ undocumented
1702
+ - `SOIL_KIND` (const): const SOIL_KIND: "soil" — The editor volume kind marking a box as a soil crack/moss patch.
1703
+ - `SOIL_SCHEMA` (const): const SOIL_SCHEMA: ParamSchema — The soil parameter schema — drives the inspector and `meta` parse via the studio seam.
1704
+ - `SampleBatchOptions` (interface): interface SampleBatchOptions<P extends SamplePoint = SamplePoint> — Inputs for a {@link sampleBatch} draw of many spaced points.
1705
+ - `SampleBatchResult` (interface): interface SampleBatchResult<P extends SamplePoint = SamplePoint> — Structured batch outcome: the placed points plus whether the full count was met.
1706
+ - `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`.
1707
+ - `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.
1708
+ - `SamplePointOptions` (interface): interface SamplePointOptions<P extends SamplePoint = SamplePoint> — Inputs for a single {@link samplePoint} draw.
1709
+ - `SampleReason` (type): type SampleReason = "accepted" | "exhausted" | "empty-region" — Why a sample ended: a clean hit, budget exhausted, or the region was degenerate.
1710
+ - `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.
1711
+ - `SampleResult` (interface): interface SampleResult<P extends SamplePoint = SamplePoint> — Structured single-sample outcome — never a bare point, so failure and fallback are visible.
1712
+ - `ScatterInstance` (interface): interface ScatterInstance — ⚠ undocumented
1713
+ - `ScatterPoint` (interface): interface ScatterPoint — ⚠ undocumented
1714
+ - `ScatterTerrain` (interface): interface ScatterTerrain — Ground sampler a scatter resolve reads height/normal from (the sculpt terrain or the game's ground).
1715
+ - `SceneEntity` (interface): interface SceneEntity<TMeta = unknown> — ⚠ undocumented
1716
+ - `SceneKindObject` (interface): interface SceneKindObject — The raw document object a resolver receives — shape shared by markers, volumes, and paths.
1717
+ - `SceneKindResolveContext` (interface): interface SceneKindResolveContext — Ground sampler + options a resolver may read (terrain height/normal snap).
1718
+ - `SceneObject` (interface): interface SceneObject — ⚠ undocumented
1719
+ - `SceneRaycastApi` (interface): interface SceneRaycastApi — ⚠ undocumented
1720
+ - `SceneRaycastHit` (interface): interface SceneRaycastHit — ⚠ undocumented
1721
+ - `ScreenRect` (interface): interface ScreenRect — ⚠ undocumented
1722
+ - `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.
1723
+ - `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.
1724
+ - `SelectionPruneResult` (interface): interface SelectionPruneResult — Outcome of a {@link SelectionBookmarks.prune} pass — what the validity predicate removed.
1725
+ - `SelectionSet` (interface): interface SelectionSet — ⚠ undocumented
1726
+ - `SensorProbeOptions` (interface): interface SensorProbeOptions — ⚠ undocumented
1727
+ - `SensorReading` (interface): interface SensorReading — ⚠ undocumented
1728
+ - `SimClock` (interface): interface SimClock — ⚠ undocumented
1729
+ - `SkillCheckConfig` (interface): interface SkillCheckConfig — ⚠ undocumented
1730
+ - `SkillCheckResult` (interface): interface SkillCheckResult — ⚠ undocumented
1731
+ - `SkyEnvironmentDescriptor` (type): type SkyEnvironmentDescriptor = { kind: "sky" } & Required< Pick<SkyEnvironmentConfig, "preset" | "timeOfDay"> > & Omit<SkyEnvironmentConfig, "preset" | "timeOfDay"> — ⚠ undocumented
1732
+ - `SlotAssignmentOptions` (interface): interface SlotAssignmentOptions — Tuning for {@link assignFormationSlots}' stable, low-churn matching.
1733
+ - `SnapMode` (type): type SnapMode = "grid" | "free" | "surface" — ⚠ undocumented
1734
+ - `SnowEnvironmentDescriptor` (type): type SnowEnvironmentDescriptor = { kind: "snow" } & Required< Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color" | "opacity"> > — ⚠ undocumented
1735
+ - `SoilRules` (interface): interface SoilRules — Fully-defaulted soil params parsed from a volume's `meta`.
1736
+ - `SoundDef` (interface): interface SoundDef — ⚠ undocumented
1737
+ - `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.
1738
+ - `SpawnDirectorConfig` (interface): interface SpawnDirectorConfig — ⚠ undocumented
1739
+ - `SpawnDirectorState` (interface): interface SpawnDirectorState — ⚠ undocumented
1740
+ - `SpawnEntry` (interface): interface SpawnEntry — ⚠ undocumented
1741
+ - `SpawnRequest` (interface): interface SpawnRequest — ⚠ undocumented
1742
+ - `StatCatalog` (type): type StatCatalog = Record<string, { max: number; min?: number; current?: number }> — ⚠ undocumented
1743
+ - `StatValue` (interface): interface StatValue extends StatPool — Native entity-stat name retained as a compatibility bridge to the portable pool model.
1744
+ - `Station` (interface): interface Station — ⚠ undocumented
1745
+ - `StratifiedOptions` (interface): interface StratifiedOptions — Inputs for {@link sampleStratified}: a grid over `area` with one jittered point per cell.
1746
+ - `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.
1747
+ - `StructureMaterial` (interface): interface StructureMaterial — ⚠ undocumented
1748
+ - `SupportResult` (interface): interface SupportResult — ⚠ undocumented
1749
+ - `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.
1750
+ - `SurfaceGridLine` (interface): interface SurfaceGridLine — One draped grid line from {@link surfaceGridLines}: its axis, emphasis, and draped vertices.
1751
+ - `SurfaceGridOptions` (interface): interface SurfaceGridOptions — Shaping for {@link surfaceGridLines}: region, spacing, emphasis cadence, and draping.
1752
+ - `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.
1753
+ - `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.
1754
+ - `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`.
1755
+ - `TERRAIN_MATERIAL_PALETTES` (const): const TERRAIN_MATERIAL_PALETTES: Record<TerrainMaterial, TerrainPalette> — ⚠ undocumented
1756
+ - `TargetAcquirer` (interface): interface TargetAcquirer — A stateful acquirer that holds the current target across passes — sugar over {@link acquireTarget}.
1757
+ - `TargetedOrderPayload` (interface): interface TargetedOrderPayload — Payload for a targeted action: pursue one target until in range, holding within a leash.
1758
+ - `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.
1759
+ - `TerraformEdit` (interface): interface TerraformEdit — A single sculpt stamp: which brush, where, and its shaping parameters.
1760
+ - `TerraformFalloff` (type): type TerraformFalloff = "smooth" | "linear" | "none" — How a brush's strength fades from its center to its rim.
1761
+ - `TerraformMode` (type): type TerraformMode = "raise" | "lower" | "smooth" | "flatten" | "noise" | "ramp" | "paint" — A sculpt operation kind: heightfield brushes plus the surface-paint brush.
1762
+ - `TerraformShape` (type): type TerraformShape = "circle" | "square" — A brush footprint: a round disc or an axis-aligned square.
1763
+ - `TerraformSnapshot` (interface): interface TerraformSnapshot — ⚠ undocumented
1764
+ - `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.
1765
+ - `TerrainCircleRegion` (interface): interface TerrainCircleRegion extends TerrainRegionStyle — A circular palette zone painted over the base terrain palette — snow caps, ash wastes, spawn circles.
1766
+ - `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.
1767
+ - `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.
1768
+ - `TerrainEnvironmentDescriptor` (type): type TerrainEnvironmentDescriptor = { kind: "terrain" } & Required< Pick<TerrainEnvironmentConfig, "bounds" | "height"> > & Omit<TerrainEnvironmentConfig, "bounds" | "height"> — ⚠ undocumented
1769
+ - `TerrainField` (interface): interface TerrainField — A sampleable ground surface: height and normal at any x/z, with optional bounds and water level.
1770
+ - `TerrainFlattenMask` (interface): interface TerrainFlattenMask — ⚠ undocumented
1771
+ - `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.
1772
+ - `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.
1773
+ - `TerrainPalette` (interface): interface TerrainPalette — ⚠ undocumented
1774
+ - `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.
1775
+ - `TerrainPolylineRegion` (interface): interface TerrainPolylineRegion extends TerrainRegionStyle — A ribbon palette zone following a centerline — roads and rivers, instead of chaining overlapping circles.
1776
+ - `TerrainRectRegion` (interface): interface TerrainRectRegion extends TerrainRegionStyle — A rectangular palette zone, optionally rotated about the world y axis — plazas, fields, districts.
1777
+ - `TerrainRegionStyle` (interface): interface TerrainRegionStyle — Palette and blend fields shared by every `TerrainMaterialRegion` shape.
1778
+ - `TerrainSurfaceRule` (interface): interface TerrainSurfaceRule — A height/slope predicate for auto-painting a surface layer (e.g. rock on steep slopes, snow up high).
1779
+ - `ThreatTable` (interface): interface ThreatTable — ⚠ undocumented
1780
+ - `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`.
1781
+ - `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.
1782
+ - `TriggerDispatchEvent` (interface): interface TriggerDispatchEvent — Fired when a watched actor trips an authored trigger edge.
1783
+ - `TriggerEvent` (type): type TriggerEvent = "enter" | "exit" | "interact" — Event edge that can fire an authored trigger.
1784
+ - `TriggerHandlers` (type): type TriggerHandlers = Readonly<Record<string, (event: TriggerDispatchEvent) => void>> — Handler map keyed by action id — unknown actions are skipped unless `onDispatch` is set.
1785
+ - `TriggerSourceKind` (type): type TriggerSourceKind = "marker" | "volume" — Document collection a trigger source lives on.
1786
+ - `VEGETATION_VOLUME_KIND` (const): const VEGETATION_VOLUME_KIND: "vegetation" — The editor volume kind that marks an area as vegetation fill.
1787
+ - `VISIBILITY_HIDDEN` (const): const VISIBILITY_HIDDEN: 0 — Numeric code for a cell no group member has seen, or has fully forgotten.
1788
+ - `VISIBILITY_OBSERVED` (const): const VISIBILITY_OBSERVED: 2 — Numeric code for a cell a group currently observes.
1789
+ - `VISIBILITY_REMEMBERED` (const): const VISIBILITY_REMEMBERED: 1 — Numeric code for a cell seen before but not currently in view (last-known).
1790
+ - `Vec3` (type): type Vec3 = EntityPosition — ⚠ undocumented
1791
+ - `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}.
1792
+ - `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.
1793
+ - `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`.
1794
+ - `VisibilityCells` (interface): interface VisibilityCells — Dense per-cell readout for one group, shaped for minimap/overlay drawing.
1795
+ - `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).
1796
+ - `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.
1797
+ - `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.
1798
+ - `VisibilityFieldConfig` (interface): interface VisibilityFieldConfig — Construction options for {@link createVisibilityField}.
1799
+ - `VisibilityFieldState` (interface): interface VisibilityFieldState — Serializable snapshot of a whole field — JSON round-trips losslessly.
1800
+ - `VisibilityGroupState` (interface): interface VisibilityGroupState — Sparse serialized knowledge for one group — only non-hidden cells are stored.
1801
+ - `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.
1802
+ - `VisibilityState` (type): type VisibilityState = "hidden" | "remembered" | "observed" — One viewer group's knowledge of a cell: never/forgotten, last-known, or live.
1803
+ - `VisibilitySystem` (interface): interface VisibilitySystem — ⚠ undocumented
1804
+ - `VolumeDistribution` (type): type VolumeDistribution = "volume" | "radial" — Fill policy for a sphere/shell: `"volume"` = volume-uniform (even density); `"radial"` = radius-uniform.
1805
+ - `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.
1806
+ - `VolumetricCloudsRules` (interface): interface VolumetricCloudsRules — Fully-defaulted volumetric cloud params, resolved from a `VolumetricCloudsConfig`.
1807
+ - `VoxelFace` (type): type VoxelFace = "px" | "nx" | "py" | "ny" | "pz" | "nz" — ⚠ undocumented
1808
+ - `VoxelGround` (interface): interface VoxelGround — A procedural volume of blocks. `size` is the generator domain; `generator` is algorithm params only.
1809
+ - `VoxelGroundSize` (interface): interface VoxelGroundSize — Size of a `voxel` ground: the generator's domain per axis; axes may be `Infinity` for streaming volumes.
1810
+ - `VoxelMaterial` (interface): interface VoxelMaterial — ⚠ undocumented
1811
+ - `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`.
1812
+ - `WATER_SCHEMA` (const): const WATER_SCHEMA: ParamSchema — The water parameter schema — drives the inspector and `meta` parse via the studio seam.
1813
+ - `WaterRules` (interface): interface WaterRules — Fully-defaulted water surface params parsed from a volume's `meta`.
1814
+ - `WaterSurface` (interface): interface WaterSurface — ⚠ undocumented
1815
+ - `WaveManifest` (interface): interface WaveManifest — ⚠ undocumented
1816
+ - `Waypoint` (type): type Waypoint = readonly [number, number, number] — ⚠ undocumented
1817
+ - `WeatherEnvironmentDescriptor` (type): type WeatherEnvironmentDescriptor = RainEnvironmentDescriptor | SnowEnvironmentDescriptor — ⚠ undocumented
1818
+ - `WeatherModifierTable` (type): type WeatherModifierTable<K extends string = string> = Record<K, WeatherModifier> — ⚠ undocumented
1819
+ - `WeatherState` (interface): interface WeatherState — ⚠ undocumented
1820
+ - `WedgeFormationOptions` (interface): interface WedgeFormationOptions — Options for {@link wedgeFormation}.
1821
+ - `WeightedParamEntry` (interface): interface WeightedParamEntry — One weighted entry in a `weightedList` param — an item id and its relative spawn weight.
1822
+ - `WeightedRegionEntry` (interface): interface WeightedRegionEntry<P extends SamplePoint = SamplePoint> — A weighted member of a {@link weightedRegion} composite.
1823
+ - `WindField` (interface): interface WindField — ⚠ undocumented
1824
+ - `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.
1825
+ - `WorldGridCell` (interface): interface WorldGridCell — ⚠ undocumented
1826
+ - `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.
1827
+ - `WorldXZ` (type): type WorldXZ = readonly [number, number] — ⚠ undocumented
1828
+ - `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.
1829
+ - `advanceBehaviors` (function): function advanceBehaviors(ctx: GameContext, dt: number): void — Advance every spawned entity carrying a `patrol` or `wander` {@link BehaviorDescriptor} 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.
1830
+ - `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.
1831
+ - `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).
1832
+ - `advanceSpawnDirector` (function): function advanceSpawnDirector(config: SpawnDirectorConfig, state: SpawnDirectorState, dt: number, ctx: DirectorContext): DirectorStep — ⚠ undocumented
1833
+ - `advanceWave` (function): function advanceWave(config: SpawnDirectorConfig, state: SpawnDirectorState): SpawnDirectorState — ⚠ undocumented
1834
+ - `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.
1835
+ - `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).
1836
+ - `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.
1837
+ - `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.
1838
+ - `applySurfaceDeltaToSnapshot` (function): function applySurfaceDeltaToSnapshot(snapshot: TerraformSnapshot, delta: SurfaceDelta): TerraformSnapshot — Returns a new snapshot with a surface delta's `after` ids applied (copy-on-write).
1839
+ - `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.
1840
+ - `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.
1841
+ - `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.
1842
+ - `bearingToCardinal` (function): function bearingToCardinal(bearing: number): Cardinal — ⚠ undocumented
1843
+ - `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.
1844
+ - `beginTerraformStroke` (function): function beginTerraformStroke(terrain: Pick<EditableTerrain, "applyRecording">): TerraformStroke — Opens a stroke recorder over `terrain`; stamp edits into it, then read one net delta.
1845
+ - `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.
1846
+ - `biomes` (function): function biomes(config: BiomesWorldConfig): WorldFeature — Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain.
1847
+ - `boundaryNeighbors` (function): function boundaryNeighbors(grid: FootprintGrid, cells: readonly GridCell[]): AdjacentCell[] — Every occupied cell orthogonally touching `cells` but outside them — the connective-piece neighbor set.
1848
+ - `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.
1849
+ - `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.
1850
+ - `buildContextMenu` (function): function buildContextMenu(input: BuildContextMenuInput): ContextMenu | null — Assemble a menu from a target's catalog verbs; null when the target lists none.
1851
+ - `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.
1852
+ - `building` (function): function building(config: BuildingEnvironmentConfig = {}): BuildingEnvironmentDescriptor — Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style.
1853
+ - `buildingIndex` (function): function buildingIndex(buildings: readonly GeneratedBuilding[]): BuildingIndex — ⚠ undocumented
1854
+ - `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.
1855
+ - `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.).
1856
+ - `carvableTerrain` (function): function carvableTerrain(base: TerrainField): CarvableField — ⚠ undocumented
1857
+ - `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.
1858
+ - `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).
1859
+ - `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.
1860
+ - `clampToMinimapEdge` (function): function clampToMinimapEdge(point: MinimapPoint, size: number): { x: number; y: number } — Clamp a projected point to the minimap edge, preserving direction (edge markers).
1861
+ - `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.
1862
+ - `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.
1863
+ - `combineGravity` (function): function combineGravity(fields: readonly GravityField[]): GravityField — Adds several gravity sources into one field.
1864
+ - `command` (function): function command(name: string, input?: unknown): PromptCommand — ⚠ undocumented
1865
+ - `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.
1866
+ - `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.
1867
+ - `computeFalloffGain` (function): function computeFalloffGain(distance: number, config: AudioFalloffConfig = {}): number — ⚠ undocumented
1868
+ - `constrainToNavGrid` (function): function constrainToNavGrid(grid: NavGrid, options?: NavConstrainOptions): (proposed: NavConstrainProposed, entity: NavConstrainEntity) => NavConstrainProposed | null — ⚠ undocumented
1869
+ - `contextVerb` (function): function contextVerb(label: string, command: string, args?: Record<string, unknown>): ContextVerb — Builds a {@link ContextVerb} for a right-click menu entry.
1870
+ - `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.
1871
+ - `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}.
1872
+ - `createAircraftDynamics` (function): function createAircraftDynamics(tuning: AircraftTuning, options: AircraftOptions = {}): AircraftDynamics — Six-degree-of-freedom arcade flight model for fixed-wing, helicopter, and VTOL aircraft.
1873
+ - `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.
1874
+ - `createAssetCatalog` (function): function createAssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef>(): AssetCatalog<TMeta> — ⚠ undocumented
1875
+ - `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.
1876
+ - `createBallisticSweep` (function): function createBallisticSweep(world: PhysicsWorld, options: BallisticSweepOptions = {}): BallisticSweep — Marches the closed-form arc (constant gravity, straight lateral) through `world` and reports the first sample inside any live body's AABB — sleeping bodies included — refined by one bisection between the last clear sample and the hit sample. Returns `null` when the whole arc is clear.
1877
+ - `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.
1878
+ - `createBuoyantBody` (function): function createBuoyantBody(world: PhysicsWorld, config: BuoyantBodyConfig): BuoyantBody — ⚠ undocumented
1879
+ - `createContributionPool` (function): function createContributionPool(goal: ContributionGoal): ContributionPool — ⚠ undocumented
1880
+ - `createDamageModel` (function): function createDamageModel(config: DamageModelConfig): DamageModel — ⚠ undocumented
1881
+ - `createEditableTerrain` (function): function createEditableTerrain(config: EditableTerrainConfig): EditableTerrain — ⚠ undocumented
1882
+ - `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.
1883
+ - `createFactionGraph` (function): function createFactionGraph(config: FactionGraphConfig): FactionGraph — ⚠ undocumented
1884
+ - `createFactionRoster` (function): function createFactionRoster(graph: FactionGraph): FactionRoster — ⚠ undocumented
1885
+ - `createFireGrid` (function): function createFireGrid(config: FireGridConfig): FireGrid — ⚠ undocumented
1886
+ - `createFogField` (function): function createFogField(config: FogConfig): FogField — ⚠ undocumented
1887
+ - `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.
1888
+ - `createGlideModel` (function): function createGlideModel(config: GlideModelConfig = {}): GlideModel — Gliding/wingsuit descent control — lift, drag, and steering from a launch.
1889
+ - `createGrappleSwing` (function): function createGrappleSwing(config: GrappleSwingConfig = {}): GrappleSwing — Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.
1890
+ - `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.
1891
+ - `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.
1892
+ - `createKinematicVehicle` (function): function createKinematicVehicle(tuning: KinematicVehicleTuning, options: KinematicVehicleOptions = {}): KinematicVehicle — ⚠ undocumented
1893
+ - `createLeaderTrail` (function): function createLeaderTrail(config: LeaderTrailConfig): LeaderTrail — A trailing follower formation that chases a leader along its past path — snake/convoy trails.
1894
+ - `createLodScheduler` (function): function createLodScheduler(config: LodSchedulerConfig): LodScheduler — ⚠ undocumented
1895
+ - `createMarkerSet` (function): function createMarkerSet<TMeta = unknown>(now: () => number = Date.now): MarkerSet<TMeta> — ⚠ undocumented
1896
+ - `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.
1897
+ - `createMountController` (function): function createMountController(): MountController — ⚠ undocumented
1898
+ - `createNavGrid` (function): function createNavGrid(config: NavGridConfig): NavGrid — ⚠ undocumented
1899
+ - `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.
1900
+ - `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.
1901
+ - `createPathFollow` (function): function createPathFollow(config: PathFollowConfig): PathFollowState — ⚠ undocumented
1902
+ - `createPlacedStructureStore` (function): function createPlacedStructureStore(): PlacedStructureStore — ⚠ undocumented
1903
+ - `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}.
1904
+ - `createPlotPermissions` (function): function createPlotPermissions(config: PlotPermissionConfig): PlotPermissions — ⚠ undocumented
1905
+ - `createPoseState` (function): function createPoseState(resolveAllowed: (instanceId: string) => PoseAllowedStates | null | undefined): PoseState — Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.
1906
+ - `createRagdoll` (function): function createRagdoll(world: PhysicsWorld, config: RagdollConfig): Ragdoll — ⚠ undocumented
1907
+ - `createRegionField` (function): function createRegionField<T = unknown>(config: RegionFieldConfig<T>): RegionField<T> — ⚠ undocumented
1908
+ - `createReputationLedger` (function): function createReputationLedger(config: ReputationLedgerConfig = {}): ReputationLedger — ⚠ undocumented
1909
+ - `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.
1910
+ - `createSelectionSet` (function): function createSelectionSet(initial?: Iterable<string>): SelectionSet — An ordered, deduplicated set of selected instance ids for RTS unit-command routing.
1911
+ - `createSpawnDirectorState` (function): function createSpawnDirectorState(config: SpawnDirectorConfig): SpawnDirectorState — ⚠ undocumented
1912
+ - `createStationClaim` (function): function createStationClaim(controller?: MountController): StationClaim — ⚠ undocumented
1913
+ - `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}.
1914
+ - `createTerraformBrush` (function): function createTerraformBrush(terrain: Pick<EditableTerrain, "apply">, config: TerraformBrushConfig = {}): TerraformBrush — ⚠ undocumented
1915
+ - `createTerrainSnapshot` (function): function createTerrainSnapshot(config: EditableTerrainConfig): TerraformSnapshot — A fresh, unedited terrain snapshot sized to `bounds`/`cellSize` — the seed for a new sculpt document.
1916
+ - `createThreatTable` (function): function createThreatTable(config: ThreatTableConfig = {}): ThreatTable — ⚠ undocumented
1917
+ - `createVehicleBody` (function): function createVehicleBody(world: PhysicsWorld, config: VehicleBodyConfig): VehicleBody — ⚠ undocumented
1918
+ - `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}).
1919
+ - `createVehicleSeats` (function): function createVehicleSeats(controller?: MountController): VehicleSeats — Builds a {@link VehicleSeats}, optionally over an existing `MountController` to share its occupancy.
1920
+ - `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.
1921
+ - `createVisibilitySystem` (function): function createVisibilitySystem(options: VisibilitySystemOptions): VisibilitySystem — ⚠ undocumented
1922
+ - `createVoxelField` (function): function createVoxelField<T extends string = string>(config?: VoxelFieldConfig): VoxelField<T> — ⚠ undocumented
1923
+ - `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).
1924
+ - `dashSegments` (function): function dashSegments(path: readonly RoadPoint[], dashLength = 3, gapLength = 3): 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.
1925
+ - `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.
1926
+ - `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.
1927
+ - `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`.
1928
+ - `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`.
1929
+ - `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.
1930
+ - `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.
1931
+ - `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.
1932
+ - `distance` (function): function distance(a: Vec3, b: Vec3): number — ⚠ undocumented
1933
+ - `distance3` (function): function distance3(a: { x: number; y: number; z: number }, b: { x: number; y: number; z: number }): number — ⚠ undocumented
1934
+ - `distanceToPolygonEdge` (function): function distanceToPolygonEdge(point: Vec2, polygon: readonly Vec2[]): number — Shortest distance from a point to a polygon's boundary.
1935
+ - `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.
1936
+ - `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.
1937
+ - `editableTerrainFromSnapshot` (function): function editableTerrainFromSnapshot(snapshot: TerraformSnapshot, base?: TerrainField): EditableTerrain — Rebuilds a live {@link EditableTerrain} from a snapshot, layered over `base` ground.
1938
+ - `effectiveRelation` (function): function effectiveRelation(input: EffectiveRelationInput): FactionRelation — ⚠ undocumented
1939
+ - `encodeBakePng` (function): function encodeBakePng(bake: MinimapBake): Uint8Array — Encodes an RGBA bake to raw PNG bytes (pure; stored DEFLATE, valid for any decoder).
1940
+ - `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.
1941
+ - `environment` (function): function environment(config: EnvironmentWorldConfig = {}): EnvironmentWorldFeature — Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
1942
+ - `evaluateQteSequence` (function): function evaluateQteSequence(steps: readonly QteStep[], inputs: readonly QteInputEvent[]): QteOutcome — Evaluate a quick-time-event input sequence against timed hit windows.
1943
+ - `evaluateSkillCheck` (function): function evaluateSkillCheck(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckResult — ⚠ undocumented
1944
+ - `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.
1945
+ - `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.
1946
+ - `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.
1947
+ - `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.
1948
+ - `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.
1949
+ - `firstImpact` (function): function firstImpact(hits: readonly SceneRaycastHit[]): SceneRaycastHit | null — First impact: nearest hit that blocks, or nearest hit if none block.
1950
+ - `flat` (function): function flat(): WorldFeature — Declares an empty flat world — the minimal `WorldFeature` for games with no terrain of their own.
1951
+ - `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.
1952
+ - `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.
1953
+ - `gauge` (function): function gauge(gaugeId: string): GaugePromptDisplay — ⚠ undocumented
1954
+ - `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.
1955
+ - `getCurrentGameTimestamp` (function): function getCurrentGameTimestamp(createdAt: number, now: number, timeScale?: number | null): number — ⚠ undocumented
1956
+ - `getTriggerAction` (function): function getTriggerAction(id: string): TriggerActionDefinition | undefined — Registered definition for an action id, or undefined when the game never declared it.
1957
+ - `grass` (function): function grass(config: GrassEnvironmentConfig = {}): GrassEnvironmentDescriptor — Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
1958
+ - `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.
1959
+ - `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.
1960
+ - `headingToBearing` (function): function headingToBearing(yaw: number): number — Bearing of an entity facing direction given its `rotationY` (yaw) in radians.
1961
+ - `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.
1962
+ - `hitsUntilBlocked` (function): function hitsUntilBlocked(hits: readonly SceneRaycastHit[]): SceneRaycastHit[] — Hits up to and including the first blocking collider (damage hitboxes before a wall stay).
1963
+ - `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.
1964
+ - `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}.
1965
+ - `isMarquee` (function): function isMarquee(rect: ScreenRect, thresholdPx = 4): boolean — True when the drag is large enough to be a marquee rather than a click.
1966
+ - `isPlaceWorld` (function): function isPlaceWorld(worldFeature: { kind: string } | undefined): worldFeature is PlaceWorldFeature — Type guard for the place-model world feature.
1967
+ - `isRegionField` (function): function isRegionField(field: TerrainField): field is RegionField — ⚠ undocumented
1968
+ - `isScatterPath` (function): function isScatterPath(path: ScenePathLike): boolean — True when an editor path is a foliage/scatter region.
1969
+ - `keybind` (function): function keybind(actionId: string, label?: string): KeybindPromptDisplay — ⚠ undocumented
1970
+ - `label` (function): function label(text: string): LabelPromptDisplay — ⚠ undocumented
1971
+ - `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.
1972
+ - `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.
1973
+ - `listTriggerActions` (function): function listTriggerActions(target?: TriggerSourceKind): TriggerActionDefinition[] — Every registered action, optionally filtered by target collection.
1974
+ - `mapLayerColor` (function): function mapLayerColor(tone: MapLayerTone | undefined): string — ⚠ undocumented
1975
+ - `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, …).
1976
+ - `markerKindStyle` (function): function markerKindStyle(kind: string | undefined, styles: Record<string, MarkerKindStyle> = DEFAULT_MARKER_KINDS): MarkerKindStyle — ⚠ undocumented
1977
+ - `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.
1978
+ - `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.
1979
+ - `mtof` (function): function mtof(midi: number): number — Standard equal-temperament MIDI-to-frequency (A4 = 440 Hz at MIDI 69).
1980
+ - `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.
1981
+ - `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.
1982
+ - `objectVisualScale` (function): function objectVisualScale(visual: ObjectVisual | undefined): readonly [number, number, number] — ⚠ undocumented
1983
+ - `ocean` (function): function ocean(config: OceanEnvironmentConfig = {}): OceanEnvironmentDescriptor — Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
1984
+ - `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.
1985
+ - `pad` (function): function pad(config: PadEnvironmentConfig): PadEnvironmentDescriptor — ⚠ undocumented
1986
+ - `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.
1987
+ - `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.
1988
+ - `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.
1989
+ - `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.
1990
+ - `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.
1991
+ - `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.
1992
+ - `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.
1993
+ - `pathFromNav` (function): function pathFromNav(points: readonly NavPoint[], elevation: number | HeightSampler = 0, offset = 0): Waypoint[] — ⚠ undocumented
1994
+ - `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.
1995
+ - `patrol` (function): function patrol({ waypoints, speed, loop = true, startProgress, groundClamp, }: { waypoints: readonly Waypoint[]; speed: number; loop?: boolean; startProgress?: PathProgress; groundClamp?: boolean; }): PatrolBehavior — ⚠ undocumented
1996
+ - `pendingQteStep` (function): function pendingQteStep(steps: readonly QteStep[], elapsedSeconds: number): QteStep | null — ⚠ undocumented
1997
+ - `pickSpawnPoint` (function): function pickSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null — Selects a candidate spawn point using a semantic distance preference and caller-supplied randomness.
1998
+ - `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.
1999
+ - `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.
2000
+ - `placeAssetFromCommit` (function): function placeAssetFromCommit(commit: PlacementCommit, assetId: string, options: PlaceAssetFromCommitOptions = {}): PlaceAssetResult — Bridge a {@link PlacementCommit} into the shared place-asset verb.
2001
+ - `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).
2002
+ - `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.
2003
+ - `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.
2004
+ - `player` (function): function player(): PlayerBehavior — ⚠ undocumented
2005
+ - `plots` (function): function plots(config: PlotsWorldConfig = {}): WorldFeature — Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts.
2006
+ - `pointGravity` (function): function pointGravity(options: PointGravityOptions): GravityField — Radial gravity toward one center, with optional inverse-square falloff for planetary worlds.
2007
+ - `pointInPolygon` (function): function pointInPolygon(point: Vec2, polygon: readonly Vec2[]): boolean — Ray-casting point-in-polygon test on the XZ plane.
2008
+ - `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.
2009
+ - `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.
2010
+ - `polygonArea` (function): function polygonArea(polygon: readonly Vec2[]): number — Shoelace area of a polygon (always non-negative), in square meters.
2011
+ - `polygonBounds` (function): function polygonBounds(polygon: readonly Vec2[]): Aabb | null — Axis-aligned bounds of a polygon, or null if it has no points.
2012
+ - `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).
2013
+ - `populateNavGridFromEnvironment` (function): function populateNavGridFromEnvironment(grid: NavObstacleGrid, world: EnvironmentWorldFeature): number — Expands every structure descriptor on an environment world feature into its generated buildings and blocks their footprints on `grid`. Returns the number of buildings blocked.
2014
+ - `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.
2015
+ - `proximityPrompt` (function): function proximityPrompt({ radius, display, invoke = null }: ProximityPromptConfig): ProximityPrompt — ⚠ undocumented
2016
+ - `quarterTurnsToRotationY` (function): function quarterTurnsToRotationY(quarterTurns: number): number — Maps 0–3 quarter turns onto radians for ghost/commit rotation.
2017
+ - `rain` (function): function rain(config: RainEnvironmentConfig = {}): RainEnvironmentDescriptor — Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
2018
+ - `raiseAlert` (function): function raiseAlert(state: SpawnDirectorState, amount: number): SpawnDirectorState — ⚠ undocumented
2019
+ - `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.
2020
+ - `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`.
2021
+ - `readScatterRules` (function): function readScatterRules(path: ScenePathLike): ScatterRegionRules | null — The path's scatter rules with defaults filled in; null for non-scatter paths.
2022
+ - `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.
2023
+ - `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.
2024
+ - `registerAssetGenerator` (function): function registerAssetGenerator(definition: AssetGeneratorDefinition): void — Register a parametric asset generator. Idempotent per id (last wins); call at module load.
2025
+ - `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.
2026
+ - `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.
2027
+ - `relativeBearing` (function): function relativeBearing(bearing: number, reference: number): number — Signed offset of `bearing` from `reference`, wrapped into (−π, π].
2028
+ - `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.
2029
+ - `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.
2030
+ - `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.
2031
+ - `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.
2032
+ - `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.
2033
+ - `resolveEmitterGain` (function): function resolveEmitterGain(distance: number, sound: Pick<SoundDef, "gain" | "positional" | "falloff">, busGain: number): number — ⚠ undocumented
2034
+ - `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`.
2035
+ - `resolveGridInstances` (function): function resolveGridInstances(config: WorldGridConfig | GridWorldFeature): readonly GridInstanceTransform[] — ⚠ undocumented
2036
+ - `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.
2037
+ - `resolvePlaceAsset` (function): function resolvePlaceAsset(input: ResolvePlaceAssetInput): PlaceAssetResult — Resolve a place-asset intent into a shared payload (editor + games, one verb).
2038
+ - `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}.
2039
+ - `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.
2040
+ - `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.
2041
+ - `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.
2042
+ - `resolveStructureBuildings` (function): function resolveStructureBuildings(descriptor: BuildingEnvironmentDescriptor): GeneratedBuilding[] — ⚠ undocumented
2043
+ - `resolveWeather` (function): function resolveWeather<TTable extends WeatherModifierTable>(state: WeatherState, table: TTable): ResolvedWeather — ⚠ undocumented
2044
+ - `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.
2045
+ - `revertDeltaFromSnapshot` (function): function revertDeltaFromSnapshot(snapshot: TerraformSnapshot, delta: TerraformDelta): TerraformSnapshot — Returns a new snapshot with a delta's `before` offsets restored (copy-on-write undo).
2046
+ - `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).
2047
+ - `road` (function): function road(config: RoadEnvironmentConfig): RoadEnvironmentDescriptor — Declare a road ribbon for an `environment()` world; the shell drapes and renders it over the terrain.
2048
+ - `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.
2049
+ - `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.
2050
+ - `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.
2051
+ - `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.
2052
+ - `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.
2053
+ - `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.
2054
+ - `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.
2055
+ - `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.
2056
+ - `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.
2057
+ - `sanitizeGameTimeScale` (function): function sanitizeGameTimeScale(timeScale?: number | null): number — ⚠ undocumented
2058
+ - `scatter` (function): function scatter(config: ScatterConfig): ScatterPoint[] — ⚠ undocumented
2059
+ - `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.
2060
+ - `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.
2061
+ - `scatterRegionFromPath` (function): function scatterRegionFromPath(path: ScenePathLike): ScatterRegion | null — Builds a resolvable {@link ScatterRegion} from a scatter path (XZ polygon + rules), or null.
2062
+ - `screenRect` (function): function screenRect(ax: number, ay: number, bx: number, by: number): ScreenRect — Normalize two drag corners (in any order) into a rectangle.
2063
+ - `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.
2064
+ - `selectAutoTarget` (function): function selectAutoTarget(policy: AutoTargetPolicy, fromId: string, deps: AutoTargetDeps): string | null — ⚠ undocumented
2065
+ - `selectWithinRect` (function): function selectWithinRect(candidates: readonly ScreenPoint[], rect: ScreenRect): string[] — Ids of the projected candidates whose screen point falls inside the marquee.
2066
+ - `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.
2067
+ - `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.
2068
+ - `sidewalkWidthOf` (function): function sidewalkWidthOf(road: RoadEnvironmentDescriptor): number — Resolved sidewalk band widths for a road; zero when the road declares no sidewalk.
2069
+ - `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.
2070
+ - `sky` (function): function sky(config: SkyEnvironmentConfig = {}): SkyEnvironmentDescriptor — ⚠ undocumented
2071
+ - `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.
2072
+ - `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}.
2073
+ - `snapToNearest` (function): function snapToNearest(registry: ConnectorRegistry, placed: readonly PlacedPiece[], movingDef: ConnectorPieceDef, cursor: ConnectorVec3, options: SnapOptions = {}): SnapResult | null — ⚠ undocumented
2074
+ - `snow` (function): function snow(config: SnowEnvironmentConfig = {}): SnowEnvironmentDescriptor — Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
2075
+ - `socketWorldPosition` (function): function socketWorldPosition(socket: ConnectorSocket, origin: ConnectorVec3, rotationY: number): ConnectorVec3 — ⚠ undocumented
2076
+ - `socketsCompatible` (function): function socketsCompatible(a: ConnectorSocket, b: ConnectorSocket): boolean — ⚠ undocumented
2077
+ - `solveLock` (function): function solveLock(spec: LockSpec): boolean — Whether the board has a path from the start row to the bolt seat at all.
2078
+ - `solveLockPath` (function): function solveLockPath(spec: LockSpec): number[] | null — Return a concrete row-per-column solution, or null if the board is unsolvable.
2079
+ - `solveSupport` (function): function solveSupport(pieces: readonly SupportPiece[], links: readonly SupportLink[], config: SupportConfig = {}): SupportResult — ⚠ undocumented
2080
+ - `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.
2081
+ - `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.
2082
+ - `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.
2083
+ - `stepPlayerMovement` (function): function stepPlayerMovement(ctx: GameContext, userId: string, input: InputFrame, dt: number, tuning: PlayerMovementTuning, heading?: 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.
2084
+ - `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.
2085
+ - `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.
2086
+ - `summarizeEnvironment` (function): function summarizeEnvironment(feature: EnvironmentWorldFeature): EnvironmentSummary — ⚠ undocumented
2087
+ - `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.
2088
+ - `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.
2089
+ - `talkable` (function): function talkable(dialogueId: string): PromptableBehavior — ⚠ undocumented
2090
+ - `terrain` (function): function terrain(config: TerrainEnvironmentConfig = {}): TerrainEnvironmentDescriptor — Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
2091
+ - `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.
2092
+ - `themeLoopSeconds` (function): function themeLoopSeconds(theme: MusicTheme): number — Loop length of a theme in seconds.
2093
+ - `tickDrivableVehicle` (function): function tickDrivableVehicle(vehicle: KinematicVehicle, dt: number, axis: AxisInput, options: DrivableVehicleOptions = {}): DrivableVehicleStep — Connects an `AxisInput` sample straight through a {@link KinematicVehicle} 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.
2094
+ - `tierForStanding` (function): function tierForStanding(tiers: readonly ReputationTier[], standing: number): ReputationTier — Map a faction standing value to its named reputation tier.
2095
+ - `tilemap` (function): function tilemap(config: TilemapWorldConfig): WorldFeature — Declares a 2D tilemap world from a map string.
2096
+ - `toDebrisBodies` (function): function toDebrisBodies(pieces: readonly SupportPiece[], collapsedIds: readonly string[], options: DebrisOptions = {}): AddBodyOptions[] — ⚠ undocumented
2097
+ - `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.
2098
+ - `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).
2099
+ - `toStructureInput` (function): function toStructureInput(result: PlaceAssetResult): AddStructureInput — Game-state form: feed {@link createPlacedStructureStore}.add.
2100
+ - `uniformGravity` (function): function uniformGravity(vector: GravityVector = [0, -9.81, 0]): GravityField — Constant vector gravity for ordinary worlds, space stations, and sideways-gravity levels.
2101
+ - `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.
2102
+ - `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.
2103
+ - `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.
2104
+ - `validatePlacement` (function): function validatePlacement(request: PlacementRequest, rules: PlacementRules = {}): PlacementResult — Footprint validity: bounds + obstacle overlap after optional grid snap.
2105
+ - `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.
2106
+ - `voxel` (function): function voxel(config: VoxelWorldConfig): WorldFeature — Declares a voxel-grid world for block-based games.
2107
+ - `wander` (function): function wander({ radius }: { radius: number }): WanderBehavior — ⚠ undocumented
2108
+ - `waterSurface` (function): function waterSurface(config: WaterSurfaceConfig = {}): WaterSurface — ⚠ undocumented
2109
+ - `waterSurfaceFromDescriptor` (function): function waterSurfaceFromDescriptor(descriptor: OceanEnvironmentDescriptor, waves?: number): WaterSurface — ⚠ undocumented
2110
+ - `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.
2111
+ - `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.
2112
+ - `windField` (function): function windField(config: WindFieldConfig = {}): WindField — ⚠ undocumented
2113
+ - `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.
2114
+ - `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.
2115
+ - `worldSockets` (function): function worldSockets(def: ConnectorPieceDef, piece: PlacedPiece): WorldSocket[] — ⚠ undocumented
2116
+
2117
+ ## @jgengine/core/world/authoredEntities
2118
+
2119
+ - `AuthoredEntityDocumentLike` (interface): interface AuthoredEntityDocumentLike — The minimal document shape {@link authoredEntitySpawns} walks; any `EditorDocument` satisfies it.
2120
+ - `AuthoredEntityMarkerLike` (type): type AuthoredEntityMarkerLike = AuthoredObjectMarkerLike — The minimal marker shape entity spawns read; any `EditorMarker` satisfies it.
2121
+ - `AuthoredEntitySpawn` (interface): interface AuthoredEntitySpawn — One resolved entity to spawn from the authored scene — its marker id, catalog id, and pose.
2122
+ - `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.
2123
+ - `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).
2124
+
2125
+ ## @jgengine/core/world/authoredObjects
2126
+
2127
+ - `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}.
2128
+ - `AuthoredObjectMarkerLike` (interface): interface AuthoredObjectMarkerLike extends SceneMarkerLike — Minimal marker shape {@link resolveAuthoredObjects} reads; any `EditorMarker` satisfies it.
2129
+ - `AuthoredObjectPlaceTarget` (interface): interface AuthoredObjectPlaceTarget — Structural place target — any `ObjectStore` satisfies it.
2130
+ - `AuthoredObjectsDocumentLike` (interface): interface AuthoredObjectsDocumentLike — Minimal document shape {@link resolveAuthoredObjects} walks; any `EditorDocument` satisfies it.
2131
+ - `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.
2132
+ - `PlaceAuthoredObjectsOptions` (interface): interface PlaceAuthoredObjectsOptions — Options for {@link placeAuthoredObjects}.
2133
+ - `ResolveAuthoredObjectsOptions` (interface): interface ResolveAuthoredObjectsOptions — Options for {@link resolveAuthoredObjects}.
2134
+ - `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, …).
2135
+ - `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).
2136
+ - `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.
2137
+ - `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.
2138
+
2139
+ ## @jgengine/core/world/authoredSpawn
2140
+
2141
+ - `AuthoredSpawnDocumentLike` (interface): interface AuthoredSpawnDocumentLike — Minimal document shape spawn queries walk; any `EditorDocument` satisfies it.
2142
+ - `AuthoredSpawnMarkerLike` (interface): interface AuthoredSpawnMarkerLike extends SceneMarkerLike — Minimal marker shape spawn queries read; any `EditorMarker` satisfies it.
2143
+ - `AuthoredSpawnOptions` (interface): interface AuthoredSpawnOptions — Options for {@link authoredSpawnPosition}: pick a specific marker id or a non-default kind.
2144
+ - `PLAYER_SPAWN_KIND` (const): const PLAYER_SPAWN_KIND: "player_spawn" — Marker kind {@link authoredSpawnPosition} resolves by default.
2145
+ - `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.
2146
+ - `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.
2147
+ - `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.
2148
+
2149
+ ## @jgengine/core/world/buildPermissions
2150
+
2151
+ - `BuildActor` (interface): interface BuildActor — ⚠ undocumented
2152
+ - `BuildRole` (type): type BuildRole = "owner" | "editor" | "viewer" — ⚠ undocumented
2153
+ - `ContributionGoal` (type): type ContributionGoal = Readonly<Record<string, number>> — ⚠ undocumented
2154
+ - `ContributionPool` (interface): interface ContributionPool — ⚠ undocumented
2155
+ - `ContributionResult` (interface): interface ContributionResult — ⚠ undocumented
2156
+ - `PlotPermissionConfig` (interface): interface PlotPermissionConfig — ⚠ undocumented
2157
+ - `PlotPermissionSnapshot` (interface): interface PlotPermissionSnapshot — ⚠ undocumented
2158
+ - `PlotPermissions` (interface): interface PlotPermissions — ⚠ undocumented
2159
+ - `createContributionPool` (function): function createContributionPool(goal: ContributionGoal): ContributionPool — ⚠ undocumented
2160
+ - `createPlotPermissions` (function): function createPlotPermissions(config: PlotPermissionConfig): PlotPermissions — ⚠ undocumented
2161
+
2162
+ ## @jgengine/core/world/buildSockets
2163
+
2164
+ - `BuildCell` (interface): interface BuildCell — One integer grid cell — structurally the `GridCell` of `world/footprintGrid` (no import needed).
2165
+ - `BuildFootprint` (interface): interface BuildFootprint — A rectangular footprint (world units) a piece occupies on the build grid — the occupancy bridge.
2166
+ - `BuildPieceDef` (interface): interface BuildPieceDef — A registered piece type: its named sockets and, optionally, the footprint it claims when placed.
2167
+ - `BuildSocketCatalog` (interface): interface BuildSocketCatalog — Handle returned by {@link createBuildSocketCatalog}.
2168
+ - `BuildSocketCatalogConfig` (interface): interface BuildSocketCatalogConfig — Serializable catalog config; also the shape returned by {@link BuildSocketCatalog.toJSON}.
2169
+ - `ConnectionRule` (interface): interface ConnectionRule — Declares that two socket kinds may snap together; `mutual` (default `true`) also allows `b`→`a`.
2170
+ - `ModelSocketLike` (interface): interface ModelSocketLike — A `{ name, offset }` attach point — structurally the `ModelSocket` of `scene/modelSockets`.
2171
+ - `PieceTransform` (interface): interface PieceTransform — World transform of a placed piece: position plus a yaw about +Y.
2172
+ - `PlacedPiece` (interface): interface PlacedPiece — An already-placed piece the resolver snaps candidates against.
2173
+ - `PlacedSocket` (interface): interface PlacedSocket — A piece's socket resolved into world space.
2174
+ - `ResolveSnapsOptions` (interface): interface ResolveSnapsOptions — Options for {@link BuildSocketCatalog.resolveSnaps}.
2175
+ - `SnapCandidate` (interface): interface SnapCandidate — A resolved snap: which sockets mate and the world transform that lands the candidate onto the target.
2176
+ - `SocketDef` (interface): interface SocketDef — One named socket on a piece: where it sits and which horizontal direction it faces (yaw about Y).
2177
+ - `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}).
2178
+ - `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.
2179
+ - `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.
2180
+ - `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.
2181
+
2182
+ ## @jgengine/core/world/buildingGenerator
2183
+
2184
+ - `BUILDING_GENERATOR_ID` (const): const BUILDING_GENERATOR_ID: "building" — The generator id a catalog entry / placed marker references.
2185
+ - `BUILDING_GENERATOR_SCHEMA` (const): const BUILDING_GENERATOR_SCHEMA: ParamSchema — The building generator's slider schema — drives the inspector via #809.
2186
+
2187
+ ## @jgengine/core/world/buildingIndex
2188
+
2189
+ - `BuildingHit` (interface): interface BuildingHit — ⚠ undocumented
2190
+ - `BuildingIndex` (interface): interface BuildingIndex — ⚠ undocumented
2191
+ - `buildingIndex` (function): function buildingIndex(buildings: readonly GeneratedBuilding[]): BuildingIndex — ⚠ undocumented
2192
+
2193
+ ## @jgengine/core/world/buildings
2194
+
2195
+ - `BUILDING_STYLE_PALETTES` (const): const BUILDING_STYLE_PALETTES: Record<BuildingStyle, BuildingPalette> — ⚠ undocumented
2196
+ - `BuildingCellRef` (interface): interface BuildingCellRef — ⚠ undocumented
2197
+ - `BuildingConfig` (interface): interface BuildingConfig — ⚠ undocumented
2198
+ - `BuildingConfigInput` (type): type BuildingConfigInput = Partial< Omit<BuildingConfig, "probabilities" | "variants"> > & { probabilities?: Partial<BuildingProbabilities>; variants?: Partial<BuildingVariantCounts>; } — ⚠ undocumented
2199
+ - `BuildingFacade` (type): type BuildingFacade = "front" | "back" | "left" | "right" | "roof" — ⚠ undocumented
2200
+ - `BuildingGridConfig` (interface): interface BuildingGridConfig — ⚠ undocumented
2201
+ - `BuildingKitSlot` (interface): interface BuildingKitSlot — ⚠ undocumented
2202
+ - `BuildingLot` (interface): interface BuildingLot — ⚠ undocumented
2203
+ - `BuildingPalette` (type): type BuildingPalette = Record<BuildingPartKind, string> — ⚠ undocumented
2204
+ - `BuildingPaletteOverrides` (type): type BuildingPaletteOverrides = Partial<BuildingPalette> — ⚠ undocumented
2205
+ - `BuildingPartKind` (type): type BuildingPartKind = | "wall" | "window" | "awning" | "airConditioner" | "clothesline" | "storefront" | "shutter" | "storeSign" | "roof" | "roofProp" | "guardrail" | "corner" — ⚠ undocumented
2206
+ - `BuildingPartPlacement` (interface): interface BuildingPartPlacement — ⚠ undocumented
2207
+ - `BuildingPartTag` (type): type BuildingPartTag = "ground" | "upper" | "open" | "closed" | "decor" | "structure" — ⚠ undocumented
2208
+ - `BuildingProbabilities` (interface): interface BuildingProbabilities — ⚠ undocumented
2209
+ - `BuildingSeed` (type): type BuildingSeed = number | string — ⚠ undocumented
2210
+ - `BuildingStyle` (type): type BuildingStyle = | "generic" | "capital" | "village" | "desert" | "industrial" | "coastal" | "neon" | "ruin" | "frontier" | "aerial" — ⚠ undocumented
2211
+ - `BuildingVariantCounts` (interface): interface BuildingVariantCounts — ⚠ undocumented
2212
+ - `DEFAULT_BUILDING_CONFIG` (const): const DEFAULT_BUILDING_CONFIG: BuildingConfig — ⚠ undocumented
2213
+ - `DEFAULT_BUILDING_STYLE` (const): const DEFAULT_BUILDING_STYLE: BuildingStyle — ⚠ undocumented
2214
+ - `GeneratedBuilding` (interface): interface GeneratedBuilding — ⚠ undocumented
2215
+ - `Vec3` (type): type Vec3 = readonly [number, number, number] — ⚠ undocumented
2216
+
2217
+ ## @jgengine/core/world/carve
2218
+
2219
+ - `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.
2220
+ - `CarveOp` (interface): interface CarveOp — ⚠ undocumented
2221
+ - `CraterOp` (interface): interface CraterOp — ⚠ undocumented
2222
+ - `DepositOp` (interface): interface DepositOp — ⚠ undocumented
2223
+ - `EMPTY_VOXEL` (const): const EMPTY_VOXEL: 0 — ⚠ undocumented
2224
+ - `MoundOp` (interface): interface MoundOp — ⚠ undocumented
2225
+ - `VoxelMaterial` (interface): interface VoxelMaterial — ⚠ undocumented
2226
+ - `VoxelMaterialTable` (type): type VoxelMaterialTable = Readonly<Record<number, VoxelMaterial>> — ⚠ undocumented
2227
+ - `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`.
2228
+ - `VoxelVolumeConfig` (interface): interface VoxelVolumeConfig — ⚠ undocumented
2229
+ - `carvableTerrain` (function): function carvableTerrain(base: TerrainField): CarvableField — ⚠ undocumented
2230
+
2231
+ ## @jgengine/core/world/catenary
2232
+
2233
+ - `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.
2234
+ - `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.
2235
+ - `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.
2236
+
2237
+ ## @jgengine/core/world/cellStates
2238
+
2239
+ - `CellRef` (interface): interface CellRef — ⚠ undocumented
2240
+ - `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.
2241
+ - `CellStateGridConfig` (interface): interface CellStateGridConfig<TState extends string> — ⚠ undocumented
2242
+ - `createCellStateGrid` (function): function createCellStateGrid<TState extends string>(config: CellStateGridConfig<TState>): CellStateGrid<TState> — ⚠ undocumented
2243
+
2244
+ ## @jgengine/core/world/cityBlocks
2245
+
2246
+ - `BlockRings` (interface): interface BlockRings — A block's derived rings plus the sidewalk band (outer = curb line, inner = land line).
2247
+ - `CityBlockKind` (type): type CityBlockKind = "buildable" | "park" | "plaza" | "field" | "buffer" — How a block (a face of the road graph) is used.
2248
+ - `CityBlockLocal` (interface): interface CityBlockLocal — One closed block: a face of the road network, inset to its curb and land boundaries.
2249
+ - `CityParcelFrontage` (interface): interface CityParcelFrontage — One street-frontage reference of a parcel.
2250
+ - `CityParcelKind` (type): type CityParcelKind = "built" | "vacant" | "yard" — How a parcel is used after occupancy/fitting rolls.
2251
+ - `CityParcelLocal` (interface): interface CityParcelLocal — One polygonal parcel subdivided out of a block's street frontage.
2252
+ - `FabricParams` (interface): interface FabricParams — Everything block extraction needs from the district rules.
2253
+ - `FabricStreet` (interface): interface FabricStreet — Minimal street shape the fabric needs (matches cityKind's LocalStreet).
2254
+ - `GraphFace` (interface): interface GraphFace — One extracted face: closed centerline polygon + the street index along each polygon edge.
2255
+ - `ParcelCut` (interface): interface ParcelCut — Inputs for one parcel strip cut from a block ring.
2256
+ - `RingWalker` (class): class RingWalker — Arc-length station lookup along a closed ring.
2257
+ - `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.
2258
+ - `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.
2259
+ - `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.
2260
+ - `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).
2261
+ - `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.
2262
+ - `isSliverBlock` (function): function isSliverBlock(land: readonly Vec2[], minArea: number, minWidth: number): boolean — Deterministic sliver verdict shared by classification and tests.
2263
+ - `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.
2264
+ - `sidewalkWidthFor` (function): function sidewalkWidthFor(level: FabricStreet["level"], base: number): number — Sidewalk band width by street hierarchy (base = the district's street-level width).
2265
+
2266
+ ## @jgengine/core/world/cityContent
2267
+
2268
+ - `CITY_LOT_CLASSES` (const): const CITY_LOT_CLASSES: readonly CityLotClass[] — All classes, for schema hints and validation.
2269
+ - `CITY_TREE_SPECIES` (const): const CITY_TREE_SPECIES: readonly CityTreeSpecies[] — All species, for schema hints and validation.
2270
+ - `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.
2271
+ - `CityLotPiece` (interface): interface CityLotPiece — One massing piece in LOT-LOCAL space: x along frontage width, z into the block, y up from grade.
2272
+ - `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).
2273
+ - `CityPieceShape` (type): type CityPieceShape = "box" | "gable" | "cylinder" | "dome" — Primitive shapes massing pieces instance — the renderer keeps one InstancedMesh per shape.
2274
+ - `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.
2275
+ - `CityZoneBand` (type): type CityZoneBand = "core" | "mid" | "edge" — Zone band a lot falls in: dense core, middle ring, or the district edge.
2276
+ - `CityZoneProfile` (type): type CityZoneProfile = "core-out" | "inverted" | "uniform" — How the radial zone metric maps to bands.
2277
+
2278
+ ## @jgengine/core/world/cityGeometry
2279
+
2280
+ - `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.
2281
+ - `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.
2282
+ - `dedupeRing` (function): function dedupeRing(ring: readonly Vec2[], epsilon = 1e-6): Vec2[] — Remove consecutive (near-)duplicate vertices; returns [] when fewer than 3 survive.
2283
+ - `distanceToRing` (function): function distanceToRing(ring: readonly Vec2[], x: number, z: number): number — Distance from a point to the nearest boundary segment of a ring.
2284
+ - `ensureCcw` (function): function ensureCcw(ring: readonly Vec2[]): Vec2[] — Ensure counter-clockwise winding (positive signed area) without mutating the input.
2285
+ - `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.
2286
+ - `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.
2287
+ - `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.
2288
+ - `insetRingUniform` (function): function insetRingUniform(ring: readonly Vec2[], distance: number): Vec2[] — Uniform-distance convenience over {@link insetRing}.
2289
+ - `pointInPolygon` (function): function pointInPolygon(ring: readonly Vec2[], x: number, z: number): boolean — Even-odd point-in-polygon test.
2290
+ - `polygonArea` (function): function polygonArea(ring: readonly Vec2[]): number — Absolute polygon area.
2291
+ - `polygonCentroid` (function): function polygonCentroid(ring: readonly Vec2[]): Vec2 — Area centroid of a simple polygon (falls back to the vertex mean for degenerate rings).
2292
+ - `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).
2293
+ - `polygonPerimeter` (function): function polygonPerimeter(ring: readonly Vec2[]): number — Ring perimeter length.
2294
+ - `polygonSignedArea` (function): function polygonSignedArea(ring: readonly Vec2[]): number — Signed area of a polygon ring (positive = counter-clockwise in XZ).
2295
+ - `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.
2296
+ - `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.
2297
+ - `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).
2298
+ - `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.
2299
+ - `ringBounds` (function): function ringBounds(ring: readonly Vec2[]): { minX: number; minZ: number; maxX: number; maxZ: number } — Axis-aligned bounding box of a ring.
2300
+ - `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.
2301
+ - `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.
2302
+ - `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.
2303
+ - `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.
2304
+
2305
+ ## @jgengine/core/world/cityKind
2306
+
2307
+ - `CITY_DEFAULTS` (const): const CITY_DEFAULTS: CityRules — City defaults: a zoned mixed metropolis — towers downtown, slabs mid-ring, houses at the edge.
2308
+ - `CITY_KIND` (const): const CITY_KIND: "city" — The editor volume kind marking a box as a procedural city district.
2309
+ - `CITY_SCHEMA` (const): const CITY_SCHEMA: ParamSchema — The city parameter schema — drives the inspector sliders and `meta` parse via the studio seam.
2310
+ - `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.
2311
+ - `CITY_ZONE_SCHEMA` (const): const CITY_ZONE_SCHEMA: ParamSchema — Zone-override schema for `cityzone` volumes: pin a band and optionally a bespoke class mix.
2312
+ - `CityBlock` (interface): interface CityBlock — One closed city block: a face of the road graph, inset to curb and land boundaries.
2313
+ - `CityBridge` (interface): interface CityBridge — One bridge deck spanning water: bank-to-bank polyline plus the silhouette style.
2314
+ - `CityDriveway` (interface): interface CityDriveway — One driveway ribbon from a street to a lot.
2315
+ - `CityHedge` (interface): interface CityHedge — One hedge run: a thin box strip (estate perimeter).
2316
+ - `CityIntersection` (interface): interface CityIntersection — One crossing of two through streets: patch center/radius plus crosswalk arm directions.
2317
+ - `CityLight` (interface): interface CityLight — One street light: curb position plus the yaw its arm faces (over the road).
2318
+ - `CityLot` (interface): interface CityLot — One building lot: footprint, zone band, class, seeded floors, massing pieces, street anchor.
2319
+ - `CityParcel` (interface): interface CityParcel — One polygonal parcel subdivided from a block's street frontage.
2320
+ - `CityParcelFrontageOut` (interface): interface CityParcelFrontageOut — One street-frontage edge of a parcel.
2321
+ - `CityPark` (interface): interface CityPark — One intentional open space: an unbuilt block, a block-interior courtyard, or a buffer sliver.
2322
+ - `CityParking` (interface): interface CityParking — One parking pad behind a commercial lot.
2323
+ - `CityResolveContext` (interface): interface CityResolveContext extends SceneKindResolveContext — Extended resolve context: sibling `cityzone` volumes that override the band/mix locally.
2324
+ - `CityRules` (interface): interface CityRules — Fully-defaulted city params parsed from a volume's `meta`.
2325
+ - `CityStreet` (interface): interface CityStreet — One synthesized street: a world-space XZ polyline with width, hierarchy level, and surface.
2326
+ - `CityTree` (interface): interface CityTree — One placed tree: world XZ, species, and seeded scale/color jitter.
2327
+ - `CityTunnel` (interface): interface CityTunnel — One tunnel bore piercing a ridge: portal-to-portal polyline held at bank height.
2328
+ - `ResolvedCity` (interface): interface ResolvedCity — A resolved city district: world-space network, zoned lots, parks, and furniture.
2329
+ - `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.
2330
+
2331
+ ## @jgengine/core/world/connectors
2332
+
2333
+ - `ConnectorPieceDef` (interface): interface ConnectorPieceDef — ⚠ undocumented
2334
+ - `ConnectorRegistry` (type): type ConnectorRegistry = (kind: string) => ConnectorPieceDef | null — ⚠ undocumented
2335
+ - `ConnectorSocket` (interface): interface ConnectorSocket — ⚠ undocumented
2336
+ - `ConnectorVec3` (type): type ConnectorVec3 = readonly [number, number, number] — ⚠ undocumented
2337
+ - `PlacedPiece` (interface): interface PlacedPiece — ⚠ undocumented
2338
+ - `SnapOptions` (interface): interface SnapOptions — ⚠ undocumented
2339
+ - `SnapResult` (interface): interface SnapResult — ⚠ undocumented
2340
+ - `WorldSocket` (interface): interface WorldSocket — ⚠ undocumented
2341
+ - `collectWorldSockets` (function): function collectWorldSockets(registry: ConnectorRegistry, pieces: readonly PlacedPiece[]): WorldSocket[] — ⚠ undocumented
2342
+ - `snapToNearest` (function): function snapToNearest(registry: ConnectorRegistry, placed: readonly PlacedPiece[], movingDef: ConnectorPieceDef, cursor: ConnectorVec3, options: SnapOptions = {}): SnapResult | null — ⚠ undocumented
2343
+ - `socketWorldPosition` (function): function socketWorldPosition(socket: ConnectorSocket, origin: ConnectorVec3, rotationY: number): ConnectorVec3 — ⚠ undocumented
2344
+ - `socketsCompatible` (function): function socketsCompatible(a: ConnectorSocket, b: ConnectorSocket): boolean — ⚠ undocumented
2345
+ - `worldSockets` (function): function worldSockets(def: ConnectorPieceDef, piece: PlacedPiece): WorldSocket[] — ⚠ undocumented
2346
+
2347
+ ## @jgengine/core/world/envField
2348
+
2349
+ - `EnvironmentField` (interface): interface EnvironmentField — ⚠ undocumented
2350
+ - `EnvironmentFieldConfig` (interface): interface EnvironmentFieldConfig — ⚠ undocumented
2351
+ - `EnvironmentSample` (interface): interface EnvironmentSample — ⚠ undocumented
2352
+ - `HeatSource` (interface): interface HeatSource — A localized warmth source — campfire, forge, geothermal vent.
2353
+ - `OccluderRect` (interface): interface OccluderRect — A sky-occluding footprint — a roof, dense canopy, a cave mouth. `shade` 0..1 = fraction of sky blocked.
2354
+ - `ScalarField` (type): type ScalarField = number | ((x: number, z: number, time: number) => number) — ⚠ undocumented
2355
+ - `ShadeProvider` (type): type ShadeProvider = readonly OccluderRect[] | ((x: number, z: number) => number) — ⚠ undocumented
2356
+ - `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.
2357
+
2358
+ ## @jgengine/core/world/environmentSummary
2359
+
2360
+ - `EnvironmentCounts` (interface): interface EnvironmentCounts — ⚠ undocumented
2361
+ - `EnvironmentSummary` (interface): interface EnvironmentSummary — ⚠ undocumented
2362
+ - `IslandSummary` (interface): interface IslandSummary extends TerrainSummary — ⚠ undocumented
2363
+ - `RoadSummary` (interface): interface RoadSummary — One road descriptor's resolved footprint: vertex count, width, and total centerline length.
2364
+ - `StructureSummary` (interface): interface StructureSummary — ⚠ undocumented
2365
+ - `TerrainHeightStats` (interface): interface TerrainHeightStats — ⚠ undocumented
2366
+ - `TerrainSummary` (interface): interface TerrainSummary — ⚠ undocumented
2367
+ - `VegetationSummary` (interface): interface VegetationSummary — ⚠ undocumented
2368
+ - `WaterSummary` (interface): interface WaterSummary — ⚠ undocumented
2369
+ - `WeatherSummary` (interface): interface WeatherSummary — ⚠ undocumented
2370
+ - `resolveStructureBuildings` (function): function resolveStructureBuildings(descriptor: BuildingEnvironmentDescriptor): GeneratedBuilding[] — ⚠ undocumented
2371
+ - `summarizeEnvironment` (function): function summarizeEnvironment(feature: EnvironmentWorldFeature): EnvironmentSummary — ⚠ undocumented
2372
+
2373
+ ## @jgengine/core/world/features
2374
+
2375
+ - `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`.
2376
+ - `BiomeFog` (interface): interface BiomeFog — Per-band fog override cross-faded along z by `createBiomeFogSampler`; unset fields fall through to the base sky fog.
2377
+ - `BiomeSky` (interface): interface BiomeSky — Per-band sky/light override cross-faded along z by `createBiomeSkySampler`; unset fields fall through to the base sky.
2378
+ - `BiomesWorldConfig` (interface): interface BiomesWorldConfig extends WorldGridConfig — ⚠ undocumented
2379
+ - `BuildingEnvironmentConfig` (interface): interface BuildingEnvironmentConfig — ⚠ undocumented
2380
+ - `BuildingEnvironmentDescriptor` (type): type BuildingEnvironmentDescriptor = { kind: "building" } & Required< Pick<BuildingEnvironmentConfig, "count" | "footprint" | "stories" | "storyHeight" | "spacing" | "style"> > & Pick<BuildingEnvironmentConfig, "seed" | "position" | "palette"> — ⚠ undocumented
2381
+ - `EnvironmentArea` (interface): interface EnvironmentArea extends WorldBounds — ⚠ undocumented
2382
+ - `EnvironmentDescriptorList` (type): type EnvironmentDescriptorList<T> = T | readonly T[] — ⚠ undocumented
2383
+ - `EnvironmentVec2` (type): type EnvironmentVec2 = readonly [number, number] — ⚠ undocumented
2384
+ - `EnvironmentWorldConfig` (interface): interface EnvironmentWorldConfig — ⚠ undocumented
2385
+ - `EnvironmentWorldFeature` (interface): interface EnvironmentWorldFeature — ⚠ undocumented
2386
+ - `GrassEnvironmentConfig` (interface): interface GrassEnvironmentConfig — ⚠ undocumented
2387
+ - `GrassEnvironmentDescriptor` (type): type GrassEnvironmentDescriptor = { kind: "grass" } & Required< Pick<GrassEnvironmentConfig, "area" | "density" | "bladeHeight" | "bladeWidth" | "windStrength" | "colors"> > & Pick<GrassEnvironmentConfig, "seed"> — ⚠ undocumented
2388
+ - `OceanEnvironmentConfig` (interface): interface OceanEnvironmentConfig — ⚠ undocumented
2389
+ - `OceanEnvironmentDescriptor` (type): type OceanEnvironmentDescriptor = { kind: "ocean" } & Required< Pick<OceanEnvironmentConfig, "bounds" | "level" | "waveHeight" | "waveScale" | "waveSpeed" | "color"> > & Pick<OceanEnvironmentConfig, "position" | "levelAt"> — ⚠ undocumented
2390
+ - `PadEnvironmentConfig` (interface): interface PadEnvironmentConfig — ⚠ undocumented
2391
+ - `PadEnvironmentDescriptor` (type): type PadEnvironmentDescriptor = { kind: "pad" } & Required< Pick<PadEnvironmentConfig, "center" | "size" | "height" | "color"> > & Pick<PadEnvironmentConfig, "rotationY" | "elevation"> — ⚠ undocumented
2392
+ - `PadSize` (type): type PadSize = readonly [number, number] | { radius: number } — ⚠ undocumented
2393
+ - `PlotsWorldConfig` (interface): interface PlotsWorldConfig extends WorldGridConfig — ⚠ undocumented
2394
+ - `RainEnvironmentConfig` (interface): interface RainEnvironmentConfig — ⚠ undocumented
2395
+ - `RainEnvironmentDescriptor` (type): type RainEnvironmentDescriptor = { kind: "rain" } & Required< Pick<RainEnvironmentConfig, "area" | "density" | "speed" | "dropLength" | "wind" | "color" | "width" | "opacity"> > — ⚠ undocumented
2396
+ - `RoadEnvironmentConfig` (interface): interface RoadEnvironmentConfig — Config for {@link road}: a flat asphalt ribbon draped over the terrain along a centerline.
2397
+ - `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; } — Resolved road descriptor produced by {@link road} and rendered by the shell environment scene.
2398
+ - `SkyEnvironmentConfig` (interface): interface SkyEnvironmentConfig — ⚠ undocumented
2399
+ - `SkyEnvironmentDescriptor` (type): type SkyEnvironmentDescriptor = { kind: "sky" } & Required< Pick<SkyEnvironmentConfig, "preset" | "timeOfDay"> > & Omit<SkyEnvironmentConfig, "preset" | "timeOfDay"> — ⚠ undocumented
2400
+ - `SnowEnvironmentConfig` (interface): interface SnowEnvironmentConfig — ⚠ undocumented
2401
+ - `SnowEnvironmentDescriptor` (type): type SnowEnvironmentDescriptor = { kind: "snow" } & Required< Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color" | "opacity"> > — ⚠ undocumented
2402
+ - `StructureEnvironmentDescriptor` (type): type StructureEnvironmentDescriptor = BuildingEnvironmentDescriptor — ⚠ undocumented
2403
+ - `TerrainCircleRegion` (interface): interface TerrainCircleRegion extends TerrainRegionStyle — A circular palette zone painted over the base terrain palette — snow caps, ash wastes, spawn circles.
2404
+ - `TerrainColors` (interface): interface TerrainColors — ⚠ undocumented
2405
+ - `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.
2406
+ - `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.
2407
+ - `TerrainEnvironmentConfig` (interface): interface TerrainEnvironmentConfig — ⚠ undocumented
2408
+ - `TerrainEnvironmentDescriptor` (type): type TerrainEnvironmentDescriptor = { kind: "terrain" } & Required< Pick<TerrainEnvironmentConfig, "bounds" | "height"> > & Omit<TerrainEnvironmentConfig, "bounds" | "height"> — ⚠ undocumented
2409
+ - `TerrainFlattenMask` (interface): interface TerrainFlattenMask — ⚠ undocumented
2410
+ - `TerrainIslandConfig` (interface): interface TerrainIslandConfig extends TerrainEnvironmentConfig — A bounded terrain patch floating at its own altitude — sky islands, arena platforms, split landmasses with void between.
2411
+ - `TerrainIslandDescriptor` (type): type TerrainIslandDescriptor = Omit<TerrainEnvironmentDescriptor, "kind"> & { kind: "island"; origin: EnvironmentVec2; } — ⚠ undocumented
2412
+ - `TerrainMaterial` (type): type TerrainMaterial = "grass" | "sand" | "snow" | "rock" | "ash" | "highland" | "slate" — ⚠ undocumented
2413
+ - `TerrainMaterialMaps` (interface): interface TerrainMaterialMaps — PBR map URLs for a real ground texture — the same shape `buildMaterialCatalog({ basePath }).resolve(id)!.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.
2414
+ - `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.
2415
+ - `TerrainPolylineRegion` (interface): interface TerrainPolylineRegion extends TerrainRegionStyle — A ribbon palette zone following a centerline — roads and rivers, instead of chaining overlapping circles.
2416
+ - `TerrainRectRegion` (interface): interface TerrainRectRegion extends TerrainRegionStyle — A rectangular palette zone, optionally rotated about the world y axis — plazas, fields, districts.
2417
+ - `TerrainRegionStyle` (interface): interface TerrainRegionStyle — Palette and blend fields shared by every `TerrainMaterialRegion` shape.
2418
+ - `TilemapWorldConfig` (interface): interface TilemapWorldConfig extends WorldGridConfig — ⚠ undocumented
2419
+ - `VegetationEnvironmentDescriptor` (type): type VegetationEnvironmentDescriptor = GrassEnvironmentDescriptor — ⚠ undocumented
2420
+ - `VoxelWorldConfig` (interface): interface VoxelWorldConfig extends WorldGridConfig — ⚠ undocumented
2421
+ - `WaterEnvironmentDescriptor` (type): type WaterEnvironmentDescriptor = OceanEnvironmentDescriptor — ⚠ undocumented
2422
+ - `WeatherEnvironmentDescriptor` (type): type WeatherEnvironmentDescriptor = RainEnvironmentDescriptor | SnowEnvironmentDescriptor — ⚠ undocumented
2423
+ - `WorldBounds` (interface): interface WorldBounds — ⚠ undocumented
2424
+ - `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.
2425
+ - `WorldGridCell` (interface): interface WorldGridCell — ⚠ undocumented
2426
+ - `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.
2427
+ - `biomes` (function): function biomes(config: BiomesWorldConfig): WorldFeature — Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain.
2428
+ - `building` (function): function building(config: BuildingEnvironmentConfig = {}): BuildingEnvironmentDescriptor — Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style.
2429
+ - `environment` (function): function environment(config: EnvironmentWorldConfig = {}): EnvironmentWorldFeature — Composes an `environment()` feature from terrain, sky, weather, vegetation, water, structures, roads, and pads.
2430
+ - `flat` (function): function flat(): WorldFeature — Declares an empty flat world — the minimal `WorldFeature` for games with no terrain of their own.
2431
+ - `grass` (function): function grass(config: GrassEnvironmentConfig = {}): GrassEnvironmentDescriptor — Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors.
2432
+ - `island` (function): function island(config: TerrainIslandConfig): TerrainIslandDescriptor — ⚠ undocumented
2433
+ - `ocean` (function): function ocean(config: OceanEnvironmentConfig = {}): OceanEnvironmentDescriptor — Declares an ocean water body for `environment()` — bounds, level, and wave tuning.
2434
+ - `pad` (function): function pad(config: PadEnvironmentConfig): PadEnvironmentDescriptor — ⚠ undocumented
2435
+ - `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.
2436
+ - `plots` (function): function plots(config: PlotsWorldConfig = {}): WorldFeature — Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts.
2437
+ - `rain` (function): function rain(config: RainEnvironmentConfig = {}): RainEnvironmentDescriptor — Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity.
2438
+ - `road` (function): function road(config: RoadEnvironmentConfig): RoadEnvironmentDescriptor — Declare a road ribbon for an `environment()` world; the shell drapes and renders it over the terrain.
2439
+ - `sky` (function): function sky(config: SkyEnvironmentConfig = {}): SkyEnvironmentDescriptor — ⚠ undocumented
2440
+ - `snow` (function): function snow(config: SnowEnvironmentConfig = {}): SnowEnvironmentDescriptor — Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
2441
+ - `terrain` (function): function terrain(config: TerrainEnvironmentConfig = {}): TerrainEnvironmentDescriptor — Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks.
2442
+ - `tilemap` (function): function tilemap(config: TilemapWorldConfig): WorldFeature — Declares a 2D tilemap world from a map string.
2443
+ - `voxel` (function): function voxel(config: VoxelWorldConfig): WorldFeature — Declares a voxel-grid world for block-based games.
2444
+
2445
+ ## @jgengine/core/world/fog
2446
+
2447
+ - `FogBounds` (interface): interface FogBounds — ⚠ undocumented
2448
+ - `FogCells` (interface): interface FogCells — ⚠ undocumented
2449
+ - `FogConfig` (interface): interface FogConfig — ⚠ undocumented
2450
+ - `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()`.
2451
+ - `createFogField` (function): function createFogField(config: FogConfig): FogField — ⚠ undocumented
2452
+
2453
+ ## @jgengine/core/world/footprintGrid
2454
+
2455
+ - `AdjacentCell` (interface): interface AdjacentCell — One occupied neighbor cell reported by {@link boundaryNeighbors}.
2456
+ - `FootprintGrid` (interface): interface FootprintGrid — Handle returned by {@link createFootprintGrid}.
2457
+ - `FootprintGridOptions` (interface): interface FootprintGridOptions — Config for {@link createFootprintGrid}.
2458
+ - `FootprintReservation` (interface): interface FootprintReservation — A live claim on a {@link FootprintGrid}: which cells `id` (a `kind` tag for adjacency checks) holds.
2459
+ - `GridCell` (interface): interface GridCell — One integer cell address on a {@link FootprintGrid}.
2460
+ - `boundaryNeighbors` (function): function boundaryNeighbors(grid: FootprintGrid, cells: readonly GridCell[]): AdjacentCell[] — Every occupied cell orthogonally touching `cells` but outside them — the connective-piece neighbor set.
2461
+ - `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.
2462
+ - `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.
2463
+ - `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.
2464
+
2465
+ ## @jgengine/core/world/geometry
2466
+
2467
+ - `Aabb` (interface): interface Aabb — ⚠ undocumented
2468
+ - `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.
2469
+ - `AvoidMasks` (interface): interface AvoidMasks — A clearance region: point discs (spawns/plots) plus centerline corridors (paths).
2470
+ - `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`.
2471
+ - `Ellipse` (interface): interface Ellipse — An axis-aligned ellipse: `center` with semi-axes `radiusX` and `radiusY`.
2472
+ - `Footprint` (interface): interface Footprint — ⚠ undocumented
2473
+ - `MoveOptions` (interface): interface MoveOptions — ⚠ undocumented
2474
+ - `Vec2` (type): type Vec2 = readonly [number, number] — ⚠ undocumented
2475
+ - `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.
2476
+
2477
+ ## @jgengine/core/world/grassKind
2478
+
2479
+ - `GRASS_DEFAULTS` (const): const GRASS_DEFAULTS: GrassRules — Grass defaults: a lush, lightly-swaying meadow.
2480
+ - `GRASS_FIELD_KIND` (const): const GRASS_FIELD_KIND: "grass_field" — The editor volume kind marking a box as a GPU grass patch.
2481
+ - `GRASS_SCHEMA` (const): const GRASS_SCHEMA: ParamSchema — The grass parameter schema — drives the inspector and `meta` parse via the studio seam.
2482
+ - `GrassRules` (interface): interface GrassRules — Fully-defaulted grass params parsed from a volume's `meta`.
2483
+ - `ResolvedGrass` (interface): interface ResolvedGrass — A resolved grass patch: world-space area center at ground height, footprint size (XZ), and rules.
2484
+
2485
+ ## @jgengine/core/world/gridInstances
2486
+
2487
+ - `GridInstanceTransform` (interface): interface GridInstanceTransform — ⚠ undocumented
2488
+ - `resolveGridCells` (function): function resolveGridCells(config: WorldGridConfig | GridWorldFeature): readonly WorldGridCell[] — ⚠ undocumented
2489
+ - `resolveGridInstances` (function): function resolveGridInstances(config: WorldGridConfig | GridWorldFeature): readonly GridInstanceTransform[] — ⚠ undocumented
2490
+
2491
+ ## @jgengine/core/world/interiors
2492
+
2493
+ - `EntityLocation` (interface): interface EntityLocation — ⚠ undocumented
2494
+ - `Exterior` (interface): interface Exterior — ⚠ undocumented
2495
+ - `Interior` (interface): interface Interior — ⚠ undocumented
2496
+ - `Interiors` (interface): interface Interiors — ⚠ undocumented
2497
+ - `InteriorsConfig` (interface): interface InteriorsConfig — ⚠ undocumented
2498
+ - `SpaceRef` (type): type SpaceRef = { kind: "exterior" } | { kind: "interior"; id: string } — ⚠ undocumented
2499
+ - `createInteriors` (function): function createInteriors(config: InteriorsConfig = {}): Interiors — ⚠ undocumented
2500
+
2501
+ ## @jgengine/core/world/lod
2502
+
2503
+ - `LodBand` (interface): interface LodBand — ⚠ undocumented
2504
+ - `LodScheduler` (interface): interface LodScheduler — ⚠ undocumented
2505
+ - `LodSchedulerConfig` (interface): interface LodSchedulerConfig — ⚠ undocumented
2506
+ - `createLodScheduler` (function): function createLodScheduler(config: LodSchedulerConfig): LodScheduler — ⚠ undocumented
2507
+
2508
+ ## @jgengine/core/world/mapLayers
2509
+
2510
+ - `MAP_LAYER_TONE_COLORS` (const): const MAP_LAYER_TONE_COLORS: Record<MapLayerTone, string> — ⚠ undocumented
2511
+ - `MapCellStates` (interface): interface MapCellStates — ⚠ undocumented
2512
+ - `MapLayerTone` (type): type MapLayerTone = "danger" | "warning" | "info" | "safe" | "neutral" — ⚠ undocumented
2513
+ - `MapRoute` (interface): interface MapRoute — ⚠ undocumented
2514
+ - `MapXZ` (type): type MapXZ = readonly [number, number] — ⚠ undocumented
2515
+ - `MapZone` (interface): interface MapZone — ⚠ undocumented
2516
+ - `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
2517
+ - `mapLayerColor` (function): function mapLayerColor(tone: MapLayerTone | undefined): string — ⚠ undocumented
2518
+ - `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.
2519
+
2520
+ ## @jgengine/core/world/markers
2521
+
2522
+ - `DEFAULT_MARKER_KINDS` (const): const DEFAULT_MARKER_KINDS: Record<string, MarkerKindStyle> — ⚠ undocumented
2523
+ - `MapMarker` (interface): interface MapMarker<TMeta = unknown> extends MarkerView<TMeta> — A marker owned by {@link MarkerSet}, including its lifecycle and query fields.
2524
+ - `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.
2525
+ - `MarkerInput` (interface): interface MarkerInput<TMeta = unknown> — ⚠ undocumented
2526
+ - `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.
2527
+ - `MarkerPosition` (type): type MarkerPosition = readonly [number, number, number] — ⚠ undocumented
2528
+ - `MarkerQuery` (interface): interface MarkerQuery — ⚠ undocumented
2529
+ - `MarkerSet` (interface): interface MarkerSet<TMeta = unknown> — ⚠ undocumented
2530
+ - `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.
2531
+ - `MarkerSourceOptions` (interface): interface MarkerSourceOptions<TEntity, TMarker extends MarkerView = MarkerView> — Configuration for projecting a caller-owned collection into display-only markers.
2532
+ - `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}.
2533
+ - `createMarkerSet` (function): function createMarkerSet<TMeta = unknown>(now: () => number = Date.now): MarkerSet<TMeta> — ⚠ undocumented
2534
+ - `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.
2535
+ - `markerKindStyle` (function): function markerKindStyle(kind: string | undefined, styles: Record<string, MarkerKindStyle> = DEFAULT_MARKER_KINDS): MarkerKindStyle — ⚠ undocumented
2536
+
2537
+ ## @jgengine/core/world/massing
2538
+
2539
+ - `MASSING_COMPOSITIONS` (const): const MASSING_COMPOSITIONS: readonly MassingComposition[] — ⚠ undocumented
2540
+ - `MASSING_PROFILES` (const): const MASSING_PROFILES: readonly MassingProfile[] — ⚠ undocumented
2541
+ - `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
2542
+ - `MassingBodyRole` (type): type MassingBodyRole = "mass" | "core" | "transfer" — ⚠ undocumented
2543
+ - `MassingComposition` (type): type MassingComposition = | "bar" | "split" | "cluster" | "stack" | "court" | "bridge" | "ring" | "capsule" | "megastructure" — ⚠ undocumented
2544
+ - `MassingProfile` (type): type MassingProfile = "straight" | "stepped" | "tapered" | "top-heavy" | "offset" | "twisted" — ⚠ undocumented
2545
+ - `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
2546
+ - `composeMassing` (function): function composeMassing(b: MassingSpec): MassingBody[] — ⚠ undocumented
2547
+ - `hashMassingSeed` (const): const hashMassingSeed: (text: string) => number — ⚠ undocumented
2548
+ - `isVillageMassing` (const): const isVillageMassing: (spec: Pick<MassingSpec, "height" | "composition" | "articulation" | "moduleDensity">) => boolean — ⚠ undocumented
2549
+ - `massingBase` (const): const massingBase: (spec: Pick<MassingSpec, "pilotis" | "height">, cap?: number) => number — ⚠ undocumented
2550
+ - `massingFloorCount` (function): function massingFloorCount(spec: Pick<MassingSpec, "pilotis" | "height" | "floorHeight">): number — ⚠ undocumented
2551
+
2552
+ ## @jgengine/core/world/minimap
2553
+
2554
+ - `Cardinal` (type): type Cardinal = "N" | "NE" | "E" | "SE" | "S" | "SW" | "W" | "NW" — ⚠ undocumented
2555
+ - `MinimapPoint` (interface): interface MinimapPoint — ⚠ undocumented
2556
+ - `MinimapView` (interface): interface MinimapView — ⚠ undocumented
2557
+ - `WorldXZ` (type): type WorldXZ = readonly [number, number] — ⚠ undocumented
2558
+ - `bearingToCardinal` (function): function bearingToCardinal(bearing: number): Cardinal — ⚠ undocumented
2559
+ - `clampToMinimapEdge` (function): function clampToMinimapEdge(point: MinimapPoint, size: number): { x: number; y: number } — Clamp a projected point to the minimap edge, preserving direction (edge markers).
2560
+ - `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.
2561
+ - `headingToBearing` (function): function headingToBearing(yaw: number): number — Bearing of an entity facing direction given its `rotationY` (yaw) in radians.
2562
+ - `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.
2563
+ - `relativeBearing` (function): function relativeBearing(bearing: number, reference: number): number — Signed offset of `bearing` from `reference`, wrapped into (−π, π].
2564
+ - `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.
2565
+
2566
+ ## @jgengine/core/world/minimapBake
2567
+
2568
+ - `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.
2569
+ - `MinimapBake` (interface): interface MinimapBake — A baked minimap image: RGBA pixels plus the world bounds they span.
2570
+ - `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.
2571
+ - `MinimapBakeOptions` (interface): interface MinimapBakeOptions — Options for {@link bakeMinimapImage}.
2572
+ - `MinimapBakePalette` (interface): interface MinimapBakePalette — The height→color ramp and water color used by the bake.
2573
+ - `MinimapBakeSource` (interface): interface MinimapBakeSource — The authored world a bake reads — a height sampler, its bounds, and optional zones/water.
2574
+ - `MinimapBakeZone` (interface): interface MinimapBakeZone — One biome/region tint painted over the terrain shade where the ground falls inside its polygon.
2575
+ - `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.
2576
+ - `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.
2577
+ - `encodeBakePng` (function): function encodeBakePng(bake: MinimapBake): Uint8Array — Encodes an RGBA bake to raw PNG bytes (pure; stored DEFLATE, valid for any decoder).
2578
+ - `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.
2579
+
2580
+ ## @jgengine/core/world/minimapTrack
2581
+
2582
+ - `TrackAxis` (interface): interface TrackAxis — A world-space segment defining a linear "track" minimap — points are projected onto the `from`→`to` axis.
2583
+ - `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.
2584
+
2585
+ ## @jgengine/core/world/pathInstances
2586
+
2587
+ - `PathInstance` (interface): interface PathInstance — One placed transform along a path: grounded position, facing yaw, and its ordinal + arc distance.
2588
+ - `PlaceAlongPathOptions` (interface): interface PlaceAlongPathOptions — Options for {@link placeAlongPath}.
2589
+ - `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.
2590
+
2591
+ ## @jgengine/core/world/pathNetwork
2592
+
2593
+ - `PathDeadEnd` (interface): interface PathDeadEnd — One dangling street end kept as a cul-de-sac: node position plus the heading pointing off the road.
2594
+ - `PathEdge` (interface): interface PathEdge — One atomic node-to-node edge — the fabric graph consumes these (welds at shared node coords).
2595
+ - `PathFeature` (interface): interface PathFeature — A resolved path feature in world-of-the-volume space: a bridge deck or tunnel bore centerline.
2596
+ - `PathFeatureKind` (type): type PathFeatureKind = "bridge" | "tunnel" — A path feature spanning part of an edge/street: a bridge deck over a gap or a tunnel bore under a ridge.
2597
+ - `PathFeatureSpan` (interface): interface PathFeatureSpan — A feature span carried by a street: a `[from, to]` index window into the street's `points`.
2598
+ - `PathJunction` (interface): interface PathJunction — One crossing of three or more streets: patch center/radius plus outgoing arm directions.
2599
+ - `PathLevel` (type): type PathLevel = "boulevard" | "avenue" | "street" | "lane" — Road hierarchy, widest to narrowest — shared by the city fabric and the renderer.
2600
+ - `PathNetwork` (interface): interface PathNetwork — The fully-resolved network in volume-local coords.
2601
+ - `PathNetworkContext` (interface): interface PathNetworkContext — Ground sampler + feature toggles enabling bridges/tunnels; omit for a flat, feature-free network.
2602
+ - `PathNetworkMode` (type): type PathNetworkMode = "net" | "circuit" — The generator's chosen topology family: an open street `net`, or a closed `circuit` loop.
2603
+ - `PathNetworkRules` (interface): interface PathNetworkRules — Fully-defaulted slider set the generator reads.
2604
+ - `PathNode` (interface): interface PathNode — One graph node: a junction, a dead end, or a mid-street bend, with its connection count.
2605
+ - `PathStreet` (interface): interface PathStreet — One chained through-street: a maximal run of edges through degree-2 nodes, for rendering + furniture.
2606
+ - `PathVec2` (type): type PathVec2 = readonly [number, number] — A path vertex in the volume-local XZ frame.
2607
+ - `buildPathNetwork` (function): function buildPathNetwork(rules: PathNetworkRules, hx: number, hz: number, context: PathNetworkContext = {}): PathNetwork — 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 PathNetworkContext} with a ground sampler to turn water gaps into bridges and ridges into tunnels. Coordinates are volume-local; the caller maps to world space.
2608
+
2609
+ ## @jgengine/core/world/pathTerrain
2610
+
2611
+ - `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).
2612
+ - `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.
2613
+ - `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.
2614
+ - `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.
2615
+
2616
+ ## @jgengine/core/world/place
2617
+
2618
+ - `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.
2619
+ - `BoardGroundSize` (interface): interface BoardGroundSize — Size of a `board` ground: a 2D surface you look at, in cells or layout units.
2620
+ - `FlatGround` (interface): interface FlatGround — A 3D walkable plane/slab. `Infinity` axes are unbounded; no separate "infinite" mode exists.
2621
+ - `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.
2622
+ - `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`.
2623
+ - `GroundGenerator` (interface): interface GroundGenerator — Serializable algorithm parameters for a procedural ground generator. Never a genre kit.
2624
+ - `GroundMode` (type): type GroundMode = "flat" | "round" | "voxel" | "board" — Canonical ground modes after normalization (`stage` → `board`).
2625
+ - `PlaceConfig` (interface): interface PlaceConfig — Input to {@link world}: place identity, substrate, and the laws of this place.
2626
+ - `PlaceWorldFeature` (interface): interface PlaceWorldFeature — A declared place — the `world()` result carried on `GameDefinition.world`.
2627
+ - `ResolvedBoardGround` (type): type ResolvedBoardGround = Omit<BoardGround, "mode"> & { mode: "board" } — {@link BoardGround} with the `stage` alias resolved away.
2628
+ - `ResolvedGround` (type): type ResolvedGround = FlatGround | RoundGround | VoxelGround | ResolvedBoardGround — A place's ground after `world()` normalization.
2629
+ - `RoundGround` (interface): interface RoundGround — A planet/sphere you play on the outside of. Sized by `radius` only.
2630
+ - `RoundGroundSize` (interface): interface RoundGroundSize — Size of a `round` ground: the planet/sphere radius in world units. Nothing else.
2631
+ - `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.
2632
+ - `VoxelGround` (interface): interface VoxelGround — A procedural volume of blocks. `size` is the generator domain; `generator` is algorithm params only.
2633
+ - `VoxelGroundSize` (interface): interface VoxelGroundSize — Size of a `voxel` ground: the generator's domain per axis; axes may be `Infinity` for streaming volumes.
2634
+ - `isPlaceWorld` (function): function isPlaceWorld(worldFeature: { kind: string } | undefined): worldFeature is PlaceWorldFeature — Type guard for the place-model world feature.
2635
+ - `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.
2636
+ - `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.
2637
+ - `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.
2638
+
2639
+ ## @jgengine/core/world/placeAsset
2640
+
2641
+ - `PlaceAssetFromCommitOptions` (interface): interface PlaceAssetFromCommitOptions — Optional catalog/label overrides for {@link placeAssetFromCommit}.
2642
+ - `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}.
2643
+ - `PlaceAssetVec3` (type): type PlaceAssetVec3 = { x: number; y: number; z: number } — World-space point shared by structure stores and editor markers.
2644
+ - `ResolvePlaceAssetInput` (interface): interface ResolvePlaceAssetInput — Inputs to {@link resolvePlaceAsset}: asset id, pose, and optional catalog/known fields.
2645
+ - `placeAssetFromCommit` (function): function placeAssetFromCommit(commit: PlacementCommit, assetId: string, options: PlaceAssetFromCommitOptions = {}): PlaceAssetResult — Bridge a {@link PlacementCommit} into the shared place-asset verb.
2646
+ - `resolvePlaceAsset` (function): function resolvePlaceAsset(input: ResolvePlaceAssetInput): PlaceAssetResult — Resolve a place-asset intent into a shared payload (editor + games, one verb).
2647
+ - `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.
2648
+ - `toStructureInput` (function): function toStructureInput(result: PlaceAssetResult): AddStructureInput — Game-state form: feed {@link createPlacedStructureStore}.add.
2649
+
2650
+ ## @jgengine/core/world/placedStructureStore
2651
+
2652
+ - `AddStructureInput` (interface): interface AddStructureInput — ⚠ undocumented
2653
+ - `PlacedStructure` (interface): interface PlacedStructure — ⚠ undocumented
2654
+ - `PlacedStructureSnapshot` (interface): interface PlacedStructureSnapshot — ⚠ undocumented
2655
+ - `PlacedStructureStore` (interface): interface PlacedStructureStore — ⚠ undocumented
2656
+ - `StructureFilter` (interface): interface StructureFilter — ⚠ undocumented
2657
+ - `StructureVec3` (type): type StructureVec3 = readonly [number, number, number] — ⚠ undocumented
2658
+ - `createPlacedStructureStore` (function): function createPlacedStructureStore(): PlacedStructureStore — ⚠ undocumented
2659
+
2660
+ ## @jgengine/core/world/placement
2661
+
2662
+ - `PlacementObstacle` (interface): interface PlacementObstacle — ⚠ undocumented
2663
+ - `PlacementRequest` (interface): interface PlacementRequest — ⚠ undocumented
2664
+ - `PlacementResult` (type): type PlacementResult = | { status: "ok"; center: Vec2; aabb: Aabb } | { status: "rejected"; reason: "out-of-bounds" } | { status: "rejected"; reason: "overlap"; obstacle: PlacementObstacle; index: number } — ⚠ undocumented
2665
+ - `PlacementRules` (interface): interface PlacementRules — ⚠ undocumented
2666
+ - `footprintObstacle` (function): function footprintObstacle(request: PlacementRequest, id?: string): PlacementObstacle — ⚠ undocumented
2667
+ - `validatePlacement` (function): function validatePlacement(request: PlacementRequest, rules: PlacementRules = {}): PlacementResult — Footprint validity: bounds + obstacle overlap after optional grid snap.
2668
+
2669
+ ## @jgengine/core/world/placementController
2670
+
2671
+ - `PlacementCommit` (interface): interface PlacementCommit — ⚠ undocumented
2672
+ - `PlacementController` (interface): interface PlacementController — ⚠ undocumented
2673
+ - `PlacementControllerConfig` (interface): interface PlacementControllerConfig — ⚠ undocumented
2674
+ - `PlacementHit` (interface): interface PlacementHit — ⚠ undocumented
2675
+ - `PlacementPreview` (interface): interface PlacementPreview — ⚠ undocumented
2676
+ - `PlacementSlot` (interface): interface PlacementSlot — A fixed buildable slot the placement controller snaps to instead of grid/free positioning.
2677
+ - `PlacementVec3` (type): type PlacementVec3 = readonly [number, number, number] — ⚠ undocumented
2678
+ - `SnapMode` (type): type SnapMode = "grid" | "free" | "surface" — ⚠ undocumented
2679
+ - `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}.
2680
+ - `quarterTurnsToRotationY` (function): function quarterTurnsToRotationY(quarterTurns: number): number — Maps 0–3 quarter turns onto radians for ghost/commit rotation.
2681
+
2682
+ ## @jgengine/core/world/poleLineKind
2683
+
2684
+ - `Cable` (interface): interface Cable — One resolved cable span: a point string to loft into a tube, plus its radius.
2685
+ - `POLE_LINE_KIND` (const): const POLE_LINE_KIND: "pole_line" — The editor path kind marking a polyline as a pole/cable run.
2686
+ - `POLE_LINE_SCHEMA` (const): const POLE_LINE_SCHEMA: ParamSchema — The pole-line parameter schema — drives the inspector and `meta` parse via the studio seam.
2687
+ - `Pole` (interface): interface Pole — One placed pole: grounded base position plus facing yaw along the run.
2688
+ - `ResolvedPoleLine` (interface): interface ResolvedPoleLine — The renderable payload the resolver returns and the shell renderer consumes.
2689
+ - `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.
2690
+
2691
+ ## @jgengine/core/world/polyline
2692
+
2693
+ - `Polyline` (interface): interface Polyline — A polyline prepared for repeated distance/fraction sampling, with cumulative arc-length precomputed.
2694
+ - `PolylineHit` (interface): interface PolylineHit — The closest point on a polyline to a query point, with where it lands along the line.
2695
+
2696
+ ## @jgengine/core/world/realm
2697
+
2698
+ - `ComposedRealm` (interface): interface ComposedRealm — ⚠ undocumented
2699
+ - `DEFAULT_REALM_ENVIRONMENT` (const): const DEFAULT_REALM_ENVIRONMENT: RealmEnvironmentParams — ⚠ undocumented
2700
+ - `RealmBase` (interface): interface RealmBase — ⚠ undocumented
2701
+ - `RealmCard` (interface): interface RealmCard — ⚠ undocumented
2702
+ - `RealmEnvironmentParams` (interface): interface RealmEnvironmentParams — The recomposable environment parameters a realm card can override.
2703
+ - `SpawnTableOverride` (interface): interface SpawnTableOverride — Spawn-table edits a card layers on: replace weights, add/scale, or remove ids.
2704
+ - `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.
2705
+
2706
+ ## @jgengine/core/world/regions
2707
+
2708
+ - `ColorInput` (type): type ColorInput = string | Rgb — ⚠ undocumented
2709
+ - `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, …).
2710
+ - `RegionField` (interface): interface RegionField<T = unknown> extends TerrainField — ⚠ undocumented
2711
+ - `RegionFieldConfig` (interface): interface RegionFieldConfig<T = unknown> — ⚠ undocumented
2712
+ - `RegionHeight` (interface): interface RegionHeight — ⚠ undocumented
2713
+ - `RegionSample` (interface): interface RegionSample<T = unknown> — ⚠ undocumented
2714
+ - `Rgb` (type): type Rgb = readonly [number, number, number] — ⚠ undocumented
2715
+ - `createRegionField` (function): function createRegionField<T = unknown>(config: RegionFieldConfig<T>): RegionField<T> — ⚠ undocumented
2716
+ - `isRegionField` (function): function isRegionField(field: TerrainField): field is RegionField — ⚠ undocumented
2717
+
2718
+ ## @jgengine/core/world/resourceNode
2719
+
2720
+ - `HarvestOptions` (interface): interface HarvestOptions — Options for a single harvest.
2721
+ - `HarvestResult` (interface): interface HarvestResult — Outcome of one harvest attempt.
2722
+ - `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.
2723
+ - `ResourceGrant` (interface): interface ResourceGrant — One resource kind granted by a harvest and its resolved amount.
2724
+ - `ResourceNodeDef` (interface): interface ResourceNodeDef — A harvestable node definition: a finite budget, the resources it yields, and how it respawns.
2725
+ - `ResourceNodeField` (interface): interface ResourceNodeField — A set of harvestable nodes: harvest with tool profiles, tick respawn timers, snapshot/hydrate for save-load.
2726
+ - `ResourceNodeFieldConfig` (interface): interface ResourceNodeFieldConfig — Construction options for {@link createResourceNodeField}: node definitions and an optional RNG/suppression hook.
2727
+ - `ResourceNodeState` (interface): interface ResourceNodeState — Serializable per-node runtime state — round-trips through save/load and multiplayer sync.
2728
+ - `ResourceYield` (interface): interface ResourceYield — One resource kind a node can yield and its base per-harvest amount (before tool bias and harvester multiplier).
2729
+ - `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.
2730
+ - `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}.
2731
+
2732
+ ## @jgengine/core/world/roads
2733
+
2734
+ - `RoadPoint` (type): type RoadPoint = readonly [number, number] — A road centerline vertex in world XZ.
2735
+ - `RoadRibbon` (interface): interface RoadRibbon — Renderer-ready triangle ribbon: flat position triples plus triangle indices.
2736
+ - `RoadRibbonOptions` (interface): interface RoadRibbonOptions — Options for {@link buildRoadRibbon}.
2737
+ - `RoadSample` (interface): interface RoadSample — Result of {@link nearestOnPath}: closest point on the centerline plus distance and tangent.
2738
+ - `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.
2739
+ - `dashSegments` (function): function dashSegments(path: readonly RoadPoint[], dashLength = 3, gapLength = 3): 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.
2740
+ - `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.
2741
+ - `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.
2742
+ - `pathLength` (function): function pathLength(path: readonly RoadPoint[]): number — Total arc length of a centerline in world units.
2743
+
2744
+ ## @jgengine/core/world/scatter
2745
+
2746
+ - `ScatterArea` (interface): interface ScatterArea — ⚠ undocumented
2747
+ - `ScatterConfig` (interface): interface ScatterConfig — ⚠ undocumented
2748
+ - `ScatterPoint` (interface): interface ScatterPoint — ⚠ undocumented
2749
+ - `scatter` (function): function scatter(config: ScatterConfig): ScatterPoint[] — ⚠ undocumented
2750
+ - `scatterAabb` (function): function scatterAabb(area: ScatterArea | Aabb): Aabb — ⚠ undocumented
2751
+
2752
+ ## @jgengine/core/world/scatterItems
2753
+
2754
+ - `ScatterInstance` (interface): interface ScatterInstance — ⚠ undocumented
2755
+ - `ScatterLayer` (interface): interface ScatterLayer — One placeable class. `item` is an opaque id the caller maps to a mesh/entity.
2756
+ - `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.
2757
+ - `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.
2758
+
2759
+ ## @jgengine/core/world/scatterRegion
2760
+
2761
+ - `ClearanceOptions` (interface): interface ClearanceOptions — Controls which gameplay objects auto-repel scatter (and, for markers, flatten terrain).
2762
+ - `DEFAULT_CLEARANCE_KINDS` (const): const DEFAULT_CLEARANCE_KINDS: readonly string[] — Marker/volume kinds that repel scatter and flatten terrain by default (spawns, objectives, vendors).
2763
+ - `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`.
2764
+ - `ResolveScatterOptions` (interface): interface ResolveScatterOptions extends ClearanceOptions — Extra inputs for {@link resolveScatter}: manual discs plus the auto-clearance toggle/scoping.
2765
+ - `SCATTER_DEFAULTS` (const): const SCATTER_DEFAULTS: ScatterRegionRules — Defaults a bare scatter region fills with: sparse grass, lightly spaced.
2766
+ - `SCATTER_PATH_KIND` (const): const SCATTER_PATH_KIND: "scatter" — The editor path kind that marks a closed polyline as a foliage/scatter region.
2767
+ - `ScatterChunk` (interface): interface ScatterChunk — A spatial bucket of scatter instances — one draw unit the renderer can frustum-cull as a whole.
2768
+ - `ScatterInstance` (interface): interface ScatterInstance — A single placed scatter instance — grounded world position plus per-instance variation.
2769
+ - `ScatterPaletteEntry` (interface): interface ScatterPaletteEntry — One species/prop in a scatter region's palette, with a relative spawn weight.
2770
+ - `ScatterRegion` (interface): interface ScatterRegion — A resolvable scatter region: a closed polygon footprint plus its fill rules.
2771
+ - `ScatterRegionRules` (interface): interface ScatterRegionRules — How a scatter region fills its polygon: density, spacing, variation, and masking rules.
2772
+ - `ScatterTerrain` (interface): interface ScatterTerrain — Ground sampler a scatter resolve reads height/normal from (the sculpt terrain or the game's ground).
2773
+ - `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.
2774
+ - `distanceToPolygonEdge` (function): function distanceToPolygonEdge(point: Vec2, polygon: readonly Vec2[]): number — Shortest distance from a point to a polygon's boundary.
2775
+ - `isScatterPath` (function): function isScatterPath(path: ScenePathLike): boolean — True when an editor path is a foliage/scatter region.
2776
+ - `pointInPolygon` (function): function pointInPolygon(point: Vec2, polygon: readonly Vec2[]): boolean — Ray-casting point-in-polygon test on the XZ plane.
2777
+ - `polygonArea` (function): function polygonArea(polygon: readonly Vec2[]): number — Shoelace area of a polygon (always non-negative), in square meters.
2778
+ - `polygonBounds` (function): function polygonBounds(polygon: readonly Vec2[]): Aabb | null — Axis-aligned bounds of a polygon, or null if it has no points.
2779
+ - `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`.
2780
+ - `readScatterRules` (function): function readScatterRules(path: ScenePathLike): ScatterRegionRules | null — The path's scatter rules with defaults filled in; null for non-scatter paths.
2781
+ - `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.
2782
+ - `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.
2783
+ - `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.
2784
+ - `scatterRegionFromPath` (function): function scatterRegionFromPath(path: ScenePathLike): ScatterRegion | null — Builds a resolvable {@link ScatterRegion} from a scatter path (XZ polygon + rules), or null.
2785
+
2786
+ ## @jgengine/core/world/sceneShapes
2787
+
2788
+ - `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.
2789
+ - `SceneMarkerLike` (interface): interface SceneMarkerLike — The minimal point-object shape clearance reads from a document's markers; any `EditorMarker` satisfies it.
2790
+ - `ScenePathLike` (interface): interface ScenePathLike — The minimal polyline shape {@link resolveScatterRegion} et al. read; any `EditorPath` satisfies it.
2791
+ - `ScenePoint3` (interface): interface ScenePoint3 — A world-space point — structurally compatible with the editor's `EditorVec3`.
2792
+ - `SceneVolumeLike` (interface): interface SceneVolumeLike — The minimal volume shape vegetation/clearance/triggers read; any `EditorVolume` satisfies it.
2793
+
2794
+ ## @jgengine/core/world/segment
2795
+
2796
+ - `CircleSegmentHit` (interface): interface CircleSegmentHit — A resolved circle-vs-segment contact.
2797
+ - `ClosestOnSegment` (interface): interface ClosestOnSegment — Closest point on segment `a`→`b` to `p`, and the clamped parameter `t` in [0,1] where it lies.
2798
+ - `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.
2799
+ - `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`).
2800
+
2801
+ ## @jgengine/core/world/soilKind
2802
+
2803
+ - `ResolvedSoil` (interface): interface ResolvedSoil — A resolved soil patch: world-space area center at ground height, footprint size (XZ), and rules.
2804
+ - `SOIL_DEFAULTS` (const): const SOIL_DEFAULTS: SoilRules — Soil defaults: sun-cracked dirt with light moss creep.
2805
+ - `SOIL_KIND` (const): const SOIL_KIND: "soil" — The editor volume kind marking a box as a soil crack/moss patch.
2806
+ - `SOIL_SCHEMA` (const): const SOIL_SCHEMA: ParamSchema — The soil parameter schema — drives the inspector and `meta` parse via the studio seam.
2807
+ - `SoilRules` (interface): interface SoilRules — Fully-defaulted soil params parsed from a volume's `meta`.
2808
+
2809
+ ## @jgengine/core/world/spatialSample
2810
+
2811
+ - `AreaDistribution` (type): type AreaDistribution = "uniform" | "edge" — Fill policy for a rect/box: `"uniform"` = even coverage; `"edge"` = biased to a boundary band.
2812
+ - `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.
2813
+ - `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.
2814
+ - `RadialDistribution` (type): type RadialDistribution = "area" | "radial" — Fill policy for a circle/ring: `"area"` = area-uniform (even density); `"radial"` = radius-uniform (clumps toward center).
2815
+ - `SampleBatchOptions` (interface): interface SampleBatchOptions<P extends SamplePoint = SamplePoint> — Inputs for a {@link sampleBatch} draw of many spaced points.
2816
+ - `SampleBatchResult` (interface): interface SampleBatchResult<P extends SamplePoint = SamplePoint> — Structured batch outcome: the placed points plus whether the full count was met.
2817
+ - `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`.
2818
+ - `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.
2819
+ - `SamplePointOptions` (interface): interface SamplePointOptions<P extends SamplePoint = SamplePoint> — Inputs for a single {@link samplePoint} draw.
2820
+ - `SampleReason` (type): type SampleReason = "accepted" | "exhausted" | "empty-region" — Why a sample ended: a clean hit, budget exhausted, or the region was degenerate.
2821
+ - `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.
2822
+ - `SampleResult` (interface): interface SampleResult<P extends SamplePoint = SamplePoint> — Structured single-sample outcome — never a bare point, so failure and fallback are visible.
2823
+ - `StratifiedOptions` (interface): interface StratifiedOptions — Inputs for {@link sampleStratified}: a grid over `area` with one jittered point per cell.
2824
+ - `VolumeDistribution` (type): type VolumeDistribution = "volume" | "radial" — Fill policy for a sphere/shell: `"volume"` = volume-uniform (even density); `"radial"` = radius-uniform.
2825
+ - `WeightedRegionEntry` (interface): interface WeightedRegionEntry<P extends SamplePoint = SamplePoint> — A weighted member of a {@link weightedRegion} composite.
2826
+ - `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.
2827
+ - `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.
2828
+ - `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).
2829
+ - `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.
2830
+ - `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.
2831
+ - `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).
2832
+ - `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.
2833
+ - `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.
2834
+ - `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.
2835
+ - `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.
2836
+ - `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.
2837
+ - `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.
2838
+ - `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.
2839
+
2840
+ ## @jgengine/core/world/streets
2841
+
2842
+ - `FurnitureSpot` (interface): interface FurnitureSpot — A placement anchor on the curb line: position, outward-facing heading, and which side it sits on.
2843
+ - `FurnitureSpotOptions` (interface): interface FurnitureSpotOptions — Options for {@link furnitureSpots}.
2844
+ - `ParkingSpot` (interface): interface ParkingSpot — A curbside parking anchor: position at the road edge and a heading parallel to the street.
2845
+ - `ParkingSpotOptions` (interface): interface ParkingSpotOptions — Options for {@link parkingSpots}.
2846
+ - `RoadSurfaceOptions` (interface): interface RoadSurfaceOptions — Grip levels and blend width for {@link roadSurfaceSampler}; each field is optional and defaulted.
2847
+ - `StreetLane` (interface): interface StreetLane — A directed lane derived from a road: an offset centerline plus its direction of travel.
2848
+ - `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.
2849
+ - `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.
2850
+ - `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.
2851
+ - `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.
2852
+ - `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.
2853
+ - `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.
2854
+ - `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.
2855
+ - `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.
2856
+ - `sidewalkWidthOf` (function): function sidewalkWidthOf(road: RoadEnvironmentDescriptor): number — Resolved sidewalk band widths for a road; zero when the road declares no sidewalk.
2857
+
2858
+ ## @jgengine/core/world/support
2859
+
2860
+ - `DebrisOptions` (interface): interface DebrisOptions — ⚠ undocumented
2861
+ - `SupportConfig` (interface): interface SupportConfig — ⚠ undocumented
2862
+ - `SupportLink` (interface): interface SupportLink — ⚠ undocumented
2863
+ - `SupportPiece` (interface): interface SupportPiece — ⚠ undocumented
2864
+ - `SupportResult` (interface): interface SupportResult — ⚠ undocumented
2865
+ - `solveSupport` (function): function solveSupport(pieces: readonly SupportPiece[], links: readonly SupportLink[], config: SupportConfig = {}): SupportResult — ⚠ undocumented
2866
+ - `toDebrisBodies` (function): function toDebrisBodies(pieces: readonly SupportPiece[], collapsedIds: readonly string[], options: DebrisOptions = {}): AddBodyOptions[] — ⚠ undocumented
2867
+
2868
+ ## @jgengine/core/world/terraform
2869
+
2870
+ - `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.
2871
+ - `EditableTerrain` (interface): interface EditableTerrain extends TerrainField — ⚠ undocumented
2872
+ - `EditableTerrainConfig` (interface): interface EditableTerrainConfig — ⚠ undocumented
2873
+ - `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.
2874
+ - `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.
2875
+ - `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.
2876
+ - `TerraformBrush` (interface): interface TerraformBrush — ⚠ undocumented
2877
+ - `TerraformBrushConfig` (interface): interface TerraformBrushConfig — ⚠ undocumented
2878
+ - `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.
2879
+ - `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.
2880
+ - `TerraformEdit` (interface): interface TerraformEdit — A single sculpt stamp: which brush, where, and its shaping parameters.
2881
+ - `TerraformFalloff` (type): type TerraformFalloff = "smooth" | "linear" | "none" — How a brush's strength fades from its center to its rim.
2882
+ - `TerraformHeightLimit` (interface): interface TerraformHeightLimit — Clamp bounds applied to the resulting terrain height after a heightfield edit.
2883
+ - `TerraformMode` (type): type TerraformMode = "raise" | "lower" | "smooth" | "flatten" | "noise" | "ramp" | "paint" — A sculpt operation kind: heightfield brushes plus the surface-paint brush.
2884
+ - `TerraformShape` (type): type TerraformShape = "circle" | "square" — A brush footprint: a round disc or an axis-aligned square.
2885
+ - `TerraformSnapshot` (interface): interface TerraformSnapshot — ⚠ undocumented
2886
+ - `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.
2887
+ - `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.
2888
+ - `TerrainSurfaceRule` (interface): interface TerrainSurfaceRule — A height/slope predicate for auto-painting a surface layer (e.g. rock on steep slopes, snow up high).
2889
+ - `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.
2890
+ - `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.
2891
+ - `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).
2892
+ - `applySurfaceDeltaToSnapshot` (function): function applySurfaceDeltaToSnapshot(snapshot: TerraformSnapshot, delta: SurfaceDelta): TerraformSnapshot — Returns a new snapshot with a surface delta's `after` ids applied (copy-on-write).
2893
+ - `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.
2894
+ - `beginTerraformStroke` (function): function beginTerraformStroke(terrain: Pick<EditableTerrain, "applyRecording">): TerraformStroke — Opens a stroke recorder over `terrain`; stamp edits into it, then read one net delta.
2895
+ - `brushWeight` (function): function brushWeight(distance: number, radius: number, falloff: TerraformFalloff): number — Smooth/linear/hard brush weight for a sample `distance` from the brush center.
2896
+ - `createEditableTerrain` (function): function createEditableTerrain(config: EditableTerrainConfig): EditableTerrain — ⚠ undocumented
2897
+ - `createTerraformBrush` (function): function createTerraformBrush(terrain: Pick<EditableTerrain, "apply">, config: TerraformBrushConfig = {}): TerraformBrush — ⚠ undocumented
2898
+ - `createTerrainSnapshot` (function): function createTerrainSnapshot(config: EditableTerrainConfig): TerraformSnapshot — A fresh, unedited terrain snapshot sized to `bounds`/`cellSize` — the seed for a new sculpt document.
2899
+ - `editableTerrainFromSnapshot` (function): function editableTerrainFromSnapshot(snapshot: TerraformSnapshot, base?: TerrainField): EditableTerrain — Rebuilds a live {@link EditableTerrain} from a snapshot, layered over `base` ground.
2900
+ - `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.
2901
+ - `revertDeltaFromSnapshot` (function): function revertDeltaFromSnapshot(snapshot: TerraformSnapshot, delta: TerraformDelta): TerraformSnapshot — Returns a new snapshot with a delta's `before` offsets restored (copy-on-write undo).
2902
+ - `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).
2903
+
2904
+ ## @jgengine/core/world/terrain
2905
+
2906
+ - `ARENA_WATER_LEVEL` (const): const ARENA_WATER_LEVEL: -0.9 — ⚠ undocumented
2907
+ - `ArenaFieldConfig` (interface): interface ArenaFieldConfig — ⚠ undocumented
2908
+ - `BiomeFogValue` (interface): interface BiomeFogValue — A concrete fog look — the shape `createBiomeFogSampler` resolves per z from a band's `fog` over the base fog.
2909
+ - `BiomeSkyValue` (interface): interface BiomeSkyValue — A concrete sky look — the shape `createBiomeSkySampler` resolves per z from a band's `sky` over the base sky.
2910
+ - `DEFAULT_MAX_WALK_SLOPE` (const): const DEFAULT_MAX_WALK_SLOPE: 0.6 — ⚠ undocumented
2911
+ - `DEFAULT_TERRAIN_MATERIAL` (const): const DEFAULT_TERRAIN_MATERIAL: TerrainMaterial — ⚠ undocumented
2912
+ - `FLAT_FIELD` (const): const FLAT_FIELD: TerrainField — ⚠ undocumented
2913
+ - `FractalNoiseConfig` (interface): interface FractalNoiseConfig — Octave settings for {@link fractalNoise}: frequency, layering, and optional ridged shaping.
2914
+ - `GroundSnapEntityStore` (interface): interface GroundSnapEntityStore — ⚠ undocumented
2915
+ - `GroundSnapTarget` (interface): interface GroundSnapTarget — ⚠ undocumented
2916
+ - `HeightFieldRayBounds` (interface): interface HeightFieldRayBounds — XZ region a {@link raycastHeightField} march is clipped to.
2917
+ - `HeightFieldRayHit` (interface): interface HeightFieldRayHit — Where a {@link raycastHeightField} march crossed the surface.
2918
+ - `HeightFieldRaycastOptions` (interface): interface HeightFieldRaycastOptions — Tuning for {@link raycastHeightField}: march resolution and refinement depth.
2919
+ - `HeightMapFieldConfig` (interface): interface HeightMapFieldConfig — ⚠ undocumented
2920
+ - `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.
2921
+ - `NoiseFieldConfig` (interface): interface NoiseFieldConfig — Configuration for {@link noiseField}: seed, amplitude, and fractal noise shaping.
2922
+ - `ResolvedTerrainDetail` (type): type ResolvedTerrainDetail = Required<Omit<TerrainDetailConfig, "waterLevel" | "material">> & { waterLevel: number; material?: ResolvedTerrainDetailMaterial; } — A {@link TerrainDetailConfig} with every field resolved to a concrete value — the shape the shell's detail material consumes.
2923
+ - `ResolvedTerrainDetailMaterial` (interface): interface ResolvedTerrainDetailMaterial — A resolved {@link TerrainDetailMaterialConfig} — `repeat`/`strength` filled with defaults, `maps` passed through.
2924
+ - `RollingFieldConfig` (interface): interface RollingFieldConfig — ⚠ undocumented
2925
+ - `TERRAIN_MATERIAL_PALETTES` (const): const TERRAIN_MATERIAL_PALETTES: Record<TerrainMaterial, TerrainPalette> — ⚠ undocumented
2926
+ - `TerrainField` (interface): interface TerrainField — A sampleable ground surface: height and normal at any x/z, with optional bounds and water level.
2927
+ - `TerrainNormal` (type): type TerrainNormal = readonly [number, number, number] — A surface normal vector at a terrain sample point.
2928
+ - `TerrainPalette` (interface): interface TerrainPalette — ⚠ undocumented
2929
+ - `TerrainSlopeSample` (interface): interface TerrainSlopeSample — ⚠ undocumented
2930
+ - `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.
2931
+ - `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.
2932
+
2933
+ ## @jgengine/core/world/terrainGuides
2934
+
2935
+ - `ContourLine` (interface): interface ContourLine — A single iso-elevation contour traced across a region as a flat list of XZ line segments.
2936
+ - `ContourOptions` (interface): interface ContourOptions — Shaping for {@link extractContours}: region, vertical spacing, emphasis cadence, and sample budget.
2937
+ - `DrapeOptions` (interface): interface DrapeOptions — Shaping for surface draping: subdivision spacing and a lift to keep the line off the ground.
2938
+ - `ElevationReadout` (interface): interface ElevationReadout — Measurable elevation readout at a single world point — the cursor/hover feedback value.
2939
+ - `ElevationSummary` (interface): interface ElevationSummary — Aggregate elevation statistics over a region — the selection min/max/mean and legend range.
2940
+ - `GroundPoint` (type): type GroundPoint = readonly [number, number] — A world-space point on the ground plane as an `[x, z]` pair.
2941
+ - `GuideRegion` (interface): interface GuideRegion — An axis-aligned XZ rectangle to generate terrain-readability guides within.
2942
+ - `HeightSampler` (type): type HeightSampler = (x: number, z: number) => number — A height sampler over the ground: world elevation at any `x`/`z`.
2943
+ - `SurfaceGridLine` (interface): interface SurfaceGridLine — One draped grid line from {@link surfaceGridLines}: its axis, emphasis, and draped vertices.
2944
+ - `SurfaceGridOptions` (interface): interface SurfaceGridOptions — Shaping for {@link surfaceGridLines}: region, spacing, emphasis cadence, and draping.
2945
+ - `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).
2946
+ - `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.
2947
+ - `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.
2948
+ - `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.
2949
+ - `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.
2950
+ - `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.
2951
+ - `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.
2952
+ - `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.
2953
+
2954
+ ## @jgengine/core/world/vegetation
2955
+
2956
+ - `VEGETATION_DEFAULTS` (const): const VEGETATION_DEFAULTS: VegetationSettings — Defaults a bare `kind: "vegetation"` volume grows with: grass at 4 blades/m².
2957
+ - `VEGETATION_VOLUME_KIND` (const): const VEGETATION_VOLUME_KIND: "vegetation" — The editor volume kind that marks an area as vegetation fill.
2958
+ - `VegetationPlacement` (interface): interface VegetationPlacement — One placed vegetation instance — position on the ground plane plus per-instance variation.
2959
+ - `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.
2960
+
2961
+ ## @jgengine/core/world/visibilityField
2962
+
2963
+ - `VISIBILITY_HIDDEN` (const): const VISIBILITY_HIDDEN: 0 — Numeric code for a cell no group member has seen, or has fully forgotten.
2964
+ - `VISIBILITY_OBSERVED` (const): const VISIBILITY_OBSERVED: 2 — Numeric code for a cell a group currently observes.
2965
+ - `VISIBILITY_REMEMBERED` (const): const VISIBILITY_REMEMBERED: 1 — Numeric code for a cell seen before but not currently in view (last-known).
2966
+ - `VisibilityCells` (interface): interface VisibilityCells — Dense per-cell readout for one group, shaped for minimap/overlay drawing.
2967
+ - `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.
2968
+ - `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.
2969
+ - `VisibilityFieldConfig` (interface): interface VisibilityFieldConfig — Construction options for {@link createVisibilityField}.
2970
+ - `VisibilityFieldState` (interface): interface VisibilityFieldState — Serializable snapshot of a whole field — JSON round-trips losslessly.
2971
+ - `VisibilityGroupState` (interface): interface VisibilityGroupState — Sparse serialized knowledge for one group — only non-hidden cells are stored.
2972
+ - `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.
2973
+ - `VisibilityState` (type): type VisibilityState = "hidden" | "remembered" | "observed" — One viewer group's knowledge of a cell: never/forgotten, last-known, or live.
2974
+ - `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.
2975
+
2976
+ ## @jgengine/core/world/volumetricClouds
2977
+
2978
+ - `VOLUMETRIC_CLOUDS_DEFAULTS` (const): const VOLUMETRIC_CLOUDS_DEFAULTS: VolumetricCloudsRules — Volumetric cloud defaults: a moderate, drifting cumulus layer.
2979
+ - `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.
2980
+ - `VolumetricCloudsRules` (interface): interface VolumetricCloudsRules — Fully-defaulted volumetric cloud params, resolved from a `VolumetricCloudsConfig`.
2981
+
2982
+ ## @jgengine/core/world/voxelField
2983
+
2984
+ - `VOXEL_FACES` (const): const VOXEL_FACES: readonly VoxelFace[] — ⚠ undocumented
2985
+ - `VOXEL_FACE_NORMALS` (const): const VOXEL_FACE_NORMALS: Record<VoxelFace, VoxelCoord> — ⚠ undocumented
2986
+ - `VoxelBounds` (interface): interface VoxelBounds — ⚠ undocumented
2987
+ - `VoxelCell` (interface): interface VoxelCell<T extends string = string> — ⚠ undocumented
2988
+ - `VoxelCoord` (type): type VoxelCoord = readonly [number, number, number] — ⚠ undocumented
2989
+ - `VoxelFace` (type): type VoxelFace = "px" | "nx" | "py" | "ny" | "pz" | "nz" — ⚠ undocumented
2990
+ - `VoxelField` (interface): interface VoxelField<T extends string = string> — ⚠ undocumented
2991
+ - `VoxelFieldConfig` (interface): interface VoxelFieldConfig — ⚠ undocumented
2992
+ - `VoxelFieldSummary` (interface): interface VoxelFieldSummary<T extends string = string> — ⚠ undocumented
2993
+ - `VoxelHit` (interface): interface VoxelHit<T extends string = string> — ⚠ undocumented
2994
+ - `createVoxelField` (function): function createVoxelField<T extends string = string>(config?: VoxelFieldConfig): VoxelField<T> — ⚠ undocumented
2995
+
2996
+ ## @jgengine/core/world/walls
2997
+
2998
+ - `EnclosedFootprint` (interface): interface EnclosedFootprint — ⚠ undocumented
2999
+ - `PaintTarget` (type): type PaintTarget = "floor" | "wall" — ⚠ undocumented
3000
+ - `RoofConfig` (interface): interface RoofConfig — ⚠ undocumented
3001
+ - `RoofPlan` (interface): interface RoofPlan — ⚠ undocumented
3002
+ - `RoofStyle` (type): type RoofStyle = "hip" | "gable" | "flat" — ⚠ undocumented
3003
+ - `SurfacePaintStore` (interface): interface SurfacePaintStore — ⚠ undocumented
3004
+ - `WallDrawTool` (interface): interface WallDrawTool — ⚠ undocumented
3005
+ - `WallSegment` (interface): interface WallSegment — ⚠ undocumented
3006
+ - `WallVec3` (type): type WallVec3 = readonly [number, number, number] — ⚠ undocumented
3007
+
3008
+ ## @jgengine/core/world/water
3009
+
3010
+ - `GerstnerWave` (interface): interface GerstnerWave — ⚠ undocumented
3011
+ - `WaterNormal` (type): type WaterNormal = readonly [number, number, number] — ⚠ undocumented
3012
+ - `WaterSurface` (interface): interface WaterSurface — ⚠ undocumented
3013
+ - `WaterSurfaceConfig` (interface): interface WaterSurfaceConfig — ⚠ undocumented
3014
+ - `synthesizeWaves` (function): function synthesizeWaves(config: WaterSurfaceConfig = {}): GerstnerWave[] — ⚠ undocumented
3015
+ - `waterSurface` (function): function waterSurface(config: WaterSurfaceConfig = {}): WaterSurface — ⚠ undocumented
3016
+ - `waterSurfaceFromDescriptor` (function): function waterSurfaceFromDescriptor(descriptor: OceanEnvironmentDescriptor, waves?: number): WaterSurface — ⚠ undocumented
3017
+
3018
+ ## @jgengine/core/world/waterKind
3019
+
3020
+ - `ResolvedWater` (interface): interface ResolvedWater — A resolved water surface: world-space plane center/size (XZ) at surface height `y`, plus its params.
3021
+ - `WATER_DEFAULTS` (const): const WATER_DEFAULTS: WaterRules — Water defaults: a calm blue-green pond with a soft foam edge.
3022
+ - `WATER_SCHEMA` (const): const WATER_SCHEMA: ParamSchema — The water parameter schema — drives the inspector and `meta` parse via the studio seam.
3023
+ - `WATER_VOLUME_KIND` (const): const WATER_VOLUME_KIND: "water" — The editor volume kind marking a box as a water surface.
3024
+ - `WaterRules` (interface): interface WaterRules — Fully-defaulted water surface params parsed from a volume's `meta`.
3025
+
3026
+ ## @jgengine/core/world/weather
3027
+
3028
+ - `FireCell` (interface): interface FireCell — ⚠ undocumented
3029
+ - `FireCellState` (type): type FireCellState = "unburnt" | "burning" | "burnt" — ⚠ undocumented
3030
+ - `FireGrid` (interface): interface FireGrid — ⚠ undocumented
3031
+ - `FireGridConfig` (interface): interface FireGridConfig — ⚠ undocumented
3032
+ - `FireStepOptions` (interface): interface FireStepOptions — ⚠ undocumented
3033
+ - `ResolvedWeather` (interface): interface ResolvedWeather — ⚠ undocumented
3034
+ - `WeatherKind` (type): type WeatherKind = string — ⚠ undocumented
3035
+ - `WeatherKindOf` (type): type WeatherKindOf<TTable extends WeatherModifierTable> = Extract<keyof TTable, string> — ⚠ undocumented
3036
+ - `WeatherModifier` (interface): interface WeatherModifier — ⚠ undocumented
3037
+ - `WeatherModifierTable` (type): type WeatherModifierTable<K extends string = string> = Record<K, WeatherModifier> — ⚠ undocumented
3038
+ - `WeatherState` (interface): interface WeatherState — ⚠ undocumented
3039
+ - `createFireGrid` (function): function createFireGrid(config: FireGridConfig): FireGrid — ⚠ undocumented
3040
+ - `resolveWeather` (function): function resolveWeather<TTable extends WeatherModifierTable>(state: WeatherState, table: TTable): ResolvedWeather — ⚠ undocumented
3041
+
3042
+ ## @jgengine/core/world/wind
3043
+
3044
+ - `WindField` (interface): interface WindField — ⚠ undocumented
3045
+ - `WindFieldConfig` (interface): interface WindFieldConfig — ⚠ undocumented
3046
+ - `WindVector` (type): type WindVector = readonly [number, number] — ⚠ undocumented
3047
+ - `windField` (function): function windField(config: WindFieldConfig = {}): WindField — ⚠ undocumented
3048
+
3049
+ ## @jgengine/core/world/windZones
3050
+
3051
+ - `WindShiftForecast` (interface): interface WindShiftForecast — ⚠ undocumented
3052
+ - `WindZoneConfig` (interface): interface WindZoneConfig — ⚠ undocumented
3053
+ - `WindZoneState` (interface): interface WindZoneState — ⚠ undocumented
3054
+ - `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.
3055
+ - `WindZonesConfig` (interface): interface WindZonesConfig — ⚠ undocumented
3056
+ - `createWindZones` (function): function createWindZones(config: WindZonesConfig): WindZones — ⚠ undocumented