@jgengine/core 0.10.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 (607) hide show
  1. package/CHANGELOG.md +13 -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/spawnDirector.d.ts +7 -2
  21. package/dist/ai/spawnDirector.js +18 -15
  22. package/dist/ai/spawnPoint.d.ts +3 -1
  23. package/dist/ai/spawnPoint.js +3 -1
  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/authoring.d.ts +1 -0
  35. package/dist/authoring.js +1 -0
  36. package/dist/board/laneBoard.d.ts +13 -0
  37. package/dist/board/laneBoard.js +13 -0
  38. package/dist/board/timelineBoard.d.ts +10 -0
  39. package/dist/board/timelineBoard.js +10 -0
  40. package/dist/combat/abilityKit.d.ts +18 -0
  41. package/dist/combat/abilityKit.js +24 -9
  42. package/dist/combat/animationState.d.ts +5 -0
  43. package/dist/combat/animationState.js +5 -0
  44. package/dist/combat/breakMeters.d.ts +10 -0
  45. package/dist/combat/breakMeters.js +10 -0
  46. package/dist/combat/castRunner.d.ts +5 -0
  47. package/dist/combat/castRunner.js +5 -0
  48. package/dist/combat/comboPoints.d.ts +5 -0
  49. package/dist/combat/comboPoints.js +5 -0
  50. package/dist/combat/comboString.d.ts +5 -0
  51. package/dist/combat/comboString.js +5 -0
  52. package/dist/combat/damageInterceptors.d.ts +192 -0
  53. package/dist/combat/damageInterceptors.js +251 -0
  54. package/dist/combat/damageMatchup.d.ts +68 -0
  55. package/dist/combat/damageMatchup.js +42 -0
  56. package/dist/combat/damageResolution.d.ts +63 -0
  57. package/dist/combat/damageResolution.js +50 -0
  58. package/dist/combat/death.d.ts +7 -1
  59. package/dist/combat/death.js +5 -0
  60. package/dist/combat/deathReason.d.ts +14 -0
  61. package/dist/combat/deathReason.js +1 -0
  62. package/dist/combat/defensiveWindow.d.ts +5 -0
  63. package/dist/combat/defensiveWindow.js +5 -0
  64. package/dist/combat/dotField.d.ts +5 -1
  65. package/dist/combat/dotField.js +5 -1
  66. package/dist/combat/downed.d.ts +5 -0
  67. package/dist/combat/downed.js +5 -0
  68. package/dist/combat/effects.d.ts +5 -0
  69. package/dist/combat/effects.js +5 -0
  70. package/dist/combat/encounterSequence.d.ts +258 -0
  71. package/dist/combat/encounterSequence.js +426 -0
  72. package/dist/combat/hitReaction.d.ts +57 -1
  73. package/dist/combat/hitReaction.js +45 -5
  74. package/dist/combat/magazine.d.ts +54 -0
  75. package/dist/combat/magazine.js +96 -0
  76. package/dist/combat/projectiles.d.ts +5 -0
  77. package/dist/combat/projectiles.js +32 -14
  78. package/dist/combat/receivedDamage.d.ts +117 -0
  79. package/dist/combat/receivedDamage.js +92 -0
  80. package/dist/combat/regenShield.d.ts +5 -1
  81. package/dist/combat/regenShield.js +5 -1
  82. package/dist/combat/renderCues.d.ts +51 -0
  83. package/dist/combat/renderCues.js +44 -0
  84. package/dist/combat/resourcePool.d.ts +5 -0
  85. package/dist/combat/resourcePool.js +5 -0
  86. package/dist/combat/rewardAllocation.d.ts +121 -0
  87. package/dist/combat/rewardAllocation.js +251 -0
  88. package/dist/combat/shotOrigin.d.ts +18 -1
  89. package/dist/combat/shotOrigin.js +39 -0
  90. package/dist/combat/statusApplication.d.ts +96 -0
  91. package/dist/combat/statusApplication.js +81 -0
  92. package/dist/combat/telegraph.d.ts +11 -2
  93. package/dist/combat/telegraph.js +11 -2
  94. package/dist/combat/thresholdCrossings.d.ts +85 -0
  95. package/dist/combat/thresholdCrossings.js +116 -0
  96. package/dist/combat.d.ts +34 -0
  97. package/dist/combat.js +34 -0
  98. package/dist/commands/commandRegistry.d.ts +11 -0
  99. package/dist/commands/commandRegistry.js +9 -2
  100. package/dist/crafting/crop.d.ts +18 -0
  101. package/dist/crafting/crop.js +18 -0
  102. package/dist/crafting/production.d.ts +5 -0
  103. package/dist/crafting/production.js +5 -0
  104. package/dist/devtools/rewriteTunables.d.ts +17 -0
  105. package/dist/devtools/rewriteTunables.js +276 -0
  106. package/dist/devtools/saveEndpoint.d.ts +46 -0
  107. package/dist/devtools/saveEndpoint.js +48 -0
  108. package/dist/devtools/transformTunables.d.ts +3 -0
  109. package/dist/devtools/transformTunables.js +3 -0
  110. package/dist/devtools/tunableSchema.d.ts +31 -0
  111. package/dist/devtools/tunableSchema.js +31 -0
  112. package/dist/economy/currency.d.ts +12 -1
  113. package/dist/economy/currency.js +12 -1
  114. package/dist/economy/listingBook.d.ts +91 -0
  115. package/dist/economy/listingBook.js +144 -0
  116. package/dist/economy/resourceLedger.d.ts +222 -0
  117. package/dist/economy/resourceLedger.js +353 -0
  118. package/dist/economy/sharedWallet.d.ts +14 -0
  119. package/dist/economy/sharedWallet.js +14 -0
  120. package/dist/economy/techTree.d.ts +12 -0
  121. package/dist/economy/techTree.js +12 -0
  122. package/dist/economy/wallet.d.ts +26 -2
  123. package/dist/economy/wallet.js +35 -6
  124. package/dist/editor/commands.d.ts +190 -7
  125. package/dist/editor/commands.js +727 -55
  126. package/dist/editor/document.d.ts +159 -13
  127. package/dist/editor/document.js +750 -19
  128. package/dist/editor/grid.d.ts +229 -0
  129. package/dist/editor/grid.js +366 -0
  130. package/dist/editor/gridAdapters.d.ts +80 -0
  131. package/dist/editor/gridAdapters.js +134 -0
  132. package/dist/editor/index.d.ts +73 -6
  133. package/dist/editor/index.js +6 -2
  134. package/dist/editor/liveSync.d.ts +127 -0
  135. package/dist/editor/liveSync.js +249 -0
  136. package/dist/editor/runtimeInspector.d.ts +88 -0
  137. package/dist/editor/runtimeInspector.js +239 -0
  138. package/dist/editor/types.d.ts +107 -1
  139. package/dist/faction/reputation.d.ts +5 -0
  140. package/dist/faction/reputation.js +5 -0
  141. package/dist/format/distance.d.ts +17 -0
  142. package/dist/format/distance.js +18 -0
  143. package/dist/format/duration.d.ts +27 -0
  144. package/dist/format/duration.js +45 -0
  145. package/dist/format/speed.d.ts +17 -0
  146. package/dist/format/speed.js +25 -0
  147. package/dist/game/connectedPlayers.d.ts +6 -4
  148. package/dist/game/connectedPlayers.js +2 -2
  149. package/dist/game/cosmetics.d.ts +9 -0
  150. package/dist/game/cosmetics.js +16 -0
  151. package/dist/game/defineGame.d.ts +100 -2
  152. package/dist/game/defineGame.js +39 -2
  153. package/dist/game/defineSystem.d.ts +88 -0
  154. package/dist/game/defineSystem.js +45 -0
  155. package/dist/game/dialogue.d.ts +33 -0
  156. package/dist/game/dialogue.js +21 -0
  157. package/dist/game/events.d.ts +35 -13
  158. package/dist/game/events.js +5 -0
  159. package/dist/game/feed.d.ts +33 -0
  160. package/dist/game/feed.js +35 -2
  161. package/dist/game/gamePhase.d.ts +11 -0
  162. package/dist/game/gamePhase.js +16 -0
  163. package/dist/game/leaderboard.d.ts +5 -0
  164. package/dist/game/leaderboard.js +5 -0
  165. package/dist/game/loadout.d.ts +5 -0
  166. package/dist/game/loadout.js +5 -0
  167. package/dist/game/lootFilter.d.ts +2 -0
  168. package/dist/game/lootFilter.js +2 -0
  169. package/dist/game/lootPipeline.d.ts +164 -0
  170. package/dist/game/lootPipeline.js +216 -0
  171. package/dist/game/lootTable.d.ts +19 -2
  172. package/dist/game/lootTable.js +15 -5
  173. package/dist/game/objectives.d.ts +43 -0
  174. package/dist/game/objectives.js +36 -0
  175. package/dist/game/paramLayers.d.ts +148 -0
  176. package/dist/game/paramLayers.js +185 -0
  177. package/dist/game/ping.d.ts +5 -0
  178. package/dist/game/ping.js +5 -0
  179. package/dist/game/playableGame.d.ts +92 -7
  180. package/dist/game/quest.d.ts +8 -0
  181. package/dist/game/quest.js +29 -0
  182. package/dist/game/race.d.ts +141 -0
  183. package/dist/game/race.js +169 -0
  184. package/dist/game/recordBook.d.ts +3 -1
  185. package/dist/game/recordBook.js +4 -1
  186. package/dist/game/ruleSelection.d.ts +75 -0
  187. package/dist/game/ruleSelection.js +127 -0
  188. package/dist/game/runDraft.d.ts +5 -0
  189. package/dist/game/runDraft.js +5 -0
  190. package/dist/game/saveStore.d.ts +111 -0
  191. package/dist/game/saveStore.js +312 -0
  192. package/dist/game/snapshotHistory.d.ts +67 -0
  193. package/dist/game/snapshotHistory.js +95 -0
  194. package/dist/game/social.d.ts +38 -1
  195. package/dist/game/social.js +71 -0
  196. package/dist/game/spawnPoints.d.ts +5 -0
  197. package/dist/game/spawnPoints.js +5 -0
  198. package/dist/game/systemRuntime.d.ts +50 -0
  199. package/dist/game/systemRuntime.js +157 -0
  200. package/dist/game/systemSchedule.d.ts +72 -0
  201. package/dist/game/systemSchedule.js +242 -0
  202. package/dist/game/toasts.d.ts +43 -0
  203. package/dist/game/toasts.js +44 -0
  204. package/dist/game/trade.d.ts +10 -0
  205. package/dist/game/trade.js +10 -0
  206. package/dist/game/unlocks.d.ts +8 -0
  207. package/dist/game/unlocks.js +16 -0
  208. package/dist/game/vfxInstance.d.ts +138 -0
  209. package/dist/game/vfxInstance.js +96 -0
  210. package/dist/game/worldItem.d.ts +17 -4
  211. package/dist/game/worldItem.js +17 -4
  212. package/dist/gameplay.d.ts +91 -0
  213. package/dist/gameplay.js +91 -0
  214. package/dist/index.d.ts +5 -14
  215. package/dist/index.js +5 -14
  216. package/dist/input/actionBindings.d.ts +23 -6
  217. package/dist/input/actionBindings.js +23 -6
  218. package/dist/input/axisInput.d.ts +7 -2
  219. package/dist/input/axisInput.js +7 -2
  220. package/dist/input/controlGroups.d.ts +67 -0
  221. package/dist/input/controlGroups.js +41 -0
  222. package/dist/input/touchScheme.d.ts +82 -6
  223. package/dist/input/touchScheme.js +123 -10
  224. package/dist/interaction/lockpick.d.ts +61 -0
  225. package/dist/interaction/lockpick.js +168 -0
  226. package/dist/interaction/proximityPrompt.d.ts +2 -0
  227. package/dist/interaction/proximityPrompt.js +2 -0
  228. package/dist/interaction/qte.d.ts +5 -0
  229. package/dist/interaction/qte.js +5 -0
  230. package/dist/interaction/skillCheck.d.ts +5 -0
  231. package/dist/interaction/skillCheck.js +5 -0
  232. package/dist/inventory/inventoryModel.d.ts +12 -0
  233. package/dist/inventory/inventoryModel.js +12 -0
  234. package/dist/inventory/shapedGrid.d.ts +16 -0
  235. package/dist/inventory/shapedGrid.js +16 -0
  236. package/dist/inventory/slotModel.d.ts +10 -0
  237. package/dist/inventory/slotModel.js +10 -0
  238. package/dist/item/durability.d.ts +5 -0
  239. package/dist/item/durability.js +5 -0
  240. package/dist/item/itemIdentity.d.ts +171 -0
  241. package/dist/item/itemIdentity.js +138 -0
  242. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  243. package/dist/item/itemInstanceRegistry.js +34 -0
  244. package/dist/item/itemgen.d.ts +163 -0
  245. package/dist/item/itemgen.js +151 -0
  246. package/dist/item/modularItem.d.ts +5 -0
  247. package/dist/item/modularItem.js +5 -0
  248. package/dist/item/use.d.ts +5 -0
  249. package/dist/item/use.js +5 -0
  250. package/dist/item/useBehavior.d.ts +142 -0
  251. package/dist/item/useBehavior.js +105 -0
  252. package/dist/item/weapon.d.ts +5 -0
  253. package/dist/item/weapon.js +5 -0
  254. package/dist/math/scalar.d.ts +25 -0
  255. package/dist/math/scalar.js +47 -0
  256. package/dist/meta/changelog.d.ts +4 -1
  257. package/dist/meta/changelog.js +16 -2
  258. package/dist/movement/avoidance.d.ts +45 -0
  259. package/dist/movement/avoidance.js +123 -0
  260. package/dist/movement/cameraRig.d.ts +8 -0
  261. package/dist/movement/cameraRig.js +8 -0
  262. package/dist/movement/dash.d.ts +11 -0
  263. package/dist/movement/dash.js +11 -0
  264. package/dist/movement/formation.d.ts +135 -0
  265. package/dist/movement/formation.js +194 -0
  266. package/dist/movement/glideModel.d.ts +5 -0
  267. package/dist/movement/glideModel.js +5 -0
  268. package/dist/movement/grappleSwing.d.ts +5 -0
  269. package/dist/movement/grappleSwing.js +5 -0
  270. package/dist/movement/leaderTrail.d.ts +5 -0
  271. package/dist/movement/leaderTrail.js +5 -0
  272. package/dist/movement/movementModel.d.ts +35 -8
  273. package/dist/movement/movementModel.js +42 -14
  274. package/dist/movement/playerMovement.js +65 -10
  275. package/dist/movement/poseState.d.ts +13 -0
  276. package/dist/movement/poseState.js +16 -0
  277. package/dist/movement/steering.d.ts +8 -0
  278. package/dist/movement/steering.js +18 -0
  279. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  280. package/dist/multiplayer/combatSnapshot.js +3 -0
  281. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  282. package/dist/multiplayer/lagCompensation.js +5 -0
  283. package/dist/multiplayer/presenceModel.d.ts +9 -1
  284. package/dist/multiplayer/presenceModel.js +9 -1
  285. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  286. package/dist/multiplayer/simultaneousCommit.js +3 -0
  287. package/dist/multiplayer.d.ts +11 -0
  288. package/dist/multiplayer.js +11 -0
  289. package/dist/nav/pathFollow.d.ts +57 -0
  290. package/dist/nav/pathFollow.js +109 -0
  291. package/dist/orders/orderKinds.d.ts +156 -0
  292. package/dist/orders/orderKinds.js +197 -0
  293. package/dist/orders/orderQueue.d.ts +208 -0
  294. package/dist/orders/orderQueue.js +211 -0
  295. package/dist/physics/drivableVehicle.d.ts +29 -0
  296. package/dist/physics/drivableVehicle.js +16 -0
  297. package/dist/physics/kinematicVehicle.d.ts +21 -1
  298. package/dist/physics/kinematicVehicle.js +23 -8
  299. package/dist/physics/physicsWorld.d.ts +24 -12
  300. package/dist/physics/physicsWorld.js +11 -5
  301. package/dist/physics/radialImpulse.d.ts +25 -0
  302. package/dist/physics/radialImpulse.js +27 -0
  303. package/dist/procedural.d.ts +3 -0
  304. package/dist/procedural.js +3 -0
  305. package/dist/progression/statGraph.d.ts +116 -0
  306. package/dist/progression/statGraph.js +318 -0
  307. package/dist/puzzle/cellGrid.d.ts +9 -0
  308. package/dist/puzzle/cellGrid.js +9 -0
  309. package/dist/puzzle/fallingPiece.d.ts +9 -0
  310. package/dist/puzzle/fallingPiece.js +9 -0
  311. package/dist/puzzle/nonogram.d.ts +39 -0
  312. package/dist/puzzle/nonogram.js +136 -0
  313. package/dist/random/nameGen.d.ts +5 -0
  314. package/dist/random/nameGen.js +5 -0
  315. package/dist/random/pick.d.ts +8 -0
  316. package/dist/random/pick.js +31 -0
  317. package/dist/random/rng.d.ts +22 -0
  318. package/dist/random/rng.js +28 -8
  319. package/dist/random/seedLink.d.ts +4 -0
  320. package/dist/random/seedLink.js +4 -0
  321. package/dist/relation/keyedValues.d.ts +54 -0
  322. package/dist/relation/keyedValues.js +115 -0
  323. package/dist/relation/thresholds.d.ts +62 -0
  324. package/dist/relation/thresholds.js +62 -0
  325. package/dist/render/color.d.ts +12 -0
  326. package/dist/render/color.js +26 -0
  327. package/dist/render/lookPreset.d.ts +41 -0
  328. package/dist/render/lookPreset.js +29 -0
  329. package/dist/render/postProcessing.d.ts +20 -0
  330. package/dist/render/postProcessing.js +21 -1
  331. package/dist/rules/predicate.d.ts +53 -0
  332. package/dist/rules/predicate.js +64 -0
  333. package/dist/rules/ruleEffects.d.ts +38 -0
  334. package/dist/rules/ruleEffects.js +37 -0
  335. package/dist/rules/triggeredRules.d.ts +160 -0
  336. package/dist/rules/triggeredRules.js +241 -0
  337. package/dist/runtime/adapter.d.ts +42 -3
  338. package/dist/runtime/adapter.js +44 -1
  339. package/dist/runtime/cameraDirector.d.ts +1 -0
  340. package/dist/runtime/cameraDirector.js +1 -0
  341. package/dist/runtime/commandRunner.d.ts +1 -0
  342. package/dist/runtime/commandRunner.js +1 -0
  343. package/dist/runtime/context/combatFx.d.ts +23 -0
  344. package/dist/runtime/context/combatFx.js +161 -0
  345. package/dist/runtime/context/registries.d.ts +13 -0
  346. package/dist/runtime/context/registries.js +84 -0
  347. package/dist/runtime/context/worldItems.d.ts +21 -0
  348. package/dist/runtime/context/worldItems.js +37 -0
  349. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  350. package/dist/runtime/descriptors/baseline.js +134 -0
  351. package/dist/runtime/descriptors/features.d.ts +74 -0
  352. package/dist/runtime/descriptors/features.js +281 -0
  353. package/dist/runtime/gameContext.d.ts +114 -13
  354. package/dist/runtime/gameContext.js +303 -395
  355. package/dist/runtime/gameRuntime.d.ts +1 -0
  356. package/dist/runtime/gameRuntime.js +1 -0
  357. package/dist/runtime/headlessRunner.d.ts +60 -0
  358. package/dist/runtime/headlessRunner.js +44 -0
  359. package/dist/runtime/hostPersistence.d.ts +12 -0
  360. package/dist/runtime/hostPersistence.js +12 -0
  361. package/dist/runtime/hostedGameRunner.d.ts +8 -3
  362. package/dist/runtime/hostedGameRunner.js +26 -3
  363. package/dist/runtime/hostedWorldSession.d.ts +12 -4
  364. package/dist/runtime/hostedWorldSession.js +11 -4
  365. package/dist/runtime/inputSnapshot.d.ts +8 -3
  366. package/dist/runtime/inputSnapshot.js +6 -2
  367. package/dist/runtime/motionIntents.d.ts +11 -2
  368. package/dist/runtime/motionIntents.js +16 -2
  369. package/dist/runtime/perContext.d.ts +15 -0
  370. package/dist/runtime/perContext.js +21 -0
  371. package/dist/runtime/runtimeSave.d.ts +79 -0
  372. package/dist/runtime/runtimeSave.js +105 -0
  373. package/dist/runtime/save.d.ts +4 -0
  374. package/dist/runtime/save.js +4 -0
  375. package/dist/runtime/snapshot.d.ts +7 -0
  376. package/dist/runtime/snapshot.js +7 -0
  377. package/dist/runtime/visibility.d.ts +2 -1
  378. package/dist/runtime/visibility.js +2 -1
  379. package/dist/runtime/worldChannel.d.ts +7 -3
  380. package/dist/runtime/worldChannel.js +51 -6
  381. package/dist/runtime/worldMirror.d.ts +14 -2
  382. package/dist/runtime/worldMirror.js +15 -2
  383. package/dist/runtime/worldProjection.d.ts +47 -0
  384. package/dist/runtime/worldProjection.js +52 -0
  385. package/dist/runtime/worldReplication.d.ts +30 -7
  386. package/dist/runtime/worldReplication.js +41 -9
  387. package/dist/runtime/worldSnapshot.d.ts +30 -3
  388. package/dist/runtime/worldSnapshot.js +20 -5
  389. package/dist/scene/assetCatalog.d.ts +21 -0
  390. package/dist/scene/assetCatalog.js +4 -0
  391. package/dist/scene/assetDiagnostics.d.ts +69 -0
  392. package/dist/scene/assetDiagnostics.js +110 -0
  393. package/dist/scene/assetGenerator.d.ts +65 -0
  394. package/dist/scene/assetGenerator.js +64 -0
  395. package/dist/scene/assetSpace.d.ts +137 -0
  396. package/dist/scene/assetSpace.js +259 -0
  397. package/dist/scene/authoredTriggers.d.ts +169 -0
  398. package/dist/scene/authoredTriggers.js +340 -0
  399. package/dist/scene/behaviorRuntime.d.ts +75 -0
  400. package/dist/scene/behaviorRuntime.js +217 -0
  401. package/dist/scene/behaviors.d.ts +14 -2
  402. package/dist/scene/behaviors.js +7 -2
  403. package/dist/scene/bodyBind.d.ts +60 -0
  404. package/dist/scene/bodyBind.js +51 -0
  405. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  406. package/dist/scene/builtinSceneKinds.js +62 -0
  407. package/dist/scene/colliders.d.ts +13 -1
  408. package/dist/scene/colliders.js +37 -1
  409. package/dist/scene/entityStats.d.ts +11 -2
  410. package/dist/scene/entityStats.js +11 -2
  411. package/dist/scene/entityStore.d.ts +12 -1
  412. package/dist/scene/entityStore.js +15 -0
  413. package/dist/scene/facing.d.ts +18 -0
  414. package/dist/scene/facing.js +26 -0
  415. package/dist/scene/modelSockets.d.ts +33 -0
  416. package/dist/scene/modelSockets.js +29 -0
  417. package/dist/scene/objectQuery.d.ts +2 -0
  418. package/dist/scene/objectQuery.js +2 -0
  419. package/dist/scene/objectStore.d.ts +4 -0
  420. package/dist/scene/objectStore.js +6 -0
  421. package/dist/scene/possession.d.ts +8 -0
  422. package/dist/scene/possession.js +14 -0
  423. package/dist/scene/roster.d.ts +3 -0
  424. package/dist/scene/roster.js +12 -0
  425. package/dist/scene/sceneKinds.d.ts +240 -0
  426. package/dist/scene/sceneKinds.js +214 -0
  427. package/dist/scene/sceneOwnership.d.ts +169 -0
  428. package/dist/scene/sceneOwnership.js +179 -0
  429. package/dist/scene/selectionBookmarks.d.ts +93 -0
  430. package/dist/scene/selectionBookmarks.js +122 -0
  431. package/dist/scene/vehicleSeat.d.ts +68 -0
  432. package/dist/scene/vehicleSeat.js +59 -0
  433. package/dist/sensor/concealment.d.ts +3 -0
  434. package/dist/sensor/concealment.js +3 -0
  435. package/dist/sensor/freezeMonitor.d.ts +1 -0
  436. package/dist/sensor/freezeMonitor.js +1 -0
  437. package/dist/sensor/frustumSensor.d.ts +7 -3
  438. package/dist/sensor/frustumSensor.js +7 -3
  439. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  440. package/dist/sensor/hiddenStateProbe.js +5 -2
  441. package/dist/sensor/recordingBuffer.d.ts +2 -1
  442. package/dist/sensor/recordingBuffer.js +2 -1
  443. package/dist/sensor/replayLoop.d.ts +6 -2
  444. package/dist/sensor/replayLoop.js +6 -2
  445. package/dist/sensor/revealQuery.d.ts +2 -1
  446. package/dist/sensor/revealQuery.js +2 -1
  447. package/dist/sensor/visionCone.d.ts +10 -3
  448. package/dist/sensor/visionCone.js +10 -3
  449. package/dist/session/contestedChannel.d.ts +1 -0
  450. package/dist/session/contestedChannel.js +1 -0
  451. package/dist/session/extraction.d.ts +1 -0
  452. package/dist/session/extraction.js +1 -0
  453. package/dist/session/roles.d.ts +6 -0
  454. package/dist/session/roles.js +6 -0
  455. package/dist/session/roundState.d.ts +8 -0
  456. package/dist/session/roundState.js +2 -0
  457. package/dist/settings/settingsModel.d.ts +1 -0
  458. package/dist/settings/settingsModel.js +1 -0
  459. package/dist/stats/accumulatorMeter.d.ts +6 -0
  460. package/dist/stats/accumulatorMeter.js +6 -0
  461. package/dist/stats/eventMeter.d.ts +5 -0
  462. package/dist/stats/eventMeter.js +5 -0
  463. package/dist/stats/rollCheck.d.ts +5 -0
  464. package/dist/stats/rollCheck.js +5 -0
  465. package/dist/stats/statModifiers.d.ts +5 -0
  466. package/dist/stats/statModifiers.js +5 -0
  467. package/dist/store/defineKeyedStore.d.ts +38 -0
  468. package/dist/store/defineKeyedStore.js +42 -0
  469. package/dist/store/defineStore.d.ts +33 -0
  470. package/dist/store/defineStore.js +35 -0
  471. package/dist/store/observableKeyedStore.d.ts +5 -0
  472. package/dist/store/observableKeyedStore.js +34 -2
  473. package/dist/survival/decayMeter.d.ts +55 -0
  474. package/dist/survival/decayMeter.js +130 -55
  475. package/dist/survival/moodle.d.ts +2 -0
  476. package/dist/survival/regionHealth.d.ts +6 -0
  477. package/dist/survival/regionHealth.js +5 -0
  478. package/dist/tactics/fallingGrid.d.ts +4 -2
  479. package/dist/tactics/fallingGrid.js +4 -2
  480. package/dist/tactics/predictiveQuery.d.ts +3 -0
  481. package/dist/tactics/predictiveQuery.js +3 -0
  482. package/dist/tactics/snapshot.d.ts +2 -0
  483. package/dist/tactics/snapshot.js +2 -0
  484. package/dist/tactics/surface.d.ts +1 -0
  485. package/dist/tactics/surface.js +1 -0
  486. package/dist/tactics/tacticalGrid.d.ts +1 -0
  487. package/dist/tactics/tacticalGrid.js +1 -0
  488. package/dist/time/beatClock.d.ts +14 -4
  489. package/dist/time/beatClock.js +14 -4
  490. package/dist/time/calendarClock.d.ts +3 -0
  491. package/dist/time/calendarClock.js +3 -0
  492. package/dist/time/idleProgress.d.ts +4 -0
  493. package/dist/time/idleProgress.js +4 -0
  494. package/dist/time/simClock.d.ts +2 -0
  495. package/dist/time/simClock.js +20 -5
  496. package/dist/ui/actionModel.d.ts +110 -0
  497. package/dist/ui/actionModel.js +159 -0
  498. package/dist/ui/gameLayout.d.ts +30 -11
  499. package/dist/ui/gameLayout.js +30 -11
  500. package/dist/ui/hudDocument.d.ts +114 -0
  501. package/dist/ui/hudDocument.js +220 -0
  502. package/dist/ui/hudLayout.d.ts +33 -1
  503. package/dist/ui/hudLayout.js +204 -17
  504. package/dist/ui/selectionModel.d.ts +92 -0
  505. package/dist/ui/selectionModel.js +88 -0
  506. package/dist/ui/tooltipModel.d.ts +63 -0
  507. package/dist/ui/tooltipModel.js +82 -0
  508. package/dist/ui.d.ts +15 -0
  509. package/dist/ui.js +15 -0
  510. package/dist/visibility/bounds.d.ts +8 -1
  511. package/dist/visibility/bounds.js +8 -1
  512. package/dist/visibility/frustum.d.ts +12 -3
  513. package/dist/visibility/frustum.js +12 -3
  514. package/dist/work/jobQueue.d.ts +201 -0
  515. package/dist/work/jobQueue.js +253 -0
  516. package/dist/work/unitTraining.d.ts +58 -0
  517. package/dist/work/unitTraining.js +52 -0
  518. package/dist/world/authoredObjects.d.ts +58 -0
  519. package/dist/world/authoredObjects.js +69 -0
  520. package/dist/world/buildingGenerator.d.ts +18 -0
  521. package/dist/world/buildingGenerator.js +62 -0
  522. package/dist/world/buildings.d.ts +5 -0
  523. package/dist/world/buildings.js +5 -0
  524. package/dist/world/catenary.d.ts +22 -0
  525. package/dist/world/catenary.js +69 -0
  526. package/dist/world/features.d.ts +115 -7
  527. package/dist/world/features.js +56 -5
  528. package/dist/world/footprintGrid.d.ts +59 -0
  529. package/dist/world/footprintGrid.js +141 -0
  530. package/dist/world/geometry.d.ts +64 -0
  531. package/dist/world/geometry.js +94 -0
  532. package/dist/world/grassKind.d.ts +51 -0
  533. package/dist/world/grassKind.js +101 -0
  534. package/dist/world/pathInstances.d.ts +27 -0
  535. package/dist/world/pathInstances.js +27 -0
  536. package/dist/world/pathTerrain.d.ts +80 -0
  537. package/dist/world/pathTerrain.js +142 -0
  538. package/dist/world/placeAsset.d.ts +81 -0
  539. package/dist/world/placeAsset.js +77 -0
  540. package/dist/world/placement.d.ts +4 -0
  541. package/dist/world/placement.js +4 -0
  542. package/dist/world/placementController.d.ts +6 -0
  543. package/dist/world/placementController.js +6 -0
  544. package/dist/world/polyline.d.ts +34 -0
  545. package/dist/world/polyline.js +81 -0
  546. package/dist/world/roads.d.ts +8 -0
  547. package/dist/world/roads.js +38 -0
  548. package/dist/world/scatterRegion.d.ts +164 -0
  549. package/dist/world/scatterRegion.js +409 -0
  550. package/dist/world/sceneShapes.d.ts +43 -0
  551. package/dist/world/sceneShapes.js +1 -0
  552. package/dist/world/segment.d.ts +27 -0
  553. package/dist/world/segment.js +43 -0
  554. package/dist/world/soilKind.d.ts +48 -0
  555. package/dist/world/soilKind.js +92 -0
  556. package/dist/world/spatialSample.d.ts +241 -0
  557. package/dist/world/spatialSample.js +465 -0
  558. package/dist/world/terraform.d.ts +213 -1
  559. package/dist/world/terraform.js +655 -20
  560. package/dist/world/terrain.d.ts +119 -20
  561. package/dist/world/terrain.js +247 -41
  562. package/dist/world/terrainGuides.d.ts +182 -0
  563. package/dist/world/terrainGuides.js +343 -0
  564. package/dist/world/vec2.d.ts +81 -0
  565. package/dist/world/vec2.js +128 -0
  566. package/dist/world/vec3.d.ts +49 -0
  567. package/dist/world/vec3.js +76 -0
  568. package/dist/world/vegetation.d.ts +71 -0
  569. package/dist/world/vegetation.js +151 -0
  570. package/dist/world/visibilityField.d.ts +154 -0
  571. package/dist/world/visibilityField.js +271 -0
  572. package/dist/world/volumetricClouds.d.ts +52 -0
  573. package/dist/world/volumetricClouds.js +43 -0
  574. package/dist/world/walls.d.ts +9 -0
  575. package/dist/world/walls.js +9 -0
  576. package/dist/world/waterKind.d.ts +55 -0
  577. package/dist/world/waterKind.js +99 -0
  578. package/dist/world.d.ts +132 -0
  579. package/dist/world.js +132 -0
  580. package/package.json +32 -8
  581. package/skills/jgengine/SKILL.md +51 -0
  582. package/skills/jgengine/api.md +434 -0
  583. package/skills/jgengine/capabilities.md +29 -0
  584. package/skills/jgengine/reference-cartridge.md +72 -0
  585. package/skills/jgengine-combat/SKILL.md +34 -0
  586. package/skills/jgengine-combat/api.md +549 -0
  587. package/skills/jgengine-combat/capabilities.md +169 -0
  588. package/skills/jgengine-combat/reference.md +98 -0
  589. package/skills/jgengine-gameplay/SKILL.md +39 -0
  590. package/skills/jgengine-gameplay/api.md +1794 -0
  591. package/skills/jgengine-gameplay/capabilities.md +378 -0
  592. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  593. package/skills/jgengine-world/SKILL.md +38 -0
  594. package/skills/jgengine-world/api.md +2652 -0
  595. package/skills/jgengine-world/capabilities.md +370 -0
  596. package/skills/jgengine-world/reference.md +222 -0
  597. package/dist/cartridge/runtime.d.ts +0 -15
  598. package/dist/cartridge/runtime.js +0 -556
  599. package/dist/cartridge/spec.d.ts +0 -188
  600. package/dist/cartridge/spec.js +0 -19
  601. package/dist/cartridge/validate.d.ts +0 -2
  602. package/dist/cartridge/validate.js +0 -78
  603. package/dist/store/engineStore.d.ts +0 -22
  604. package/dist/store/engineStore.js +0 -50
  605. package/dist/store/features.d.ts +0 -10
  606. package/dist/store/features.js +0 -23
  607. package/llms.txt +0 -5389
