@jgengine/core 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/CHANGELOG.md +39 -2
  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/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -1,12 +1,14 @@
1
+ import { randomSeedFrom, stepRandomSeed } from "../random/rng.js";
2
+ const BIAS_STRENGTH_EXPONENT = {
3
+ subtle: 0.5,
4
+ moderate: 1,
5
+ strong: 2,
6
+ };
7
+ function biasStrengthFromMagnitude(magnitude) {
8
+ return magnitude <= 0.5 ? "subtle" : magnitude >= 1.5 ? "strong" : "moderate";
9
+ }
1
10
  const DEFAULT_MAX_SPAWNS_PER_TICK = 64;
2
11
  const DEFAULT_ALERT_DECAY = 0.1;
3
- function nextRandom(seed) {
4
- const next = (seed + 0x6d2b79f5) | 0;
5
- let t = Math.imul(next ^ (next >>> 15), 1 | next);
6
- t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
7
- const value = ((t ^ (t >>> 14)) >>> 0) / 4294967296;
8
- return [value, next];
9
- }
10
12
  function clamp01(value) {
11
13
  return value < 0 ? 0 : value > 1 ? 1 : value;
12
14
  }
@@ -20,7 +22,7 @@ export function createSpawnDirectorState(config) {
20
22
  alert: 0,
21
23
  spawnedThisWave: 0,
22
24
  spawnedTotal: 0,
23
- rng: (config.seed ?? 1) | 0,
25
+ rng: randomSeedFrom(config.seed ?? 1),
24
26
  done: config.waves.length === 0,
25
27
  };
26
28
  }
@@ -56,7 +58,7 @@ function pickEntry(entries, wave, budget, rng) {
56
58
  }
57
59
  if (affordable.length === 0 || total <= 0)
58
60
  return null;
59
- const [roll, nextRng] = nextRandom(rng);
61
+ const [roll, nextRng] = stepRandomSeed(rng);
60
62
  let cursor = roll * total;
