@jgengine/core 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (631) hide show
  1. package/CHANGELOG.md +34 -3
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/spawnDirector.d.ts +19 -1
  21. package/dist/ai/spawnDirector.js +53 -26
  22. package/dist/ai/spawnPoint.d.ts +7 -0
  23. package/dist/ai/spawnPoint.js +7 -0
  24. package/dist/ai/targetAcquisition.d.ts +84 -0
  25. package/dist/ai/targetAcquisition.js +92 -0
  26. package/dist/anim/easing.d.ts +19 -0
  27. package/dist/anim/easing.js +19 -0
  28. package/dist/anim/oscillator.d.ts +12 -0
  29. package/dist/anim/oscillator.js +25 -0
  30. package/dist/area/areaEffectField.d.ts +127 -0
  31. package/dist/area/areaEffectField.js +175 -0
  32. package/dist/area/stackPolicy.d.ts +47 -0
  33. package/dist/area/stackPolicy.js +99 -0
  34. package/dist/audio/audioFalloff.d.ts +5 -2
  35. package/dist/audio/music.d.ts +53 -0
  36. package/dist/audio/music.js +34 -0
  37. package/dist/audio/synth.d.ts +60 -0
  38. package/dist/audio/synth.js +8 -0
  39. package/dist/authoring.d.ts +15 -0
  40. package/dist/authoring.js +15 -0
  41. package/dist/board/laneBoard.d.ts +13 -0
  42. package/dist/board/laneBoard.js +13 -0
  43. package/dist/board/timelineBoard.d.ts +10 -0
  44. package/dist/board/timelineBoard.js +10 -0
  45. package/dist/combat/abilityKit.d.ts +18 -0
  46. package/dist/combat/abilityKit.js +24 -9
  47. package/dist/combat/animationState.d.ts +5 -0
  48. package/dist/combat/animationState.js +5 -0
  49. package/dist/combat/breakMeters.d.ts +10 -0
  50. package/dist/combat/breakMeters.js +10 -0
  51. package/dist/combat/castRunner.d.ts +5 -0
  52. package/dist/combat/castRunner.js +5 -0
  53. package/dist/combat/comboPoints.d.ts +5 -0
  54. package/dist/combat/comboPoints.js +5 -0
  55. package/dist/combat/comboString.d.ts +5 -0
  56. package/dist/combat/comboString.js +5 -0
  57. package/dist/combat/damageInterceptors.d.ts +192 -0
  58. package/dist/combat/damageInterceptors.js +251 -0
  59. package/dist/combat/damageMatchup.d.ts +68 -0
  60. package/dist/combat/damageMatchup.js +42 -0
  61. package/dist/combat/damageResolution.d.ts +63 -0
  62. package/dist/combat/damageResolution.js +50 -0
  63. package/dist/combat/death.d.ts +7 -1
  64. package/dist/combat/death.js +5 -0
  65. package/dist/combat/deathReason.d.ts +14 -0
  66. package/dist/combat/deathReason.js +1 -0
  67. package/dist/combat/defensiveWindow.d.ts +5 -0
  68. package/dist/combat/defensiveWindow.js +5 -0
  69. package/dist/combat/dotField.d.ts +47 -0
  70. package/dist/combat/dotField.js +52 -0
  71. package/dist/combat/downed.d.ts +5 -0
  72. package/dist/combat/downed.js +5 -0
  73. package/dist/combat/effects.d.ts +5 -0
  74. package/dist/combat/effects.js +5 -0
  75. package/dist/combat/encounterSequence.d.ts +258 -0
  76. package/dist/combat/encounterSequence.js +426 -0
  77. package/dist/combat/hitReaction.d.ts +57 -1
  78. package/dist/combat/hitReaction.js +45 -5
  79. package/dist/combat/magazine.d.ts +54 -0
  80. package/dist/combat/magazine.js +96 -0
  81. package/dist/combat/projectiles.d.ts +7 -2
  82. package/dist/combat/projectiles.js +48 -17
  83. package/dist/combat/receivedDamage.d.ts +117 -0
  84. package/dist/combat/receivedDamage.js +92 -0
  85. package/dist/combat/regenShield.d.ts +39 -0
  86. package/dist/combat/regenShield.js +49 -0
  87. package/dist/combat/renderCues.d.ts +51 -0
  88. package/dist/combat/renderCues.js +44 -0
  89. package/dist/combat/resourcePool.d.ts +5 -0
  90. package/dist/combat/resourcePool.js +5 -0
  91. package/dist/combat/rewardAllocation.d.ts +121 -0
  92. package/dist/combat/rewardAllocation.js +251 -0
  93. package/dist/combat/shotOrigin.d.ts +30 -1
  94. package/dist/combat/shotOrigin.js +70 -2
  95. package/dist/combat/statusApplication.d.ts +96 -0
  96. package/dist/combat/statusApplication.js +81 -0
  97. package/dist/combat/telegraph.d.ts +11 -2
  98. package/dist/combat/telegraph.js +11 -2
  99. package/dist/combat/thresholdCrossings.d.ts +85 -0
  100. package/dist/combat/thresholdCrossings.js +116 -0
  101. package/dist/combat.d.ts +34 -0
  102. package/dist/combat.js +34 -0
  103. package/dist/commands/commandRegistry.d.ts +11 -0
  104. package/dist/commands/commandRegistry.js +9 -2
  105. package/dist/crafting/crop.d.ts +18 -0
  106. package/dist/crafting/crop.js +18 -0
  107. package/dist/crafting/production.d.ts +5 -0
  108. package/dist/crafting/production.js +5 -0
  109. package/dist/devtools/rewriteTunables.d.ts +17 -0
  110. package/dist/devtools/rewriteTunables.js +276 -0
  111. package/dist/devtools/saveEndpoint.d.ts +46 -0
  112. package/dist/devtools/saveEndpoint.js +48 -0
  113. package/dist/devtools/transformTunables.d.ts +3 -0
  114. package/dist/devtools/transformTunables.js +3 -0
  115. package/dist/devtools/tunableSchema.d.ts +31 -0
  116. package/dist/devtools/tunableSchema.js +31 -0
  117. package/dist/economy/currency.d.ts +12 -1
  118. package/dist/economy/currency.js +12 -1
  119. package/dist/economy/listingBook.d.ts +91 -0
  120. package/dist/economy/listingBook.js +144 -0
  121. package/dist/economy/resourceLedger.d.ts +222 -0
  122. package/dist/economy/resourceLedger.js +353 -0
  123. package/dist/economy/sharedWallet.d.ts +14 -0
  124. package/dist/economy/sharedWallet.js +14 -0
  125. package/dist/economy/techTree.d.ts +12 -0
  126. package/dist/economy/techTree.js +12 -0
  127. package/dist/economy/wallet.d.ts +26 -2
  128. package/dist/economy/wallet.js +35 -6
  129. package/dist/editor/commands.d.ts +248 -0
  130. package/dist/editor/commands.js +865 -0
  131. package/dist/editor/document.d.ts +186 -0
  132. package/dist/editor/document.js +884 -0
  133. package/dist/editor/grid.d.ts +229 -0
  134. package/dist/editor/grid.js +366 -0
  135. package/dist/editor/gridAdapters.d.ts +80 -0
  136. package/dist/editor/gridAdapters.js +134 -0
  137. package/dist/editor/index.d.ts +97 -0
  138. package/dist/editor/index.js +10 -0
  139. package/dist/editor/liveSync.d.ts +127 -0
  140. package/dist/editor/liveSync.js +249 -0
  141. package/dist/editor/runtimeInspector.d.ts +88 -0
  142. package/dist/editor/runtimeInspector.js +239 -0
  143. package/dist/editor/types.d.ts +175 -0
  144. package/dist/editor/types.js +29 -0
  145. package/dist/faction/reputation.d.ts +5 -0
  146. package/dist/faction/reputation.js +5 -0
  147. package/dist/format/distance.d.ts +17 -0
  148. package/dist/format/distance.js +18 -0
  149. package/dist/format/duration.d.ts +27 -0
  150. package/dist/format/duration.js +45 -0
  151. package/dist/format/speed.d.ts +17 -0
  152. package/dist/format/speed.js +25 -0
  153. package/dist/game/connectedPlayers.d.ts +30 -0
  154. package/dist/game/connectedPlayers.js +21 -0
  155. package/dist/game/cosmetics.d.ts +9 -0
  156. package/dist/game/cosmetics.js +16 -0
  157. package/dist/game/defineGame.d.ts +141 -2
  158. package/dist/game/defineGame.js +39 -1
  159. package/dist/game/defineSystem.d.ts +88 -0
  160. package/dist/game/defineSystem.js +45 -0
  161. package/dist/game/dialogue.d.ts +33 -0
  162. package/dist/game/dialogue.js +21 -0
  163. package/dist/game/events.d.ts +50 -13
  164. package/dist/game/events.js +5 -0
  165. package/dist/game/feed.d.ts +33 -0
  166. package/dist/game/feed.js +35 -2
  167. package/dist/game/gamePhase.d.ts +11 -0
  168. package/dist/game/gamePhase.js +16 -0
  169. package/dist/game/keyValueStore.d.ts +25 -0
  170. package/dist/game/keyValueStore.js +61 -0
  171. package/dist/game/leaderboard.d.ts +5 -0
  172. package/dist/game/leaderboard.js +5 -0
  173. package/dist/game/levelSequence.d.ts +24 -2
  174. package/dist/game/levelSequence.js +51 -2
  175. package/dist/game/loadout.d.ts +5 -0
  176. package/dist/game/loadout.js +5 -0
  177. package/dist/game/lootFilter.d.ts +2 -0
  178. package/dist/game/lootFilter.js +2 -0
  179. package/dist/game/lootPipeline.d.ts +164 -0
  180. package/dist/game/lootPipeline.js +216 -0
  181. package/dist/game/lootTable.d.ts +21 -0
  182. package/dist/game/lootTable.js +15 -4
  183. package/dist/game/modelAnimation.d.ts +8 -0
  184. package/dist/game/modelAnimation.js +18 -0
  185. package/dist/game/objectives.d.ts +43 -0
  186. package/dist/game/objectives.js +36 -0
  187. package/dist/game/paramLayers.d.ts +148 -0
  188. package/dist/game/paramLayers.js +185 -0
  189. package/dist/game/ping.d.ts +5 -0
  190. package/dist/game/ping.js +5 -0
  191. package/dist/game/playableGame.d.ts +160 -12
  192. package/dist/game/quest.d.ts +8 -0
  193. package/dist/game/quest.js +29 -0
  194. package/dist/game/race.d.ts +141 -0
  195. package/dist/game/race.js +169 -0
  196. package/dist/game/recordBook.d.ts +5 -5
  197. package/dist/game/recordBook.js +4 -1
  198. package/dist/game/ruleSelection.d.ts +75 -0
  199. package/dist/game/ruleSelection.js +127 -0
  200. package/dist/game/runDraft.d.ts +5 -0
  201. package/dist/game/runDraft.js +5 -0
  202. package/dist/game/saveStore.d.ts +111 -0
  203. package/dist/game/saveStore.js +312 -0
  204. package/dist/game/snapshotHistory.d.ts +67 -0
  205. package/dist/game/snapshotHistory.js +95 -0
  206. package/dist/game/social.d.ts +38 -1
  207. package/dist/game/social.js +71 -0
  208. package/dist/game/spawnPoints.d.ts +5 -0
  209. package/dist/game/spawnPoints.js +5 -0
  210. package/dist/game/systemRuntime.d.ts +50 -0
  211. package/dist/game/systemRuntime.js +157 -0
  212. package/dist/game/systemSchedule.d.ts +72 -0
  213. package/dist/game/systemSchedule.js +242 -0
  214. package/dist/game/toasts.d.ts +43 -0
  215. package/dist/game/toasts.js +44 -0
  216. package/dist/game/trade.d.ts +10 -0
  217. package/dist/game/trade.js +10 -0
  218. package/dist/game/unlocks.d.ts +8 -0
  219. package/dist/game/unlocks.js +16 -0
  220. package/dist/game/vfxInstance.d.ts +138 -0
  221. package/dist/game/vfxInstance.js +96 -0
  222. package/dist/game/worldItem.d.ts +17 -4
  223. package/dist/game/worldItem.js +17 -4
  224. package/dist/gameplay.d.ts +91 -0
  225. package/dist/gameplay.js +91 -0
  226. package/dist/index.d.ts +5 -7
  227. package/dist/index.js +5 -7
  228. package/dist/input/actionBindings.d.ts +24 -5
  229. package/dist/input/actionBindings.js +23 -5
  230. package/dist/input/axisInput.d.ts +13 -1
  231. package/dist/input/axisInput.js +22 -1
  232. package/dist/input/controlGroups.d.ts +67 -0
  233. package/dist/input/controlGroups.js +41 -0
  234. package/dist/input/touchScheme.d.ts +82 -6
  235. package/dist/input/touchScheme.js +123 -10
  236. package/dist/interaction/contextMenu.d.ts +1 -0
  237. package/dist/interaction/contextMenu.js +1 -0
  238. package/dist/interaction/lockpick.d.ts +61 -0
  239. package/dist/interaction/lockpick.js +168 -0
  240. package/dist/interaction/proximityPrompt.d.ts +5 -1
  241. package/dist/interaction/proximityPrompt.js +5 -3
  242. package/dist/interaction/qte.d.ts +5 -0
  243. package/dist/interaction/qte.js +5 -0
  244. package/dist/interaction/skillCheck.d.ts +5 -0
  245. package/dist/interaction/skillCheck.js +5 -0
  246. package/dist/inventory/inventoryModel.d.ts +12 -0
  247. package/dist/inventory/inventoryModel.js +12 -0
  248. package/dist/inventory/shapedGrid.d.ts +16 -0
  249. package/dist/inventory/shapedGrid.js +16 -0
  250. package/dist/inventory/slotModel.d.ts +10 -0
  251. package/dist/inventory/slotModel.js +10 -0
  252. package/dist/item/durability.d.ts +5 -0
  253. package/dist/item/durability.js +5 -0
  254. package/dist/item/itemIdentity.d.ts +171 -0
  255. package/dist/item/itemIdentity.js +138 -0
  256. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  257. package/dist/item/itemInstanceRegistry.js +34 -0
  258. package/dist/item/itemgen.d.ts +163 -0
  259. package/dist/item/itemgen.js +151 -0
  260. package/dist/item/modularItem.d.ts +5 -0
  261. package/dist/item/modularItem.js +5 -0
  262. package/dist/item/use.d.ts +5 -0
  263. package/dist/item/use.js +5 -0
  264. package/dist/item/useBehavior.d.ts +142 -0
  265. package/dist/item/useBehavior.js +105 -0
  266. package/dist/item/weapon.d.ts +5 -0
  267. package/dist/item/weapon.js +5 -0
  268. package/dist/math/scalar.d.ts +25 -0
  269. package/dist/math/scalar.js +47 -0
  270. package/dist/meta/changelog.d.ts +4 -1
  271. package/dist/meta/changelog.js +36 -1
  272. package/dist/movement/avoidance.d.ts +45 -0
  273. package/dist/movement/avoidance.js +123 -0
  274. package/dist/movement/cameraRig.d.ts +8 -0
  275. package/dist/movement/cameraRig.js +8 -0
  276. package/dist/movement/dash.d.ts +11 -0
  277. package/dist/movement/dash.js +11 -0
  278. package/dist/movement/formation.d.ts +135 -0
  279. package/dist/movement/formation.js +194 -0
  280. package/dist/movement/glideModel.d.ts +5 -0
  281. package/dist/movement/glideModel.js +5 -0
  282. package/dist/movement/grappleSwing.d.ts +5 -0
  283. package/dist/movement/grappleSwing.js +5 -0
  284. package/dist/movement/leaderTrail.d.ts +5 -0
  285. package/dist/movement/leaderTrail.js +5 -0
  286. package/dist/movement/movementModel.d.ts +38 -7
  287. package/dist/movement/movementModel.js +54 -13
  288. package/dist/movement/playerMovement.d.ts +41 -0
  289. package/dist/movement/playerMovement.js +236 -0
  290. package/dist/movement/poseState.d.ts +13 -0
  291. package/dist/movement/poseState.js +16 -0
  292. package/dist/movement/steering.d.ts +8 -0
  293. package/dist/movement/steering.js +18 -0
  294. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  295. package/dist/multiplayer/combatSnapshot.js +3 -0
  296. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  297. package/dist/multiplayer/lagCompensation.js +5 -0
  298. package/dist/multiplayer/presenceModel.d.ts +9 -1
  299. package/dist/multiplayer/presenceModel.js +9 -1
  300. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  301. package/dist/multiplayer/simultaneousCommit.js +3 -0
  302. package/dist/multiplayer.d.ts +11 -0
  303. package/dist/multiplayer.js +11 -0
  304. package/dist/nav/pathFollow.d.ts +57 -0
  305. package/dist/nav/pathFollow.js +109 -0
  306. package/dist/orders/orderKinds.d.ts +156 -0
  307. package/dist/orders/orderKinds.js +197 -0
  308. package/dist/orders/orderQueue.d.ts +208 -0
  309. package/dist/orders/orderQueue.js +211 -0
  310. package/dist/physics/drivableVehicle.d.ts +29 -0
  311. package/dist/physics/drivableVehicle.js +16 -0
  312. package/dist/physics/kinematicVehicle.d.ts +21 -1
  313. package/dist/physics/kinematicVehicle.js +23 -8
  314. package/dist/physics/physicsWorld.d.ts +24 -12
  315. package/dist/physics/physicsWorld.js +11 -5
  316. package/dist/physics/radialImpulse.d.ts +25 -0
  317. package/dist/physics/radialImpulse.js +27 -0
  318. package/dist/procedural.d.ts +3 -0
  319. package/dist/procedural.js +3 -0
  320. package/dist/progression/statGraph.d.ts +116 -0
  321. package/dist/progression/statGraph.js +318 -0
  322. package/dist/puzzle/cellGrid.d.ts +9 -0
  323. package/dist/puzzle/cellGrid.js +9 -0
  324. package/dist/puzzle/fallingPiece.d.ts +9 -0
  325. package/dist/puzzle/fallingPiece.js +9 -0
  326. package/dist/puzzle/nonogram.d.ts +39 -0
  327. package/dist/puzzle/nonogram.js +136 -0
  328. package/dist/random/nameGen.d.ts +5 -0
  329. package/dist/random/nameGen.js +5 -0
  330. package/dist/random/pick.d.ts +8 -0
  331. package/dist/random/pick.js +31 -0
  332. package/dist/random/rng.d.ts +24 -0
  333. package/dist/random/rng.js +30 -8
  334. package/dist/random/seedLink.d.ts +4 -0
  335. package/dist/random/seedLink.js +4 -0
  336. package/dist/relation/keyedValues.d.ts +54 -0
  337. package/dist/relation/keyedValues.js +115 -0
  338. package/dist/relation/thresholds.d.ts +62 -0
  339. package/dist/relation/thresholds.js +62 -0
  340. package/dist/render/color.d.ts +12 -0
  341. package/dist/render/color.js +26 -0
  342. package/dist/render/lookPreset.d.ts +41 -0
  343. package/dist/render/lookPreset.js +29 -0
  344. package/dist/render/postProcessing.d.ts +76 -0
  345. package/dist/render/postProcessing.js +21 -0
  346. package/dist/rules/predicate.d.ts +53 -0
  347. package/dist/rules/predicate.js +64 -0
  348. package/dist/rules/ruleEffects.d.ts +38 -0
  349. package/dist/rules/ruleEffects.js +37 -0
  350. package/dist/rules/triggeredRules.d.ts +160 -0
  351. package/dist/rules/triggeredRules.js +241 -0
  352. package/dist/runtime/adapter.d.ts +58 -0
  353. package/dist/runtime/adapter.js +54 -5
  354. package/dist/runtime/cameraDirector.d.ts +1 -0
  355. package/dist/runtime/cameraDirector.js +1 -0
  356. package/dist/runtime/commandRunner.d.ts +1 -0
  357. package/dist/runtime/commandRunner.js +1 -0
  358. package/dist/runtime/context/combatFx.d.ts +23 -0
  359. package/dist/runtime/context/combatFx.js +161 -0
  360. package/dist/runtime/context/registries.d.ts +13 -0
  361. package/dist/runtime/context/registries.js +84 -0
  362. package/dist/runtime/context/worldItems.d.ts +21 -0
  363. package/dist/runtime/context/worldItems.js +37 -0
  364. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  365. package/dist/runtime/descriptors/baseline.js +134 -0
  366. package/dist/runtime/descriptors/features.d.ts +74 -0
  367. package/dist/runtime/descriptors/features.js +281 -0
  368. package/dist/runtime/gameContext.d.ts +163 -19
  369. package/dist/runtime/gameContext.js +385 -339
  370. package/dist/runtime/gameRuntime.d.ts +1 -0
  371. package/dist/runtime/gameRuntime.js +1 -0
  372. package/dist/runtime/headlessRunner.d.ts +60 -0
  373. package/dist/runtime/headlessRunner.js +44 -0
  374. package/dist/runtime/hostPersistence.d.ts +12 -0
  375. package/dist/runtime/hostPersistence.js +12 -0
  376. package/dist/runtime/hostedGameRunner.d.ts +54 -0
  377. package/dist/runtime/hostedGameRunner.js +85 -0
  378. package/dist/runtime/hostedWorldSession.d.ts +73 -0
  379. package/dist/runtime/hostedWorldSession.js +64 -0
  380. package/dist/runtime/inputSnapshot.d.ts +21 -3
  381. package/dist/runtime/inputSnapshot.js +8 -2
  382. package/dist/runtime/motionIntents.d.ts +12 -1
  383. package/dist/runtime/motionIntents.js +26 -1
  384. package/dist/runtime/perContext.d.ts +15 -0
  385. package/dist/runtime/perContext.js +21 -0
  386. package/dist/runtime/runtimeSave.d.ts +79 -0
  387. package/dist/runtime/runtimeSave.js +105 -0
  388. package/dist/runtime/save.d.ts +4 -0
  389. package/dist/runtime/save.js +4 -0
  390. package/dist/runtime/snapshot.d.ts +7 -0
  391. package/dist/runtime/snapshot.js +7 -0
  392. package/dist/runtime/visibility.d.ts +2 -1
  393. package/dist/runtime/visibility.js +2 -1
  394. package/dist/runtime/worldChannel.d.ts +62 -0
  395. package/dist/runtime/worldChannel.js +114 -0
  396. package/dist/runtime/worldMirror.d.ts +36 -0
  397. package/dist/runtime/worldMirror.js +44 -0
  398. package/dist/runtime/worldProjection.d.ts +47 -0
  399. package/dist/runtime/worldProjection.js +52 -0
  400. package/dist/runtime/worldReplication.d.ts +69 -0
  401. package/dist/runtime/worldReplication.js +217 -0
  402. package/dist/runtime/worldSnapshot.d.ts +44 -0
  403. package/dist/runtime/worldSnapshot.js +30 -0
  404. package/dist/scene/assetCatalog.d.ts +22 -0
  405. package/dist/scene/assetCatalog.js +4 -0
  406. package/dist/scene/assetDiagnostics.d.ts +69 -0
  407. package/dist/scene/assetDiagnostics.js +110 -0
  408. package/dist/scene/assetGenerator.d.ts +65 -0
  409. package/dist/scene/assetGenerator.js +64 -0
  410. package/dist/scene/assetSpace.d.ts +137 -0
  411. package/dist/scene/assetSpace.js +259 -0
  412. package/dist/scene/authoredTriggers.d.ts +169 -0
  413. package/dist/scene/authoredTriggers.js +340 -0
  414. package/dist/scene/behaviorRuntime.d.ts +75 -0
  415. package/dist/scene/behaviorRuntime.js +217 -0
  416. package/dist/scene/behaviors.d.ts +14 -2
  417. package/dist/scene/behaviors.js +7 -2
  418. package/dist/scene/bodyBind.d.ts +60 -0
  419. package/dist/scene/bodyBind.js +51 -0
  420. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  421. package/dist/scene/builtinSceneKinds.js +62 -0
  422. package/dist/scene/colliders.d.ts +18 -0
  423. package/dist/scene/colliders.js +61 -1
  424. package/dist/scene/entityStats.d.ts +13 -0
  425. package/dist/scene/entityStats.js +30 -0
  426. package/dist/scene/entityStore.d.ts +41 -1
  427. package/dist/scene/entityStore.js +75 -0
  428. package/dist/scene/facing.d.ts +18 -0
  429. package/dist/scene/facing.js +26 -0
  430. package/dist/scene/modelSockets.d.ts +33 -0
  431. package/dist/scene/modelSockets.js +29 -0
  432. package/dist/scene/objectQuery.d.ts +2 -0
  433. package/dist/scene/objectQuery.js +2 -0
  434. package/dist/scene/objectStore.d.ts +4 -0
  435. package/dist/scene/objectStore.js +6 -0
  436. package/dist/scene/possession.d.ts +8 -0
  437. package/dist/scene/possession.js +14 -0
  438. package/dist/scene/roster.d.ts +3 -0
  439. package/dist/scene/roster.js +12 -0
  440. package/dist/scene/sceneKinds.d.ts +240 -0
  441. package/dist/scene/sceneKinds.js +214 -0
  442. package/dist/scene/sceneOwnership.d.ts +169 -0
  443. package/dist/scene/sceneOwnership.js +179 -0
  444. package/dist/scene/selectionBookmarks.d.ts +93 -0
  445. package/dist/scene/selectionBookmarks.js +122 -0
  446. package/dist/scene/vehicleSeat.d.ts +68 -0
  447. package/dist/scene/vehicleSeat.js +59 -0
  448. package/dist/sensor/concealment.d.ts +3 -0
  449. package/dist/sensor/concealment.js +3 -0
  450. package/dist/sensor/freezeMonitor.d.ts +1 -0
  451. package/dist/sensor/freezeMonitor.js +1 -0
  452. package/dist/sensor/frustumSensor.d.ts +7 -3
  453. package/dist/sensor/frustumSensor.js +7 -3
  454. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  455. package/dist/sensor/hiddenStateProbe.js +5 -2
  456. package/dist/sensor/recordingBuffer.d.ts +2 -1
  457. package/dist/sensor/recordingBuffer.js +2 -1
  458. package/dist/sensor/replayLoop.d.ts +6 -2
  459. package/dist/sensor/replayLoop.js +6 -2
  460. package/dist/sensor/revealQuery.d.ts +2 -1
  461. package/dist/sensor/revealQuery.js +2 -1
  462. package/dist/sensor/visionCone.d.ts +10 -3
  463. package/dist/sensor/visionCone.js +10 -3
  464. package/dist/session/contestedChannel.d.ts +1 -0
  465. package/dist/session/contestedChannel.js +1 -0
  466. package/dist/session/extraction.d.ts +1 -0
  467. package/dist/session/extraction.js +1 -0
  468. package/dist/session/roles.d.ts +6 -0
  469. package/dist/session/roles.js +6 -0
  470. package/dist/session/roundState.d.ts +8 -0
  471. package/dist/session/roundState.js +2 -0
  472. package/dist/settings/settingsModel.d.ts +1 -0
  473. package/dist/settings/settingsModel.js +1 -0
  474. package/dist/stats/accumulatorMeter.d.ts +6 -0
  475. package/dist/stats/accumulatorMeter.js +6 -0
  476. package/dist/stats/eventMeter.d.ts +5 -0
  477. package/dist/stats/eventMeter.js +5 -0
  478. package/dist/stats/rollCheck.d.ts +5 -0
  479. package/dist/stats/rollCheck.js +5 -0
  480. package/dist/stats/statModifiers.d.ts +5 -0
  481. package/dist/stats/statModifiers.js +5 -0
  482. package/dist/store/defineKeyedStore.d.ts +38 -0
  483. package/dist/store/defineKeyedStore.js +42 -0
  484. package/dist/store/defineStore.d.ts +33 -0
  485. package/dist/store/defineStore.js +35 -0
  486. package/dist/store/observableKeyedStore.d.ts +9 -0
  487. package/dist/store/observableKeyedStore.js +43 -2
  488. package/dist/survival/decayMeter.d.ts +55 -0
  489. package/dist/survival/decayMeter.js +130 -55
  490. package/dist/survival/moodle.d.ts +2 -0
  491. package/dist/survival/regionHealth.d.ts +6 -0
  492. package/dist/survival/regionHealth.js +5 -0
  493. package/dist/tactics/fallingGrid.d.ts +6 -4
  494. package/dist/tactics/fallingGrid.js +6 -4
  495. package/dist/tactics/predictiveQuery.d.ts +3 -0
  496. package/dist/tactics/predictiveQuery.js +3 -0
  497. package/dist/tactics/snapshot.d.ts +2 -0
  498. package/dist/tactics/snapshot.js +2 -0
  499. package/dist/tactics/surface.d.ts +1 -0
  500. package/dist/tactics/surface.js +1 -0
  501. package/dist/tactics/tacticalGrid.d.ts +1 -0
  502. package/dist/tactics/tacticalGrid.js +1 -0
  503. package/dist/time/beatClock.d.ts +14 -4
  504. package/dist/time/beatClock.js +14 -4
  505. package/dist/time/calendarClock.d.ts +3 -0
  506. package/dist/time/calendarClock.js +3 -0
  507. package/dist/time/idleProgress.d.ts +4 -0
  508. package/dist/time/idleProgress.js +4 -0
  509. package/dist/time/simClock.d.ts +2 -0
  510. package/dist/time/simClock.js +20 -5
  511. package/dist/ui/actionModel.d.ts +110 -0
  512. package/dist/ui/actionModel.js +159 -0
  513. package/dist/ui/gameLayout.d.ts +144 -0
  514. package/dist/ui/gameLayout.js +148 -0
  515. package/dist/ui/hudDocument.d.ts +114 -0
  516. package/dist/ui/hudDocument.js +220 -0
  517. package/dist/ui/hudLayout.d.ts +33 -1
  518. package/dist/ui/hudLayout.js +204 -17
  519. package/dist/ui/orientation.d.ts +39 -0
  520. package/dist/ui/orientation.js +49 -0
  521. package/dist/ui/selectionModel.d.ts +92 -0
  522. package/dist/ui/selectionModel.js +88 -0
  523. package/dist/ui/swingTimer.d.ts +42 -0
  524. package/dist/ui/swingTimer.js +38 -0
  525. package/dist/ui/tooltipModel.d.ts +63 -0
  526. package/dist/ui/tooltipModel.js +82 -0
  527. package/dist/ui.d.ts +15 -0
  528. package/dist/ui.js +15 -0
  529. package/dist/visibility/bounds.d.ts +8 -1
  530. package/dist/visibility/bounds.js +8 -1
  531. package/dist/visibility/frustum.d.ts +12 -3
  532. package/dist/visibility/frustum.js +12 -3
  533. package/dist/visibility/spatialIndex.js +34 -20
  534. package/dist/work/jobQueue.d.ts +201 -0
  535. package/dist/work/jobQueue.js +253 -0
  536. package/dist/work/unitTraining.d.ts +58 -0
  537. package/dist/work/unitTraining.js +52 -0
  538. package/dist/world/authoredObjects.d.ts +58 -0
  539. package/dist/world/authoredObjects.js +69 -0
  540. package/dist/world/buildingGenerator.d.ts +18 -0
  541. package/dist/world/buildingGenerator.js +62 -0
  542. package/dist/world/buildings.d.ts +5 -0
  543. package/dist/world/buildings.js +5 -0
  544. package/dist/world/catenary.d.ts +22 -0
  545. package/dist/world/catenary.js +69 -0
  546. package/dist/world/environmentSummary.d.ts +11 -2
  547. package/dist/world/environmentSummary.js +11 -1
  548. package/dist/world/features.d.ts +244 -7
  549. package/dist/world/features.js +92 -4
  550. package/dist/world/footprintGrid.d.ts +59 -0
  551. package/dist/world/footprintGrid.js +141 -0
  552. package/dist/world/geometry.d.ts +64 -0
  553. package/dist/world/geometry.js +94 -0
  554. package/dist/world/grassKind.d.ts +51 -0
  555. package/dist/world/grassKind.js +101 -0
  556. package/dist/world/pathInstances.d.ts +27 -0
  557. package/dist/world/pathInstances.js +27 -0
  558. package/dist/world/pathTerrain.d.ts +80 -0
  559. package/dist/world/pathTerrain.js +142 -0
  560. package/dist/world/placeAsset.d.ts +81 -0
  561. package/dist/world/placeAsset.js +77 -0
  562. package/dist/world/placement.d.ts +4 -0
  563. package/dist/world/placement.js +4 -0
  564. package/dist/world/placementController.d.ts +6 -0
  565. package/dist/world/placementController.js +6 -0
  566. package/dist/world/polyline.d.ts +34 -0
  567. package/dist/world/polyline.js +81 -0
  568. package/dist/world/roads.d.ts +55 -0
  569. package/dist/world/roads.js +184 -0
  570. package/dist/world/scatterRegion.d.ts +164 -0
  571. package/dist/world/scatterRegion.js +409 -0
  572. package/dist/world/sceneShapes.d.ts +43 -0
  573. package/dist/world/sceneShapes.js +1 -0
  574. package/dist/world/segment.d.ts +27 -0
  575. package/dist/world/segment.js +43 -0
  576. package/dist/world/soilKind.d.ts +48 -0
  577. package/dist/world/soilKind.js +92 -0
  578. package/dist/world/spatialSample.d.ts +241 -0
  579. package/dist/world/spatialSample.js +465 -0
  580. package/dist/world/streets.d.ts +80 -0
  581. package/dist/world/streets.js +144 -0
  582. package/dist/world/terraform.d.ts +213 -1
  583. package/dist/world/terraform.js +655 -20
  584. package/dist/world/terrain.d.ts +138 -12
  585. package/dist/world/terrain.js +346 -28
  586. package/dist/world/terrainGuides.d.ts +182 -0
  587. package/dist/world/terrainGuides.js +343 -0
  588. package/dist/world/vec2.d.ts +81 -0
  589. package/dist/world/vec2.js +128 -0
  590. package/dist/world/vec3.d.ts +49 -0
  591. package/dist/world/vec3.js +76 -0
  592. package/dist/world/vegetation.d.ts +71 -0
  593. package/dist/world/vegetation.js +151 -0
  594. package/dist/world/visibilityField.d.ts +154 -0
  595. package/dist/world/visibilityField.js +271 -0
  596. package/dist/world/volumetricClouds.d.ts +52 -0
  597. package/dist/world/volumetricClouds.js +43 -0
  598. package/dist/world/walls.d.ts +9 -0
  599. package/dist/world/walls.js +9 -0
  600. package/dist/world/waterKind.d.ts +55 -0
  601. package/dist/world/waterKind.js +99 -0
  602. package/dist/world.d.ts +132 -0
  603. package/dist/world.js +132 -0
  604. package/package.json +32 -8
  605. package/skills/jgengine/SKILL.md +51 -0
  606. package/skills/jgengine/api.md +434 -0
  607. package/skills/jgengine/capabilities.md +29 -0
  608. package/skills/jgengine/reference-cartridge.md +72 -0
  609. package/skills/jgengine-combat/SKILL.md +34 -0
  610. package/skills/jgengine-combat/api.md +549 -0
  611. package/skills/jgengine-combat/capabilities.md +169 -0
  612. package/skills/jgengine-combat/reference.md +98 -0
  613. package/skills/jgengine-gameplay/SKILL.md +39 -0
  614. package/skills/jgengine-gameplay/api.md +1794 -0
  615. package/skills/jgengine-gameplay/capabilities.md +378 -0
  616. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  617. package/skills/jgengine-world/SKILL.md +38 -0
  618. package/skills/jgengine-world/api.md +2652 -0
  619. package/skills/jgengine-world/capabilities.md +370 -0
  620. package/skills/jgengine-world/reference.md +222 -0
  621. package/dist/cartridge/runtime.d.ts +0 -15
  622. package/dist/cartridge/runtime.js +0 -556
  623. package/dist/cartridge/spec.d.ts +0 -188
  624. package/dist/cartridge/spec.js +0 -19
  625. package/dist/cartridge/validate.d.ts +0 -2
  626. package/dist/cartridge/validate.js +0 -78
  627. package/dist/store/engineStore.d.ts +0 -22
  628. package/dist/store/engineStore.js +0 -50
  629. package/dist/store/features.d.ts +0 -10
  630. package/dist/store/features.js +0 -23
  631. package/llms.txt +0 -4983
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Ordered, inspectable damage-resolution interception (#931).
3
+ *
4
+ * A pending damage application flows through an ordered list of interceptors
5
+ * BEFORE lethality is resolved. Each interceptor may pass, transform, clamp,
6
+ * redirect, split, defer, or reject the application, and every decision is
7
+ * recorded as provenance so combat resolution stays auditable — no hidden
8
+ * callbacks. Invulnerability, i-frames, and anti-one-shot clamps are ordinary
9
+ * interceptors installed and removed by state transitions, not a boss branch.
10
+ *
11
+ * All state is serializable (`Record<string, number>` maps), all randomness is
12
+ * absent (pure), and work is bounded by `MAX_INTERCEPT_STEPS` so split/redirect
13
+ * can never recurse without limit.
14
+ */
15
+ /** Upper bound on interceptor evaluations for a single resolution; guards against runaway `split`/`redirect` loops. */
16
+ export const MAX_INTERCEPT_STEPS = 256;
17
+ /**
18
+ * Run one pending damage application through an ordered interceptor list before
19
+ * lethality resolves, returning the final applications, any deferred ones, and
20
+ * full provenance. Pure and deterministic; bounded by `MAX_INTERCEPT_STEPS`.
21
+ *
22
+ * @capability damage-interception intercept a pending damage application before lethal resolution with ordered, inspectable stages
23
+ */
24
+ export function resolveDamage(interceptors, pending, ctx) {
25
+ const applications = [];
26
+ const deferred = [];
27
+ const provenance = [];
28
+ const queue = [{ pending: normalize(pending), next: 0 }];
29
+ let steps = 0;
30
+ while (queue.length > 0) {
31
+ if (++steps > MAX_INTERCEPT_STEPS)
32
+ break;
33
+ const item = queue.shift();
34
+ if (item === undefined)
35
+ break;
36
+ if (item.next >= interceptors.length) {
37
+ applications.push(item.pending);
38
+ continue;
39
+ }
40
+ const interceptor = interceptors[item.next];
41
+ if (interceptor === undefined) {
42
+ applications.push(item.pending);
43
+ continue;
44
+ }
45
+ const current = item.pending;
46
+ const interceptorId = interceptor.id;
47
+ const decision = interceptor.intercept(current, ctx);
48
+ const before = current.amount;
49
+ function record(after, note) {
50
+ const row = {
51
+ interceptor: interceptorId,
52
+ kind: decision.kind,
53
+ target: current.target,
54
+ before,
55
+ after,
56
+ };
57
+ if (note !== undefined)
58
+ row.note = note;
59
+ provenance.push(row);
60
+ }
61
+ const nextIndex = item.next + 1;
62
+ switch (decision.kind) {
63
+ case "pass":
64
+ record(before);
65
+ queue.push({ pending: current, next: nextIndex });
66
+ break;
67
+ case "transform": {
68
+ const amount = Math.max(0, decision.amount);
69
+ record(amount, decision.note);
70
+ queue.push({ pending: { ...current, amount }, next: nextIndex });
71
+ break;
72
+ }
73
+ case "clamp": {
74
+ const amount = Math.min(current.amount, Math.max(0, decision.max));
75
+ record(amount, decision.note);
76
+ queue.push({ pending: { ...current, amount }, next: nextIndex });
77
+ break;
78
+ }
79
+ case "redirect":
80
+ record(before, decision.note);
81
+ queue.push({ pending: { ...current, target: decision.target }, next: nextIndex });
82
+ break;
83
+ case "split":
84
+ record(before, decision.note);
85
+ for (const part of decision.parts)
86
+ queue.push({ pending: normalize(part), next: nextIndex });
87
+ break;
88
+ case "defer":
89
+ record(before, decision.note);
90
+ deferred.push(current);
91
+ break;
92
+ case "reject":
93
+ record(0, decision.note);
94
+ break;
95
+ }
96
+ }
97
+ return { applications, deferred, provenance };
98
+ }
99
+ function normalize(pending) {
100
+ return pending.amount >= 0 ? pending : { ...pending, amount: 0 };
101
+ }
102
+ /**
103
+ * Create a mutable damage interception chain that state transitions install into
104
+ * and remove from — e.g. add an invulnerability interceptor on phase enter and
105
+ * drop it on phase exit. Evaluation order is install order.
106
+ *
107
+ * @capability damage-pipeline install and remove ordered damage interceptors that transitions toggle at runtime
108
+ */
109
+ export function createDamagePipeline(initial) {
110
+ const interceptors = initial === undefined ? [] : [...initial];
111
+ function indexOf(id) {
112
+ return interceptors.findIndex((entry) => entry.id === id);
113
+ }
114
+ return {
115
+ install(interceptor) {
116
+ const idx = indexOf(interceptor.id);
117
+ if (idx >= 0)
118
+ interceptors[idx] = interceptor;
119
+ else
120
+ interceptors.push(interceptor);
121
+ },
122
+ remove(id) {
123
+ const idx = indexOf(id);
124
+ if (idx < 0)
125
+ return false;
126
+ interceptors.splice(idx, 1);
127
+ return true;
128
+ },
129
+ has(id) {
130
+ return indexOf(id) >= 0;
131
+ },
132
+ interceptorIds() {
133
+ return interceptors.map((entry) => entry.id);
134
+ },
135
+ resolve(pending, ctx) {
136
+ return resolveDamage(interceptors, pending, ctx);
137
+ },
138
+ };
139
+ }
140
+ /**
141
+ * A stateless interceptor that caps any single application at `maxPerHit`.
142
+ *
143
+ * @capability damage-clamp cap incoming damage per hit at a configured maximum
144
+ */
145
+ export function createDamageClamp(config) {
146
+ const id = config.id ?? "damage-clamp";
147
+ return {
148
+ id,
149
+ intercept(pending) {
150
+ if (pending.amount <= config.maxPerHit)
151
+ return { kind: "pass" };
152
+ return { kind: "clamp", max: config.maxPerHit, note: `capped at ${config.maxPerHit}` };
153
+ },
154
+ };
155
+ }
156
+ /**
157
+ * A per-target immunity/invulnerability window as an ordinary damage policy —
158
+ * granted and cleared by state transitions (i-frames, phase invuln), rejecting
159
+ * damage while active. Deterministic (time is passed in) and serializable.
160
+ *
161
+ * @capability immunity-window reject damage during a per-target invulnerability window installed by transitions
162
+ */
163
+ export function createImmunityWindow(id = "immunity") {
164
+ const until = new Map();
165
+ const window = {
166
+ interceptor: {
167
+ id,
168
+ intercept(pending, ctx) {
169
+ const expiry = until.get(pending.target);
170
+ if (expiry !== undefined && ctx.nowMs < expiry)
171
+ return { kind: "reject", note: `immune until ${expiry}` };
172
+ return { kind: "pass" };
173
+ },
174
+ },
175
+ grant(target, untilMs) {
176
+ const prev = until.get(target);
177
+ until.set(target, prev === undefined ? untilMs : Math.max(prev, untilMs));
178
+ },
179
+ grantFor(target, nowMs, durationMs) {
180
+ window.grant(target, nowMs + durationMs);
181
+ },
182
+ active(target, nowMs) {
183
+ const expiry = until.get(target);
184
+ return expiry !== undefined && nowMs < expiry;
185
+ },
186
+ clear(target) {
187
+ until.delete(target);
188
+ },
189
+ clearExpired(nowMs) {
190
+ for (const [target, expiry] of [...until])
191
+ if (nowMs >= expiry)
192
+ until.delete(target);
193
+ },
194
+ snapshot() {
195
+ return Object.fromEntries(until);
196
+ },
197
+ restore(snap) {
198
+ until.clear();
199
+ for (const [target, expiry] of Object.entries(snap))
200
+ until.set(target, expiry);
201
+ },
202
+ };
203
+ return window;
204
+ }
205
+ /**
206
+ * Compose a reusable anti-one-shot / chip-guard clamp from caller data:
207
+ * while above `guardAboveFraction` a hit cannot drop the target below
208
+ * `leaveFraction`, and after such a save the target gets `recoverMs` of
209
+ * immunity. Below the guard fraction, lethal hits pass unchanged.
210
+ *
211
+ * @capability anti-one-shot clamp a near-lethal hit to leave a health floor then grant recovery immunity
212
+ */
213
+ export function createAntiOneShotPolicy(config) {
214
+ const id = config.id ?? "anti-one-shot";
215
+ const immuneUntil = new Map();
216
+ const policy = {
217
+ interceptor: {
218
+ id,
219
+ intercept(pending, ctx) {
220
+ const expiry = immuneUntil.get(pending.target);
221
+ if (expiry !== undefined && ctx.nowMs < expiry)
222
+ return { kind: "reject", note: "anti-one-shot i-frame" };
223
+ const hp = ctx.healthOf?.(pending.target);
224
+ if (hp === undefined || hp.max <= 0)
225
+ return { kind: "pass" };
226
+ const fraction = hp.current / hp.max;
227
+ if (fraction <= config.guardAboveFraction)
228
+ return { kind: "pass" };
229
+ const floor = config.leaveFraction * hp.max;
230
+ if (hp.current - pending.amount >= floor)
231
+ return { kind: "pass" };
232
+ const clamped = Math.max(0, hp.current - floor);
233
+ immuneUntil.set(pending.target, ctx.nowMs + config.recoverMs);
234
+ return { kind: "clamp", max: clamped, note: `anti-one-shot: leave ${floor}, recover ${config.recoverMs}ms` };
235
+ },
236
+ },
237
+ immune(target, nowMs) {
238
+ const expiry = immuneUntil.get(target);
239
+ return expiry !== undefined && nowMs < expiry;
240
+ },
241
+ snapshot() {
242
+ return Object.fromEntries(immuneUntil);
243
+ },
244
+ restore(snap) {
245
+ immuneUntil.clear();
246
+ for (const [target, expiry] of Object.entries(snap))
247
+ immuneUntil.set(target, expiry);
248
+ },
249
+ };
250
+ return policy;
251
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Caller-owned id for a damage channel — `"fire"`, `"ballistic"`, `"physical"`, `"corrosive"`.
3
+ * The engine never branches on the value; a channel is whatever a game's data declares.
4
+ */
5
+ export type DamageChannelId = string;
6
+ /**
7
+ * Caller-owned id for a target trait — `"armored"`, `"fleshy"`, `"wet"`, `"boss"`.
8
+ * Traits are the receiver-side facets a matchup scores a channel against.
9
+ */
10
+ export type TargetTraitId = string;
11
+ /**
12
+ * The independent, typed outputs a channel-vs-trait matchup can scale. Every field is an
13
+ * optional multiplier that defaults to `1` (identity), so a matchup entry names only the axes
14
+ * it bends. `impact` scales the direct hit, `applyChance` the odds a status lands, `magnitude`
15
+ * and `duration` the applied status itself, and `extra` carries any further caller-defined
16
+ * scalar (knockback, stagger, heat) the engine forwards without interpreting.
17
+ */
18
+ export interface MatchupOutputs {
19
+ /** Multiplier on direct impact magnitude. */
20
+ impact?: number;
21
+ /** Multiplier on status application probability. */
22
+ applyChance?: number;
23
+ /** Multiplier on applied status magnitude (e.g. damage per tick). */
24
+ magnitude?: number;
25
+ /** Multiplier on applied status duration/ticks. */
26
+ duration?: number;
27
+ /** Caller-defined extra scalar outputs, multiplied per axis like the named ones. */
28
+ extra?: Record<string, number>;
29
+ }
30
+ /**
31
+ * A serializable, data-defined matchup table: `channel → trait → outputs`. When a hit's channel
32
+ * meets a target carrying several traits, every matching entry's outputs multiply together, so
33
+ * axes compose independently (a trait can halve impact yet double status duration). `default`
34
+ * applies for a channel/trait pair the table does not mention.
35
+ */
36
+ export interface DamageMatchup<TChannel extends string = DamageChannelId, TTrait extends string = TargetTraitId> {
37
+ /** Channel keyed to a per-trait outputs table. */
38
+ entries: Partial<Record<TChannel, Partial<Record<TTrait, MatchupOutputs>>>>;
39
+ /** Outputs used when no listed trait matches the channel; identity when omitted. */
40
+ default?: MatchupOutputs;
41
+ }
42
+ /** One `(trait → outputs)` pair that contributed to a resolved matchup — provenance for UI/debug. */
43
+ export interface MatchupContribution {
44
+ trait: TargetTraitId;
45
+ outputs: MatchupOutputs;
46
+ }
47
+ /** Fully-resolved matchup outputs (every axis populated) plus the contributions that produced them. */
48
+ export interface ResolvedMatchup {
49
+ channel: DamageChannelId;
50
+ impact: number;
51
+ applyChance: number;
52
+ magnitude: number;
53
+ duration: number;
54
+ /** Extra scalar outputs, each defaulting to 1 unless a contribution set it. */
55
+ extra: Record<string, number>;
56
+ /** Whether at least one listed trait matched (false means `default`/identity was used). */
57
+ matched: boolean;
58
+ contributions: MatchupContribution[];
59
+ }
60
+ /**
61
+ * Resolve a channel against a target's traits into independent, multiplied outputs. Pure and
62
+ * order-independent: every trait the channel has an entry for contributes, its axes multiplying
63
+ * into the running product; unmatched traits are skipped, and when nothing matches the table's
64
+ * `default` (or identity) is used. Bounded by the trait count — no world scan.
65
+ *
66
+ * @capability damage-matchup score a data-defined damage channel against a target's traits into independent typed multipliers
67
+ */
68
+ export declare function resolveMatchup<TChannel extends string = DamageChannelId, TTrait extends string = TargetTraitId>(matchup: DamageMatchup<TChannel, TTrait>, channel: TChannel | string, targetTraits: readonly (TTrait | string)[]): ResolvedMatchup;
@@ -0,0 +1,42 @@
1
+ function multiplyInto(acc, outputs) {
2
+ if (outputs.impact !== undefined)
3
+ acc.impact *= outputs.impact;
4
+ if (outputs.applyChance !== undefined)
5
+ acc.applyChance *= outputs.applyChance;
6
+ if (outputs.magnitude !== undefined)
7
+ acc.magnitude *= outputs.magnitude;
8
+ if (outputs.duration !== undefined)
9
+ acc.duration *= outputs.duration;
10
+ if (outputs.extra !== undefined) {
11
+ for (const [key, value] of Object.entries(outputs.extra)) {
12
+ acc.extra[key] = (acc.extra[key] ?? 1) * value;
13
+ }
14
+ }
15
+ }
16
+ /**
17
+ * Resolve a channel against a target's traits into independent, multiplied outputs. Pure and
18
+ * order-independent: every trait the channel has an entry for contributes, its axes multiplying
19
+ * into the running product; unmatched traits are skipped, and when nothing matches the table's
20
+ * `default` (or identity) is used. Bounded by the trait count — no world scan.
21
+ *
22
+ * @capability damage-matchup score a data-defined damage channel against a target's traits into independent typed multipliers
23
+ */
24
+ export function resolveMatchup(matchup, channel, targetTraits) {
25
+ const acc = { impact: 1, applyChance: 1, magnitude: 1, duration: 1, extra: {} };
26
+ const contributions = [];
27
+ const byTrait = matchup.entries[channel];
28
+ if (byTrait !== undefined) {
29
+ for (const trait of targetTraits) {
30
+ const outputs = byTrait[trait];
31
+ if (outputs === undefined)
32
+ continue;
33
+ multiplyInto(acc, outputs);
34
+ contributions.push({ trait, outputs });
35
+ }
36
+ }
37
+ const matched = contributions.length > 0;
38
+ if (!matched && matchup.default !== undefined) {
39
+ multiplyInto(acc, matchup.default);
40
+ }
41
+ return { channel, ...acc, matched, contributions };
42
+ }
@@ -0,0 +1,63 @@
1
+ import { type DamageChannelId, type DamageMatchup, type ResolvedMatchup, type TargetTraitId } from "./damageMatchup.js";
2
+ import { type ReceivedDamageResult, type ReceivedModifier } from "./receivedDamage.js";
3
+ import { type StatusApplicationOutcome, type StatusApplicationSpec, type StatusImmunity, type StatusInstance } from "./statusApplication.js";
4
+ /**
5
+ * One data-defined damage hit: a channel, a base impact, the target's traits and carried statuses,
6
+ * and the caller-owned matchup/received/status data that shapes the outcome. Everything is
7
+ * serializable; the only non-data input is the injected `rng`, so authority can resolve a hit and
8
+ * replicate the returned instances.
9
+ */
10
+ export interface DamageHitInput {
11
+ channel: DamageChannelId;
12
+ /** Base direct impact before matchup and receiver modifiers. */
13
+ impact: number;
14
+ target: string;
15
+ source?: string;
16
+ /** Traits the target presents to the matchup (`"armored"`, `"shielded"`). */
17
+ targetTraits?: readonly TargetTraitId[];
18
+ /** Statuses the target already carries — feeds received predicates and stacking. */
19
+ targetStatuses?: readonly string[];
20
+ /** Caller tags on the hit (`"crit"`, `"aoe"`). */
21
+ tags?: readonly string[];
22
+ /** Channel-vs-trait table; omitted means identity outputs. */
23
+ matchup?: DamageMatchup;
24
+ /** Receiver-side modifiers to run over the post-matchup impact. */
25
+ received?: readonly ReceivedModifier[];
26
+ /** A status this hit tries to apply; omitted means impact only. */
27
+ status?: StatusApplicationSpec;
28
+ /** The target's existing instance of `status`, for stacking/refresh. */
29
+ currentStatus?: StatusInstance | null;
30
+ /** Statuses the target is immune to. */
31
+ immunity?: StatusImmunity | null;
32
+ /** Deterministic RNG for the status roll; defaults to `Math.random`. */
33
+ rng?: () => number;
34
+ }
35
+ /**
36
+ * The full, provenance-rich result of resolving a hit — every stage kept for UI and debugging.
37
+ * `impact` is the final number to drain; `matchup`, `received`, and `status` expose exactly how it
38
+ * got there. Authority applies `impact` (plus `received.redirects`/`conversions`) and the returned
39
+ * status `instance`; nothing here mutates game state.
40
+ */
41
+ export interface DamageHitResolution {
42
+ channel: DamageChannelId;
43
+ /** Final impact on the primary target/channel after matchup and receiver modifiers. */
44
+ impact: number;
45
+ immune: boolean;
46
+ /** The matchup outputs and their contributions. */
47
+ matchup: ResolvedMatchup;
48
+ /** The receiver-side pass over the matchup-scaled impact. */
49
+ received: ReceivedDamageResult;
50
+ /** The status application outcome, when the hit carried a `status`. */
51
+ status?: StatusApplicationOutcome;
52
+ }
53
+ /**
54
+ * Resolve a full damage hit through the data-defined pipeline: score the channel against the
55
+ * target's traits ({@link resolveMatchup}), scale base impact by the matchup's `impact` axis,
56
+ * run receiver-side modifiers ({@link resolveReceivedDamage}), then roll status application scaled
57
+ * by the matchup's `applyChance`/`magnitude`/`duration` axes ({@link resolveStatusApplication}).
58
+ * Pure and deterministic given a seeded `rng`; returns full provenance and never mutates state, so
59
+ * it is safe to run on the authority and replicate the results.
60
+ *
61
+ * @capability damage-hit resolve a full data-defined damage hit — matchup, impact, receiver modifiers, and status application — with provenance
62
+ */
63
+ export declare function resolveDamageHit(input: DamageHitInput): DamageHitResolution;
@@ -0,0 +1,50 @@
1
+ import { resolveMatchup, } from "./damageMatchup.js";
2
+ import { resolveReceivedDamage, } from "./receivedDamage.js";
3
+ import { resolveStatusApplication, } from "./statusApplication.js";
4
+ /**
5
+ * Resolve a full damage hit through the data-defined pipeline: score the channel against the
6
+ * target's traits ({@link resolveMatchup}), scale base impact by the matchup's `impact` axis,
7
+ * run receiver-side modifiers ({@link resolveReceivedDamage}), then roll status application scaled
8
+ * by the matchup's `applyChance`/`magnitude`/`duration` axes ({@link resolveStatusApplication}).
9
+ * Pure and deterministic given a seeded `rng`; returns full provenance and never mutates state, so
10
+ * it is safe to run on the authority and replicate the results.
11
+ *
12
+ * @capability damage-hit resolve a full data-defined damage hit — matchup, impact, receiver modifiers, and status application — with provenance
13
+ */
14
+ export function resolveDamageHit(input) {
15
+ const matchup = resolveMatchup(input.matchup ?? { entries: {} }, input.channel, input.targetTraits ?? []);
16
+ const context = {
17
+ channel: input.channel,
18
+ target: input.target,
19
+ ...(input.source !== undefined ? { source: input.source } : {}),
20
+ ...(input.targetStatuses !== undefined ? { targetStatuses: input.targetStatuses } : {}),
21
+ ...(input.tags !== undefined ? { tags: input.tags } : {}),
22
+ };
23
+ const received = resolveReceivedDamage({
24
+ amount: input.impact * matchup.impact,
25
+ context,
26
+ modifiers: input.received ?? [],
27
+ });
28
+ const resolution = {
29
+ channel: input.channel,
30
+ impact: received.amount,
31
+ immune: received.immune,
32
+ matchup,
33
+ received,
34
+ };
35
+ if (input.status !== undefined) {
36
+ resolution.status = resolveStatusApplication({
37
+ spec: input.status,
38
+ scale: {
39
+ applyChance: matchup.applyChance,
40
+ magnitude: matchup.magnitude,
41
+ duration: matchup.duration,
42
+ },
43
+ current: input.currentStatus ?? null,
44
+ immunity: input.immunity ?? null,
45
+ ...(input.source !== undefined ? { source: input.source } : {}),
46
+ ...(input.rng !== undefined ? { rng: input.rng } : {}),
47
+ });
48
+ }
49
+ return resolution;
50
+ }
@@ -1,6 +1,7 @@
1
- import type { DeathReason, GameEvents } from "../game/events.js";
1
+ import type { GameEvents } from "../game/events.js";
2
2
  import type { Drop } from "../game/lootTable.js";
3
3
  import type { ScatterOptions } from "../game/worldItem.js";
4
+ import type { DeathReason } from "./deathReason.js";
4
5
  import type { EffectVia } from "./effects.js";
5
6
  export type DeathReasonKind = DeathReason["kind"];
6
7
  export interface OnDeathDropRule {
@@ -60,6 +61,11 @@ export interface DeathSystem {
60
61
  resolveDeath(instanceId: string, reason: DeathReason): DeathResolution;
61
62
  revive(instanceId: string): boolean;
62
63
  }
64
+ /**
65
+ * Resolve entity death and the on-death consequences — drops, respawn eligibility, kill credit.
66
+ *
67
+ * @capability death-system resolve entity death and its on-death consequences
68
+ */
63
69
  export declare function createDeathSystem(deps: DeathSystemDeps): DeathSystem;
64
70
  export interface EffectDeathContext {
65
71
  from: string;
@@ -11,6 +11,11 @@ export function normalizeOnDeath(spec) {
11
11
  function matchesReason(when, reason) {
12
12
  return when === undefined || when.reason === reason.kind;
13
13
  }
14
+ /**
15
+ * Resolve entity death and the on-death consequences — drops, respawn eligibility, kill credit.
16
+ *
17
+ * @capability death-system resolve entity death and its on-death consequences
18
+ */
14
19
  export function createDeathSystem(deps) {
15
20
  const dead = new Set();
16
21
  return {
@@ -0,0 +1,14 @@
1
+ /** Why an entity died — who or what gets credit, for drop/command rules and the `entity.died` event. */
2
+ export type DeathReason = {
3
+ kind: "player_kill";
4
+ killerUserId: string;
5
+ via?: {
6
+ item?: string;
7
+ };
8
+ } | {
9
+ kind: "environment";
10
+ source: string;
11
+ } | {
12
+ kind: "self";
13
+ source: string;
14
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -31,4 +31,9 @@ export interface DefensiveWindow {
31
31
  evaluate(nowMs: number, attack: AttackMeta): DefenseResolution;
32
32
  isInvulnerable(nowMs: number): boolean;
33
33
  }
34
+ /**
35
+ * Open a timed defensive window — block, parry, or i-frames — and test incoming hits against it.
36
+ *
37
+ * @capability parry-window time a block/parry/i-frame defensive window against incoming hits
38
+ */
34
39
  export declare function createDefensiveWindow(config: DefensiveWindowConfig): DefensiveWindow;
@@ -32,6 +32,11 @@ export function resolveDefense(input) {
32
32
  return { outcome: "block", perfect: true };
33
33
  return { outcome: "hit", perfect: false };
34
34
  }
35
+ /**
36
+ * Open a timed defensive window — block, parry, or i-frames — and test incoming hits against it.
37
+ *
38
+ * @capability parry-window time a block/parry/i-frame defensive window against incoming hits
39
+ */
35
40
  export function createDefensiveWindow(config) {
36
41
  let openedAt = null;
37
42
  function elapsed(nowMs) {
@@ -0,0 +1,47 @@
1
+ import type { BuildupProc } from "./breakMeters.js";
2
+ /** A single damage-over-time instance: how hard, how often, and for how long. */
3
+ export interface DotSpec {
4
+ /** Damage dealt at each interval. */
5
+ damagePerTick: number;
6
+ /** Milliseconds between damage ticks; clamped to a positive minimum. */
7
+ intervalMs: number;
8
+ /** Total lifetime in milliseconds; the DoT expires once its age reaches this. */
9
+ durationMs: number;
10
+ /** Label echoed on each emitted tick (bleed, poison, burn); defaults to the apply key. */
11
+ status?: string;
12
+ }
13
+ /** One damage event (or expiry marker) emitted by `DotField.tick` for the game to route through its effects. */
14
+ export interface DotTick {
15
+ /** The key the DoT was applied under. */
16
+ id: string;
17
+ /** The DoT's `status` label, or its key when none was given. */
18
+ status: string;
19
+ /** Damage to route through the game's effect pipeline this frame; 0 on a bare expiry marker. */
20
+ damage: number;
21
+ /** True on the entry that ends the DoT — remove any HUD icon on it. */
22
+ expired: boolean;
23
+ }
24
+ /**
25
+ * A pool of timed damage-over-time instances keyed by string (`bleed`, `poison`, `burn`) — the
26
+ * recurring-damage counterpart to `breakMeters`' one-shot buildup procs (#536.4). `tick` advances
27
+ * every active DoT and returns the damage due this frame, one entry per interval crossed, so the game
28
+ * routes each through its own effect pipeline; a pure scheduler that never applies damage itself.
29
+ */
30
+ export interface DotField {
31
+ /** Start or refresh a DoT under `id`; reapplying the same key restarts its age and lifetime. */
32
+ apply(id: string, spec: DotSpec): void;
33
+ /** Bridge a `breakMeters` buildup proc into recurring damage under `id`. */
34
+ applyProc(id: string, proc: BuildupProc, damagePerTick: number, intervalMs: number): void;
35
+ active(id: string): boolean;
36
+ cancel(id: string): void;
37
+ clear(): void;
38
+ count(): number;
39
+ /** Advance every active DoT; returns the damage due this frame plus an `expired` marker per finished DoT. */
40
+ tick(dtSeconds: number): DotTick[];
41
+ }
42
+ /**
43
+ * Builds an empty {@link DotField}; `apply` DoTs onto it and drain damage each frame with `tick`.
44
+ *
45
+ * @capability dot-field track stacking damage-over-time effects and drain damage each frame
46
+ */
47
+ export declare function createDotField(): DotField;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Builds an empty {@link DotField}; `apply` DoTs onto it and drain damage each frame with `tick`.
3
+ *
4
+ * @capability dot-field track stacking damage-over-time effects and drain damage each frame
5
+ */
6
+ export function createDotField() {
7
+ const dots = new Map();
8
+ return {
9
+ apply(id, spec) {
10
+ dots.set(id, {
11
+ status: spec.status ?? id,
12
+ damagePerTick: spec.damagePerTick,
13
+ intervalMs: Math.max(1, spec.intervalMs),
14
+ durationMs: Math.max(0, spec.durationMs),
15
+ ageMs: 0,
16
+ ticksEmitted: 0,
17
+ });
18
+ },
19
+ applyProc(id, proc, damagePerTick, intervalMs) {
20
+ this.apply(id, { damagePerTick, intervalMs, durationMs: proc.durationMs, status: proc.status });
21
+ },
22
+ active: (id) => dots.has(id),
23
+ cancel: (id) => void dots.delete(id),
24
+ clear: () => dots.clear(),
25
+ count: () => dots.size,
26
+ tick(dtSeconds) {
27
+ if (dtSeconds <= 0)
28
+ return [];
29
+ const dtMs = dtSeconds * 1000;
30
+ const emitted = [];
31
+ for (const [id, dot] of dots) {
32
+ dot.ageMs += dtMs;
33
+ const activeMs = Math.min(dot.ageMs, dot.durationMs);
34
+ const dueTicks = Math.floor(activeMs / dot.intervalMs);
35
+ let last = null;
36
+ while (dot.ticksEmitted < dueTicks) {
37
+ dot.ticksEmitted += 1;
38
+ last = { id, status: dot.status, damage: dot.damagePerTick, expired: false };
39
+ emitted.push(last);
40
+ }
41
+ if (dot.ageMs >= dot.durationMs) {
42
+ dots.delete(id);
43
+ if (last !== null)
44
+ last.expired = true;
45
+ else
46
+ emitted.push({ id, status: dot.status, damage: 0, expired: true });
47
+ }
48
+ }
49
+ return emitted;
50
+ },
51
+ };
52
+ }
@@ -32,4 +32,9 @@ export interface DownedState {
32
32
  clear(instanceId: string): void;
33
33
  snapshot(): Record<string, DownedEntry>;
34
34
  }
35
+ /**
36
+ * A downed/bleed-out state that ticks toward death and that teammates can revive before the timer runs out.
37
+ *
38
+ * @capability downed-revive a downed/bleed-out state teammates can revive before death
39
+ */
35
40
  export declare function createDownedState(config: DownedConfig): DownedState;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * A downed/bleed-out state that ticks toward death and that teammates can revive before the timer runs out.
3
+ *
4
+ * @capability downed-revive a downed/bleed-out state teammates can revive before death
5
+ */
1
6
  export function createDownedState(config) {
2
7
  const bleedoutSeconds = Math.max(0, config.bleedoutSeconds);
3
8
  const reviveSeconds = config.reviveSeconds !== undefined ? Math.max(0, config.reviveSeconds) : 0;