@jgengine/core 0.18.1 → 0.21.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 (404) hide show
  1. package/CHANGELOG.md +504 -7
  2. package/dist/ai/decisionGraph.d.ts +50 -4
  3. package/dist/ai/decisionGraph.js +159 -23
  4. package/dist/ai/flock.d.ts +1 -1
  5. package/dist/ai/flock.js +7 -4
  6. package/dist/ai/groupAssist.d.ts +10 -0
  7. package/dist/ai/groupAssist.js +11 -0
  8. package/dist/ai/pursuit.d.ts +1 -1
  9. package/dist/ai/pursuit.js +1 -1
  10. package/dist/ai/threat.d.ts +8 -0
  11. package/dist/ai/threat.js +10 -0
  12. package/dist/anim/animGraph.d.ts +43 -1
  13. package/dist/anim/animGraph.js +326 -10
  14. package/dist/anim/boneTexture.d.ts +55 -0
  15. package/dist/anim/boneTexture.js +43 -0
  16. package/dist/anim/footPlacement.d.ts +57 -0
  17. package/dist/anim/footPlacement.js +67 -0
  18. package/dist/anim/locomotionGraph.d.ts +18 -1
  19. package/dist/anim/locomotionGraph.js +42 -3
  20. package/dist/audio/audioFalloff.d.ts +6 -0
  21. package/dist/audio/doppler.d.ts +21 -0
  22. package/dist/audio/doppler.js +32 -0
  23. package/dist/audio/engineLayers.d.ts +83 -0
  24. package/dist/audio/engineLayers.js +115 -0
  25. package/dist/audio/voiceAllocator.d.ts +46 -0
  26. package/dist/audio/voiceAllocator.js +76 -0
  27. package/dist/combat/abilityKit.d.ts +20 -0
  28. package/dist/combat/abilityKit.js +41 -4
  29. package/dist/combat/death.d.ts +11 -3
  30. package/dist/combat/death.js +3 -3
  31. package/dist/combat/magazine.d.ts +9 -0
  32. package/dist/combat/magazine.js +24 -2
  33. package/dist/combat/projectiles.d.ts +94 -2
  34. package/dist/combat/projectiles.js +282 -61
  35. package/dist/combat/regenShield.d.ts +14 -0
  36. package/dist/combat/regenShield.js +23 -7
  37. package/dist/combat/shotOrigin.d.ts +6 -0
  38. package/dist/combat/shotOrigin.js +6 -0
  39. package/dist/combat/weaponFeedback.d.ts +36 -0
  40. package/dist/combat/weaponFeedback.js +42 -0
  41. package/dist/combat/weaponHandling.d.ts +161 -0
  42. package/dist/combat/weaponHandling.js +202 -0
  43. package/dist/combat/weaponPresentation.d.ts +115 -0
  44. package/dist/combat/weaponPresentation.js +96 -0
  45. package/dist/crafting/recipeCatalog.d.ts +16 -0
  46. package/dist/crafting/recipeCatalog.js +55 -0
  47. package/dist/devtools/warnOnce.d.ts +8 -0
  48. package/dist/devtools/warnOnce.js +18 -0
  49. package/dist/economy/auctionBook.d.ts +1 -1
  50. package/dist/economy/auctionBook.js +11 -1
  51. package/dist/economy/listingBook.d.ts +1 -1
  52. package/dist/economy/listingBook.js +11 -1
  53. package/dist/economy/resourceLedger.js +3 -3
  54. package/dist/economy/shopStock.js +7 -6
  55. package/dist/economy/techTree.js +7 -6
  56. package/dist/economy/unlockPoints.js +3 -6
  57. package/dist/editor/commandApply.js +89 -16
  58. package/dist/editor/commands.d.ts +38 -1
  59. package/dist/editor/commands.js +320 -3
  60. package/dist/editor/creatorStorage.d.ts +59 -0
  61. package/dist/editor/creatorStorage.js +164 -0
  62. package/dist/editor/document.d.ts +4 -0
  63. package/dist/editor/document.js +119 -18
  64. package/dist/editor/environment.js +8 -0
  65. package/dist/editor/index.d.ts +2 -0
  66. package/dist/editor/liveSync.d.ts +4 -1
  67. package/dist/editor/liveSync.js +26 -10
  68. package/dist/editor/materialAuthoring.d.ts +14 -0
  69. package/dist/editor/materialAuthoring.js +38 -0
  70. package/dist/editor/modelNodeVisibility.d.ts +11 -0
  71. package/dist/editor/modelNodeVisibility.js +29 -0
  72. package/dist/editor/movementCatalog.d.ts +90 -0
  73. package/dist/editor/movementCatalog.js +144 -0
  74. package/dist/editor/simulation.d.ts +60 -0
  75. package/dist/editor/simulation.js +202 -0
  76. package/dist/editor/staticPrefab.d.ts +17 -0
  77. package/dist/editor/staticPrefab.js +51 -0
  78. package/dist/editor/types.d.ts +15 -0
  79. package/dist/faction/reputation.d.ts +6 -0
  80. package/dist/faction/reputation.js +11 -0
  81. package/dist/game/cameraConfig.d.ts +54 -2
  82. package/dist/game/clipRoles.d.ts +2 -1
  83. package/dist/game/clipRoles.js +7 -3
  84. package/dist/game/contentValidation.d.ts +69 -0
  85. package/dist/game/contentValidation.js +118 -0
  86. package/dist/game/controlGate.d.ts +8 -0
  87. package/dist/game/controlGate.js +43 -6
  88. package/dist/game/defineGame.d.ts +32 -3
  89. package/dist/game/dialogueGraph.d.ts +20 -0
  90. package/dist/game/dialogueGraph.js +107 -0
  91. package/dist/game/events.d.ts +11 -0
  92. package/dist/game/keyValueStore.d.ts +17 -4
  93. package/dist/game/keyValueStore.js +35 -23
  94. package/dist/game/lootModifiers.d.ts +17 -0
  95. package/dist/game/lootModifiers.js +26 -0
  96. package/dist/game/lootTable.d.ts +4 -0
  97. package/dist/game/lootTable.js +16 -0
  98. package/dist/game/narrativeAuthoring.d.ts +67 -0
  99. package/dist/game/narrativeAuthoring.js +122 -0
  100. package/dist/game/playableGame.d.ts +134 -35
  101. package/dist/game/quest.d.ts +15 -0
  102. package/dist/game/quest.js +209 -63
  103. package/dist/game/questCatalog.d.ts +50 -0
  104. package/dist/game/questCatalog.js +205 -0
  105. package/dist/game/saveStore.d.ts +6 -5
  106. package/dist/game/saveStore.js +57 -57
  107. package/dist/game/systemRuntime.d.ts +2 -2
  108. package/dist/game/systemRuntime.js +84 -33
  109. package/dist/game/toasts.d.ts +8 -0
  110. package/dist/game/toasts.js +7 -0
  111. package/dist/game/vfxInstance.d.ts +9 -0
  112. package/dist/game/vfxInstance.js +12 -1
  113. package/dist/game/viewports.d.ts +43 -0
  114. package/dist/game/viewports.js +46 -0
  115. package/dist/game/worldItem.d.ts +5 -1
  116. package/dist/game/worldItem.js +0 -1
  117. package/dist/gameplay.d.ts +3 -0
  118. package/dist/gameplay.js +3 -0
  119. package/dist/input/actionBindings.d.ts +15 -1
  120. package/dist/input/actionBindings.js +14 -3
  121. package/dist/input/actionContexts.d.ts +25 -1
  122. package/dist/input/actionContexts.js +82 -25
  123. package/dist/input/axisInput.d.ts +4 -0
  124. package/dist/input/axisInput.js +4 -0
  125. package/dist/input/axisShaper.d.ts +73 -0
  126. package/dist/input/axisShaper.js +105 -0
  127. package/dist/input/gamepadModel.d.ts +36 -2
  128. package/dist/input/gamepadModel.js +69 -30
  129. package/dist/input/haptics.d.ts +50 -0
  130. package/dist/input/haptics.js +74 -0
  131. package/dist/input/inputBuffer.d.ts +40 -0
  132. package/dist/input/inputBuffer.js +59 -0
  133. package/dist/input/lookChannel.d.ts +10 -0
  134. package/dist/input/lookChannel.js +6 -0
  135. package/dist/input/pointer.d.ts +2 -0
  136. package/dist/input/pointer.js +4 -0
  137. package/dist/interaction/promptRegistry.d.ts +5 -4
  138. package/dist/interaction/promptRegistry.js +8 -2
  139. package/dist/inventory/inventoryModel.js +9 -6
  140. package/dist/inventory/shapedGrid.d.ts +48 -9
  141. package/dist/inventory/shapedGrid.js +69 -10
  142. package/dist/item/affix.d.ts +6 -0
  143. package/dist/item/affix.js +6 -0
  144. package/dist/item/durability.js +4 -0
  145. package/dist/item/itemInstanceRegistry.d.ts +32 -1
  146. package/dist/item/itemInstanceRegistry.js +111 -7
  147. package/dist/item/itemgen.d.ts +1 -1
  148. package/dist/item/itemgen.js +1 -1
  149. package/dist/item/modularItem.js +7 -1
  150. package/dist/material/appearanceSignals.d.ts +53 -0
  151. package/dist/material/appearanceSignals.js +47 -0
  152. package/dist/material/hairCards.d.ts +47 -0
  153. package/dist/material/hairCards.js +136 -0
  154. package/dist/material/materialAsset.d.ts +162 -0
  155. package/dist/material/materialAsset.js +382 -0
  156. package/dist/meta/changelog.d.ts +1 -1
  157. package/dist/meta/changelog.js +444 -1
  158. package/dist/movement/characterController.d.ts +5 -2
  159. package/dist/movement/characterController.js +50 -23
  160. package/dist/movement/freeFlight.d.ts +2 -2
  161. package/dist/movement/freeFlight.js +3 -3
  162. package/dist/movement/glideModel.d.ts +3 -0
  163. package/dist/movement/glideModel.js +6 -0
  164. package/dist/movement/grappleSwing.d.ts +2 -0
  165. package/dist/movement/grappleSwing.js +5 -1
  166. package/dist/movement/movementModel.d.ts +63 -1
  167. package/dist/movement/movementModel.js +136 -26
  168. package/dist/movement/movementProbe.d.ts +51 -0
  169. package/dist/movement/movementProbe.js +119 -0
  170. package/dist/movement/playerMovement.d.ts +48 -2
  171. package/dist/movement/playerMovement.js +493 -87
  172. package/dist/movement/poseState.d.ts +2 -0
  173. package/dist/movement/poseState.js +29 -1
  174. package/dist/movement/solidObstacles.d.ts +11 -1
  175. package/dist/movement/solidObstacles.js +48 -3
  176. package/dist/movement/terrainGrade.d.ts +13 -0
  177. package/dist/movement/terrainGrade.js +33 -0
  178. package/dist/movement/voxelController.d.ts +2 -2
  179. package/dist/movement/voxelController.js +10 -10
  180. package/dist/nav/navFromEnvironment.d.ts +9 -3
  181. package/dist/nav/navFromEnvironment.js +18 -12
  182. package/dist/nav/navGrid.d.ts +19 -1
  183. package/dist/nav/navGrid.js +26 -10
  184. package/dist/nav/navMesh.d.ts +43 -2
  185. package/dist/nav/navMesh.js +534 -128
  186. package/dist/nav/solidRoute.d.ts +50 -0
  187. package/dist/nav/solidRoute.js +144 -0
  188. package/dist/physics/aircraftDynamics.d.ts +390 -0
  189. package/dist/physics/aircraftDynamics.js +704 -0
  190. package/dist/physics/ballisticSweep.d.ts +10 -3
  191. package/dist/physics/ballisticSweep.js +53 -29
  192. package/dist/physics/boatDynamics.d.ts +116 -0
  193. package/dist/physics/boatDynamics.js +160 -0
  194. package/dist/physics/drivableVehicle.d.ts +22 -8
  195. package/dist/physics/drivableVehicle.js +4 -2
  196. package/dist/physics/flightDynamics.d.ts +21 -4
  197. package/dist/physics/flightDynamics.js +28 -5
  198. package/dist/physics/forceVolume.d.ts +41 -0
  199. package/dist/physics/forceVolume.js +88 -0
  200. package/dist/physics/handlingProbe.d.ts +249 -0
  201. package/dist/physics/handlingProbe.js +606 -0
  202. package/dist/physics/kinematicVehicle.d.ts +40 -5
  203. package/dist/physics/kinematicVehicle.js +17 -2
  204. package/dist/physics/physicsBackend.d.ts +12 -0
  205. package/dist/physics/physicsBackendConformance.js +34 -0
  206. package/dist/physics/physicsWorldBackend.d.ts +1 -0
  207. package/dist/physics/physicsWorldBackend.js +52 -3
  208. package/dist/physics/spatialGrid.d.ts +1 -1
  209. package/dist/physics/spatialGrid.js +8 -9
  210. package/dist/physics/vehicleBackendLink.d.ts +49 -0
  211. package/dist/physics/vehicleBackendLink.js +102 -0
  212. package/dist/physics/vehicleDynamics.d.ts +375 -0
  213. package/dist/physics/vehicleDynamics.js +737 -0
  214. package/dist/physics/vehicleObstacles.d.ts +3 -2
  215. package/dist/physics/vehicleObstacles.js +29 -5
  216. package/dist/physics/worldColliders.d.ts +1 -1
  217. package/dist/physics/worldColliders.js +35 -3
  218. package/dist/puzzle/cellGrid.d.ts +15 -9
  219. package/dist/puzzle/cellGrid.js +13 -9
  220. package/dist/render/lookPreset.d.ts +9 -2
  221. package/dist/render/lookPreset.js +29 -2
  222. package/dist/render/postProcessing.d.ts +30 -0
  223. package/dist/render/postProcessing.js +1 -1
  224. package/dist/runtime/cameraDirector.d.ts +54 -3
  225. package/dist/runtime/cameraDirector.js +187 -0
  226. package/dist/runtime/commandDispatch.d.ts +14 -0
  227. package/dist/runtime/commandDispatch.js +19 -0
  228. package/dist/runtime/commandInput.d.ts +37 -0
  229. package/dist/runtime/commandInput.js +58 -0
  230. package/dist/runtime/commandRunner.d.ts +27 -0
  231. package/dist/runtime/commandRunner.js +31 -3
  232. package/dist/runtime/context/combat.d.ts +12 -4
  233. package/dist/runtime/context/combat.js +179 -11
  234. package/dist/runtime/context/deathLoot.d.ts +11 -8
  235. package/dist/runtime/context/deathLoot.js +17 -16
  236. package/dist/runtime/context/scene.d.ts +2 -0
  237. package/dist/runtime/context/scene.js +13 -21
  238. package/dist/runtime/descriptors/baseline.js +34 -3
  239. package/dist/runtime/descriptors/features.d.ts +2 -1
  240. package/dist/runtime/descriptors/features.js +18 -0
  241. package/dist/runtime/gameContext.js +86 -13
  242. package/dist/runtime/gameContextTypes.d.ts +33 -3
  243. package/dist/runtime/gameRuntime.d.ts +3 -1
  244. package/dist/runtime/gameRuntime.js +4 -0
  245. package/dist/runtime/headlessRunner.d.ts +3 -1
  246. package/dist/runtime/headlessRunner.js +11 -11
  247. package/dist/runtime/hostedGameRunner.d.ts +24 -1
  248. package/dist/runtime/hostedGameRunner.js +156 -10
  249. package/dist/runtime/hostedWorldSession.d.ts +17 -5
  250. package/dist/runtime/hostedWorldSession.js +154 -16
  251. package/dist/runtime/hostedWorldStore.d.ts +2 -2
  252. package/dist/runtime/inputRecorder.d.ts +1 -1
  253. package/dist/runtime/inputRecorder.js +21 -1
  254. package/dist/runtime/inputSnapshot.d.ts +22 -4
  255. package/dist/runtime/inputSnapshot.js +41 -3
  256. package/dist/runtime/localPlayers.d.ts +73 -0
  257. package/dist/runtime/localPlayers.js +119 -0
  258. package/dist/runtime/runtimeSave.d.ts +10 -6
  259. package/dist/runtime/runtimeSave.js +11 -5
  260. package/dist/runtime/simContext.d.ts +8 -3
  261. package/dist/runtime/simContext.js +7 -3
  262. package/dist/runtime/simSnapshot.js +2 -0
  263. package/dist/runtime/transport.d.ts +9 -0
  264. package/dist/runtime/transport.js +7 -1
  265. package/dist/runtime/worldReplication.d.ts +2 -0
  266. package/dist/runtime/worldReplication.js +1 -1
  267. package/dist/scene/assetCatalog.d.ts +2 -0
  268. package/dist/scene/behaviorRuntime.d.ts +38 -7
  269. package/dist/scene/behaviorRuntime.js +293 -30
  270. package/dist/scene/behaviors.d.ts +35 -2
  271. package/dist/scene/behaviors.js +29 -0
  272. package/dist/scene/entityStore.d.ts +14 -3
  273. package/dist/scene/entityStore.js +45 -9
  274. package/dist/scene/mount.d.ts +9 -0
  275. package/dist/scene/mount.js +35 -0
  276. package/dist/scene/possession.d.ts +2 -0
  277. package/dist/scene/possession.js +21 -1
  278. package/dist/scene/sceneKinds.d.ts +9 -0
  279. package/dist/scene/sceneRaycast.d.ts +7 -0
  280. package/dist/scene/sceneRaycast.js +55 -0
  281. package/dist/scene/spatial.d.ts +20 -1
  282. package/dist/scene/spatial.js +94 -2
  283. package/dist/scene/vehicleSeat.d.ts +41 -3
  284. package/dist/scene/vehicleSeat.js +94 -3
  285. package/dist/sensor/concealment.d.ts +6 -0
  286. package/dist/sensor/concealment.js +8 -0
  287. package/dist/sensor/freezeMonitor.d.ts +6 -0
  288. package/dist/sensor/freezeMonitor.js +8 -0
  289. package/dist/sensor/perception.d.ts +11 -1
  290. package/dist/sensor/perception.js +57 -10
  291. package/dist/sensor/recordingBuffer.d.ts +3 -0
  292. package/dist/sensor/recordingBuffer.js +8 -0
  293. package/dist/session/roundState.d.ts +4 -0
  294. package/dist/session/roundState.js +11 -0
  295. package/dist/settings/frameRateLimit.d.ts +16 -0
  296. package/dist/settings/frameRateLimit.js +37 -0
  297. package/dist/settings/graphicsProfile.d.ts +2 -0
  298. package/dist/settings/graphicsProfile.js +12 -0
  299. package/dist/settings/graphicsSettings.d.ts +40 -0
  300. package/dist/settings/graphicsSettings.js +81 -0
  301. package/dist/settings/settingsModel.d.ts +9 -1
  302. package/dist/settings/settingsModel.js +10 -0
  303. package/dist/stats/accumulatorMeter.d.ts +10 -0
  304. package/dist/stats/accumulatorMeter.js +6 -0
  305. package/dist/stats/eventMeter.d.ts +10 -3
  306. package/dist/stats/eventMeter.js +6 -3
  307. package/dist/store/defineStore.d.ts +3 -1
  308. package/dist/store/defineStore.js +3 -1
  309. package/dist/store/observableKeyedStore.d.ts +1 -1
  310. package/dist/store/observableKeyedStore.js +8 -6
  311. package/dist/time/simClock.d.ts +6 -2
  312. package/dist/time/simClock.js +5 -0
  313. package/dist/vfx/feedbackMixer.d.ts +61 -0
  314. package/dist/vfx/feedbackMixer.js +106 -0
  315. package/dist/vfx/particleDirector.d.ts +58 -6
  316. package/dist/vfx/particleDirector.js +113 -22
  317. package/dist/vfx/particles.d.ts +68 -5
  318. package/dist/vfx/particles.js +284 -32
  319. package/dist/visibility/assetStreaming.d.ts +21 -3
  320. package/dist/visibility/assetStreaming.js +108 -24
  321. package/dist/visibility/settings.d.ts +8 -2
  322. package/dist/visibility/settings.js +3 -0
  323. package/dist/visibility/simulationCulling.d.ts +8 -1
  324. package/dist/visibility/simulationCulling.js +7 -0
  325. package/dist/visibility/spatialIndex.d.ts +21 -0
  326. package/dist/visibility/spatialIndex.js +16 -0
  327. package/dist/visibility/visibilitySystem.js +1 -0
  328. package/dist/work/expedition.d.ts +110 -0
  329. package/dist/work/expedition.js +195 -0
  330. package/dist/work/staffedStation.d.ts +29 -0
  331. package/dist/work/staffedStation.js +27 -0
  332. package/dist/world/authoredAnimation.d.ts +38 -0
  333. package/dist/world/authoredAnimation.js +99 -0
  334. package/dist/world/authoredObjects.d.ts +24 -4
  335. package/dist/world/authoredObjects.js +43 -16
  336. package/dist/world/authoredSimulation.d.ts +74 -0
  337. package/dist/world/authoredSimulation.js +302 -0
  338. package/dist/world/authoredSolids.d.ts +46 -0
  339. package/dist/world/authoredSolids.js +75 -0
  340. package/dist/world/authoredWeather.d.ts +120 -0
  341. package/dist/world/authoredWeather.js +314 -0
  342. package/dist/world/buildingGenerator.js +2 -2
  343. package/dist/world/buildingKit.d.ts +11 -4
  344. package/dist/world/buildingKit.js +21 -8
  345. package/dist/world/buildings.d.ts +34 -2
  346. package/dist/world/buildings.js +11 -1
  347. package/dist/world/cityKind.d.ts +7 -0
  348. package/dist/world/cityKind.js +52 -1
  349. package/dist/world/environmentForces.d.ts +21 -0
  350. package/dist/world/environmentForces.js +42 -0
  351. package/dist/world/features.d.ts +32 -5
  352. package/dist/world/features.js +6 -0
  353. package/dist/world/footprintGrid.d.ts +62 -0
  354. package/dist/world/footprintGrid.js +217 -0
  355. package/dist/world/interiors.d.ts +1 -0
  356. package/dist/world/interiors.js +5 -3
  357. package/dist/world/lod.d.ts +6 -0
  358. package/dist/world/lod.js +8 -0
  359. package/dist/world/pathTerrain.d.ts +1 -1
  360. package/dist/world/terraform.d.ts +9 -1
  361. package/dist/world/terraform.js +53 -18
  362. package/dist/world/walls.d.ts +7 -0
  363. package/dist/world/walls.js +7 -0
  364. package/dist/world/weather.d.ts +17 -0
  365. package/dist/world/weather.js +116 -20
  366. package/dist/world/worldSolids.d.ts +95 -0
  367. package/dist/world/worldSolids.js +351 -0
  368. package/dist/world.d.ts +6 -6
  369. package/dist/world.js +5 -5
  370. package/package.json +1 -1
  371. package/skills/ce-handoff/SKILL.md +2 -2
  372. package/skills/game-design/SKILL.md +2 -2
  373. package/skills/jgengine/SKILL.md +28 -6
  374. package/skills/jgengine/api.md +139 -99
  375. package/skills/jgengine/capabilities.md +28 -0
  376. package/skills/jgengine/recipes/minimal-game.md +10 -2
  377. package/skills/jgengine-combat/SKILL.md +13 -2
  378. package/skills/jgengine-combat/api.md +150 -103
  379. package/skills/jgengine-combat/capabilities.md +29 -1
  380. package/skills/jgengine-combat/recipes/portable-runtime-state.md +60 -6
  381. package/skills/jgengine-combat/recipes/portable-weapon-plumbing.md +37 -3
  382. package/skills/jgengine-combat/recipes/weapon-feel.md +50 -0
  383. package/skills/jgengine-combat/reference.md +24 -2
  384. package/skills/jgengine-gameplay/SKILL.md +63 -0
  385. package/skills/jgengine-gameplay/api.md +583 -463
  386. package/skills/jgengine-gameplay/capabilities.md +92 -0
  387. package/skills/jgengine-gameplay/recipes/device-save-status.md +46 -0
  388. package/skills/jgengine-gameplay/recipes/expeditions.md +108 -0
  389. package/skills/jgengine-gameplay/recipes/narrative-authoring.md +76 -0
  390. package/skills/jgengine-gameplay/recipes/paged-item-storage.md +101 -0
  391. package/skills/jgengine-gameplay/recipes/quest-authoring.md +63 -0
  392. package/skills/jgengine-gameplay/recipes/shaped-inventory.md +50 -0
  393. package/skills/jgengine-gameplay/reference-content-validation.md +74 -0
  394. package/skills/jgengine-gameplay/reference-systems.md +123 -0
  395. package/skills/jgengine-world/SKILL.md +25 -4
  396. package/skills/jgengine-world/api.md +1045 -655
  397. package/skills/jgengine-world/capabilities.md +246 -9
  398. package/skills/jgengine-world/recipes/character-animation.md +62 -0
  399. package/skills/jgengine-world/recipes/controls.md +48 -0
  400. package/skills/jgengine-world/recipes/flight-feel.md +76 -0
  401. package/skills/jgengine-world/recipes/npc-senses.md +55 -0
  402. package/skills/jgengine-world/recipes/vehicle-feel.md +87 -0
  403. package/skills/jgengine-world/reference.md +180 -4
  404. package/skills/jgengine-world/visibility.md +139 -0