61
63
  for (const entry of affordable) {
62
64
  cursor -= entry.weight ?? 1;
@@ -116,7 +118,7 @@ export function advanceSpawnDirector(config, state, dt, ctx) {
116
118
  budget -= picked.entry.cost;
117
119
  const spawn = { entryId: picked.entry.id, cost: picked.entry.cost, wave };
118
120
  if (spawnPoints !== undefined && spawnPoints.length > 0) {
119
- const [roll, nextRng] = nextRandom(rng);
121
+ const [roll, nextRng] = stepRandomSeed(rng);
120
122
  rng = nextRng;
121
123
  const bias = config.spawnPointBias ?? 1;
122
124
  const point = pickSpawnPoint({
@@ -124,7 +126,7 @@ export function advanceSpawnDirector(config, state, dt, ctx) {
124
126
  avoid: playerPositions,
125
127
  random: () => roll,
126
128
  distanceBias: bias < 0 ? "far" : bias > 0 ? "near" : "none",
127
- biasStrength: Math.abs(bias),
129
+ biasStrength: biasStrengthFromMagnitude(Math.abs(bias)),
128
130
  });
129
131
  if (point !== null) {
130
132
  spawn.point = point;
@@ -150,19 +152,20 @@ export function pickSpawnPoint(optionsOrPoints, legacyPlayers = [], legacyOption
150
152
  avoid: legacyPlayers,
151
153
  random: () => legacyOptions.roll,
152
154
  distanceBias: legacyBias < 0 ? "far" : legacyBias > 0 ? "near" : "none",
153
- biasStrength: Math.abs(legacyBias),
155
+ biasStrength: biasStrengthFromMagnitude(Math.abs(legacyBias)),
154
156
  };
155
157
  }
156
158
  else {
157
159
  options = optionsOrPoints;
158
160
  }
159
- const { candidates, avoid = [], random, distanceBias = "near", biasStrength = 1 } = options;
161
+ const { candidates, avoid = [], random, distanceBias = "near", biasStrength = "moderate" } = options;
160
162
  if (candidates.length === 0)
161
163
  return null;
162
- if (distanceBias === "none" || avoid.length === 0 || biasStrength === 0) {
164
+ if (distanceBias === "none" || avoid.length === 0) {
163
165
  return candidates[Math.min(candidates.length - 1, Math.floor(clamp01(random()) * candidates.length))];
164
166
  }
165
- const exponent = distanceBias === "far" ? biasStrength : -biasStrength;
167
+ const strength = BIAS_STRENGTH_EXPONENT[biasStrength];
168
+ const exponent = distanceBias === "far" ? strength : -strength;
166
169
  const weights = [];
167
170
  let total = 0;
168
171
  for (const point of candidates) {
@@ -1,5 +1,7 @@
1
1
  import type { NavPoint } from "../nav/navGrid.js";
2
2
  import { type SpawnPointDistanceBias, type SpawnPointSelectionOptions } from "./spawnDirector.js";
3
3
  export type { SpawnPointDistanceBias, SpawnPointSelectionOptions };
4
- /** Selects a spawn point by game intent while keeping weighting mechanics internal. */
4
+ /** Selects a spawn point by game intent while keeping weighting mechanics internal.
5
+ * @internal
6
+ */
5
7
  export declare function selectSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null;
@@ -1,5 +1,7 @@
1
1
  import { pickSpawnPoint, } from "./spawnDirector.js";
2
- /** Selects a spawn point by game intent while keeping weighting mechanics internal. */
2
+ /** Selects a spawn point by game intent while keeping weighting mechanics internal.
3
+ * @internal
4
+ */
3
5
  export function selectSpawnPoint(options) {
4
6
  return pickSpawnPoint(options);
5
7
  }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Composable target acquisition: the "which enemy do I lock onto?" decision split into the
3
+ * independent concerns every aggro system tangles together — a bounded candidate provider, an
4
+ * eligibility filter, a per-pair acquisition envelope (dynamic range), a perception/LOS gate,
5
+ * scoring, deterministic tie-break, and retention hysteresis. This owns *policy*; threat, brains,
6
+ * and movement stay separate. Feed `candidates` a spatial-index query, never a full-world scan.
7
+ */
8
+ /** A per-pair acquisition range: a static radius, or a function that varies range by pair. */
9
+ export type AcquisitionEnvelope = number | ((selfId: string, candidateId: string) => number);
10
+ /** Retention hysteresis that keeps an already-held target from flickering under churn. */
11
+ export interface AcquisitionRetention {
12
+ /**
13
+ * A challenger's score must beat the held target's by at least this additive margin to steal
14
+ * acquisition. Keeps the lock stable when scores are near-tied. Default `0` (any win switches).
15
+ */
16
+ readonly switchMargin?: number;
17
+ /**
18
+ * The held target keeps acquisition out to `range * dropRangeScale` before it is dropped, so a
19
+ * target does not un-acquire the instant it steps past the acquisition edge. Default `1`.
20
+ */
21
+ readonly dropRangeScale?: number;
22
+ }
23
+ /**
24
+ * A fully composed acquisition policy. Every concern is an independent, injectable seam; the only
25
+ * required pieces are the bounded `candidates` provider and the `distance` metric. Omit the rest to
26
+ * fall back to the thin default — a static/unbounded range, everything eligible and perceptible,
27
+ * nearest-wins scoring, id tie-break, no hysteresis — which matches a plain proximity aggro radius.
28
+ */
29
+ export interface AcquisitionPolicy {
30
+ /** Bounded candidate ids for `selfId` — wire a spatial-index query here, not a whole-world list. */
31
+ readonly candidates: (selfId: string) => Iterable<string>;
32
+ /** Distance self→candidate; `null` rejects the candidate (despawned / unmeasurable). */
33
+ readonly distance: (selfId: string, candidateId: string) => number | null;
34
+ /** Per-pair acquisition range (the dynamic envelope). Default `Infinity` (range-unbounded). */
35
+ readonly range?: AcquisitionEnvelope;
36
+ /** Eligibility filter run first — faction, alive, targetable, stealth, ownership. Default: all pass. */
37
+ readonly eligible?: (selfId: string, candidateId: string) => boolean;
38
+ /** Perception / line-of-sight gate run last (after range) because it is the costly check. */
39
+ readonly perceptible?: (selfId: string, candidateId: string, distance: number) => boolean;
40
+ /** Score of an in-range candidate; the highest wins. Default: nearest (`-distance`). */
41
+ readonly score?: (selfId: string, candidateId: string, distance: number) => number;
42
+ /** Deterministic tie-break when scores are equal (return <0 to prefer `a`). Default: id order. */
43
+ readonly tieBreak?: (a: string, b: string) => number;
44
+ /** Retention/hysteresis for an already-held target. Omit for no stickiness. */
45
+ readonly retention?: AcquisitionRetention;
46
+ }
47
+ /** Outcome of one acquisition pass. */
48
+ export interface AcquisitionResult {
49
+ /** The chosen target, or `null` when nothing qualifies. */
50
+ readonly targetId: string | null;
51
+ /** True when `targetId` differs from the `held` target passed in (a fresh acquire or a switch). */
52
+ readonly changed: boolean;
53
+ /** Candidates that passed eligibility + range + perception this pass — a cheap tuning/metric signal. */
54
+ readonly considered: number;
55
+ }
56
+ /**
57
+ * Run one acquisition pass and pick the best target under `policy`. Pass the currently `held` target
58
+ * so retention hysteresis (`switchMargin`, `dropRangeScale`) can keep the lock stable; pass `null`
59
+ * for a cold acquire. Pure and allocation-light — the caller owns the held-target state.
60
+ *
61
+ * @capability target-acquisition composable candidate/eligibility/range/perception/score/tie-break/retention target pick
62
+ */
63
+ export declare function acquireTarget(policy: AcquisitionPolicy, selfId: string, held?: string | null): AcquisitionResult;
64
+ /** A stateful acquirer that holds the current target across passes — sugar over {@link acquireTarget}. */
65
+ export interface TargetAcquirer {
66
+ /** Re-run acquisition for `selfId`, update the held target, and return it. */
67
+ acquire(selfId: string): string | null;
68
+ /** The held target without re-running acquisition. */
69
+ target(): string | null;
70
+ /** Candidates considered on the last {@link acquire} pass. */
71
+ considered(): number;
72
+ /** Force the held target — external override for taunt, script, or ownership handoff. */
73
+ hold(targetId: string | null): void;
74
+ /** Drop back to unacquired. */
75
+ clear(): void;
76
+ }
77
+ /**
78
+ * Wrap an {@link AcquisitionPolicy} in a small object that remembers the held target between passes,
79
+ * so callers get retention hysteresis for free without threading the previous target by hand. The
80
+ * only state is the held id (a string) — trivially serializable; round-trip it with {@link TargetAcquirer.hold}.
81
+ *
82
+ * @capability target-acquirer stateful held-target wrapper over an acquisition policy with retention
83
+ */
84
+ export declare function createTargetAcquirer(policy: AcquisitionPolicy): TargetAcquirer;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Composable target acquisition: the "which enemy do I lock onto?" decision split into the
3
+ * independent concerns every aggro system tangles together — a bounded candidate provider, an
4
+ * eligibility filter, a per-pair acquisition envelope (dynamic range), a perception/LOS gate,
5
+ * scoring, deterministic tie-break, and retention hysteresis. This owns *policy*; threat, brains,
6
+ * and movement stay separate. Feed `candidates` a spatial-index query, never a full-world scan.
7
+ */
8
+ function resolveRange(range, selfId, candidateId) {
9
+ if (range === undefined)
10
+ return Number.POSITIVE_INFINITY;
11
+ return typeof range === "number" ? range : range(selfId, candidateId);
12
+ }
13
+ function defaultTieBreak(a, b) {
14
+ return a < b ? -1 : a > b ? 1 : 0;
15
+ }
16
+ /**
17
+ * Run one acquisition pass and pick the best target under `policy`. Pass the currently `held` target
18
+ * so retention hysteresis (`switchMargin`, `dropRangeScale`) can keep the lock stable; pass `null`
19
+ * for a cold acquire. Pure and allocation-light — the caller owns the held-target state.
20
+ *
21
+ * @capability target-acquisition composable candidate/eligibility/range/perception/score/tie-break/retention target pick
22
+ */
23
+ export function acquireTarget(policy, selfId, held = null) {
24
+ const tieBreak = policy.tieBreak ?? defaultTieBreak;
25
+ const dropScale = Math.max(0, policy.retention?.dropRangeScale ?? 1);
26
+ const switchMargin = policy.retention?.switchMargin ?? 0;
27
+ let considered = 0;
28
+ let bestId = null;
29
+ let bestScore = Number.NEGATIVE_INFINITY;
30
+ let heldSeen = false;
31
+ let heldScore = Number.NEGATIVE_INFINITY;
32
+ for (const candidateId of policy.candidates(selfId)) {
33
+ if (candidateId === selfId)
34
+ continue;
35
+ if (policy.eligible !== undefined && !policy.eligible(selfId, candidateId))
36
+ continue;
37
+ const d = policy.distance(selfId, candidateId);
38
+ if (d === null)
39
+ continue;
40
+ const range = resolveRange(policy.range, selfId, candidateId);
41
+ const effectiveRange = candidateId === held ? range * dropScale : range;
42
+ if (d > effectiveRange)
43
+ continue;
44
+ if (policy.perceptible !== undefined && !policy.perceptible(selfId, candidateId, d))
45
+ continue;
46
+ considered += 1;
47
+ const score = policy.score === undefined ? -d : policy.score(selfId, candidateId, d);
48
+ if (candidateId === held) {
49
+ heldSeen = true;
50
+ heldScore = score;
51
+ }
52
+ if (bestId === null ||
53
+ score > bestScore ||
54
+ (score === bestScore && tieBreak(candidateId, bestId) < 0)) {
55
+ bestId = candidateId;
56
+ bestScore = score;
57
+ }
58
+ }
59
+ // Retention: an in-range held target keeps the lock unless a challenger clears the switch margin.
60
+ if (heldSeen && held !== null && bestId !== held && bestScore < heldScore + switchMargin) {
61
+ return { targetId: held, changed: false, considered };
62
+ }
63
+ return { targetId: bestId, changed: bestId !== held, considered };
64
+ }
65
+ /**
66
+ * Wrap an {@link AcquisitionPolicy} in a small object that remembers the held target between passes,
67
+ * so callers get retention hysteresis for free without threading the previous target by hand. The
68
+ * only state is the held id (a string) — trivially serializable; round-trip it with {@link TargetAcquirer.hold}.
69
+ *
70
+ * @capability target-acquirer stateful held-target wrapper over an acquisition policy with retention
71
+ */
72
+ export function createTargetAcquirer(policy) {
73
+ let held = null;
74
+ let considered = 0;
75
+ return {
76
+ acquire(selfId) {
77
+ const result = acquireTarget(policy, selfId, held);
78
+ held = result.targetId;
79
+ considered = result.considered;
80
+ return held;
81
+ },
82
+ target: () => held,
83
+ considered: () => considered,
84
+ hold(targetId) {
85
+ held = targetId;
86
+ },
87
+ clear() {
88
+ held = null;
89
+ considered = 0;
90
+ },
91
+ };
92
+ }
@@ -1,14 +1,33 @@
1
1
  export type Easing = (t: number) => number;
2
+ /** Linearly interpolate from `from` to `to` by fraction `t` (unclamped).
3
+ * @internal
4
+ */
2
5
  export declare function lerp(from: number, to: number, t: number): number;
6
+ /** Constrain `t` to the unit range `[0, 1]`.
7
+ * @internal
8
+ */
3
9
  export declare function clamp01(t: number): number;
10
+ /** Smooth Hermite interpolation of `t` across `[0, 1]`, easing both ends.
11
+ * @internal
12
+ */
4
13
  export declare function smoothstep(t: number): number;
14
+ /** @internal */
5
15
  export declare function easeInQuad(t: number): number;
16
+ /** @internal */
6
17
  export declare function easeOutQuad(t: number): number;
18
+ /** @internal */
7
19
  export declare function easeInOutQuad(t: number): number;
20
+ /** @internal */
8
21
  export declare function easeInCubic(t: number): number;
22
+ /** @internal */
9
23
  export declare function easeOutCubic(t: number): number;
24
+ /** @internal */
10
25
  export declare function easeInOutCubic(t: number): number;
26
+ /** @internal */
11
27
  export declare function easeOutBack(t: number): number;
28
+ /** @internal */
12
29
  export declare function easeOutElastic(t: number): number;
30
+ /** @internal */
13
31
  export declare function tween(from: number, to: number, t: number, easing?: Easing): number;
32
+ /** @internal */
14
33
  export declare function timedProgress(startedAt: number, now: number, durationMs: number): number;
@@ -1,53 +1,72 @@
1
+ /** Linearly interpolate from `from` to `to` by fraction `t` (unclamped).
2
+ * @internal
3
+ */
1
4
  export function lerp(from, to, t) {
2
5
  return from + (to - from) * t;
3
6
  }
7
+ /** Constrain `t` to the unit range `[0, 1]`.
8
+ * @internal
9
+ */
4
10
  export function clamp01(t) {
5
11
  return t < 0 ? 0 : t > 1 ? 1 : t;
6
12
  }
13
+ /** Smooth Hermite interpolation of `t` across `[0, 1]`, easing both ends.
14
+ * @internal
15
+ */
7
16
  export function smoothstep(t) {
8
17
  const c = clamp01(t);
9
18
  return c * c * (3 - 2 * c);
10
19
  }
20
+ /** @internal */
11
21
  export function easeInQuad(t) {
12
22
  const c = clamp01(t);
13
23
  return c * c;
14
24
  }
25
+ /** @internal */
15
26
  export function easeOutQuad(t) {
16
27
  const c = clamp01(t);
17
28
  return 1 - (1 - c) * (1 - c);
18
29
  }
30
+ /** @internal */
19
31
  export function easeInOutQuad(t) {
20
32
  const c = clamp01(t);
21
33
  return c < 0.5 ? 2 * c * c : 1 - ((-2 * c + 2) ** 2) / 2;
22
34
  }
35
+ /** @internal */
23
36
  export function easeInCubic(t) {
24
37
  const c = clamp01(t);
25
38
  return c * c * c;
26
39
  }
40
+ /** @internal */
27
41
  export function easeOutCubic(t) {
28
42
  const c = clamp01(t);
29
43
  return 1 - (1 - c) ** 3;
30
44
  }
45
+ /** @internal */
31
46
  export function easeInOutCubic(t) {
32
47
  const c = clamp01(t);
33
48
  return c < 0.5 ? 4 * c * c * c : 1 - ((-2 * c + 2) ** 3) / 2;
34
49
  }
35
50
  const BACK_OVERSHOOT = 1.70158;
51
+ /** @internal */
36
52
  export function easeOutBack(t) {
37
53
  const c = clamp01(t);
38
54
  const s = BACK_OVERSHOOT + 1;
39
55
  return 1 + s * (c - 1) ** 3 + BACK_OVERSHOOT * (c - 1) ** 2;
40
56
  }
41
57
  const ELASTIC_PERIOD = (2 * Math.PI) / 3;
58
+ /** @internal */
42
59
  export function easeOutElastic(t) {
43
60
  const c = clamp01(t);
44
61
  if (c === 0 || c === 1)
45
62
  return c;
46
63
  return 2 ** (-10 * c) * Math.sin((c * 10 - 0.75) * ELASTIC_PERIOD) + 1;
47
64
  }
65
+ /** @internal */
48
66
  export function tween(from, to, t, easing = smoothstep) {
49
67
  return lerp(from, to, easing(clamp01(t)));
50
68
  }
69
+ /** @internal */
51
70
  export function timedProgress(startedAt, now, durationMs) {
52
71
  if (durationMs <= 0)
53
72
  return now >= startedAt ? 1 : 0;
@@ -0,0 +1,12 @@
1
+ /** Sawtooth ramp: rises 0→1 over each `period` then resets, for looping sweeps and scrolls.
2
+ * @internal
3
+ */
4
+ export declare function sawWave(time: number, period: number): number;
5
+ /** Triangle wave: ramps 0→1→0 across each `period`, for patrols, searchlights, and pulsing glows.
6
+ * @internal
7
+ */
8
+ export declare function triangleWave(time: number, period: number): number;
9
+ /** Ping-pong a value across `[0, length]`, bouncing at each edge — the index/position analog of {@link triangleWave}.
10
+ * @internal
11
+ */
12
+ export declare function pingPong(value: number, length: number): number;
@@ -0,0 +1,25 @@
1
+ /** Sawtooth ramp: rises 0→1 over each `period` then resets, for looping sweeps and scrolls.
2
+ * @internal
3
+ */
4
+ export function sawWave(time, period) {
5
+ if (!(period > 0))
6
+ return 0;
7
+ const phase = ((time % period) + period) % period;
8
+ return phase / period;
9
+ }
10
+ /** Triangle wave: ramps 0→1→0 across each `period`, for patrols, searchlights, and pulsing glows.
11
+ * @internal
12
+ */
13
+ export function triangleWave(time, period) {
14
+ const up = sawWave(time, period);
15
+ return up < 0.5 ? up * 2 : 2 - up * 2;
16
+ }
17
+ /** Ping-pong a value across `[0, length]`, bouncing at each edge — the index/position analog of {@link triangleWave}.
18
+ * @internal
19
+ */
20
+ export function pingPong(value, length) {
21
+ if (!(length > 0))
22
+ return 0;
23
+ const t = ((value % (length * 2)) + length * 2) % (length * 2);
24
+ return t <= length ? t : length * 2 - t;
25
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Continuous area-effect membership: moving sources emit an area that follows them each tick,
3
+ * receivers that move in and out get enter / refresh / leave edges, and membership is cleaned up
4
+ * when a source is removed, disabled, or the field is cleared. A pure lifecycle machine — it never
5
+ * applies damage, heals, or stat changes itself; the caller routes each edge through its own
6
+ * effect pipeline (see `combat/effects`, `combat/dotField`, `stats/statModifiers`). This is the
7
+ * dynamic, source-following counterpart to `scene/authoredTriggers` (static document volumes).
8
+ *
9
+ * Bounded by design: the caller supplies a broad-phase `candidates(shape)` query (e.g.
10
+ * `visibility/spatialIndex`'s `querySphere`) plus a `positionOf` lookup, so a step visits only
11
+ * receivers near each source — never the whole world. Serializable: `serialize()` captures the
12
+ * membership set and each member's refresh phase so cadence and enter/leave edges survive save/load.
13
+ */
14
+ import type { EntityPosition } from "../scene/entityStore.js";
15
+ /**
16
+ * The area a source occupies this tick. `sphere` is first-class; `custom` leaves a seam for authored
17
+ * volumes and other shapes while still exposing a bounding sphere (`center`/`radius`) for the caller's
18
+ * broad-phase candidate query.
19
+ */
20
+ export type AreaShape = {
21
+ readonly kind: "sphere";
22
+ readonly center: EntityPosition;
23
+ readonly radius: number;
24
+ } | {
25
+ readonly kind: "custom";
26
+ /** Bounding-sphere center the caller's broad-phase `candidates` query is built from. */
27
+ readonly center: EntityPosition;
28
+ /** Bounding-sphere radius the caller's broad-phase `candidates` query is built from. */
29
+ readonly radius: number;
30
+ /** Authoritative containment test applied to each broad-phase candidate. */
31
+ readonly contains: (point: EntityPosition) => boolean;
32
+ };
33
+ /** Descriptor for one continuous area source; re-supplied each tick so its shape follows the emitter. */
34
+ export interface AreaSourceSpec<P> {
35
+ /** Stable source id (the emitter). Re-using an id updates the descriptor and preserves membership. */
36
+ readonly id: string;
37
+ /** The source's area this tick — pass the emitter's live position so membership follows it. */
38
+ readonly shape: AreaShape;
39
+ /** Caller data describing what this source does (damage amount, heal, buff key, capture rate…). */
40
+ readonly payload: P;
41
+ /** Milliseconds between `refresh` edges emitted for each member; omit for enter/leave only. */
42
+ readonly refreshMs?: number;
43
+ /** Aggregation group key for stacking policies; defaults to the source id. */
44
+ readonly stackKey?: string;
45
+ /** When false the source keeps its descriptor but holds no members (current members `leave`). Default true. */
46
+ readonly enabled?: boolean;
47
+ }
48
+ /** Why a `leave` edge fired. */
49
+ export type AreaLeaveReason = "exit" | "source-removed" | "disabled" | "cleared";
50
+ /** The three membership edges a step can emit. */
51
+ export type AreaEventKind = "enter" | "refresh" | "leave";
52
+ /** One membership edge emitted by `step`, `removeSource`, or `clear`. */
53
+ export interface AreaEffectEvent<P> {
54
+ readonly kind: AreaEventKind;
55
+ readonly sourceId: string;
56
+ readonly receiverId: string;
57
+ readonly stackKey: string;
58
+ readonly payload: P;
59
+ /** Number of refresh cadences crossed this step (>= 1 on `refresh`; a large dt can cross several). */
60
+ readonly ticks?: number;
61
+ /** Present only on `leave`. */
62
+ readonly reason?: AreaLeaveReason;
63
+ }
64
+ /** One active (source, receiver) membership — feed a receiver's list to a stacking policy. */
65
+ export interface AreaMembership<P> {
66
+ readonly sourceId: string;
67
+ readonly receiverId: string;
68
+ readonly stackKey: string;
69
+ readonly payload: P;
70
+ }
71
+ /** Per-tick inputs the field needs to reconcile membership without scanning the world. */
72
+ export interface AreaStepInput {
73
+ /** Milliseconds since the previous step; negative values are clamped to 0. */
74
+ readonly dtMs: number;
75
+ /** Bounded broad-phase: receiver ids possibly inside `shape` (e.g. `spatialIndex.querySphere`). */
76
+ readonly candidates: (shape: AreaShape) => Iterable<string>;
77
+ /** Precise receiver position; `undefined` means the receiver is gone (removed/dead) and is dropped. */
78
+ readonly positionOf: (receiverId: string) => EntityPosition | undefined;
79
+ /** Optional per-pair gate (team filter, immunity, line-of-sight already resolved by the caller). */
80
+ readonly eligible?: (sourceId: string, receiverId: string, payload: unknown) => boolean;
81
+ }
82
+ /** Serialized field state: source descriptors (minus their transient shape) and per-member refresh phase. */
83
+ export interface AreaFieldState<P> {
84
+ readonly sources: {
85
+ readonly id: string;
86
+ readonly payload: P;
87
+ readonly refreshMs?: number;
88
+ readonly stackKey: string;
89
+ readonly enabled: boolean;
90
+ }[];
91
+ readonly memberships: {
92
+ readonly sourceId: string;
93
+ readonly receiverId: string;
94
+ readonly sinceRefreshMs: number;
95
+ }[];
96
+ }
97
+ /** Runtime handle tracking continuous area membership across ticks. */
98
+ export interface AreaEffectField<P> {
99
+ /** Register or update a source (upsert by id); an update preserves existing membership and refresh phase. */
100
+ setSource(spec: AreaSourceSpec<P>): void;
101
+ /** Remove a source and return a `leave` (reason `source-removed`) for each of its members. */
102
+ removeSource(id: string): AreaEffectEvent<P>[];
103
+ hasSource(id: string): boolean;
104
+ sourceIds(): string[];
105
+ /** Reconcile every source against the receivers its `candidates` query returns; emit enter/refresh/leave. */
106
+ step(input: AreaStepInput): AreaEffectEvent<P>[];
107
+ /** Receiver ids currently inside `sourceId`. */
108
+ members(sourceId: string): string[];
109
+ isMember(sourceId: string, receiverId: string): boolean;
110
+ /** Every active membership across all sources. */
111
+ memberships(): AreaMembership<P>[];
112
+ /** Active memberships affecting a single receiver — the input to a stacking policy. */
113
+ membershipsOf(receiverId: string): AreaMembership<P>[];
114
+ /** Drop all sources and members; returns a `leave` (reason `cleared`) for each member. */
115
+ clear(): AreaEffectEvent<P>[];
116
+ /** Snapshot the persistent membership lifecycle for save/load; shapes are transient and re-supplied via `setSource`. */
117
+ serialize(): AreaFieldState<P>;
118
+ }
119
+ /**
120
+ * Build a continuous area-effect field. Drive it with `setSource` (once per live source per tick, so
121
+ * shapes follow their emitters) and `step` (to reconcile membership and drain enter/refresh/leave edges).
122
+ * Optionally restore prior membership by passing a `serialize()` snapshot; re-`setSource` live shapes
123
+ * before the first `step` after restore, since shapes are transient.
124
+ *
125
+ * @capability area-effect-field source-following area membership with enter/refresh/leave edges, stacking, and cleanup
126
+ */
127
+ export declare function createAreaEffectField<P = unknown>(state?: AreaFieldState<P>): AreaEffectField<P>;