@@ -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>;
@@ -0,0 +1,175 @@
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
+ const SENTINEL_SHAPE = { kind: "sphere", center: [0, 0, 0], radius: 0 };
15
+ function shapeContains(shape, point) {
16
+ if (shape.kind === "custom")
17
+ return shape.contains(point);
18
+ const dx = point[0] - shape.center[0];
19
+ const dy = point[1] - shape.center[1];
20
+ const dz = point[2] - shape.center[2];
21
+ return dx * dx + dy * dy + dz * dz <= shape.radius * shape.radius;
22
+ }
23
+ /**
24
+ * Build a continuous area-effect field. Drive it with `setSource` (once per live source per tick, so
25
+ * shapes follow their emitters) and `step` (to reconcile membership and drain enter/refresh/leave edges).
26
+ * Optionally restore prior membership by passing a `serialize()` snapshot; re-`setSource` live shapes
27
+ * before the first `step` after restore, since shapes are transient.
28
+ *
29
+ * @capability area-effect-field source-following area membership with enter/refresh/leave edges, stacking, and cleanup
30
+ */
31
+ export function createAreaEffectField(state) {
32
+ const sources = new Map();
33
+ if (state !== undefined) {
34
+ for (const source of state.sources) {
35
+ sources.set(source.id, {
36
+ shape: SENTINEL_SHAPE,
37
+ payload: source.payload,
38
+ refreshMs: source.refreshMs,
39
+ stackKey: source.stackKey,
40
+ enabled: source.enabled,
41
+ members: new Map(),
42
+ });
43
+ }
44
+ for (const membership of state.memberships) {
45
+ sources.get(membership.sourceId)?.members.set(membership.receiverId, {
46
+ sinceRefreshMs: membership.sinceRefreshMs,
47
+ });
48
+ }
49
+ }
50
+ function leaveAll(rec, sourceId, reason) {
51
+ const events = [];
52
+ for (const receiverId of rec.members.keys()) {
53
+ events.push({ kind: "leave", sourceId, receiverId, stackKey: rec.stackKey, payload: rec.payload, reason });
54
+ }
55
+ rec.members.clear();
56
+ return events;
57
+ }
58
+ return {
59
+ setSource(spec) {
60
+ const stackKey = spec.stackKey ?? spec.id;
61
+ const enabled = spec.enabled ?? true;
62
+ const existing = sources.get(spec.id);
63
+ if (existing !== undefined) {
64
+ existing.shape = spec.shape;
65
+ existing.payload = spec.payload;
66
+ existing.refreshMs = spec.refreshMs;
67
+ existing.stackKey = stackKey;
68
+ existing.enabled = enabled;
69
+ return;
70
+ }
71
+ sources.set(spec.id, {
72
+ shape: spec.shape,
73
+ payload: spec.payload,
74
+ refreshMs: spec.refreshMs,
75
+ stackKey,
76
+ enabled,
77
+ members: new Map(),
78
+ });
79
+ },
80
+ removeSource(id) {
81
+ const rec = sources.get(id);
82
+ if (rec === undefined)
83
+ return [];
84
+ const events = leaveAll(rec, id, "source-removed");
85
+ sources.delete(id);
86
+ return events;
87
+ },
88
+ hasSource: (id) => sources.has(id),
89
+ sourceIds: () => [...sources.keys()],
90
+ step(input) {
91
+ const dtMs = Math.max(0, input.dtMs);
92
+ const events = [];
93
+ for (const [sourceId, rec] of sources) {
94
+ if (!rec.enabled) {
95
+ events.push(...leaveAll(rec, sourceId, "disabled"));
96
+ continue;
97
+ }
98
+ const seen = new Set();
99
+ for (const receiverId of input.candidates(rec.shape)) {
100
+ if (seen.has(receiverId))
101
+ continue;
102
+ const position = input.positionOf(receiverId);
103
+ if (position === undefined)
104
+ continue;
105
+ if (!shapeContains(rec.shape, position))
106
+ continue;
107
+ if (input.eligible !== undefined && !input.eligible(sourceId, receiverId, rec.payload))
108
+ continue;
109
+ seen.add(receiverId);
110
+ const member = rec.members.get(receiverId);
111
+ if (member === undefined) {
112
+ rec.members.set(receiverId, { sinceRefreshMs: 0 });
113
+ events.push({ kind: "enter", sourceId, receiverId, stackKey: rec.stackKey, payload: rec.payload });
114
+ continue;
115
+ }
116
+ if (rec.refreshMs !== undefined && rec.refreshMs > 0) {
117
+ member.sinceRefreshMs += dtMs;
118
+ let ticks = 0;
119
+ while (member.sinceRefreshMs >= rec.refreshMs) {
120
+ member.sinceRefreshMs -= rec.refreshMs;
121
+ ticks += 1;
122
+ }
123
+ if (ticks > 0) {
124
+ events.push({ kind: "refresh", sourceId, receiverId, stackKey: rec.stackKey, payload: rec.payload, ticks });
125
+ }
126
+ }
127
+ }
128
+ for (const receiverId of [...rec.members.keys()]) {
129
+ if (seen.has(receiverId))
130
+ continue;
131
+ rec.members.delete(receiverId);
132
+ events.push({ kind: "leave", sourceId, receiverId, stackKey: rec.stackKey, payload: rec.payload, reason: "exit" });
133
+ }
134
+ }
135
+ return events;
136
+ },
137
+ members: (sourceId) => [...(sources.get(sourceId)?.members.keys() ?? [])],
138
+ isMember: (sourceId, receiverId) => sources.get(sourceId)?.members.has(receiverId) ?? false,
139
+ memberships() {
140
+ const out = [];
141
+ for (const [sourceId, rec] of sources) {
142
+ for (const receiverId of rec.members.keys()) {
143
+ out.push({ sourceId, receiverId, stackKey: rec.stackKey, payload: rec.payload });
144
+ }
145
+ }
146
+ return out;
147
+ },
148
+ membershipsOf(receiverId) {
149
+ const out = [];
150
+ for (const [sourceId, rec] of sources) {
151
+ if (rec.members.has(receiverId)) {
152
+ out.push({ sourceId, receiverId, stackKey: rec.stackKey, payload: rec.payload });
153
+ }
154
+ }
155
+ return out;
156
+ },
157
+ clear() {
158
+ const events = [];
159
+ for (const [sourceId, rec] of sources)
160
+ events.push(...leaveAll(rec, sourceId, "cleared"));
161
+ sources.clear();
162
+ return events;
163
+ },
164
+ serialize() {
165
+ const out = { sources: [], memberships: [] };
166
+ for (const [id, rec] of sources) {
167
+ out.sources.push({ id, payload: rec.payload, refreshMs: rec.refreshMs, stackKey: rec.stackKey, enabled: rec.enabled });
168
+ for (const [receiverId, member] of rec.members) {
169
+ out.memberships.push({ sourceId: id, receiverId, sinceRefreshMs: member.sinceRefreshMs });
170
+ }
171
+ }
172
+ return out;
173
+ },
174
+ };
175
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Overlap aggregation for {@link AreaMembership} lists: when several area sources cover the same
3
+ * receiver, a policy decides which memberships actually apply. Genre-agnostic and pure — policies
4
+ * are `(memberships) => memberships` reducers over one receiver's memberships, so the caller stays
5
+ * in control of magnitude and meaning. Pair with `createAreaEffectField().membershipsOf(receiverId)`.
6
+ */
7
+ import type { AreaMembership } from "./areaEffectField.js";
8
+ /** Reduce one receiver's overlapping memberships to the subset that applies under a stacking rule. */
9
+ export type AreaStackPolicy<P> = (memberships: readonly AreaMembership<P>[]) => AreaMembership<P>[];
10
+ /** Read a comparable magnitude from a membership (e.g. buff strength, damage per tick). */
11
+ export type MagnitudeOf<P> = (membership: AreaMembership<P>) => number;
12
+ /**
13
+ * Every overlapping membership applies independently (no deduplication) — the default for hazards,
14
+ * fields, and lights where two sources genuinely stack.
15
+ *
16
+ * @capability area-stack-independent apply every overlapping area membership independently
17
+ */
18
+ export declare function independentStacks<P>(): AreaStackPolicy<P>;
19
+ /**
20
+ * Keep at most one membership per `stackKey`. With `magnitudeOf` the strongest per key wins (ties
21
+ * broken by `sourceId` for determinism); without it the first-seen per key wins. Use for
22
+ * unique-by-key buffs where reapplying the same aura should not stack.
23
+ *
24
+ * @capability area-stack-unique keep one area membership per stack key, strongest wins
25
+ */
26
+ export declare function uniqueByStackKey<P>(magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P>;
27
+ /**
28
+ * Keep at most `limit` memberships per `stackKey` (the highest-magnitude ones when `magnitudeOf` is
29
+ * given, else the first-seen). Models capped stacks — e.g. a poison that stacks up to 5 times.
30
+ *
31
+ * @capability area-stack-capped cap area memberships per stack key at a maximum count
32
+ */
33
+ export declare function cappedStacks<P>(limit: number, magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P>;
34
+ /**
35
+ * Reduce to the single strongest membership overall (`weakest = false` picks the weakest); ties broken
36
+ * by `sourceId`. Use when only the best or worst overlapping source should apply.
37
+ *
38
+ * @capability area-stack-extremum keep only the strongest or weakest overlapping area membership
39
+ */
40
+ export declare function extremumStack<P>(magnitudeOf: MagnitudeOf<P>, weakest?: boolean): AreaStackPolicy<P>;
41
+ /**
42
+ * Sum a numeric magnitude across memberships — additive aggregation for a total field strength
43
+ * (total damage per tick, total slow). A terminal reducer, not a filter, so it returns the number.
44
+ *
45
+ * @capability area-stack-additive sum a magnitude across overlapping area memberships
46
+ */
47
+ export declare function sumMagnitude<P>(memberships: readonly AreaMembership<P>[], magnitudeOf: MagnitudeOf<P>): number;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Overlap aggregation for {@link AreaMembership} lists: when several area sources cover the same
3
+ * receiver, a policy decides which memberships actually apply. Genre-agnostic and pure — policies
4
+ * are `(memberships) => memberships` reducers over one receiver's memberships, so the caller stays
5
+ * in control of magnitude and meaning. Pair with `createAreaEffectField().membershipsOf(receiverId)`.
6
+ */
7
+ function byMagnitudeDesc(magnitudeOf) {
8
+ return (a, b) => {
9
+ const diff = magnitudeOf(b) - magnitudeOf(a);
10
+ if (diff !== 0)
11
+ return diff;
12
+ return a.sourceId < b.sourceId ? -1 : a.sourceId > b.sourceId ? 1 : 0;
13
+ };
14
+ }
15
+ function groupByStackKey(memberships) {
16
+ const groups = new Map();
17
+ for (const membership of memberships) {
18
+ const list = groups.get(membership.stackKey);
19
+ if (list === undefined)
20
+ groups.set(membership.stackKey, [membership]);
21
+ else
22
+ list.push(membership);
23
+ }
24
+ return groups;
25
+ }
26
+ /**
27
+ * Every overlapping membership applies independently (no deduplication) — the default for hazards,
28
+ * fields, and lights where two sources genuinely stack.
29
+ *
30
+ * @capability area-stack-independent apply every overlapping area membership independently
31
+ */
32
+ export function independentStacks() {
33
+ return (memberships) => [...memberships];
34
+ }
35
+ /**
36
+ * Keep at most one membership per `stackKey`. With `magnitudeOf` the strongest per key wins (ties
37
+ * broken by `sourceId` for determinism); without it the first-seen per key wins. Use for
38
+ * unique-by-key buffs where reapplying the same aura should not stack.
39
+ *
40
+ * @capability area-stack-unique keep one area membership per stack key, strongest wins
41
+ */
42
+ export function uniqueByStackKey(magnitudeOf) {
43
+ return (memberships) => {
44
+ const out = [];
45
+ for (const group of groupByStackKey(memberships).values()) {
46
+ if (magnitudeOf === undefined) {
47
+ out.push(group[0]);
48
+ }
49
+ else {
50
+ out.push([...group].sort(byMagnitudeDesc(magnitudeOf))[0]);
51
+ }
52
+ }
53
+ return out;
54
+ };
55
+ }
56
+ /**
57
+ * Keep at most `limit` memberships per `stackKey` (the highest-magnitude ones when `magnitudeOf` is
58
+ * given, else the first-seen). Models capped stacks — e.g. a poison that stacks up to 5 times.
59
+ *
60
+ * @capability area-stack-capped cap area memberships per stack key at a maximum count
61
+ */
62
+ export function cappedStacks(limit, magnitudeOf) {
63
+ const cap = Math.max(0, Math.floor(limit));
64
+ return (memberships) => {
65
+ const out = [];
66
+ for (const group of groupByStackKey(memberships).values()) {
67
+ const ordered = magnitudeOf === undefined ? group : [...group].sort(byMagnitudeDesc(magnitudeOf));
68
+ for (const membership of ordered.slice(0, cap))
69
+ out.push(membership);
70
+ }
71
+ return out;
72
+ };
73
+ }
74
+ /**
75
+ * Reduce to the single strongest membership overall (`weakest = false` picks the weakest); ties broken
76
+ * by `sourceId`. Use when only the best or worst overlapping source should apply.
77
+ *
78
+ * @capability area-stack-extremum keep only the strongest or weakest overlapping area membership
79
+ */
80
+ export function extremumStack(magnitudeOf, weakest = false) {
81
+ return (memberships) => {
82
+ if (memberships.length === 0)
83
+ return [];
84
+ const ordered = [...memberships].sort(byMagnitudeDesc(magnitudeOf));
85
+ return [weakest ? ordered[ordered.length - 1] : ordered[0]];
86
+ };
87
+ }
88
+ /**
89
+ * Sum a numeric magnitude across memberships — additive aggregation for a total field strength
90
+ * (total damage per tick, total slow). A terminal reducer, not a filter, so it returns the number.
91
+ *
92
+ * @capability area-stack-additive sum a magnitude across overlapping area memberships
93
+ */
94
+ export function sumMagnitude(memberships, magnitudeOf) {
95
+ let total = 0;
96
+ for (const membership of memberships)
97
+ total += magnitudeOf(membership);
98
+ return total;
99
+ }
@@ -12,3 +12,4 @@ export { seededRng, seededStreams } from "./random/rng.js";
12
12
  export { selectSpawnPoint, type SpawnPointSelectionOptions, type SpawnPointDistanceBias, } from "./ai/spawnPoint.js";
13
13
  export { contextVerb } from "./interaction/contextMenu.js";
14
14
  export { type ActionCodesMap } from "./input/actionBindings.js";
15
+ export { classifyOwnership, collectOwnershipDiagnostics, auditManifest, ownershipKey, isSceneOwnershipManifest, SCENE_OWNERSHIP_MANIFEST_VERSION, type SceneProvenance, type SceneProvenanceKind, type AuthoredProvenance, type GeneratedProvenance, type RuntimeProvenance, type TransientProvenance, type ProviderCapabilities, type SceneOwnershipDeclaration, type OwnershipDecision, type OwnershipVerdict, type OwnershipDiagnostic, type SceneOwnershipManifest, } from "./scene/sceneOwnership.js";
package/dist/authoring.js CHANGED
@@ -12,3 +12,4 @@ export { seededRng, seededStreams } from "./random/rng.js";
12
12
  export { selectSpawnPoint, } from "./ai/spawnPoint.js";
13
13
  export { contextVerb } from "./interaction/contextMenu.js";
14
14
  export {} from "./input/actionBindings.js";
15
+ export { classifyOwnership, collectOwnershipDiagnostics, auditManifest, ownershipKey, isSceneOwnershipManifest, SCENE_OWNERSHIP_MANIFEST_VERSION, } from "./scene/sceneOwnership.js";
@@ -43,12 +43,19 @@ export interface LanePlaceRejected {
43
43
  reason: LaneRejection;
44
44
  }
45
45
  export type LaneResult<C> = LanePlaceResult<C> | LanePlaceRejected;
46
+ /** @internal */
46
47
  export declare function createLaneBoardState<C>(config: LaneBoardConfig<C>): LaneBoardState<C>;
48
+ /** @internal */
47
49
  export declare function placeCard<C>(state: LaneBoardState<C>, config: LaneBoardConfig<C>, lane: number, side: Side, card: C): LaneResult<C>;
50
+ /** @internal */
48
51
  export declare function removeCard<C>(state: LaneBoardState<C>, lane: number, side: Side, predicate: (card: C, index: number) => boolean): LaneResult<C>;
52
+ /** @internal */
49
53
  export declare function laneAggregate<C>(state: LaneBoardState<C>, config: LaneBoardConfig<C>, lane: number, side: Side): LaneAggregate;
54
+ /** @internal */
50
55
  export declare function laneOutcome<C>(state: LaneBoardState<C>, config: LaneBoardConfig<C>, lane: number): LaneOutcome;
56
+ /** @internal */
51
57
  export declare function boardTotals<C>(state: LaneBoardState<C>, config: LaneBoardConfig<C>): Readonly<Record<Side, number>>;
58
+ /** @internal */
52
59
  export declare function lanesWon<C>(state: LaneBoardState<C>, config: LaneBoardConfig<C>): Readonly<Record<Side, number>>;
53
60
  export interface LaneBoard<C> {
54
61
  state(): LaneBoardState<C>;
@@ -60,4 +67,10 @@ export interface LaneBoard<C> {
60
67
  lanesWon(): Readonly<Record<Side, number>>;
61
68
  reset(next?: LaneBoardState<C>): void;
62
69
  }
70
+ /**
71
+ * A lane-based board where cards resolve per lane — the lane card-battler layout.
72
+ *
73
+ * @capability lane-board a lane-based card-battler board with per-lane outcomes
74
+ * @internal
75
+ */
63
76
  export declare function createLaneBoard<C>(config: LaneBoardConfig<C>): LaneBoard<C>;
@@ -4,6 +4,7 @@ function emptyLane(sides) {
4
4
  cells[side] = [];
5
5
  return cells;
6
6
  }
7
+ /** @internal */
7
8
  export function createLaneBoardState(config) {
8
9
  if (config.laneCount <= 0)
9
10
  throw new Error("laneBoard needs at least one lane");
@@ -17,6 +18,7 @@ export function createLaneBoardState(config) {
17
18
  function validLane(state, lane) {
18
19
  return Number.isInteger(lane) && lane >= 0 && lane < state.lanes.length;
19
20
  }
21
+ /** @internal */
20
22
  export function placeCard(state, config, lane, side, card) {
21
23
  if (!validLane(state, lane))
22
24
  return { status: "rejected", reason: "invalid-lane" };
@@ -27,6 +29,7 @@ export function placeCard(state, config, lane, side, card) {
27
29
  lanes[lane] = { ...cell, [side]: [...cell[side], card] };
28
30
  return { status: "ok", state: { lanes } };
29
31
  }
32
+ /** @internal */
30
33
  export function removeCard(state, lane, side, predicate) {
31
34
  if (!validLane(state, lane))
32
35
  return { status: "rejected", reason: "invalid-lane" };
@@ -37,6 +40,7 @@ export function removeCard(state, lane, side, predicate) {
37
40
  lanes[lane] = { ...cell, [side]: cell[side].filter((card, index) => !predicate(card, index)) };
38
41
  return { status: "ok", state: { lanes } };
39
42
  }
43
+ /** @internal */
40
44
  export function laneAggregate(state, config, lane, side) {
41
45
  const cards = state.lanes[lane]?.[side] ?? [];
42
46
  let subtotal = 0;
@@ -46,6 +50,7 @@ export function laneAggregate(state, config, lane, side) {
46
50
  const total = rule ? rule.apply({ lane, side, cards, subtotal }) : subtotal;
47
51
  return { lane, side, subtotal, total, count: cards.length };
48
52
  }
53
+ /** @internal */
49
54
  export function laneOutcome(state, config, lane) {
50
55
  const totals = {};
51
56
  let winner = null;
@@ -65,6 +70,7 @@ export function laneOutcome(state, config, lane) {
65
70
  }
66
71
  return { lane, totals, winner: tie ? null : winner };
67
72
  }
73
+ /** @internal */
68
74
  export function boardTotals(state, config) {
69
75
  const totals = {};
70
76
  for (const side of config.sides)
@@ -76,6 +82,7 @@ export function boardTotals(state, config) {
76
82
  }
77
83
  return totals;
78
84
  }
85
+ /** @internal */
79
86
  export function lanesWon(state, config) {
80
87
  const won = {};
81
88
  for (const side of config.sides)
@@ -87,6 +94,12 @@ export function lanesWon(state, config) {
87
94
  }
88
95
  return won;
89
96
  }
97
+ /**
98
+ * A lane-based board where cards resolve per lane — the lane card-battler layout.
99
+ *
100
+ * @capability lane-board a lane-based card-battler board with per-lane outcomes
101
+ * @internal
102
+ */
90
103
  export function createLaneBoard(config) {
91
104
  let state = createLaneBoardState(config);
92
105
  return {
@@ -23,9 +23,13 @@ export interface TimelineTickResult {
23
23
  state: TimelineBoardState;
24
24
  fires: readonly TimelineFire[];
25
25
  }
26
+ /** @internal */
26
27
  export declare function createTimelineBoardState(slots: readonly TimelineSlotConfig[]): TimelineBoardState;
28
+ /** @internal */
27
29
  export declare function tickTimeline(state: TimelineBoardState, dtMs: number): TimelineTickResult;
30
+ /** @internal */
28
31
  export declare function setSlotEnabled(state: TimelineBoardState, slotId: string, enabled: boolean): TimelineBoardState;
32
+ /** @internal */
29
33
  export declare function resetSlot(state: TimelineBoardState, slotId: string, remainingMs?: number): TimelineBoardState;
30
34
  export interface TimelineBoard {
31
35
  state(): TimelineBoardState;
@@ -33,4 +37,10 @@ export interface TimelineBoard {
33
37
  setEnabled(slotId: string, enabled: boolean): void;
34
38
  reset(slotId?: string, remainingMs?: number): void;
35
39
  }
40
+ /**
41
+ * A step-sequencer timeline board of timed, toggleable slots.
42
+ *
43
+ * @capability timeline-board a step-sequencer timeline board of timed slots
44
+ * @internal
45
+ */
36
46
  export declare function createTimelineBoard(slots: readonly TimelineSlotConfig[]): TimelineBoard;
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function createTimelineBoardState(slots) {
2
3
  const seen = new Set();
3
4
  const built = [];
@@ -16,6 +17,7 @@ export function createTimelineBoardState(slots) {
16
17
  }
17
18
  return { slots: built, elapsedMs: 0 };
18
19
  }
20
+ /** @internal */
19
21
  export function tickTimeline(state, dtMs) {
20
22
  if (dtMs <= 0)
21
23
  return { state, fires: [] };
@@ -38,18 +40,26 @@ export function tickTimeline(state, dtMs) {
38
40
  fires,
39
41
  };
40
42
  }
43
+ /** @internal */
41
44
  export function setSlotEnabled(state, slotId, enabled) {
42
45
  return {
43
46
  ...state,
44
47
  slots: state.slots.map((slot) => (slot.id === slotId ? { ...slot, enabled } : slot)),
45
48
  };
46
49
  }
50
+ /** @internal */
47
51
  export function resetSlot(state, slotId, remainingMs) {
48
52
  return {
49
53
  ...state,
50
54
  slots: state.slots.map((slot) => slot.id === slotId ? { ...slot, remainingMs: remainingMs ?? slot.cooldownMs } : slot),
51
55
  };
52
56
  }
57
+ /**
58
+ * A step-sequencer timeline board of timed, toggleable slots.
59
+ *
60
+ * @capability timeline-board a step-sequencer timeline board of timed slots
61
+ * @internal
62
+ */
53
63
  export function createTimelineBoard(slots) {
54
64
  const initial = slots;
55
65
  let state = createTimelineBoardState(slots);
@@ -15,8 +15,21 @@ export interface AbilityCooldownGroup {
15
15
  id: string;
16
16
  cooldownMs: number;
17
17
  }
18
+ /**
19
+ * A spendable resource pool (mana, energy, rage) bound to an ability kit. When bound, `cast` deducts a
20
+ * slot's `resourceCost` on success and `state`/`snapshot`/`canCast` reflect affordability without a
21
+ * per-call `resourceAvailable` argument — the cast path actually spends instead of only gating (#357).
22
+ */
23
+ export interface AbilityResource {
24
+ /** Current spendable amount, read fresh on each cast/snapshot. */
25
+ available(): number;
26
+ /** Deduct `cost` from the pool after a successful cast. */
27
+ spend(cost: number): void;
28
+ }
18
29
  export interface AbilityKitOptions {
19
30
  groups?: readonly AbilityCooldownGroup[];
31
+ /** Bind a resource pool so casting charges `resourceCost` and snapshots reflect affordability automatically. Passing an explicit `resourceAvailable` to a method overrides the bound pool for that call and never auto-spends. */
32
+ resource?: AbilityResource;
20
33
  }
21
34
  export interface AbilitySlotSnapshot {
22
35
  id: string;
@@ -59,4 +72,9 @@ export interface AbilityKit {
59
72
  reset(slotId?: string): void;
60
73
  retuneSlot(slotId: string, patch: AbilitySlotRetune): boolean;
61
74
  }
75
+ /**
76
+ * A bar of cooldown-gated abilities the player fires by slot, tracking readiness and cooldown per ability.
77
+ *
78
+ * @capability ability-bar a bar of cooldown-gated abilities the player triggers by slot
79
+ */
62
80
  export declare function createAbilityKit(configs: readonly AbilitySlotConfig[], options?: AbilityKitOptions): AbilityKit;