@@ -4,13 +4,23 @@ export type BlackboardValue = number | boolean | string;
4
4
  export type Blackboard = Record<string, BlackboardValue>;
5
5
  /** Comparison operators supported by decision conditions. */
6
6
  export type DecisionOperator = "=" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "eq" | "ne" | "lt" | "lte" | "gt" | "gte";
7
- /** Serializable selector, sequence, condition, action, or utility node. */
7
+ /**
8
+ * Serializable decision node.
9
+ * - `selector` runs children in order until one does not fail; `sequence` until one does not finish.
10
+ * With `memory`, a composite whose child was running last tick resumes at that child instead of re-checking earlier ones.
11
+ * - `condition` compares a blackboard key; `action` calls a registered action.
12
+ * - `utility` runs the option with the highest weighted blackboard score.
13
+ * - `invert` swaps `done` and `failed`; `cooldown` fails for `seconds` after its child finishes;
14
+ * `wait` stays running for `seconds`; `random` picks a child by `weights` from the runtime's `rng` and keeps it while it runs.
15
+ */
8
16
  export type DecisionNode = {
9
17
  kind: "selector";
10
18
  children: DecisionNode[];
19
+ memory?: boolean;
11
20
  } | {
12
21
  kind: "sequence";
13
22
  children: DecisionNode[];
23
+ memory?: boolean;
14
24
  } | {
15
25
  kind: "condition";
16
26
  key: string;
@@ -29,6 +39,20 @@ export type DecisionNode = {
29
39
  }[];
30
40
  node: DecisionNode;
31
41
  }[];
