@jgengine/core 0.9.0 → 0.11.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 (631) hide show
  1. package/CHANGELOG.md +34 -3
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/spawnDirector.d.ts +19 -1
  21. package/dist/ai/spawnDirector.js +53 -26
  22. package/dist/ai/spawnPoint.d.ts +7 -0
  23. package/dist/ai/spawnPoint.js +7 -0
  24. package/dist/ai/targetAcquisition.d.ts +84 -0
  25. package/dist/ai/targetAcquisition.js +92 -0
  26. package/dist/anim/easing.d.ts +19 -0
  27. package/dist/anim/easing.js +19 -0
  28. package/dist/anim/oscillator.d.ts +12 -0
  29. package/dist/anim/oscillator.js +25 -0
  30. package/dist/area/areaEffectField.d.ts +127 -0
  31. package/dist/area/areaEffectField.js +175 -0
  32. package/dist/area/stackPolicy.d.ts +47 -0
  33. package/dist/area/stackPolicy.js +99 -0
  34. package/dist/audio/audioFalloff.d.ts +5 -2
  35. package/dist/audio/music.d.ts +53 -0
  36. package/dist/audio/music.js +34 -0
  37. package/dist/audio/synth.d.ts +60 -0
  38. package/dist/audio/synth.js +8 -0
  39. package/dist/authoring.d.ts +15 -0
  40. package/dist/authoring.js +15 -0
  41. package/dist/board/laneBoard.d.ts +13 -0
  42. package/dist/board/laneBoard.js +13 -0
  43. package/dist/board/timelineBoard.d.ts +10 -0
  44. package/dist/board/timelineBoard.js +10 -0
  45. package/dist/combat/abilityKit.d.ts +18 -0
  46. package/dist/combat/abilityKit.js +24 -9
  47. package/dist/combat/animationState.d.ts +5 -0
  48. package/dist/combat/animationState.js +5 -0
  49. package/dist/combat/breakMeters.d.ts +10 -0
  50. package/dist/combat/breakMeters.js +10 -0
  51. package/dist/combat/castRunner.d.ts +5 -0
  52. package/dist/combat/castRunner.js +5 -0
  53. package/dist/combat/comboPoints.d.ts +5 -0
  54. package/dist/combat/comboPoints.js +5 -0
  55. package/dist/combat/comboString.d.ts +5 -0
  56. package/dist/combat/comboString.js +5 -0
  57. package/dist/combat/damageInterceptors.d.ts +192 -0
  58. package/dist/combat/damageInterceptors.js +251 -0
  59. package/dist/combat/damageMatchup.d.ts +68 -0
  60. package/dist/combat/damageMatchup.js +42 -0
  61. package/dist/combat/damageResolution.d.ts +63 -0
  62. package/dist/combat/damageResolution.js +50 -0
  63. package/dist/combat/death.d.ts +7 -1
  64. package/dist/combat/death.js +5 -0
  65. package/dist/combat/deathReason.d.ts +14 -0
  66. package/dist/combat/deathReason.js +1 -0
  67. package/dist/combat/defensiveWindow.d.ts +5 -0
  68. package/dist/combat/defensiveWindow.js +5 -0
  69. package/dist/combat/dotField.d.ts +47 -0
  70. package/dist/combat/dotField.js +52 -0
  71. package/dist/combat/downed.d.ts +5 -0
  72. package/dist/combat/downed.js +5 -0
  73. package/dist/combat/effects.d.ts +5 -0
  74. package/dist/combat/effects.js +5 -0
  75. package/dist/combat/encounterSequence.d.ts +258 -0
  76. package/dist/combat/encounterSequence.js +426 -0
  77. package/dist/combat/hitReaction.d.ts +57 -1
  78. package/dist/combat/hitReaction.js +45 -5
  79. package/dist/combat/magazine.d.ts +54 -0
  80. package/dist/combat/magazine.js +96 -0
  81. package/dist/combat/projectiles.d.ts +7 -2
  82. package/dist/combat/projectiles.js +48 -17
  83. package/dist/combat/receivedDamage.d.ts +117 -0
  84. package/dist/combat/receivedDamage.js +92 -0
  85. package/dist/combat/regenShield.d.ts +39 -0
  86. package/dist/combat/regenShield.js +49 -0
  87. package/dist/combat/renderCues.d.ts +51 -0
  88. package/dist/combat/renderCues.js +44 -0
  89. package/dist/combat/resourcePool.d.ts +5 -0
  90. package/dist/combat/resourcePool.js +5 -0
  91. package/dist/combat/rewardAllocation.d.ts +121 -0
  92. package/dist/combat/rewardAllocation.js +251 -0
  93. package/dist/combat/shotOrigin.d.ts +30 -1
  94. package/dist/combat/shotOrigin.js +70 -2
  95. package/dist/combat/statusApplication.d.ts +96 -0
  96. package/dist/combat/statusApplication.js +81 -0
  97. package/dist/combat/telegraph.d.ts +11 -2
  98. package/dist/combat/telegraph.js +11 -2
  99. package/dist/combat/thresholdCrossings.d.ts +85 -0
  100. package/dist/combat/thresholdCrossings.js +116 -0
  101. package/dist/combat.d.ts +34 -0
  102. package/dist/combat.js +34 -0
  103. package/dist/commands/commandRegistry.d.ts +11 -0
  104. package/dist/commands/commandRegistry.js +9 -2
  105. package/dist/crafting/crop.d.ts +18 -0
  106. package/dist/crafting/crop.js +18 -0
  107. package/dist/crafting/production.d.ts +5 -0
  108. package/dist/crafting/production.js +5 -0
  109. package/dist/devtools/rewriteTunables.d.ts +17 -0
  110. package/dist/devtools/rewriteTunables.js +276 -0
  111. package/dist/devtools/saveEndpoint.d.ts +46 -0
  112. package/dist/devtools/saveEndpoint.js +48 -0
  113. package/dist/devtools/transformTunables.d.ts +3 -0
  114. package/dist/devtools/transformTunables.js +3 -0
  115. package/dist/devtools/tunableSchema.d.ts +31 -0
  116. package/dist/devtools/tunableSchema.js +31 -0
  117. package/dist/economy/currency.d.ts +12 -1
  118. package/dist/economy/currency.js +12 -1
  119. package/dist/economy/listingBook.d.ts +91 -0
  120. package/dist/economy/listingBook.js +144 -0
  121. package/dist/economy/resourceLedger.d.ts +222 -0
  122. package/dist/economy/resourceLedger.js +353 -0
  123. package/dist/economy/sharedWallet.d.ts +14 -0
  124. package/dist/economy/sharedWallet.js +14 -0
  125. package/dist/economy/techTree.d.ts +12 -0
  126. package/dist/economy/techTree.js +12 -0
  127. package/dist/economy/wallet.d.ts +26 -2
  128. package/dist/economy/wallet.js +35 -6
  129. package/dist/editor/commands.d.ts +248 -0
  130. package/dist/editor/commands.js +865 -0
  131. package/dist/editor/document.d.ts +186 -0
  132. package/dist/editor/document.js +884 -0
  133. package/dist/editor/grid.d.ts +229 -0
  134. package/dist/editor/grid.js +366 -0
  135. package/dist/editor/gridAdapters.d.ts +80 -0
  136. package/dist/editor/gridAdapters.js +134 -0
  137. package/dist/editor/index.d.ts +97 -0
  138. package/dist/editor/index.js +10 -0
  139. package/dist/editor/liveSync.d.ts +127 -0
  140. package/dist/editor/liveSync.js +249 -0
  141. package/dist/editor/runtimeInspector.d.ts +88 -0
  142. package/dist/editor/runtimeInspector.js +239 -0
  143. package/dist/editor/types.d.ts +175 -0
  144. package/dist/editor/types.js +29 -0
  145. package/dist/faction/reputation.d.ts +5 -0
  146. package/dist/faction/reputation.js +5 -0
  147. package/dist/format/distance.d.ts +17 -0
  148. package/dist/format/distance.js +18 -0
  149. package/dist/format/duration.d.ts +27 -0
  150. package/dist/format/duration.js +45 -0
  151. package/dist/format/speed.d.ts +17 -0
  152. package/dist/format/speed.js +25 -0
  153. package/dist/game/connectedPlayers.d.ts +30 -0
  154. package/dist/game/connectedPlayers.js +21 -0
  155. package/dist/game/cosmetics.d.ts +9 -0
  156. package/dist/game/cosmetics.js +16 -0
  157. package/dist/game/defineGame.d.ts +141 -2
  158. package/dist/game/defineGame.js +39 -1
  159. package/dist/game/defineSystem.d.ts +88 -0
  160. package/dist/game/defineSystem.js +45 -0
  161. package/dist/game/dialogue.d.ts +33 -0
  162. package/dist/game/dialogue.js +21 -0
  163. package/dist/game/events.d.ts +50 -13
  164. package/dist/game/events.js +5 -0
  165. package/dist/game/feed.d.ts +33 -0
  166. package/dist/game/feed.js +35 -2
  167. package/dist/game/gamePhase.d.ts +11 -0
  168. package/dist/game/gamePhase.js +16 -0
  169. package/dist/game/keyValueStore.d.ts +25 -0
  170. package/dist/game/keyValueStore.js +61 -0
  171. package/dist/game/leaderboard.d.ts +5 -0
  172. package/dist/game/leaderboard.js +5 -0
  173. package/dist/game/levelSequence.d.ts +24 -2
  174. package/dist/game/levelSequence.js +51 -2
  175. package/dist/game/loadout.d.ts +5 -0
  176. package/dist/game/loadout.js +5 -0
  177. package/dist/game/lootFilter.d.ts +2 -0
  178. package/dist/game/lootFilter.js +2 -0
  179. package/dist/game/lootPipeline.d.ts +164 -0
  180. package/dist/game/lootPipeline.js +216 -0
  181. package/dist/game/lootTable.d.ts +21 -0
  182. package/dist/game/lootTable.js +15 -4
  183. package/dist/game/modelAnimation.d.ts +8 -0
  184. package/dist/game/modelAnimation.js +18 -0
  185. package/dist/game/objectives.d.ts +43 -0
  186. package/dist/game/objectives.js +36 -0
  187. package/dist/game/paramLayers.d.ts +148 -0
  188. package/dist/game/paramLayers.js +185 -0
  189. package/dist/game/ping.d.ts +5 -0
  190. package/dist/game/ping.js +5 -0
  191. package/dist/game/playableGame.d.ts +160 -12
  192. package/dist/game/quest.d.ts +8 -0
  193. package/dist/game/quest.js +29 -0
  194. package/dist/game/race.d.ts +141 -0
  195. package/dist/game/race.js +169 -0
  196. package/dist/game/recordBook.d.ts +5 -5
  197. package/dist/game/recordBook.js +4 -1
  198. package/dist/game/ruleSelection.d.ts +75 -0
  199. package/dist/game/ruleSelection.js +127 -0
  200. package/dist/game/runDraft.d.ts +5 -0
  201. package/dist/game/runDraft.js +5 -0
  202. package/dist/game/saveStore.d.ts +111 -0
  203. package/dist/game/saveStore.js +312 -0
  204. package/dist/game/snapshotHistory.d.ts +67 -0
  205. package/dist/game/snapshotHistory.js +95 -0
  206. package/dist/game/social.d.ts +38 -1
  207. package/dist/game/social.js +71 -0
  208. package/dist/game/spawnPoints.d.ts +5 -0
  209. package/dist/game/spawnPoints.js +5 -0
  210. package/dist/game/systemRuntime.d.ts +50 -0
  211. package/dist/game/systemRuntime.js +157 -0
  212. package/dist/game/systemSchedule.d.ts +72 -0
  213. package/dist/game/systemSchedule.js +242 -0
  214. package/dist/game/toasts.d.ts +43 -0
  215. package/dist/game/toasts.js +44 -0
  216. package/dist/game/trade.d.ts +10 -0
  217. package/dist/game/trade.js +10 -0
  218. package/dist/game/unlocks.d.ts +8 -0
  219. package/dist/game/unlocks.js +16 -0
  220. package/dist/game/vfxInstance.d.ts +138 -0
  221. package/dist/game/vfxInstance.js +96 -0
  222. package/dist/game/worldItem.d.ts +17 -4
  223. package/dist/game/worldItem.js +17 -4
  224. package/dist/gameplay.d.ts +91 -0
  225. package/dist/gameplay.js +91 -0
  226. package/dist/index.d.ts +5 -7
  227. package/dist/index.js +5 -7
  228. package/dist/input/actionBindings.d.ts +24 -5
  229. package/dist/input/actionBindings.js +23 -5
  230. package/dist/input/axisInput.d.ts +13 -1
  231. package/dist/input/axisInput.js +22 -1
  232. package/dist/input/controlGroups.d.ts +67 -0
  233. package/dist/input/controlGroups.js +41 -0
  234. package/dist/input/touchScheme.d.ts +82 -6
  235. package/dist/input/touchScheme.js +123 -10
  236. package/dist/interaction/contextMenu.d.ts +1 -0
  237. package/dist/interaction/contextMenu.js +1 -0
  238. package/dist/interaction/lockpick.d.ts +61 -0
  239. package/dist/interaction/lockpick.js +168 -0
  240. package/dist/interaction/proximityPrompt.d.ts +5 -1
  241. package/dist/interaction/proximityPrompt.js +5 -3
  242. package/dist/interaction/qte.d.ts +5 -0
  243. package/dist/interaction/qte.js +5 -0
  244. package/dist/interaction/skillCheck.d.ts +5 -0
  245. package/dist/interaction/skillCheck.js +5 -0
  246. package/dist/inventory/inventoryModel.d.ts +12 -0
  247. package/dist/inventory/inventoryModel.js +12 -0
  248. package/dist/inventory/shapedGrid.d.ts +16 -0
  249. package/dist/inventory/shapedGrid.js +16 -0
  250. package/dist/inventory/slotModel.d.ts +10 -0
  251. package/dist/inventory/slotModel.js +10 -0
  252. package/dist/item/durability.d.ts +5 -0
  253. package/dist/item/durability.js +5 -0
  254. package/dist/item/itemIdentity.d.ts +171 -0
  255. package/dist/item/itemIdentity.js +138 -0
  256. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  257. package/dist/item/itemInstanceRegistry.js +34 -0
  258. package/dist/item/itemgen.d.ts +163 -0
  259. package/dist/item/itemgen.js +151 -0
  260. package/dist/item/modularItem.d.ts +5 -0
  261. package/dist/item/modularItem.js +5 -0
  262. package/dist/item/use.d.ts +5 -0
  263. package/dist/item/use.js +5 -0
  264. package/dist/item/useBehavior.d.ts +142 -0
  265. package/dist/item/useBehavior.js +105 -0
  266. package/dist/item/weapon.d.ts +5 -0
  267. package/dist/item/weapon.js +5 -0
  268. package/dist/math/scalar.d.ts +25 -0
  269. package/dist/math/scalar.js +47 -0
  270. package/dist/meta/changelog.d.ts +4 -1
  271. package/dist/meta/changelog.js +36 -1
  272. package/dist/movement/avoidance.d.ts +45 -0
  273. package/dist/movement/avoidance.js +123 -0
  274. package/dist/movement/cameraRig.d.ts +8 -0
  275. package/dist/movement/cameraRig.js +8 -0
  276. package/dist/movement/dash.d.ts +11 -0
  277. package/dist/movement/dash.js +11 -0
  278. package/dist/movement/formation.d.ts +135 -0
  279. package/dist/movement/formation.js +194 -0
  280. package/dist/movement/glideModel.d.ts +5 -0
  281. package/dist/movement/glideModel.js +5 -0
  282. package/dist/movement/grappleSwing.d.ts +5 -0
  283. package/dist/movement/grappleSwing.js +5 -0
  284. package/dist/movement/leaderTrail.d.ts +5 -0
  285. package/dist/movement/leaderTrail.js +5 -0
  286. package/dist/movement/movementModel.d.ts +38 -7
  287. package/dist/movement/movementModel.js +54 -13
  288. package/dist/movement/playerMovement.d.ts +41 -0
  289. package/dist/movement/playerMovement.js +236 -0
  290. package/dist/movement/poseState.d.ts +13 -0
  291. package/dist/movement/poseState.js +16 -0
  292. package/dist/movement/steering.d.ts +8 -0
  293. package/dist/movement/steering.js +18 -0
  294. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  295. package/dist/multiplayer/combatSnapshot.js +3 -0
  296. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  297. package/dist/multiplayer/lagCompensation.js +5 -0
  298. package/dist/multiplayer/presenceModel.d.ts +9 -1
  299. package/dist/multiplayer/presenceModel.js +9 -1
  300. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  301. package/dist/multiplayer/simultaneousCommit.js +3 -0
  302. package/dist/multiplayer.d.ts +11 -0
  303. package/dist/multiplayer.js +11 -0
  304. package/dist/nav/pathFollow.d.ts +57 -0
  305. package/dist/nav/pathFollow.js +109 -0
  306. package/dist/orders/orderKinds.d.ts +156 -0
  307. package/dist/orders/orderKinds.js +197 -0
  308. package/dist/orders/orderQueue.d.ts +208 -0
  309. package/dist/orders/orderQueue.js +211 -0
  310. package/dist/physics/drivableVehicle.d.ts +29 -0
  311. package/dist/physics/drivableVehicle.js +16 -0
  312. package/dist/physics/kinematicVehicle.d.ts +21 -1
  313. package/dist/physics/kinematicVehicle.js +23 -8
  314. package/dist/physics/physicsWorld.d.ts +24 -12
  315. package/dist/physics/physicsWorld.js +11 -5
  316. package/dist/physics/radialImpulse.d.ts +25 -0
  317. package/dist/physics/radialImpulse.js +27 -0
  318. package/dist/procedural.d.ts +3 -0
  319. package/dist/procedural.js +3 -0
  320. package/dist/progression/statGraph.d.ts +116 -0
  321. package/dist/progression/statGraph.js +318 -0
  322. package/dist/puzzle/cellGrid.d.ts +9 -0
  323. package/dist/puzzle/cellGrid.js +9 -0
  324. package/dist/puzzle/fallingPiece.d.ts +9 -0
  325. package/dist/puzzle/fallingPiece.js +9 -0
  326. package/dist/puzzle/nonogram.d.ts +39 -0
  327. package/dist/puzzle/nonogram.js +136 -0
  328. package/dist/random/nameGen.d.ts +5 -0
  329. package/dist/random/nameGen.js +5 -0
  330. package/dist/random/pick.d.ts +8 -0
  331. package/dist/random/pick.js +31 -0
  332. package/dist/random/rng.d.ts +24 -0
  333. package/dist/random/rng.js +30 -8
  334. package/dist/random/seedLink.d.ts +4 -0
  335. package/dist/random/seedLink.js +4 -0
  336. package/dist/relation/keyedValues.d.ts +54 -0
  337. package/dist/relation/keyedValues.js +115 -0
  338. package/dist/relation/thresholds.d.ts +62 -0
  339. package/dist/relation/thresholds.js +62 -0
  340. package/dist/render/color.d.ts +12 -0
  341. package/dist/render/color.js +26 -0
  342. package/dist/render/lookPreset.d.ts +41 -0
  343. package/dist/render/lookPreset.js +29 -0
  344. package/dist/render/postProcessing.d.ts +76 -0
  345. package/dist/render/postProcessing.js +21 -0
  346. package/dist/rules/predicate.d.ts +53 -0
  347. package/dist/rules/predicate.js +64 -0
  348. package/dist/rules/ruleEffects.d.ts +38 -0
  349. package/dist/rules/ruleEffects.js +37 -0
  350. package/dist/rules/triggeredRules.d.ts +160 -0
  351. package/dist/rules/triggeredRules.js +241 -0
  352. package/dist/runtime/adapter.d.ts +58 -0
  353. package/dist/runtime/adapter.js +54 -5
  354. package/dist/runtime/cameraDirector.d.ts +1 -0
  355. package/dist/runtime/cameraDirector.js +1 -0
  356. package/dist/runtime/commandRunner.d.ts +1 -0
  357. package/dist/runtime/commandRunner.js +1 -0
  358. package/dist/runtime/context/combatFx.d.ts +23 -0
  359. package/dist/runtime/context/combatFx.js +161 -0
  360. package/dist/runtime/context/registries.d.ts +13 -0
  361. package/dist/runtime/context/registries.js +84 -0
  362. package/dist/runtime/context/worldItems.d.ts +21 -0
  363. package/dist/runtime/context/worldItems.js +37 -0
  364. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  365. package/dist/runtime/descriptors/baseline.js +134 -0
  366. package/dist/runtime/descriptors/features.d.ts +74 -0
  367. package/dist/runtime/descriptors/features.js +281 -0
  368. package/dist/runtime/gameContext.d.ts +163 -19
  369. package/dist/runtime/gameContext.js +385 -339
  370. package/dist/runtime/gameRuntime.d.ts +1 -0
  371. package/dist/runtime/gameRuntime.js +1 -0
  372. package/dist/runtime/headlessRunner.d.ts +60 -0
  373. package/dist/runtime/headlessRunner.js +44 -0
  374. package/dist/runtime/hostPersistence.d.ts +12 -0
  375. package/dist/runtime/hostPersistence.js +12 -0
  376. package/dist/runtime/hostedGameRunner.d.ts +54 -0
  377. package/dist/runtime/hostedGameRunner.js +85 -0
  378. package/dist/runtime/hostedWorldSession.d.ts +73 -0
  379. package/dist/runtime/hostedWorldSession.js +64 -0
  380. package/dist/runtime/inputSnapshot.d.ts +21 -3
  381. package/dist/runtime/inputSnapshot.js +8 -2
  382. package/dist/runtime/motionIntents.d.ts +12 -1
  383. package/dist/runtime/motionIntents.js +26 -1
  384. package/dist/runtime/perContext.d.ts +15 -0
  385. package/dist/runtime/perContext.js +21 -0
  386. package/dist/runtime/runtimeSave.d.ts +79 -0
  387. package/dist/runtime/runtimeSave.js +105 -0
  388. package/dist/runtime/save.d.ts +4 -0
  389. package/dist/runtime/save.js +4 -0
  390. package/dist/runtime/snapshot.d.ts +7 -0
  391. package/dist/runtime/snapshot.js +7 -0
  392. package/dist/runtime/visibility.d.ts +2 -1
  393. package/dist/runtime/visibility.js +2 -1
  394. package/dist/runtime/worldChannel.d.ts +62 -0
  395. package/dist/runtime/worldChannel.js +114 -0
  396. package/dist/runtime/worldMirror.d.ts +36 -0
  397. package/dist/runtime/worldMirror.js +44 -0
  398. package/dist/runtime/worldProjection.d.ts +47 -0
  399. package/dist/runtime/worldProjection.js +52 -0
  400. package/dist/runtime/worldReplication.d.ts +69 -0
  401. package/dist/runtime/worldReplication.js +217 -0
  402. package/dist/runtime/worldSnapshot.d.ts +44 -0
  403. package/dist/runtime/worldSnapshot.js +30 -0
  404. package/dist/scene/assetCatalog.d.ts +22 -0
  405. package/dist/scene/assetCatalog.js +4 -0
  406. package/dist/scene/assetDiagnostics.d.ts +69 -0
  407. package/dist/scene/assetDiagnostics.js +110 -0
  408. package/dist/scene/assetGenerator.d.ts +65 -0
  409. package/dist/scene/assetGenerator.js +64 -0
  410. package/dist/scene/assetSpace.d.ts +137 -0
  411. package/dist/scene/assetSpace.js +259 -0
  412. package/dist/scene/authoredTriggers.d.ts +169 -0
  413. package/dist/scene/authoredTriggers.js +340 -0
  414. package/dist/scene/behaviorRuntime.d.ts +75 -0
  415. package/dist/scene/behaviorRuntime.js +217 -0
  416. package/dist/scene/behaviors.d.ts +14 -2
  417. package/dist/scene/behaviors.js +7 -2
  418. package/dist/scene/bodyBind.d.ts +60 -0
  419. package/dist/scene/bodyBind.js +51 -0
  420. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  421. package/dist/scene/builtinSceneKinds.js +62 -0
  422. package/dist/scene/colliders.d.ts +18 -0
  423. package/dist/scene/colliders.js +61 -1
  424. package/dist/scene/entityStats.d.ts +13 -0
  425. package/dist/scene/entityStats.js +30 -0
  426. package/dist/scene/entityStore.d.ts +41 -1
  427. package/dist/scene/entityStore.js +75 -0
  428. package/dist/scene/facing.d.ts +18 -0
  429. package/dist/scene/facing.js +26 -0
  430. package/dist/scene/modelSockets.d.ts +33 -0
  431. package/dist/scene/modelSockets.js +29 -0
  432. package/dist/scene/objectQuery.d.ts +2 -0
  433. package/dist/scene/objectQuery.js +2 -0
  434. package/dist/scene/objectStore.d.ts +4 -0
  435. package/dist/scene/objectStore.js +6 -0
  436. package/dist/scene/possession.d.ts +8 -0
  437. package/dist/scene/possession.js +14 -0
  438. package/dist/scene/roster.d.ts +3 -0
  439. package/dist/scene/roster.js +12 -0
  440. package/dist/scene/sceneKinds.d.ts +240 -0
  441. package/dist/scene/sceneKinds.js +214 -0
  442. package/dist/scene/sceneOwnership.d.ts +169 -0
  443. package/dist/scene/sceneOwnership.js +179 -0
  444. package/dist/scene/selectionBookmarks.d.ts +93 -0
  445. package/dist/scene/selectionBookmarks.js +122 -0
  446. package/dist/scene/vehicleSeat.d.ts +68 -0
  447. package/dist/scene/vehicleSeat.js +59 -0
  448. package/dist/sensor/concealment.d.ts +3 -0
  449. package/dist/sensor/concealment.js +3 -0
  450. package/dist/sensor/freezeMonitor.d.ts +1 -0
  451. package/dist/sensor/freezeMonitor.js +1 -0
  452. package/dist/sensor/frustumSensor.d.ts +7 -3
  453. package/dist/sensor/frustumSensor.js +7 -3
  454. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  455. package/dist/sensor/hiddenStateProbe.js +5 -2
  456. package/dist/sensor/recordingBuffer.d.ts +2 -1
  457. package/dist/sensor/recordingBuffer.js +2 -1
  458. package/dist/sensor/replayLoop.d.ts +6 -2
  459. package/dist/sensor/replayLoop.js +6 -2
  460. package/dist/sensor/revealQuery.d.ts +2 -1
  461. package/dist/sensor/revealQuery.js +2 -1
  462. package/dist/sensor/visionCone.d.ts +10 -3
  463. package/dist/sensor/visionCone.js +10 -3
  464. package/dist/session/contestedChannel.d.ts +1 -0
  465. package/dist/session/contestedChannel.js +1 -0
  466. package/dist/session/extraction.d.ts +1 -0
  467. package/dist/session/extraction.js +1 -0
  468. package/dist/session/roles.d.ts +6 -0
  469. package/dist/session/roles.js +6 -0
  470. package/dist/session/roundState.d.ts +8 -0
  471. package/dist/session/roundState.js +2 -0
  472. package/dist/settings/settingsModel.d.ts +1 -0
  473. package/dist/settings/settingsModel.js +1 -0
  474. package/dist/stats/accumulatorMeter.d.ts +6 -0
  475. package/dist/stats/accumulatorMeter.js +6 -0
  476. package/dist/stats/eventMeter.d.ts +5 -0
  477. package/dist/stats/eventMeter.js +5 -0
  478. package/dist/stats/rollCheck.d.ts +5 -0
  479. package/dist/stats/rollCheck.js +5 -0
  480. package/dist/stats/statModifiers.d.ts +5 -0
  481. package/dist/stats/statModifiers.js +5 -0
  482. package/dist/store/defineKeyedStore.d.ts +38 -0
  483. package/dist/store/defineKeyedStore.js +42 -0
  484. package/dist/store/defineStore.d.ts +33 -0
  485. package/dist/store/defineStore.js +35 -0
  486. package/dist/store/observableKeyedStore.d.ts +9 -0
  487. package/dist/store/observableKeyedStore.js +43 -2
  488. package/dist/survival/decayMeter.d.ts +55 -0
  489. package/dist/survival/decayMeter.js +130 -55
  490. package/dist/survival/moodle.d.ts +2 -0
  491. package/dist/survival/regionHealth.d.ts +6 -0
  492. package/dist/survival/regionHealth.js +5 -0
  493. package/dist/tactics/fallingGrid.d.ts +6 -4
  494. package/dist/tactics/fallingGrid.js +6 -4
  495. package/dist/tactics/predictiveQuery.d.ts +3 -0
  496. package/dist/tactics/predictiveQuery.js +3 -0
  497. package/dist/tactics/snapshot.d.ts +2 -0
  498. package/dist/tactics/snapshot.js +2 -0
  499. package/dist/tactics/surface.d.ts +1 -0
  500. package/dist/tactics/surface.js +1 -0
  501. package/dist/tactics/tacticalGrid.d.ts +1 -0
  502. package/dist/tactics/tacticalGrid.js +1 -0
  503. package/dist/time/beatClock.d.ts +14 -4
  504. package/dist/time/beatClock.js +14 -4
  505. package/dist/time/calendarClock.d.ts +3 -0
  506. package/dist/time/calendarClock.js +3 -0
  507. package/dist/time/idleProgress.d.ts +4 -0
  508. package/dist/time/idleProgress.js +4 -0
  509. package/dist/time/simClock.d.ts +2 -0
  510. package/dist/time/simClock.js +20 -5
  511. package/dist/ui/actionModel.d.ts +110 -0
  512. package/dist/ui/actionModel.js +159 -0
  513. package/dist/ui/gameLayout.d.ts +144 -0
  514. package/dist/ui/gameLayout.js +148 -0
  515. package/dist/ui/hudDocument.d.ts +114 -0
  516. package/dist/ui/hudDocument.js +220 -0
  517. package/dist/ui/hudLayout.d.ts +33 -1
  518. package/dist/ui/hudLayout.js +204 -17
  519. package/dist/ui/orientation.d.ts +39 -0
  520. package/dist/ui/orientation.js +49 -0
  521. package/dist/ui/selectionModel.d.ts +92 -0
  522. package/dist/ui/selectionModel.js +88 -0
  523. package/dist/ui/swingTimer.d.ts +42 -0
  524. package/dist/ui/swingTimer.js +38 -0
  525. package/dist/ui/tooltipModel.d.ts +63 -0
  526. package/dist/ui/tooltipModel.js +82 -0
  527. package/dist/ui.d.ts +15 -0
  528. package/dist/ui.js +15 -0
  529. package/dist/visibility/bounds.d.ts +8 -1
  530. package/dist/visibility/bounds.js +8 -1
  531. package/dist/visibility/frustum.d.ts +12 -3
  532. package/dist/visibility/frustum.js +12 -3
  533. package/dist/visibility/spatialIndex.js +34 -20
  534. package/dist/work/jobQueue.d.ts +201 -0
  535. package/dist/work/jobQueue.js +253 -0
  536. package/dist/work/unitTraining.d.ts +58 -0
  537. package/dist/work/unitTraining.js +52 -0
  538. package/dist/world/authoredObjects.d.ts +58 -0
  539. package/dist/world/authoredObjects.js +69 -0
  540. package/dist/world/buildingGenerator.d.ts +18 -0
  541. package/dist/world/buildingGenerator.js +62 -0
  542. package/dist/world/buildings.d.ts +5 -0
  543. package/dist/world/buildings.js +5 -0
  544. package/dist/world/catenary.d.ts +22 -0
  545. package/dist/world/catenary.js +69 -0
  546. package/dist/world/environmentSummary.d.ts +11 -2
  547. package/dist/world/environmentSummary.js +11 -1
  548. package/dist/world/features.d.ts +244 -7
  549. package/dist/world/features.js +92 -4
  550. package/dist/world/footprintGrid.d.ts +59 -0
  551. package/dist/world/footprintGrid.js +141 -0
  552. package/dist/world/geometry.d.ts +64 -0
  553. package/dist/world/geometry.js +94 -0
  554. package/dist/world/grassKind.d.ts +51 -0
  555. package/dist/world/grassKind.js +101 -0
  556. package/dist/world/pathInstances.d.ts +27 -0
  557. package/dist/world/pathInstances.js +27 -0
  558. package/dist/world/pathTerrain.d.ts +80 -0
  559. package/dist/world/pathTerrain.js +142 -0
  560. package/dist/world/placeAsset.d.ts +81 -0
  561. package/dist/world/placeAsset.js +77 -0
  562. package/dist/world/placement.d.ts +4 -0
  563. package/dist/world/placement.js +4 -0
  564. package/dist/world/placementController.d.ts +6 -0
  565. package/dist/world/placementController.js +6 -0
  566. package/dist/world/polyline.d.ts +34 -0
  567. package/dist/world/polyline.js +81 -0
  568. package/dist/world/roads.d.ts +55 -0
  569. package/dist/world/roads.js +184 -0
  570. package/dist/world/scatterRegion.d.ts +164 -0
  571. package/dist/world/scatterRegion.js +409 -0
  572. package/dist/world/sceneShapes.d.ts +43 -0
  573. package/dist/world/sceneShapes.js +1 -0
  574. package/dist/world/segment.d.ts +27 -0
  575. package/dist/world/segment.js +43 -0
  576. package/dist/world/soilKind.d.ts +48 -0
  577. package/dist/world/soilKind.js +92 -0
  578. package/dist/world/spatialSample.d.ts +241 -0
  579. package/dist/world/spatialSample.js +465 -0
  580. package/dist/world/streets.d.ts +80 -0
  581. package/dist/world/streets.js +144 -0
  582. package/dist/world/terraform.d.ts +213 -1
  583. package/dist/world/terraform.js +655 -20
  584. package/dist/world/terrain.d.ts +138 -12
  585. package/dist/world/terrain.js +346 -28
  586. package/dist/world/terrainGuides.d.ts +182 -0
  587. package/dist/world/terrainGuides.js +343 -0
  588. package/dist/world/vec2.d.ts +81 -0
  589. package/dist/world/vec2.js +128 -0
  590. package/dist/world/vec3.d.ts +49 -0
  591. package/dist/world/vec3.js +76 -0
  592. package/dist/world/vegetation.d.ts +71 -0
  593. package/dist/world/vegetation.js +151 -0
  594. package/dist/world/visibilityField.d.ts +154 -0
  595. package/dist/world/visibilityField.js +271 -0
  596. package/dist/world/volumetricClouds.d.ts +52 -0
  597. package/dist/world/volumetricClouds.js +43 -0
  598. package/dist/world/walls.d.ts +9 -0
  599. package/dist/world/walls.js +9 -0
  600. package/dist/world/waterKind.d.ts +55 -0
  601. package/dist/world/waterKind.js +99 -0
  602. package/dist/world.d.ts +132 -0
  603. package/dist/world.js +132 -0
  604. package/package.json +32 -8
  605. package/skills/jgengine/SKILL.md +51 -0
  606. package/skills/jgengine/api.md +434 -0
  607. package/skills/jgengine/capabilities.md +29 -0
  608. package/skills/jgengine/reference-cartridge.md +72 -0
  609. package/skills/jgengine-combat/SKILL.md +34 -0
  610. package/skills/jgengine-combat/api.md +549 -0
  611. package/skills/jgengine-combat/capabilities.md +169 -0
  612. package/skills/jgengine-combat/reference.md +98 -0
  613. package/skills/jgengine-gameplay/SKILL.md +39 -0
  614. package/skills/jgengine-gameplay/api.md +1794 -0
  615. package/skills/jgengine-gameplay/capabilities.md +378 -0
  616. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  617. package/skills/jgengine-world/SKILL.md +38 -0
  618. package/skills/jgengine-world/api.md +2652 -0
  619. package/skills/jgengine-world/capabilities.md +370 -0
  620. package/skills/jgengine-world/reference.md +222 -0
  621. package/dist/cartridge/runtime.d.ts +0 -15
  622. package/dist/cartridge/runtime.js +0 -556
  623. package/dist/cartridge/spec.d.ts +0 -188
  624. package/dist/cartridge/spec.js +0 -19
  625. package/dist/cartridge/validate.d.ts +0 -2
  626. package/dist/cartridge/validate.js +0 -78
  627. package/dist/store/engineStore.d.ts +0 -22
  628. package/dist/store/engineStore.js +0 -50
  629. package/dist/store/features.d.ts +0 -10
  630. package/dist/store/features.js +0 -23
  631. package/llms.txt +0 -4983
