@jgengine/core 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -0,0 +1,241 @@
1
+ /**
2
+ * The reusable bridge from typed runtime events to effects. A triggered rule is pure data — which
3
+ * event it listens to, a declarative predicate over the event facts, how the affected target is
4
+ * resolved, an effect *reference* (never a callback), and how the resulting effect is gated, lived,
5
+ * and stacked. Affixes, talents, perks, quests, achievements, environment rules, and reactive AI all
6
+ * subscribe through this one seam instead of owning parallel trigger runtimes.
7
+ *
8
+ * Core stays decoupled from any specific effect system: `dispatch` returns provenance-rich firings
9
+ * and the game applies them to whatever effect/stat system it owns. Gate state (cooldowns, rate
10
+ * windows, remaining charges) and active timed effects serialize cleanly so future triggers survive
11
+ * save/load.
12
+ */
13
+ import { evaluatePredicate, readPath } from "./predicate.js";
14
+ function roleId(event, role, owner) {
15
+ switch (role) {
16
+ case "subject":
17
+ return event.subject;
18
+ case "object":
19
+ return event.object;
20
+ case "source":
21
+ return event.source;
22
+ case "owner":
23
+ return owner;
24
+ }
25
+ }
26
+ function resolveTarget(rule, event) {
27
+ const selector = rule.target ?? { role: "subject" };
28
+ if ("literal" in selector)
29
+ return selector.literal;
30
+ if ("path" in selector) {
31
+ const value = readPath(event.facts ?? {}, selector.path);
32
+ return typeof value === "string" ? value : undefined;
33
+ }
34
+ return roleId(event, selector.role, rule.owner);
35
+ }
36
+ function cooldownKey(ruleId, target) {
37
+ return `${ruleId}\u0000${target}`;
38
+ }
39
+ /**
40
+ * Create an empty triggered-rule engine. Rules are added as data; dispatching an event returns the
41
+ * firings the caller applies to its own effect system. Time is caller-supplied (`now` in ms), so the
42
+ * engine is deterministic and drives equally from a fixed-step loop or a save-restored timeline.
43
+ *
44
+ * @capability triggered-rules event-conditioned effects with declarative predicates, lifetimes, and stacking
45
+ */
46
+ export function createTriggeredRuleEngine(rules = []) {
47
+ const ruleList = [];
48
+ const ruleIndex = new Map();
49
+ const remainingCharges = new Map();
50
+ const lastFire = new Map();
51
+ const fireWindows = new Map();
52
+ let active = [];
53
+ let seq = 0;
54
+ function indexRules() {
55
+ ruleIndex.clear();
56
+ for (let i = 0; i < ruleList.length; i++)
57
+ ruleIndex.set(ruleList[i].id, i);
58
+ }
59
+ function add(rule) {
60
+ const existing = ruleIndex.get(rule.id);
61
+ if (existing !== undefined)
62
+ ruleList[existing] = rule;
63
+ else
64
+ ruleList.push(rule);
65
+ indexRules();
66
+ if (rule.charges !== undefined)
67
+ remainingCharges.set(rule.id, rule.charges);
68
+ else
69
+ remainingCharges.delete(rule.id);
70
+ }
71
+ for (const rule of rules)
72
+ add(rule);
73
+ function dropRuleState(ruleId) {
74
+ remainingCharges.delete(ruleId);
75
+ fireWindows.delete(ruleId);
76
+ for (const key of [...lastFire.keys()]) {
77
+ if (key.startsWith(`${ruleId}\u0000`))
78
+ lastFire.delete(key);
79
+ }
80
+ active = active.filter((instance) => instance.ruleId !== ruleId);
81
+ }
82
+ function passesRate(rule, now) {
83
+ if (rule.rateLimit === undefined)
84
+ return true;
85
+ const window = fireWindows.get(rule.id) ?? [];
86
+ const cutoff = now - rule.rateLimit.windowMs;
87
+ const kept = window.filter((stamp) => stamp > cutoff);
88
+ fireWindows.set(rule.id, kept);
89
+ return kept.length < rule.rateLimit.count;
90
+ }
91
+ function recordFire(rule, target, now) {
92
+ lastFire.set(cooldownKey(rule.id, target), now);
93
+ if (rule.rateLimit !== undefined) {
94
+ const window = fireWindows.get(rule.id) ?? [];
95
+ window.push(now);
96
+ fireWindows.set(rule.id, window);
97
+ }
98
+ if (rule.charges !== undefined) {
99
+ remainingCharges.set(rule.id, (remainingCharges.get(rule.id) ?? 0) - 1);
100
+ }
101
+ }
102
+ function applyTimed(rule, target, now) {
103
+ const duration = rule.durationMs;
104
+ const policy = rule.stacking ?? "refresh";
105
+ const expiresAt = now + duration;
106
+ if (policy !== "independent") {
107
+ const current = active.find((instance) => instance.ruleId === rule.id && instance.target === target);
108
+ if (current !== undefined) {
109
+ if (policy === "ignore")
110
+ return { blocked: "stack-ignored" };
111
+ const stacks = policy === "stack" ? Math.min(current.stacks + 1, Math.max(1, rule.maxStacks ?? 1)) : 1;
112
+ const updated = { ...current, expiresAt, stacks, appliedAt: now };
113
+ active = active.map((instance) => (instance === current ? updated : instance));
114
+ return { instanceId: updated.instanceId, stacks };
115
+ }
116
+ }
117
+ const instanceId = `${rule.id}#${seq++}`;
118
+ active.push({
119
+ instanceId,
120
+ ruleId: rule.id,
121
+ effectId: rule.effect.id,
122
+ owner: rule.owner,
123
+ target,
124
+ params: rule.effect.params,
125
+ appliedAt: now,
126
+ expiresAt,
127
+ stacks: 1,
128
+ });
129
+ return { instanceId, stacks: 1 };
130
+ }
131
+ function evaluate(rule, event, now) {
132
+ const base = { ruleId: rule.id, event: event.type, owner: rule.owner, effect: rule.effect, at: now };
133
+ if (!evaluatePredicate(rule.when, event.facts ?? {}))
134
+ return { ...base, target: "", blocked: "predicate" };
135
+ const target = resolveTarget(rule, event);
136
+ if (target === undefined || target === "")
137
+ return { ...base, target: "", blocked: "no-target" };
138
+ if (rule.charges !== undefined && (remainingCharges.get(rule.id) ?? 0) <= 0)
139
+ return { ...base, target, blocked: "no-charges" };
140
+ if (rule.cooldownMs !== undefined) {
141
+ const last = lastFire.get(cooldownKey(rule.id, target));
142
+ if (last !== undefined && now - last < rule.cooldownMs)
143
+ return { ...base, target, blocked: "cooldown" };
144
+ }
145
+ if (!passesRate(rule, now))
146
+ return { ...base, target, blocked: "rate-limit" };
147
+ if (rule.durationMs !== undefined) {
148
+ const outcome = applyTimed(rule, target, now);
149
+ if ("blocked" in outcome)
150
+ return { ...base, target, blocked: outcome.blocked };
151
+ recordFire(rule, target, now);
152
+ return { ...base, target, instanceId: outcome.instanceId, stacks: outcome.stacks };
153
+ }
154
+ recordFire(rule, target, now);
155
+ return { ...base, target };
156
+ }
157
+ return {
158
+ add,
159
+ remove(ruleId) {
160
+ const index = ruleIndex.get(ruleId);
161
+ if (index === undefined)
162
+ return;
163
+ ruleList.splice(index, 1);
164
+ indexRules();
165
+ dropRuleState(ruleId);
166
+ },
167
+ removeByOwner(owner) {
168
+ const removed = ruleList.filter((rule) => rule.owner === owner).map((rule) => rule.id);
169
+ if (removed.length === 0) {
170
+ active = active.filter((instance) => instance.owner !== owner);
171
+ return;
172
+ }
173
+ for (let i = ruleList.length - 1; i >= 0; i--) {
174
+ if (ruleList[i].owner === owner)
175
+ ruleList.splice(i, 1);
176
+ }
177
+ indexRules();
178
+ for (const ruleId of removed)
179
+ dropRuleState(ruleId);
180
+ active = active.filter((instance) => instance.owner !== owner);
181
+ },
182
+ rules: () => ruleList.slice(),
183
+ dispatch(event, now) {
184
+ const firings = [];
185
+ for (const rule of ruleList) {
186
+ if (rule.event !== event.type)
187
+ continue;
188
+ firings.push(evaluate(rule, event, now));
189
+ }
190
+ return firings;
191
+ },
192
+ tick(now) {
193
+ const expired = active.filter((instance) => instance.expiresAt <= now);
194
+ if (expired.length > 0)
195
+ active = active.filter((instance) => instance.expiresAt > now);
196
+ return expired;
197
+ },
198
+ active: () => active.slice(),
199
+ activeFor: (target) => active.filter((instance) => instance.target === target),
200
+ clearActive() {
201
+ active = [];
202
+ },
203
+ reset() {
204
+ remainingCharges.clear();
205
+ lastFire.clear();
206
+ fireWindows.clear();
207
+ active = [];
208
+ for (const rule of ruleList) {
209
+ if (rule.charges !== undefined)
210
+ remainingCharges.set(rule.id, rule.charges);
211
+ }
212
+ },
213
+ snapshot() {
214
+ return {
215
+ seq,
216
+ rules: ruleList.map((rule) => ({ ...rule })),
217
+ charges: Object.fromEntries(remainingCharges),
218
+ cooldowns: Object.fromEntries(lastFire),
219
+ windows: Object.fromEntries([...fireWindows].map(([id, stamps]) => [id, stamps.slice()])),
220
+ active: active.map((instance) => ({ ...instance })),
221
+ };
222
+ },
223
+ hydrate(state) {
224
+ ruleList.length = 0;
225
+ for (const rule of state.rules)
226
+ ruleList.push({ ...rule });
227
+ indexRules();
228
+ remainingCharges.clear();
229
+ for (const [id, value] of Object.entries(state.charges))
230
+ remainingCharges.set(id, value);
231
+ lastFire.clear();
232
+ for (const [key, value] of Object.entries(state.cooldowns))
233
+ lastFire.set(key, value);
234
+ fireWindows.clear();
235
+ for (const [id, stamps] of Object.entries(state.windows))
236
+ fireWindows.set(id, stamps.slice());
237
+ active = state.active.map((instance) => ({ ...instance }));
238
+ seq = state.seq;
239
+ },
240
+ };
241
+ }
@@ -1,8 +1,14 @@
1
1
  export type MultiplayerTopology = "shared" | "lobbies" | "private";