42
+ } | {
43
+ kind: "invert";
44
+ child: DecisionNode;
45
+ } | {
46
+ kind: "cooldown";
47
+ seconds: number;
48
+ child: DecisionNode;
49
+ } | {
50
+ kind: "wait";
51
+ seconds: number;
52
+ } | {
53
+ kind: "random";
54
+ children: DecisionNode[];
55
+ weights?: number[];
32
56
  };
33
57
  /** Root node for a serializable AI decision graph. */
34
58
  export type DecisionGraph = DecisionNode;
@@ -36,17 +60,39 @@ export type DecisionGraph = DecisionNode;
36
60
  export type DecisionStatus = "running" | "done" | "failed";
37
61
  /** Callback implementation for an action node. */
38
62
  export type DecisionAction<Context = unknown> = (ctx: Context, params: Record<string, BlackboardValue> | undefined, blackboard: Blackboard) => DecisionStatus;
39
- /** Serializable state retained by an active decision graph. */
63
+ /** Called when an action that was running last tick is not reached this tick, so it can release what it holds. */
64
+ export type DecisionAbort<Context = unknown> = (action: string, ctx: Context, params: Record<string, BlackboardValue> | undefined, blackboard: Blackboard) => void;
65
+ /** Optional hooks and injected randomness for {@link createDecisionGraphRuntime}. */
66
+ export interface DecisionGraphOptions<Context = unknown> {
67
+ onAbort?: DecisionAbort<Context>;
68
+ /** `[0, 1)` source for `random` nodes; pass `ctx.rng`. Required only when the graph has one. */
69
+ rng?: () => number;
70
+ }
71
+ /** Progress of a memory composite, `random` choice, or `wait` timer, keyed by node id (depth-first order). */
72
+ export interface DecisionNodeMemory {
73
+ index: number;
74
+ elapsed: number;
75
+ tick: number;
76
+ }
77
+ /** Serializable state retained by an active decision graph. Fields besides `runningPath` are absent in older saves. */
40
78
  export interface DecisionGraphSnapshot {
41
79
  runningPath: number[] | null;
80
+ tick?: number;
81
+ clock?: number;
82
+ nodes?: Record<string, DecisionNodeMemory>;
83
+ cooldowns?: Record<string, number>;
42
84
  }