@@ -0,0 +1,217 @@
1
+ import { seededRng } from "../random/rng.js";
2
+ import { advancePathFollow, createPathFollow, pathFollowSeek, } from "../nav/pathFollow.js";
3
+ import { perContext } from "../runtime/perContext.js";
4
+ const DEFAULT_WANDER_SPEED = 1.5;
5
+ const WANDER_ARRIVAL = 0.6;
6
+ function patrolOf(entity) {
7
+ return entity.behaviors.find((b) => b.kind === "patrol") ?? null;
8
+ }
9
+ function wanderOf(entity) {
10
+ return entity.behaviors.find((b) => b.kind === "wander") ?? null;
11
+ }
12
+ const runtimeOf = perContext((ctx) => {
13
+ const nav = new Map();
14
+ const refresh = () => {
15
+ const live = new Set();
16
+ for (const entity of ctx.scene.entity.list()) {
17
+ live.add(entity.id);
18
+ if (nav.has(entity.id))
19
+ continue;
20
+ const patrol = patrolOf(entity);
21
+ if (patrol !== null) {
22
+ const config = { waypoints: patrol.waypoints, speed: patrol.speed, loop: patrol.loop };
23
+ nav.set(entity.id, {
24
+ kind: "patrol",
25
+ config,
26
+ state: patrol.startProgress !== undefined ? pathFollowSeek(config, patrol.startProgress) : createPathFollow(config),
27
+ groundClamp: patrol.groundClamp ?? false,
28
+ status: "active",
29
+ reason: null,
30
+ pausedElapsed: 0,
31
+ });
32
+ continue;
33
+ }
34
+ const wander = wanderOf(entity);
35
+ if (wander !== null) {
36
+ nav.set(entity.id, {
37
+ kind: "wander",
38
+ radius: wander.radius,
39
+ origin: entity.position,
40
+ target: null,
41
+ roll: seededRng(`wander:${entity.id}`),
42
+ status: "active",
43
+ reason: null,
44
+ pausedElapsed: 0,
45
+ });
46
+ }
47
+ }
48
+ for (const id of nav.keys())
49
+ if (!live.has(id))
50
+ nav.delete(id);
51
+ };
52
+ ctx.scene.entity.subscribeMembership(refresh);
53
+ refresh();
54
+ return { nav };
55
+ });
56
+ function stepWander(ctx, id, nav, dt) {
57
+ const entity = ctx.scene.entity.get(id);
58
+ if (entity === null)
59
+ return;
60
+ const [px, , pz] = entity.position;
61
+ if (nav.target === null || Math.hypot(px - nav.target[0], pz - nav.target[2]) < WANDER_ARRIVAL) {
62
+ const angle = nav.roll() * Math.PI * 2;
63
+ const distance = Math.sqrt(nav.roll()) * nav.radius;
64
+ const tx = nav.origin[0] + Math.cos(angle) * distance;
65
+ const tz = nav.origin[2] + Math.sin(angle) * distance;
66
+ nav.target = [tx, ctx.world.groundHeightAt(tx, tz), tz];
67
+ }
68
+ const speed = entity.movement.walkSpeed ?? DEFAULT_WANDER_SPEED;
69
+ const dx = nav.target[0] - px;
70
+ const dz = nav.target[2] - pz;
71
+ const dist = Math.hypot(dx, dz);
72
+ if (dist < 1e-6)
73
+ return;
74
+ const step = Math.min(dist, speed * dt);
75
+ const nx = px + (dx / dist) * step;
76
+ const nz = pz + (dz / dist) * step;
77
+ ctx.scene.entity.setPose(id, {
78
+ position: [nx, ctx.world.groundHeightAt(nx, nz), nz],
79
+ rotationY: Math.atan2(dx, dz),
80
+ dt,
81
+ });
82
+ }
83
+ function posePatrol(ctx, id, nav, dt) {
84
+ const [x, y, z] = nav.state.position;
85
+ ctx.scene.entity.setPose(id, {
86
+ position: nav.groundClamp ? [x, ctx.world.groundHeightAt(x, z), z] : [x, y, z],
87
+ rotationY: nav.state.heading,
88
+ dt,
89
+ });
90
+ }
91
+ /**
92
+ * Advance every spawned entity carrying a `patrol` or `wander` {@link BehaviorDescriptor} one tick — the
93
+ * engine reads the descriptor, keeps the per-entity nav state itself, and poses the entity, so ambient
94
+ * traffic and idle NPC routes are register-once (attach the behavior at spawn) instead of a per-game
95
+ * per-frame `advancePathFollow` + `setPose` loop. Instances that are paused or disabled through
96
+ * {@link behaviorControl} retain their state and are skipped. The shell/host call this each frame; a game never does.
97
+ *
98
+ * @capability behavior-tick auto-advance patrol/wander behaviors on spawned entities, no per-game route loop
99
+ */
100
+ export function advanceBehaviors(ctx, dt) {
101
+ if (dt <= 0)
102
+ return;
103
+ const { nav } = runtimeOf(ctx);
104
+ if (nav.size === 0)
105
+ return;
106
+ for (const [id, entry] of nav) {
107
+ if (entry.status !== "active") {
108
+ if (entry.status === "paused")
109
+ entry.pausedElapsed += dt;
110
+ continue;
111
+ }
112
+ if (entry.kind === "patrol") {
113
+ entry.state = advancePathFollow(entry.config, entry.state, dt);
114
+ posePatrol(ctx, id, entry, dt);
115
+ }
116
+ else {
117
+ stepWander(ctx, id, entry, dt);
118
+ }
119
+ }
120
+ }
121
+ /**
122
+ * Obtain the per-context {@link BehaviorControl} surface for suspending, resuming, seeking, serializing,
123
+ * and inspecting behavior instances by entity id — the lifecycle contract games use to hand pose
124
+ * ownership to possession/streaming/staggering code instead of bypassing the behavior runtime.
125
+ *
126
+ * @capability behavior-control pause/disable/resume/seek/inspect behavior instances per entity
127
+ */
128
+ export function behaviorControl(ctx) {
129
+ const { nav } = runtimeOf(ctx);
130
+ const setStatus = (id, status, reason) => {
131
+ const entry = nav.get(id);
132
+ if (entry === undefined)
133
+ return false;
134
+ entry.status = status;
135
+ entry.reason = reason;
136
+ return true;
137
+ };
138
+ return {
139
+ status: (id) => nav.get(id)?.status ?? null,
140
+ reason: (id) => nav.get(id)?.reason ?? null,
141
+ pause: (id, reason) => {
142
+ const entry = nav.get(id);
143
+ if (entry === undefined || entry.status !== "active")
144
+ return false;
145
+ entry.status = "paused";
146
+ entry.reason = reason ?? null;
147
+ entry.pausedElapsed = 0;
148
+ return true;
149
+ },
150
+ resume: (id, policy = "freeze") => {
151
+ const entry = nav.get(id);
152
+ if (entry === undefined || entry.status !== "paused")
153
+ return false;
154
+ if (policy === "advance" && entry.kind === "patrol" && entry.pausedElapsed > 0) {
155
+ entry.state = advancePathFollow(entry.config, entry.state, entry.pausedElapsed);
156
+ // Emit a single final pose at the caught-up position (no intermediate writes).
157
+ posePatrol(ctx, id, entry, entry.pausedElapsed);
158
+ }
159
+ entry.status = "active";
160
+ entry.reason = null;
161
+ entry.pausedElapsed = 0;
162
+ return true;
163
+ },
164
+ disable: (id, reason) => setStatus(id, "disabled", reason ?? null),
165
+ enable: (id) => {
166
+ const entry = nav.get(id);
167
+ if (entry === undefined || entry.status !== "disabled")
168
+ return false;
169
+ entry.status = "active";
170
+ entry.reason = null;
171
+ entry.pausedElapsed = 0;
172
+ return true;
173
+ },
174
+ seek: (id, progress) => {
175
+ const entry = nav.get(id);
176
+ if (entry === undefined || entry.kind !== "patrol")
177
+ return false;
178
+ entry.state = pathFollowSeek(entry.config, progress);
179
+ return true;
180
+ },
181
+ serialize: (id) => {
182
+ const entry = nav.get(id);
183
+ if (entry === undefined)
184
+ return null;
185
+ if (entry.kind === "patrol")
186
+ return { kind: "patrol", state: { ...entry.state } };
187
+ return { kind: "wander", origin: [...entry.origin], target: entry.target === null ? null : [...entry.target] };
188
+ },
189
+ restore: (id, snapshot) => {
190
+ const entry = nav.get(id);
191
+ if (entry === undefined || entry.kind !== snapshot.kind)
192
+ return false;
193
+ if (entry.kind === "patrol" && snapshot.kind === "patrol") {
194
+ entry.state = { ...snapshot.state };
195
+ return true;
196
+ }
197
+ if (entry.kind === "wander" && snapshot.kind === "wander") {
198
+ entry.origin = [...snapshot.origin];
199
+ entry.target = snapshot.target === null ? null : [...snapshot.target];
200
+ return true;
201
+ }
202
+ return false;
203
+ },
204
+ inspect: (id) => {
205
+ const entry = nav.get(id);
206
+ if (entry === undefined)
207
+ return null;
208
+ return { id, kind: entry.kind, status: entry.status, reason: entry.reason };
209
+ },
210
+ list: () => {
211
+ const out = [];
212
+ for (const [id, entry] of nav)
213
+ out.push({ id, kind: entry.kind, status: entry.status, reason: entry.reason });
214
+ return out;
215
+ },
216
+ };
217
+ }
@@ -1,5 +1,5 @@
1
1
  import { type ProximityPrompt } from "../interaction/proximityPrompt.js";