2
2
  /**
3
- * Where the world simulation is authoritative. `"client"` (default) keeps the historical model — each client runs
4
- * its own `onTick` and syncs only presence/feeds/chat. `"server"` opts into host-authoritative replication: the
5
- * host runs the loop, and the shell mirrors the server's world into the local `ctx` instead of simulating locally.
3
+ * Where the world simulation is authoritative.
4
+ *
5
+ * - `"client"` (default when omitted) — **presence-only multiplayer**: each client runs its own `onTick` and
6
+ * syncs presence / feeds / chat. Not competitive-safe; do not treat it as a shared sim.
7
+ * - `"server"` — host-authoritative world replication: the host runs the loop; the shell mirrors the host's
8
+ * world into the local `ctx` instead of simulating locally.
9
+ *
10
+ * Prefer naming the product intent in game code: pass `authority: "server"` for shared worlds, leave unset or
11
+ * `"client"` only for co-op presence / lobbies that intentionally tick independently.
6
12
  */
7
13
  export type MultiplayerAuthority = "server" | "client";
8
14
  export type MultiplayerAdapterConfig = {
@@ -33,15 +39,36 @@ export type MultiplayerAdapterConfig = {
33
39
  } | {
34
40
  kind: "offline";
35
41
  };
42
+ /**
43
+ * Convex transport. Omitting `authority` (or passing `"client"`) is **presence-only** — prefer
44
+ * `convexPresence()` to name that intent explicitly. Pass `{ authority: "server" }` for a shared,
45
+ * host-authoritative world — see `examples/HOSTED.md`.
46
+ */
36
47
  export declare function convex(config?: {
37
48
  topology?: MultiplayerTopology;
38
49
  authority?: MultiplayerAuthority;
39
50
  }): MultiplayerAdapterConfig;
51
+ /** Presence-only Convex transport — each client runs its own `onTick`; only presence/feeds/chat sync. Sugar for `convex({ ...config, authority: "client" })`. */
52
+ export declare function convexPresence(config?: {
53
+ topology?: MultiplayerTopology;
54
+ }): MultiplayerAdapterConfig;
55
+ /**
56
+ * WebSocket transport. Omitting `authority` (or passing `"client"`) is **presence-only** — prefer
57
+ * `wsPresence()` to name that intent explicitly. Pass `{ authority: "server" }` for a shared,
58
+ * host-authoritative world — see `examples/HOSTED.md`.
59
+ *
60
+ * @capability multiplayer-ws server-hosted shared world over WebSocket — `multiplayer: ws({ authority: "server" })`
61
+ */
40
62
  export declare function ws(config?: {
41
63
  topology?: MultiplayerTopology;
42
64
  url?: string;
43
65
  authority?: MultiplayerAuthority;
44
66
  }): MultiplayerAdapterConfig;
67
+ /** Presence-only WebSocket transport — each client runs its own `onTick`; only presence/feeds/chat sync. Sugar for `ws({ ...config, authority: "client" })`. */
68
+ export declare function wsPresence(config?: {
69
+ topology?: MultiplayerTopology;
70
+ url?: string;
71
+ }): MultiplayerAdapterConfig;
45
72
  export declare function fly(config: {
46
73
  app: string;
47
74
  topology?: MultiplayerTopology;
@@ -53,6 +80,11 @@ export declare function socketIo(config?: {
53
80
  url?: string;
54
81
  authority?: MultiplayerAuthority;
55
82
  }): MultiplayerAdapterConfig;
83
+ /**
84
+ * Serverless peer-to-peer (WebRTC) session — one peer hosts, friends join by room code.
85
+ *
86
+ * @capability multiplayer-p2p serverless co-op over WebRTC — `multiplayer: p2p({ room })`
87
+ */
56
88
  export declare function p2p(config?: {
57
89
  topology?: MultiplayerTopology;
58
90
  room?: string;
@@ -66,6 +98,26 @@ export declare function lan(config?: {
66
98
  }): MultiplayerAdapterConfig;
67
99
  /** True when the adapter opts into host-authoritative world replication (`authority: "server"`). */
68
100
  export declare function isServerAuthoritative(multiplayer: unknown): boolean;
101
+ /**
102
+ * Resolved authority for a multiplayer config.
103
+ * - `offline` / missing adapter → `null` (single-player; not multiplayer authority).
104
+ * - unset or `"client"` → `"client"` (presence-only; each client ticks).
105
+ * - `"server"` → host-authoritative shared sim.
106
+ */
107
+ export declare function resolveAuthority(multiplayer: unknown): MultiplayerAuthority | null;
108
+ /**
109
+ * True when multiplayer is on but the world sim is not host-authoritative — presence/feeds/chat only.
110
+ * Equivalent to `resolveAuthority(m) === "client"`.
111
+ */
112
+ export declare function isPresenceOnly(multiplayer: unknown): boolean;
113
+ /** True for a single-player world — no adapter, or an explicit `offline()` one. Gates offline-only wiring like local whole-world save. */
114
+ export declare function isOffline(multiplayer: unknown): boolean;
115
+ /**
116
+ * Explicit single-player adapter. Solo games never need this — omitting `multiplayer` in the shell
117
+ * `defineGame` already defaults to offline; pass it only where an adapter value is structurally required.
118
+ *
119
+ * @capability multiplayer-offline explicit solo adapter — omit `multiplayer` instead; offline is the shell default
120
+ */
69
121
  export declare function offline(): MultiplayerAdapterConfig;
70
122
  export declare function adapterOf(multiplayer: unknown): MultiplayerAdapterConfig | null;
71
123
  export declare function multiplayerAdapterKind(multiplayer: unknown): string | null;
@@ -1,9 +1,29 @@
1
+ /**
2
+ * Convex transport. Omitting `authority` (or passing `"client"`) is **presence-only** — prefer
3
+ * `convexPresence()` to name that intent explicitly. Pass `{ authority: "server" }` for a shared,
4
+ * host-authoritative world — see `examples/HOSTED.md`.
5
+ */
1
6
  export function convex(config) {
2
7
  return { kind: "convex", topology: config?.topology ?? "shared", authority: config?.authority };
3
8
  }
9
+ /** Presence-only Convex transport — each client runs its own `onTick`; only presence/feeds/chat sync. Sugar for `convex({ ...config, authority: "client" })`. */
10
+ export function convexPresence(config) {
11
+ return { kind: "convex", topology: config?.topology ?? "shared", authority: "client" };
12
+ }
13
+ /**
14
+ * WebSocket transport. Omitting `authority` (or passing `"client"`) is **presence-only** — prefer
15
+ * `wsPresence()` to name that intent explicitly. Pass `{ authority: "server" }` for a shared,
16
+ * host-authoritative world — see `examples/HOSTED.md`.
17
+ *
18
+ * @capability multiplayer-ws server-hosted shared world over WebSocket — `multiplayer: ws({ authority: "server" })`
19
+ */
4
20
  export function ws(config) {
5
21
  return { kind: "ws", topology: config?.topology ?? "shared", url: config?.url, authority: config?.authority };
6
22
  }
23
+ /** Presence-only WebSocket transport — each client runs its own `onTick`; only presence/feeds/chat sync. Sugar for `ws({ ...config, authority: "client" })`. */
24
+ export function wsPresence(config) {
25
+ return { kind: "ws", topology: config?.topology ?? "shared", url: config?.url, authority: "client" };
26
+ }
7
27
  export function fly(config) {
8
28
  return {
9
29
  kind: "ws",
@@ -15,6 +35,11 @@ export function fly(config) {
15
35
  export function socketIo(config) {
16
36
  return { kind: "socketio", topology: config?.topology ?? "shared", url: config?.url, authority: config?.authority };
17
37
  }
38
+ /**
39
+ * Serverless peer-to-peer (WebRTC) session — one peer hosts, friends join by room code.
40
+ *
41
+ * @capability multiplayer-p2p serverless co-op over WebRTC — `multiplayer: p2p({ room })`
42
+ */
18
43
  export function p2p(config) {
19
44
  return { kind: "p2p", topology: config?.topology ?? "private", room: config?.room, authority: config?.authority };
20
45
  }
@@ -23,9 +48,40 @@ export function lan(config) {
23
48
  }
24
49
  /** True when the adapter opts into host-authoritative world replication (`authority: "server"`). */
25
50
  export function isServerAuthoritative(multiplayer) {
51
+ return resolveAuthority(multiplayer) === "server";
52
+ }
53
+ /**
54
+ * Resolved authority for a multiplayer config.
55
+ * - `offline` / missing adapter → `null` (single-player; not multiplayer authority).
56
+ * - unset or `"client"` → `"client"` (presence-only; each client ticks).
57
+ * - `"server"` → host-authoritative shared sim.
58
+ */
59
+ export function resolveAuthority(multiplayer) {
60
+ const adapter = adapterOf(multiplayer);
61
+ if (adapter === null || adapter.kind === "offline")
62
+ return null;
63
+ if ("authority" in adapter && adapter.authority === "server")
64
+ return "server";
65
+ return "client";
66
+ }
67
+ /**
68
+ * True when multiplayer is on but the world sim is not host-authoritative — presence/feeds/chat only.
69
+ * Equivalent to `resolveAuthority(m) === "client"`.
70
+ */
71
+ export function isPresenceOnly(multiplayer) {
72
+ return resolveAuthority(multiplayer) === "client";
73
+ }
74
+ /** True for a single-player world — no adapter, or an explicit `offline()` one. Gates offline-only wiring like local whole-world save. */
75
+ export function isOffline(multiplayer) {
26
76
  const adapter = adapterOf(multiplayer);
27
- return adapter !== null && "authority" in adapter && adapter.authority === "server";
77
+ return adapter === null || adapter.kind === "offline";
28
78
  }
79
+ /**
80
+ * Explicit single-player adapter. Solo games never need this — omitting `multiplayer` in the shell
81
+ * `defineGame` already defaults to offline; pass it only where an adapter value is structurally required.
82
+ *
83
+ * @capability multiplayer-offline explicit solo adapter — omit `multiplayer` instead; offline is the shell default
84
+ */
29
85
  export function offline() {
30
86
  return { kind: "offline" };
31
87
  }
@@ -12,4 +12,5 @@ export interface CameraDirector {
12
12
  chaseTuning(): ChaseCameraTuning | null;
13
13
  subscribe(listener: () => void): () => void;
14
14
  }
15
+ /** @internal */
15
16
  export declare function createCameraDirector(): CameraDirector;
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function createCameraDirector() {
2
3
  const listeners = new Set();
3
4
  let followEntity = undefined;
@@ -12,4 +12,5 @@ export type RunCommandResult = {
12
12
  ok: false;
13
13
  reason: string;
14
14
  };
15
+ /** @internal */
15
16
  export declare function runCommand<TInput>(snapshot: import("./snapshot.js").GameRuntimeSnapshot, commands: Record<string, CommandDef<TInput>>, commandName: string, input: TInput, actorUserId: string): RunCommandResult;
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function runCommand(snapshot, commands, commandName, input, actorUserId) {
2
3
  const command = commands[commandName];
3
4
  if (!command) {
@@ -0,0 +1,51 @@
1
+ import { type DeathSystem } from "../../combat/death.js";
2
+ import { type CombatSpatialDeps, type EffectSystem } from "../../combat/effects.js";
3
+ import { type ProjectileSystem } from "../../combat/projectiles.js";
4
+ import type { PhysicsConfig } from "../../game/defineGame.js";
5
+ import type { GameEvents } from "../../game/events.js";
6
+ import { type VfxInstanceStore } from "../../game/vfxInstance.js";
7
+ import type { LootRegistry } from "../../game/lootTable.js";
8
+ import type { EntityColliderSet } from "../../scene/colliders.js";
9
+ import type { EntityStore } from "../../scene/entityStore.js";
10
+ import type { ObjectStore } from "../../scene/objectStore.js";
11
+ import type { SceneRaycastApi } from "../../scene/sceneRaycast.js";
12
+ import type { WeaponStats } from "../../item/weapon.js";
13
+ import type { SimClock } from "../../time/simClock.js";
14
+ import type { WorldItemRecord, WorldItemSpawnInput } from "../../game/worldItem.js";
15
+ import type { GameContextContent, GameContextEntityEntry, GameContextLoot } from "../gameContext.js";
16
+ import { type CombatFx } from "./combatFx.js";
17
+ /** @internal Wiring combat needs from the live scene, loot, and command seams. */
18
+ export interface CombatSubsystemDeps {
19
+ content: GameContextContent;
20
+ signalNotify: () => void;
21
+ now: () => number;
22
+ events: GameEvents;
23
+ time: SimClock;
24
+ entities: EntityStore;
25
+ objects: ObjectStore;
26
+ combatSpatial: CombatSpatialDeps;
27
+ sceneRaycast: SceneRaycastApi;
28
+ entityCollidersOf: (instanceId: string) => EntityColliderSet | null;
29
+ objectCollidersOf: (instanceId: string) => EntityColliderSet | null;
30
+ catalogEntry: (instanceId: string) => GameContextEntityEntry | null | undefined;
31
+ statsByInstance: Map<string, import("../../scene/entityStats.js").StatValueMap>;
32
+ weapon: WeaponStats;
33
+ loot: GameContextLoot;
34
+ lootRegistry: LootRegistry;
35
+ spawnWorldItem: (input: WorldItemSpawnInput) => WorldItemRecord;
36
+ despawnEntity: (instanceId: string) => boolean;
37
+ runCommand: (name: string, args: unknown) => void;
38
+ localUserId: string;
39
+ physics?: PhysicsConfig;
40
+ }
41
+ /** @internal Effects, projectiles, death, and combat presentation surface. */
42
+ export interface CombatSubsystem {
43
+ death: DeathSystem;
44
+ effects: EffectSystem;
45
+ floatingEffects: EffectSystem;
46
+ projectiles: ProjectileSystem;
47
+ combatFx: CombatFx;
48
+ vfxInstances: VfxInstanceStore;
49
+ }
50
+ /** @internal */
51
+ export declare function createCombatSubsystem(d: CombatSubsystemDeps): CombatSubsystem;
@@ -0,0 +1,130 @@
1
+ import { createDeathSystem, deathReasonFromEffect } from "../../combat/death.js";
2
+ import { createEffectSystem, } from "../../combat/effects.js";
3
+ import { createProjectileSystem } from "../../combat/projectiles.js";
4
+ import { createVfxInstanceStore } from "../../game/vfxInstance.js";
5
+ import { notifyAfter } from "../../store/changeSignal.js";
6
+ import { createCombatFx } from "./combatFx.js";
7
+ import { applyLethalLoot, isLocalPlayerKill } from "./deathLoot.js";
8
+ /** @internal */
9
+ export function createCombatSubsystem(d) {
10
+ const { content, signalNotify, now, events, time, entities, objects, combatSpatial, sceneRaycast, entityCollidersOf, objectCollidersOf, catalogEntry, statsByInstance, weapon, loot, lootRegistry, spawnWorldItem, despawnEntity, runCommand, localUserId, } = d;
11
+ const death = createDeathSystem({
12
+ resolveOnDeath: (instanceId) => catalogEntry(instanceId)?.onDeath,
13
+ resolveIdentity(instanceId) {
14
+ const entity = entities.get(instanceId);
15
+ if (entity === null)
16
+ return null;
17
+ return {
18
+ catalogId: entity.name,
19
+ position: [entity.position[0], entity.position[1], entity.position[2]],
20
+ };
21
+ },
22
+ loot: { roll: (tableId) => (lootRegistry.has(tableId) ? lootRegistry.roll(tableId) : []) },
23
+ events,
24
+ runCommand(name, args) {
25
+ runCommand(name, args);
26
+ },
27
+ despawn(instanceId) {
28
+ despawnEntity(instanceId);
29
+ },
30
+ });
31
+ const effects = notifyAfter(createEffectSystem({
32
+ resolveReceive: (instanceId) => catalogEntry(instanceId)?.receive,
33
+ resolveStats: (instanceId) => statsByInstance.get(instanceId),
34
+ getStat: weapon.getStat,
35
+ spatial: combatSpatial,
36
+ onLethal(instanceId, lethalCtx) {
37
+ // Capture identity + onDeath *before* resolveDeath despawns the entity.
38
+ const dyingEntity = entities.get(instanceId);
39
+ const catalogId = dyingEntity?.name;
40
+ const position = dyingEntity?.position;
41
+ const onDeath = catalogEntry(instanceId)?.onDeath;
42
+ const reason = deathReasonFromEffect({
43
+ ...lethalCtx,
44
+ userIdOf: (id) => (id === localUserId ? localUserId : undefined),
45
+ });
46
+ const resolution = death.resolveDeath(instanceId, reason);
47
+ if (resolution.status !== "resolved")
48
+ return;
49
+ applyLethalLoot({
50
+ drops: resolution.drops,
51
+ grantToLocalPlayer: isLocalPlayerKill(lethalCtx, localUserId),
52
+ onDeath,
53
+ position,
54
+ catalogId,
55
+ content,
56
+ spawnWorldItem,
57
+ grantToPlayer: loot.grantToPlayer,
58
+ localUserId,
59
+ });
60
+ },
61
+ }), ["applyEffect"], signalNotify);
62
+ const combatFx = createCombatFx({
63
+ entities,
64
+ events,
65
+ time,
66
+ applyEffect: (input) => effects.applyEffect(input),
67
+ });
68
+ const vfxInstances = createVfxInstanceStore({
69
+ onOp: (op) => events.emit("combat.vfxInstance", op),
70
+ now: () => time.now() * 1000,
71
+ });
72
+ const floatingEffects = {
73
+ canReceive: effects.canReceive,
74
+ preview: effects.preview,
75
+ applyEffect: combatFx.applyEffectAndFloat,
76
+ };
77
+ const projectileObstacles = d.physics?.projectileObstacles === true;
78
+ const projectileFilterFor = (filter) => ({
79
+ entities: true,
80
+ objects: projectileObstacles,
81
+ terrain: false,
82
+ walls: projectileObstacles,
83
+ ...filter,
84
+ });
85
+ const projectileSceneRaycast = {
86
+ raycast(input) {
87
+ return sceneRaycast.raycast({ ...input, filter: projectileFilterFor(input.filter) });
88
+ },
89
+ raycastAll(input) {
90
+ return sceneRaycast.raycastAll({ ...input, filter: projectileFilterFor(input.filter) });
91
+ },
92
+ };
93
+ const projectiles = notifyAfter(createProjectileSystem({
94
+ effects: floatingEffects,
95
+ spatial: combatSpatial,
96
+ getStat: weapon.getStat,
97
+ sceneRaycast: projectileSceneRaycast,
98
+ objects: projectileObstacles
99
+ ? {
100
+ list: () => objects.list(),
101
+ inBox: (min, max) => objects.inBox(min, max),
102
+ halfExtents: (catalogId) => {
103
+ const half = content.objectById?.(catalogId)?.halfExtents;
104
+ return half === undefined ? null : [half[0], half[1], half[2]];
105
+ },
106
+ collidersOf: objectCollidersOf,
107
+ }
108
+ : undefined,
109
+ entityCollidersOf,
110
+ rotationYOf: (instanceId) => entities.get(instanceId)?.rotationY,
111
+ now,
112
+ onSettle(report) {
113
+ events.emit("projectile.settled", {
114
+ from: report.from,
115
+ origin: [report.origin[0], report.origin[1], report.origin[2]],
116
+ at: [report.at[0], report.at[1], report.at[2]],
117
+ effect: report.effect,
118
+ hit: report.hit,
119
+ });
120
+ },
121
+ }), ["fireProjectile", "settleProjectile"], signalNotify);
122
+ return {
123
+ death,
124
+ effects,
125
+ floatingEffects,
126
+ projectiles,
127
+ combatFx,
128
+ vfxInstances,
129
+ };
130
+ }
@@ -0,0 +1,23 @@
1
+ import type { EffectInput, EffectResult } from "../../combat/effects.js";
2
+ import { type HitReaction } from "../../combat/hitReaction.js";
3
+ import type { GameEvents } from "../../game/events.js";
4
+ import type { EntityStore } from "../../scene/entityStore.js";
5
+ import type { SimClock } from "../../time/simClock.js";
6
+ import type { FloatTextInput, HitReactionInput, TelegraphInput, VfxInput } from "../gameContext.js";
7
+ /** @internal What the combat-presentation helpers need from the live context: entity poses, the event bus, the sim clock (telegraph windups), and the raw effect application. */
8
+ export interface CombatFxDeps {
9
+ entities: EntityStore;
10
+ events: GameEvents;
11
+ time: SimClock;
12
+ applyEffect: (input: EffectInput) => EffectResult[];
13
+ }
14
+ /** @internal Combat presentation surface registered under `ctx.scene.entity`: float text, VFX bursts, telegraphs, hit reactions, and the effect wrapper that emits damage/heal float text. */
15
+ export interface CombatFx {
16
+ emitFloatText(input: FloatTextInput): void;
17
+ emitVfx(input: VfxInput): void;
18
+ fireTelegraph(input: TelegraphInput): () => void;
19
+ applyHitReaction(input: HitReactionInput): HitReaction | null;
20
+ applyEffectAndFloat(input: EffectInput): EffectResult[];
21
+ }
22
+ /** @internal */
23
+ export declare function createCombatFx(d: CombatFxDeps): CombatFx;