43
85
  /** Stateful evaluator for a serializable decision graph. */
44
86
  export interface DecisionGraphRuntime<Context = unknown> {
45
87
  tick(ctx: Context, blackboard: Blackboard, dt: number): DecisionStatus;
88
+ /** Name of the action left running by the last tick, or null. */
89
+ running(): string | null;
90
+ /** Abort the compiled running action once, retaining graph memory/timers. Clears ownership before invoking user onAbort, even if it throws. */
91
+ abort(ctx: Context, blackboard: Blackboard): void;
46
92
  snapshot(): DecisionGraphSnapshot;
47
93
  restore(next: DecisionGraphSnapshot): void;
48
94
  }
49
95
  /** Creates a deterministic runtime for a serializable decision graph.
50
- * @capability ai-decision-graph Evaluate serializable selector, sequence, condition, action, and utility AI decisions.
96
+ * @capability ai-decision-graph Evaluate serializable selector, sequence, condition, action, utility, timer, and random AI decisions with interrupt hooks.
51
97
  */
52
- export declare function createDecisionGraphRuntime<Context = unknown>(graph: DecisionGraph, actions: Record<string, DecisionAction<Context>>): DecisionGraphRuntime<Context>;
98
+ export declare function createDecisionGraphRuntime<Context = unknown>(graph: DecisionGraph, actions: Record<string, DecisionAction<Context>>, options?: DecisionGraphOptions<Context>): DecisionGraphRuntime<Context>;
@@ -21,12 +21,53 @@ function compare(left, op, right) {
21
21
  return typeof left === "number" && typeof right === "number" && left >= right;
22
22
  }