2
- import type { Waypoint } from "../nav/pathFollow.js";
2
+ import type { PathProgress, Waypoint } from "../nav/pathFollow.js";
3
3
  export interface WanderBehavior {
4
4
  kind: "wander";
5
5
  radius: number;
@@ -9,6 +9,16 @@ export interface PatrolBehavior {
9
9
  waypoints: readonly Waypoint[];
10
10
  speed: number;
11
11
  loop: boolean;
12
+ /**
13
+ * Optional initial progress the follower is seeded at instead of waypoint zero — lets a fleet of
14
+ * route followers start at distributed phases. Round-trips through the behavior lifecycle seek/serialize.
15
+ */
16
+ startProgress?: PathProgress;
17
+ /**
18
+ * Sample world ground height for the pose Y each tick, so a route authored in the XZ plane rides
19
+ * uneven terrain. Default false (waypoint Y is used verbatim).
20
+ */
21
+ groundClamp?: boolean;
12
22
  }
13
23
  export interface PromptableBehavior {
14
24
  kind: "promptable";
@@ -21,10 +31,12 @@ export type BehaviorDescriptor = WanderBehavior | PatrolBehavior | PromptableBeh
21
31
  export declare function wander({ radius }: {
22
32
  radius: number;
23
33
  }): WanderBehavior;
24
- export declare function patrol({ waypoints, speed, loop, }: {
34
+ export declare function patrol({ waypoints, speed, loop, startProgress, groundClamp, }: {
25
35
  waypoints: readonly Waypoint[];
26
36
  speed: number;
27
37
  loop?: boolean;
38
+ startProgress?: PathProgress;
39
+ groundClamp?: boolean;
28
40
  }): PatrolBehavior;
29
41
  export declare function promptable(prompt: ProximityPrompt): PromptableBehavior;
30
42
  export declare function talkable(dialogueId: string): PromptableBehavior;
@@ -2,8 +2,13 @@ import { command, keybind, proximityPrompt, } from "../interaction/proximityProm
2
2
  export function wander({ radius }) {
3
3
  return { kind: "wander", radius };
4
4
  }
5
- export function patrol({ waypoints, speed, loop = true, }) {
6
- return { kind: "patrol", waypoints, speed, loop };
5
+ export function patrol({ waypoints, speed, loop = true, startProgress, groundClamp, }) {
6
+ const behavior = { kind: "patrol", waypoints, speed, loop };
7
+ if (startProgress !== undefined)
8
+ behavior.startProgress = startProgress;
9
+ if (groundClamp !== undefined)
10
+ behavior.groundClamp = groundClamp;
11
+ return behavior;
7
12
  }
8
13
  export function promptable(prompt) {
9
14
  return { kind: "promptable", prompt };
@@ -0,0 +1,60 @@
1
+ import type { EntityRole, EntityUpdatePatch, SpawnPositionInput } from "./entityStore.js";
2
+ /**
3
+ * One sim body's per-tick pose, as the game's simulation computed it — the shape a game already builds
4
+ * to hand to `setPose`, just declared instead of imperatively pushed. `kind` is the entity catalog name
5
+ * used only the first time `id` is seen (a respawn/despawn never re-reads it).
6
+ */
7
+ export interface BodySnapshot {
8
+ id: string;
9
+ kind: string;
10
+ position: SpawnPositionInput;
11
+ rotationY?: number;
12
+ rotationX?: number;
13
+ rotationZ?: number;
14
+ role?: EntityRole;
15
+ meta?: unknown;
16
+ }
17
+ /** The options a {@link BodyBindDeps.spawn} call receives for an id seen for the first time. */
18
+ export interface BodyBindSpawnInput {
19
+ id: string;
20
+ position: SpawnPositionInput;
21
+ rotationY?: number;
22
+ rotationX?: number;
23
+ rotationZ?: number;
24
+ role?: EntityRole;
25
+ meta?: unknown;
26
+ }
27
+ /** The pose a {@link BodyBindDeps.setPose} call receives for an id already bound. */
28
+ export interface BodyBindPose {
29
+ position: SpawnPositionInput;
30
+ rotationY?: number;
31
+ rotationX?: number;
32
+ rotationZ?: number;
33
+ dt?: number;
34
+ }
35
+ /** Structural entity-store seam a {@link BodyBind} mirrors onto — satisfied by `ctx.scene.entity` itself. */
36
+ export interface BodyBindDeps {
37
+ has(id: string): boolean;
38
+ spawn(kind: string, options: BodyBindSpawnInput): string;
39
+ despawn(id: string): boolean;
40
+ setPose(id: string, pose: BodyBindPose): boolean;
41
+ update(id: string, patch: EntityUpdatePatch): boolean;
42
+ }
43
+ /** The lazily-keyed handle `ctx.scene.entity.bind(key)` returns. */
44
+ export interface BodyBind {
45
+ /**
46
+ * Mirror this tick's `bodies` onto scene entities: spawns an id seen for the first time (catalog
47
+ * `kind` from its snapshot), poses one already bound, despawns one this bind previously spawned that
48
+ * is now absent from `bodies`. `dt` (when given) derives `velocity` the same as a direct `setPose`.
49
+ */
50
+ sync(bodies: Iterable<BodySnapshot>, dt?: number): void;
51
+ /** Ids this bind currently considers itself responsible for (spawned by, and not yet despawned by, `sync`). */
52
+ boundIds(): ReadonlySet<string>;
53
+ }
54
+ /**
55
+ * Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
56
+ * despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
57
+ *
58
+ * @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
59
+ */
60
+ export declare function createBodyBind(deps: BodyBindDeps): BodyBind;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
3
+ * despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
4
+ *
5
+ * @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
6
+ */
7
+ export function createBodyBind(deps) {
8
+ const bound = new Set();
9
+ return {
10
+ sync(bodies, dt) {
11
+ const seen = new Set();
12
+ for (const body of bodies) {
13
+ seen.add(body.id);
14
+ const alreadyBound = bound.has(body.id);
15
+ if (!alreadyBound && !deps.has(body.id)) {
16
+ deps.spawn(body.kind, {
17
+ id: body.id,
18
+ position: body.position,
19
+ rotationY: body.rotationY,
20
+ rotationX: body.rotationX,
21
+ rotationZ: body.rotationZ,
22
+ role: body.role,
23
+ meta: body.meta,
24
+ });
25
+ }
26
+ else {
27
+ deps.setPose(body.id, {
28
+ position: body.position,
29
+ rotationY: body.rotationY,
30
+ rotationX: body.rotationX,
31
+ rotationZ: body.rotationZ,
32
+ ...(dt === undefined ? {} : { dt }),
33
+ });
34
+ if (body.role !== undefined || body.meta !== undefined) {
35
+ deps.update(body.id, { role: body.role, meta: body.meta });
36
+ }
37
+ }
38
+ bound.add(body.id);
39
+ }
40
+ for (const id of bound) {
41
+ if (seen.has(id))
42
+ continue;
43
+ deps.despawn(id);
44
+ bound.delete(id);
45
+ }
46
+ },
47
+ boundIds() {
48
+ return bound;
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,5 @@
1
+ import { type ParamSchema } from "./sceneKinds.js";
2
+ /** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
3
+ export declare const SCATTER_SCHEMA: ParamSchema;
4
+ /** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
5
+ export declare function registerBuiltinSceneKinds(): void;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Registers the engine's built-in *environment* scene kinds against the {@link registerSceneKind}
3
+ * seam: `scatter` (the proof adopter — its inspector, `+ Add` entry, and parse now come from the
4
+ * registry), `water` (a reusable parametric water surface), `grass_field` (GPU vertex-wind grass), and
5
+ * `soil` (crack/moss ground-variation patch). These are genre-agnostic engine primitives, like terrain.
6
+ * Domain studios (poles, bookcases, …) are NOT built in — they register themselves from example/game
7
+ * code via the same public seam, needing zero engine edits (see `examples/studios`). Call
8
+ * {@link registerBuiltinSceneKinds} once at startup (idempotent).
9
+ */
10
+ import { SCATTER_PATH_KIND } from "../world/scatterRegion.js";
11
+ import { registerWaterKind } from "../world/waterKind.js";
12
+ import { registerGrassKind } from "../world/grassKind.js";
13
+ import { registerSoilKind } from "../world/soilKind.js";
14
+ import { registerBuildingGenerator } from "../world/buildingGenerator.js";
15
+ import { registerSceneKind } from "./sceneKinds.js";
16
+ /** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
17
+ export const SCATTER_SCHEMA = {
18
+ fields: [
19
+ { type: "range", key: "density", label: "density", min: 0, max: 2, step: 0.01, default: 0.15, unit: "/m²" },
20
+ { type: "number", key: "minSpacing", label: "spacing", step: 0.25, default: 1.5, min: 0 },
21
+ { type: "number", key: "minScale", label: "min scale", step: 0.05, default: 0.8, min: 0 },
22
+ { type: "number", key: "maxScale", label: "max scale", step: 0.05, default: 1.3, min: 0 },
23
+ { type: "number", key: "maxSlope", label: "max slope", step: 0.05, default: 0, min: 0 },
24
+ { type: "number", key: "edgeFalloff", label: "edge fade", step: 0.5, default: 0, min: 0 },
25
+ { type: "bool", key: "alignToNormal", label: "align to slope", default: false },
26
+ { type: "bool", key: "autoAvoid", label: "auto-avoid gameplay spots", default: true },
27
+ { type: "weightedList", key: "palette", label: "species (weighted)", itemLabel: "grass / tree id", default: [{ item: "grass", weight: 1 }] },
28
+ { type: "seed", key: "seed", label: "seed", default: "" },
29
+ ],
30
+ };
31
+ let registered = false;
32
+ /** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
33
+ export function registerBuiltinSceneKinds() {
34
+ if (registered)
35
+ return;
36
+ registered = true;
37
+ registerSceneKind({
38
+ kind: SCATTER_PATH_KIND,
39
+ target: "path",
40
+ label: "Foliage / scatter",
41
+ pathShape: "area",
42
+ addCategory: "Studios",
43
+ accent: "#34d399",
44
+ schema: SCATTER_SCHEMA,
45
+ note: (object, params) => {
46
+ const points = object.points ?? [];
47
+ if (points.length < 3)
48
+ return "Draw at least 3 points to close the region.";
49
+ let area = 0;
50
+ for (let i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
51
+ area += points[j].x * points[i].z - points[i].x * points[j].z;
52
+ }
53
+ area = Math.abs(area) / 2;
54
+ const density = typeof params["density"] === "number" ? params["density"] : 0;
55
+ return `≈ ${Math.floor(area * density).toLocaleString()} placements over ${Math.round(area).toLocaleString()} m²`;
56
+ },
57
+ });
58
+ registerWaterKind();
59
+ registerGrassKind();
60
+ registerSoilKind();
61
+ registerBuildingGenerator();
62
+ }
@@ -33,11 +33,29 @@ export interface ResolvedCollider {
33
33
  }
34
34
  export declare const DEFAULT_ENTITY_HIT_RADIUS = 0.5;
35
35
  export declare const DEFAULT_OBJECT_HALF_EXTENTS: EntityPosition;
36
+ /** Matches the shell's fallback actor capsule (~0.7m wide, feet at y=0 to head at ~1.8m). */
37
+ export declare const DEFAULT_ENTITY_BODY_HALF_EXTENTS: EntityPosition;
38
+ /** Entity-local center of the default body hitbox (half its height above the feet). */
39
+ export declare const DEFAULT_ENTITY_BODY_OFFSET: EntityPosition;
40
+ /** @internal */
36
41
  export declare function defaultEntityColliders(): EntityColliderSet;
42
+ /** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
43
+ * @internal
44
+ */
45
+ export declare function scaledEntityColliders(scale: number): EntityColliderSet;
46
+ /** @internal */
37
47
  export declare function defaultObjectColliders(halfExtents?: EntityPosition): EntityColliderSet;
48
+ /** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
49
+ * @internal
50
+ */
51
+ export declare function scaledObjectColliders(scale: readonly [number, number, number]): EntityColliderSet;
52
+ /** @internal */
38
53
  export declare function resolveColliders(set: EntityColliderSet | null | undefined): ResolvedCollider[];
54
+ /** @internal */
39
55
  export declare function worldOffset(local: EntityPosition | undefined, position: EntityPosition, rotationY: number): EntityPosition;
56
+ /** @internal */
40
57
  export declare function colliderWorldCenter(collider: ResolvedCollider, position: EntityPosition, rotationY: number): EntityPosition;
58
+ /** @internal */
41
59
  export declare function colliderBounds(collider: ResolvedCollider, position: EntityPosition, rotationY: number): {
42
60
  min: EntityPosition;
43
61
  max: EntityPosition;
@@ -1,18 +1,56 @@
1
1
  export const DEFAULT_ENTITY_HIT_RADIUS = 0.5;
2
2
  export const DEFAULT_OBJECT_HALF_EXTENTS = [0.5, 0.5, 0.5];
3
+ /** Matches the shell's fallback actor capsule (~0.7m wide, feet at y=0 to head at ~1.8m). */
4
+ export const DEFAULT_ENTITY_BODY_HALF_EXTENTS = [0.35, 0.9, 0.35];
5
+ /** Entity-local center of the default body hitbox (half its height above the feet). */
6
+ export const DEFAULT_ENTITY_BODY_OFFSET = [0, 0.9, 0];
7
+ /** @internal */
3
8
  export function defaultEntityColliders() {
4
9
  return {
5
10
  hitboxes: [
6
11
  {
7
12
  name: "body",
8
13
  purpose: "damage",
9
- shape: { kind: "sphere", radius: DEFAULT_ENTITY_HIT_RADIUS },
14
+ shape: {
15
+ kind: "aabb",
16
+ halfExtents: DEFAULT_ENTITY_BODY_HALF_EXTENTS,
17
+ offset: DEFAULT_ENTITY_BODY_OFFSET,
18
+ },
10
19
  damageEligible: true,
11
20
  blocks: false,
12
21
  },
13
22
  ],
14
23
  };
15
24
  }
25
+ /** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
26
+ * @internal
27
+ */
28
+ export function scaledEntityColliders(scale) {
29
+ return {
30
+ hitboxes: [
31
+ {
32
+ name: "body",
33
+ purpose: "damage",
34
+ shape: {
35
+ kind: "aabb",
36
+ halfExtents: [
37
+ DEFAULT_ENTITY_BODY_HALF_EXTENTS[0] * scale,
38
+ DEFAULT_ENTITY_BODY_HALF_EXTENTS[1] * scale,
39
+ DEFAULT_ENTITY_BODY_HALF_EXTENTS[2] * scale,
40
+ ],
41
+ offset: [
42
+ DEFAULT_ENTITY_BODY_OFFSET[0] * scale,
43
+ DEFAULT_ENTITY_BODY_OFFSET[1] * scale,
44
+ DEFAULT_ENTITY_BODY_OFFSET[2] * scale,
45
+ ],
46
+ },
47
+ damageEligible: true,
48
+ blocks: false,
49
+ },
50
+ ],
51
+ };
52
+ }
53
+ /** @internal */
16
54
  export function defaultObjectColliders(halfExtents = DEFAULT_OBJECT_HALF_EXTENTS) {
17
55
  return {
18
56
  body: {
@@ -24,6 +62,25 @@ export function defaultObjectColliders(halfExtents = DEFAULT_OBJECT_HALF_EXTENTS
24
62
  },
25
63
  };
26
64
  }
65
+ /** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
66
+ * @internal
67
+ */
68
+ export function scaledObjectColliders(scale) {
69
+ return {
70
+ body: {
71
+ name: "body",
72
+ purpose: "physical",
73
+ shape: {
74
+ kind: "aabb",
75
+ halfExtents: [scale[0] / 2, scale[1] / 2, scale[2] / 2],
76
+ offset: [0, scale[1] / 2, 0],
77
+ },
78
+ damageEligible: false,
79
+ blocks: true,
80
+ },
81
+ };
82
+ }
83
+ /** @internal */
27
84
  export function resolveColliders(set) {
28
85
  if (set === null || set === undefined)
29
86
  return [];
@@ -47,6 +104,7 @@ function resolveOne(def) {
47
104
  blocks,
48
105
  };
49
106
  }
107
+ /** @internal */
50
108
  export function worldOffset(local, position, rotationY) {
51
109
  if (local === undefined)
52
110
  return position;
@@ -57,9 +115,11 @@ export function worldOffset(local, position, rotationY) {
57
115
  const lz = local[2];
58
116
  return [position[0] + lx * cos + lz * sin, position[1] + ly, position[2] - lx * sin + lz * cos];
59
117
  }
118
+ /** @internal */
60
119
  export function colliderWorldCenter(collider, position, rotationY) {
61
120
  return worldOffset(collider.shape.offset, position, rotationY);
62
121
  }
122
+ /** @internal */
63
123
  export function colliderBounds(collider, position, rotationY) {
64
124
  const center = colliderWorldCenter(collider, position, rotationY);
65
125
  if (collider.shape.kind === "sphere") {
@@ -24,10 +24,22 @@ export type PoolDeltaResult = {
24
24
  status: "rejected";
25
25
  reason: string;
26
26
  };
27
+ /** @internal */
27
28
  export declare function getStatValue(map: StatValueMap, statId: string): StatValue | null;
29
+ /** @internal */
28
30
  export declare function setStatValue(map: StatValueMap, statId: string, patch: StatValuePatch): StatValueMap;
31
+ /** @internal */
29
32
  export declare function applyPoolDelta(map: StatValueMap, statId: string, amount: number): PoolDeltaResult;
33
+ /** @internal */
30
34
  export declare function seedStatValues(catalogStats: StatCatalog): StatValueMap;
35
+ /** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
36
+ * @internal
37
+ */
38
+ export declare function snapshotEntityStats(store: ReadonlyMap<string, StatValueMap>): Record<string, StatValueMap>;
39
+ /** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
40
+ * @internal
41
+ */
42
+ export declare function hydrateEntityStats(store: Map<string, StatValueMap>, data: Record<string, StatValueMap>): void;
31
43
  export interface EntityStatsApi {
32
44
  get(instanceId: string, statId: string): StatValue | null;
33
45
  set(instanceId: string, statId: string, patch: StatValuePatch): boolean;
@@ -35,4 +47,5 @@ export interface EntityStatsApi {
35
47
  reason: string;
36
48
  };
37
49
  }
50
+ /** @internal */
38
51
  export declare function createEntityStatsApi(resolve: (instanceId: string) => StatValueMap | undefined): EntityStatsApi;
@@ -1,9 +1,11 @@
1
1
  function clamp(value, min, max) {
2
2
  return Math.min(max, Math.max(min, value));
3
3
  }
4
+ /** @internal */
4
5
  export function getStatValue(map, statId) {
5
6
  return map[statId] ?? null;
6
7
  }
8
+ /** @internal */
7
9
  export function setStatValue(map, statId, patch) {
8
10
  const existing = map[statId];
9
11
  const max = patch.max ?? existing?.max ?? 0;
@@ -11,6 +13,7 @@ export function setStatValue(map, statId, patch) {
11
13
  const current = clamp(patch.current ?? existing?.current ?? max, min, max);
12
14
  return { ...map, [statId]: { current, max, min } };
13
15
  }
16
+ /** @internal */
14
17
  export function applyPoolDelta(map, statId, amount) {
15
18
  const existing = map[statId];
16
19
  if (existing === undefined) {
@@ -26,6 +29,7 @@ export function applyPoolDelta(map, statId, amount) {
26
29
  hitMax: current === existing.max,
27
30
  };
28
31
  }
32
+ /** @internal */
29
33
  export function seedStatValues(catalogStats) {
30
34
  const map = {};
31
35
  for (const [statId, declaration] of Object.entries(catalogStats)) {
@@ -35,6 +39,32 @@ export function seedStatValues(catalogStats) {
35
39
  }
36
40
  return map;
37
41
  }
42
+ /** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
43
+ * @internal
44
+ */
45
+ export function snapshotEntityStats(store) {
46
+ const out = {};
47
+ for (const [instanceId, map] of store) {
48
+ const copy = {};
49
+ for (const [statId, value] of Object.entries(map))
50
+ copy[statId] = { ...value };
51
+ out[instanceId] = copy;
52
+ }
53
+ return out;
54
+ }
55
+ /** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
56
+ * @internal
57
+ */
58
+ export function hydrateEntityStats(store, data) {
59
+ store.clear();
60
+ for (const [instanceId, map] of Object.entries(data)) {
61
+ const copy = {};
62
+ for (const [statId, value] of Object.entries(map))
63
+ copy[statId] = { ...value };
64
+ store.set(instanceId, copy);
65
+ }
66
+ }
67
+ /** @internal */
38
68
  export function createEntityStatsApi(resolve) {
39
69
  return {
40
70
  get(instanceId, statId) {