23
23
  }
24
+ function childrenOf(node) {
25
+ switch (node.kind) {
26
+ case "selector":
27
+ case "sequence":
28
+ case "random":
29
+ return node.children;
30
+ case "utility":
31
+ return node.options.map((option) => option.node);
32
+ case "invert":
33
+ case "cooldown":
34
+ return [node.child];
35
+ default:
36
+ return [];
37
+ }
38
+ }
39
+ function compile(root) {
40
+ const byId = [];
41
+ const visit = (node, path) => {
42
+ const entry = { node, id: byId.length, path, children: [] };
43
+ byId.push(entry);
44
+ childrenOf(node).forEach((child, index) => entry.children.push(visit(child, [...path, index])));
45
+ return entry;
46
+ };
47
+ visit(root, []);
48
+ return byId;
49
+ }
24
50
  /** Creates a deterministic runtime for a serializable decision graph.
25
- * @capability ai-decision-graph Evaluate serializable selector, sequence, condition, action, and utility AI decisions.
51
+ * @capability ai-decision-graph Evaluate serializable selector, sequence, condition, action, utility, timer, and random AI decisions with interrupt hooks.
26
52
  */
27
- export function createDecisionGraphRuntime(graph, actions) {
28
- let runningPath = null;
29
- function run(node, ctx, blackboard, dt, path) {
53
+ export function createDecisionGraphRuntime(graph, actions, options = {}) {
54
+ const nodes = compile(graph);
55
+ const root = nodes[0];
56
+ let runningId = -1;
57
+ let tickCount = 0;
58
+ let clock = 0;
59
+ const memory = new Map();
60
+ const cooldowns = new Map();
61
+ const lastReached = new Float64Array(nodes.length).fill(-1);
62
+ function carried(id) {
63
+ const entry = memory.get(id);
64
+ return entry !== undefined && entry.tick === tickCount - 1 ? entry : undefined;
65
+ }
66
+ function hold(id, index, elapsed) {
67
+ memory.set(id, { index, elapsed, tick: tickCount });
68
+ }
69
+ function run(entry, ctx, blackboard, dt) {
70
+ const node = entry.node;
30
71
  switch (node.kind) {
31
72
  case "condition":
32
73
  return compare(blackboard[node.key], node.op, node.value) ? "done" : "failed";
@@ -34,49 +75,144 @@ export function createDecisionGraphRuntime(graph, actions) {
34
75
  const action = actions[node.action];
35
76
  if (action === undefined)
36
77
  throw new Error(`Decision action '${node.action}' is not registered`);
78
+ lastReached[entry.id] = tickCount;
37
79
  const status = action(ctx, node.params, blackboard);
38
80
  if (status === "running")
39
- runningPath = path;
81
+ runningId = entry.id;
40
82
  return status;
41
83
  }
42
84
  case "selector":
43
- for (let index = 0; index < node.children.length; index += 1) {
44
- const status = run(node.children[index], ctx, blackboard, dt, [...path, index]);
45
- if (status !== "failed")
46
- return status;
85
+ case "sequence": {
86
+ const stopOn = node.kind === "selector" ? "failed" : "done";
87
+ const start = node.memory === true ? (carried(entry.id)?.index ?? 0) : 0;
88
+ memory.delete(entry.id);
89
+ for (let index = start; index < entry.children.length; index += 1) {
90
+ const status = run(entry.children[index], ctx, blackboard, dt);
91
+ if (status === stopOn)
92
+ continue;
93
+ if (status === "running" && node.memory === true)
94
+ hold(entry.id, index, 0);
95
+ return status;
47
96
  }
48
- return "failed";
49
- case "sequence":
50
- for (let index = 0; index < node.children.length; index += 1) {
51
- const status = run(node.children[index], ctx, blackboard, dt, [...path, index]);
52
- if (status !== "done")
53
- return status;
54
- }
55
- return "done";
97
+ return node.kind === "selector" ? "failed" : "done";
98
+ }
56
99
  case "utility": {
57
100
  let best = -Infinity;
58
101
  let bestIndex = -1;
59
102
  for (let index = 0; index < node.options.length; index += 1) {
60
- const score = node.options[index].score.reduce((total, term) => total + (typeof blackboard[term.key] === "number" ? blackboard[term.key] : 0) * term.weight, 0);
103
+ let score = 0;
104
+ for (const term of node.options[index].score) {
105
+ const value = blackboard[term.key];
106
+ if (typeof value === "number")
107
+ score += value * term.weight;
108
+ }
61
109
  if (score > best) {
62
110
  best = score;
63
111
  bestIndex = index;
64
112
  }
65
113
  }
66
- return bestIndex < 0 ? "failed" : run(node.options[bestIndex].node, ctx, blackboard, dt, [...path, bestIndex]);
114
+ return bestIndex < 0 ? "failed" : run(entry.children[bestIndex], ctx, blackboard, dt);
115
+ }
116
+ case "invert": {
117
+ const status = run(entry.children[0], ctx, blackboard, dt);
118
+ return status === "running" ? status : status === "done" ? "failed" : "done";
119
+ }
120
+ case "cooldown": {
121
+ if (clock < (cooldowns.get(entry.id) ?? -Infinity))
122
+ return "failed";
123
+ const status = run(entry.children[0], ctx, blackboard, dt);
124
+ if (status === "done")
125
+ cooldowns.set(entry.id, clock + Math.max(0, node.seconds));
126
+ return status;
127
+ }
128
+ case "wait": {
129
+ const elapsed = (carried(entry.id)?.elapsed ?? 0) + dt;
130
+ if (elapsed >= node.seconds) {
131
+ memory.delete(entry.id);
132
+ return "done";
133
+ }
134
+ hold(entry.id, 0, elapsed);
135
+ runningId = entry.id;
136
+ return "running";
137
+ }
138
+ case "random": {
139
+ if (entry.children.length === 0)
140
+ return "failed";
141
+ let index = carried(entry.id)?.index ?? -1;
142
+ if (index < 0) {
143
+ if (options.rng === undefined)
144
+ throw new Error("A random decision node needs options.rng (pass ctx.rng)");
145
+ const weights = entry.children.map((_, i) => Math.max(0, node.weights?.[i] ?? 1));
146
+ const total = weights.reduce((sum, weight) => sum + weight, 0);
147
+ if (total <= 0)
148
+ return "failed";
149
+ let roll = options.rng() * total;
150
+ index = 0;
151
+ while (index < weights.length - 1 && roll >= weights[index])
152
+ roll -= weights[index++];
153
+ }
154
+ memory.delete(entry.id);
155
+ const status = run(entry.children[index], ctx, blackboard, dt);
156
+ if (status === "running")
157
+ hold(entry.id, index, 0);
158
+ return status;
67
159
  }
68
160
  }
69
161
  }
162
+ function idFromPath(path) {
163
+ let entry = root;
164
+ for (const index of path)
165
+ entry = entry?.children[index];
166
+ return entry?.id ?? -1;
167
+ }
70
168
  return {
71
169
  tick(ctx, blackboard, dt) {
72
- runningPath = null;
73
- return run(graph, ctx, blackboard, dt, []);
170
+ const previous = runningId;
171
+ tickCount += 1;
172
+ clock += Math.max(0, dt);
173
+ runningId = -1;
174
+ const status = run(root, ctx, blackboard, Math.max(0, dt));
175
+ const abandoned = previous >= 0 ? nodes[previous].node : null;
176
+ if (abandoned?.kind === "action" && lastReached[previous] !== tickCount) {
177
+ options.onAbort?.(abandoned.action, ctx, abandoned.params, blackboard);
178
+ }
179
+ return status;
180
+ },
181
+ running() {
182
+ const node = runningId >= 0 ? nodes[runningId].node : null;
183
+ return node?.kind === "action" ? node.action : null;
184
+ },
185
+ abort(ctx, blackboard) {
186
+ const node = runningId >= 0 ? nodes[runningId].node : null;
187
+ runningId = -1;
188
+ if (node?.kind === "action")
189
+ options.onAbort?.(node.action, ctx, node.params, blackboard);
74
190
  },
75
191
  snapshot() {
76
- return { runningPath: runningPath === null ? null : [...runningPath] };
192
+ const nodeState = {};
193
+ for (const [id, entry] of memory)
194
+ nodeState[id] = { ...entry };
195
+ const cooldownState = {};
196
+ for (const [id, readyAt] of cooldowns)
197
+ cooldownState[id] = readyAt;
198
+ return {
199
+ runningPath: runningId >= 0 ? [...nodes[runningId].path] : null,
200
+ tick: tickCount,
201
+ clock,
202
+ nodes: nodeState,
203
+ cooldowns: cooldownState,
204
+ };
77
205
  },
78
206
  restore(next) {
79
- runningPath = next.runningPath === null ? null : [...next.runningPath];
207
+ runningId = next.runningPath === null ? -1 : idFromPath(next.runningPath);
208
+ tickCount = next.tick ?? 0;
209
+ clock = next.clock ?? 0;
210
+ memory.clear();
211
+ cooldowns.clear();
212
+ for (const [id, entry] of Object.entries(next.nodes ?? {}))
213
+ memory.set(Number(id), { ...entry });
214
+ for (const [id, readyAt] of Object.entries(next.cooldowns ?? {}))
215
+ cooldowns.set(Number(id), readyAt);
80
216
  },
81
217
  };
82
218
  }
@@ -36,4 +36,4 @@ export interface FlockStepAgent {
36
36
  /** Integrate one tick in place: steer every agent, clamp to `maxSpeed`, advance positions.
37
37
  * @internal
38
38
  */
39
- export declare function stepFlock(agents: FlockStepAgent[], config: FlockConfig, dt: number, target?: FlockVec3): void;
39
+ export declare function stepFlock(agents: FlockStepAgent[], config: FlockConfig, dt: number, target?: FlockVec3, acceleration?: (agent: Readonly<FlockStepAgent>, index: number) => FlockVec3): void;
package/dist/ai/flock.js CHANGED
@@ -134,7 +134,7 @@ function fillNeighbors(agents, agentIndex, invCell, gridCells, neighborScratch)
134
134
  /** Integrate one tick in place: steer every agent, clamp to `maxSpeed`, advance positions.
135
135
  * @internal
136
136
  */
137
- export function stepFlock(agents, config, dt, target) {
137
+ export function stepFlock(agents, config, dt, target, acceleration) {
138
138
  const count = agents.length;
139
139
  if (count === 0)
140
140
  return;
@@ -148,9 +148,12 @@ export function stepFlock(agents, config, dt, target) {
148
148
  fillNeighbors(agents, i, invCell, gridCells, neighborScratch);
149
149
  const steer = flockSteer(agents[i], neighborScratch, config, target);
150
150
  const base = i * 3;
151
- steerScratch[base] = steer[0];
152
- steerScratch[base + 1] = steer[1];
153
- steerScratch[base + 2] = steer[2];
151
+ const external = acceleration?.(agents[i], i);
152
+ if (external !== undefined && (external.length !== 3 || external.some((axis) => !Number.isFinite(axis))))
153
+ throw new Error("flock acceleration must contain three finite components");
154
+ steerScratch[base] = steer[0] + (external?.[0] ?? 0);
155
+ steerScratch[base + 1] = steer[1] + (external?.[1] ?? 0);
156
+ steerScratch[base + 2] = steer[2] + (external?.[2] ?? 0);
154
157
  }
155
158
  for (let i = 0; i < count; i += 1) {
156
159
  const agent = agents[i];
@@ -9,12 +9,22 @@ export interface AssistNetworkConfig {
9
9
  shareFraction?: number;
10
10
  distanceBetween?: (a: string, b: string) => number;
11
11
  }
12
+ /** Plain JSON membership of an {@link AssistNetwork}, in registration order; threat lives in each member's own table. */
13
+ export interface AssistNetworkState {
14
+ members: {
15
+ id: string;
16
+ groupId: string;
17
+ }[];
18
+ }
12
19
  export interface AssistNetwork {
13
20
  register(member: AssistMember): void;
14
21
  remove(memberId: string): void;
15
22
  memberIds(groupId?: string): string[];
16
23
  assistersOf(memberId: string): string[];
17
24
  addThreat(memberId: string, sourceId: string, amount: number): string[];
25
+ snapshot(): AssistNetworkState;
26
+ /** Replaces the membership; `tableOf` supplies each member's (separately restored) threat table. */
27
+ restore(next: AssistNetworkState, tableOf: (memberId: string) => ThreatTable): void;
18
28
  }
19
29
  /** @internal */
20
30
  export declare function createAssistNetwork(config?: AssistNetworkConfig): AssistNetwork;
@@ -56,5 +56,16 @@ export function createAssistNetwork(config = {}) {
56
56
  members.get(id).table.add(sourceId, amount * shareFraction);
57
57
  return assisters;
58
58
  },
59
+ snapshot() {
60
+ return { members: order.map((id) => ({ id, groupId: members.get(id).groupId })) };
61
+ },
62
+ restore(next, tableOf) {
63
+ members.clear();
64
+ order.length = 0;
65
+ for (const { id, groupId } of next.members) {
66
+ order.push(id);
67
+ members.set(id, { id, groupId, table: tableOf(id) });
68
+ }
69
+ },
59
70
  };
60
71
  }
@@ -51,6 +51,6 @@ export declare function armPursuit(state: PursuitState, intervalSeconds: number)
51
51
  *
52
52
  * On `"attack"` the caller applies the hit and calls {@link armPursuit} with the next interval.
53
53
  *
54
- * @capability pursuit chase-to-reach cooldown-gated attack with optional leash-to-home; owns the attack cooldown
54
+ * @capability pursuit enemy/mob aggro chase-to-reach with a cooldown-gated attack and optional leash-to-home; owns the attack cooldown
55
55
  */
56
56
  export declare function advancePursuit(state: PursuitState, dt: number, targetDistance: number | null, stopDistance: number, cooldownMode?: CooldownMode, homeDistance?: number, leashRange?: number): PursuitAction;
@@ -36,7 +36,7 @@ function tickCooldown(state, dt) {
36
36
  *
37
37
  * On `"attack"` the caller applies the hit and calls {@link armPursuit} with the next interval.
38
38
  *
39
- * @capability pursuit chase-to-reach cooldown-gated attack with optional leash-to-home; owns the attack cooldown
39
+ * @capability pursuit enemy/mob aggro chase-to-reach with a cooldown-gated attack and optional leash-to-home; owns the attack cooldown
40
40
  */
41
41
  export function advancePursuit(state, dt, targetDistance, stopDistance, cooldownMode = "always", homeDistance = Number.NEGATIVE_INFINITY, leashRange = Number.POSITIVE_INFINITY) {
42
42
  if (cooldownMode === "always")
@@ -11,6 +11,12 @@ export interface HighestThreatOptions {
11
11
  current?: string | null;
12
12
  stickiness?: number;
13
13
  }
14
+ /** Plain JSON state of a {@link ThreatTable}; `entries` keeps insertion order, which breaks ties in `highest`. */
15
+ export interface ThreatTableState {
16
+ entries: [sourceId: string, threat: number][];
17
+ forcedSource: string | null;
18
+ forcedRemaining: number;
19
+ }
14
20
  export interface ThreatTable {
15
21
  add(sourceId: string, amount: number): number;
16
22
  set(sourceId: string, amount: number): void;
@@ -23,5 +29,7 @@ export interface ThreatTable {
23
29
  remove(sourceId: string): void;
24
30
  clear(): void;
25
31
  size(): number;
32
+ snapshot(): ThreatTableState;
33
+ restore(next: ThreatTableState): void;
26
34
  }
27
35
  export declare function createThreatTable(config?: ThreatTableConfig): ThreatTable;
package/dist/ai/threat.js CHANGED
@@ -97,5 +97,15 @@ export function createThreatTable(config = {}) {
97
97
  size() {
98
98
  return table.size;
99
99
  },
100
+ snapshot() {
101
+ return { entries: [...table], forcedSource, forcedRemaining };
102
+ },
103
+ restore(next) {
104
+ table.clear();
105
+ for (const [sourceId, threat] of next.entries)
106
+ table.set(sourceId, threat);
107
+ forcedSource = next.forcedSource;
108
+ forcedRemaining = next.forcedRemaining;
109
+ },
100
110
  };
101
111
  }
@@ -6,6 +6,7 @@ export type AnimParams = Readonly<Record<string, AnimParamValue>>;
6
6
  export type AnimState = {
7
7
  kind: "clip";
8
8
  clip: string;
9
+ variants?: readonly string[];
9
10
  speed?: number;
10
11
  loop?: boolean;
11
12
  rootMotion?: boolean;
@@ -88,11 +89,17 @@ interface LayerTransitionState {
88
89
  duration: number;
89
90
  fromWeights: Record<string, number>;
90
91
  fromTimes: Record<string, number>;
92
+ fromPlayback?: Record<string, {
93
+ speed: number;
94
+ loop: boolean;
95
+ rootMotion?: boolean;
96
+ }>;
91
97
  }
92
98
  interface LayerState {
93
99
  current: string;
94
100
  time: number;
95
101
  transition: LayerTransitionState | null;
102
+ selectedClip?: string;
96
103
  }
97
104
  /** Serializable evaluator state. */
98
105
  export interface AnimGraphState {
@@ -113,7 +120,10 @@ export interface AnimGraphOutput {
113
120
  name: string;
114
121
  clip: string;
115
122
  }[];
123
+ /** Root-bone travel over this advance from `rootMotion` states, in the rig's local units. */
116
124
  rootDelta?: [number, number, number];
125
+ /** `true` while an influencing current or fading-out state has `rootMotion`, even with no travel. */
126
+ rootMotion?: true;
117
127
  }
118
128
  /** The evaluator handle: arm triggers, advance, inspect, snapshot and restore. */
119
129
  export interface AnimGraphRuntime {
@@ -128,6 +138,10 @@ export interface AnimGraphRuntime {
128
138
  stateOf(layerId: string): string | null;
129
139
  advance(dt: number, params: AnimParams, clips: AnimGraphClipInfo): AnimGraphOutput;
130
140
  }
141
+ /** Randomness used only when entering a clip state with variants. Omit to choose the first variant. */
142
+ export interface AnimGraphRuntimeOptions {
143
+ rng?: () => number;
144
+ }
131
145
  /** Entity blackboard key the shell reads extra graph parameters from: `ctx.scene.entity.blackboard.set(id, ANIM_PARAMS_KEY, { aiming: true })`. */
132
146
  export declare const ANIM_PARAMS_KEY = "anim.params";
133
147
  /** Static clip weights of a state at `params`, before any crossfade. */
@@ -140,5 +154,33 @@ export declare function stateClipWeights(state: AnimState, params: AnimParams):
140
154
  *
141
155
  * @capability anim-graph data-first animation state machine with blend trees, crossfades, layers, and clip events
142
156
  */
143
- export declare function createAnimGraphRuntime(initial: AnimGraph): AnimGraphRuntime;
157
+ export declare function createAnimGraphRuntime(initial: AnimGraph, options?: AnimGraphRuntimeOptions): AnimGraphRuntime;
158
+ /**
159
+ * Validates untrusted JSON (a saved scene document, a network payload) as an {@link AnimGraph}.
160
+ * Malformed states, transitions to unknown states, and bad conditions are dropped; a layer whose
161
+ * entry state is missing is dropped; the result is `undefined` when no layer survives.
162
+ *
163
+ * @capability anim-graph load an animation graph from saved JSON without trusting its shape
164
+ */
165
+ export declare function parseAnimGraph(value: unknown): AnimGraph | undefined;
166
+ /** A located, repairable error in an authored animation graph; paths are relative to the graph value. */
167
+ export interface AnimGraphDiagnostic {
168
+ path: string;
169
+ message: string;
170
+ repair: string;
171
+ }
172
+ /** The whole authored graph is retained unchanged only when every supported field is valid. */
173
+ export interface AnimGraphValidation {
174
+ graph: AnimGraph | undefined;
175
+ diagnostics: readonly AnimGraphDiagnostic[];
176
+ }
177
+ /**
178
+ * Validate an authored graph without dropping broken combat states or weakening transition conditions.
179
+ * Known malformed fields and dangling references reject the whole graph with relative repair locations;
180
+ * valid data, including authored object/array order, is returned unchanged. Unknown extension fields are
181
+ * retained. Clip availability belongs to the imported-rig diagnostics. Use {@link parseAnimGraph} when
182
+ * permissive repair is intentional.
183
+ * @capability anim-graph validate authored animation graphs with located repair diagnostics without partial fallback
184
+ */
185
+ export declare function validateAnimGraph(value: unknown): AnimGraphValidation;
144
186
  export {};