@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,157 @@
1
+ import { compileSystemSchedule, } from "./systemSchedule.js";
2
+ function resolveModule(spec, ctx) {
3
+ if (spec === undefined)
4
+ return undefined;
5
+ return typeof spec === "function" ? spec(ctx) : spec;
6
+ }
7
+ /**
8
+ * Install systems on a live context: `create` → bind events → register save/replicate → `start`.
9
+ * Call once per world boot (from the composed loop's `onInit`).
10
+ * @internal
11
+ */
12
+ export function installSystems(ctx, systems, options) {
13
+ const schedule = compileSystemSchedule(systems, options);
14
+ const list = systems;
15
+ const unsubs = [];
16
+ const intervalAcc = new Map();
17
+ const fixedAcc = new Map();
18
+ for (const system of list) {
19
+ system.create?.(ctx);
20
+ }
21
+ for (const system of list) {
22
+ if (system.events !== undefined) {
23
+ for (const [name, handler] of Object.entries(system.events)) {
24
+ if (handler === undefined)
25
+ continue;
26
+ const off = ctx.game.events.on(name, ((event) => {
27
+ handler(ctx, event);
28
+ }));
29
+ unsubs.push(off);
30
+ }
31
+ }
32
+ const save = resolveModule(system.save, ctx);
33
+ if (save !== undefined)
34
+ options?.modules?.registerSave(save);
35
+ const replicate = resolveModule(system.replicate, ctx);
36
+ if (replicate !== undefined)
37
+ options?.modules?.registerReplicate(replicate);
38
+ }
39
+ for (const system of list) {
40
+ system.start?.(ctx);
41
+ }
42
+ for (const group of schedule.fixed) {
43
+ fixedAcc.set(group.rate, 0);
44
+ }
45
+ for (const interval of schedule.intervals) {
46
+ intervalAcc.set(interval.id, 0);
47
+ }
48
+ function runIds(ctx, ids, dt) {
49
+ for (const id of ids) {
50
+ schedule.systemsById.get(id)?.update?.(ctx, dt);
51
+ }
52
+ }
53
+ function tick(ctx, dt) {
54
+ if (!(dt > 0))
55
+ return;
56
+ for (const group of schedule.fixed) {
57
+ const step = 1 / group.rate;
58
+ let acc = (fixedAcc.get(group.rate) ?? 0) + dt;
59
+ while (acc >= step) {
60
+ runIds(ctx, group.order, step);
61
+ acc -= step;
62
+ }
63
+ fixedAcc.set(group.rate, acc);
64
+ }
65
+ runIds(ctx, schedule.frameOrder, dt);
66
+ for (const interval of schedule.intervals) {
67
+ const every = interval.every ?? 1;
68
+ let acc = (intervalAcc.get(interval.id) ?? 0) + dt;
69
+ while (acc >= every) {
70
+ schedule.systemsById.get(interval.id)?.update?.(ctx, every);
71
+ acc -= every;
72
+ }
73
+ intervalAcc.set(interval.id, acc);
74
+ }
75
+ }
76
+ function reset(ctx) {
77
+ for (const system of list)
78
+ system.reset?.(ctx);
79
+ for (const group of schedule.fixed)
80
+ fixedAcc.set(group.rate, 0);
81
+ for (const interval of schedule.intervals)
82
+ intervalAcc.set(interval.id, 0);
83
+ }
84
+ function dispose(ctx) {
85
+ for (const off of unsubs)
86
+ off();
87
+ unsubs.length = 0;
88
+ for (let i = list.length - 1; i >= 0; i -= 1) {
89
+ list[i]?.dispose?.(ctx);
90
+ }
91
+ }
92
+ function runManual(ctx, id, dt = 0) {
93
+ if (!schedule.manual.includes(id))
94
+ return;
95
+ schedule.systemsById.get(id)?.update?.(ctx, dt);
96
+ }
97
+ return { schedule, tick, reset, dispose, runManual };
98
+ }
99
+ const installedByCtx = new WeakMap();
100
+ /**
101
+ * Look up systems installed on `ctx` (if any). Used by hosts that need `reset`/`dispose` after boot.
102
+ * @internal
103
+ */
104
+ export function systemsOf(ctx) {
105
+ return installedByCtx.get(ctx);
106
+ }
107
+ /**
108
+ * Merge a system list with an optional classic `GameLoop` into one loop the shell/runners drive.
109
+ * Systems install on first `onInit`; classic hooks still run for incremental migration.
110
+ *
111
+ * @capability compose-game-loop fold composable systems into the game loop without a manual tick fan-out
112
+ */
113
+ export function composeGameLoop(systems, loop, options) {
114
+ if (systems === undefined || systems.length === 0) {
115
+ return loop ?? {};
116
+ }
117
+ let installed;
118
+ const loopBefore = options?.loopBeforeSystems === true;
119
+ return {
120
+ onInit(ctx) {
121
+ const modules = ctx.game.registerSave !== undefined && ctx.game.registerReplicate !== undefined
122
+ ? {
123
+ registerSave: (m) => ctx.game.registerSave(m),
124
+ registerReplicate: (m) => ctx.game.registerReplicate(m),
125
+ }
126
+ : undefined;
127
+ installed = installSystems(ctx, systems, { ...options, modules });
128
+ installedByCtx.set(ctx, installed);
129
+ loop?.onInit?.(ctx);
130
+ },
131
+ onNewPlayer(ctx, player) {
132
+ loop?.onNewPlayer?.(ctx, player);
133
+ },
134
+ onTick(ctx, dt) {
135
+ if (loopBefore) {
136
+ loop?.onTick?.(ctx, dt);
137
+ installed?.tick(ctx, dt);
138
+ }
139
+ else {
140
+ installed?.tick(ctx, dt);
141
+ loop?.onTick?.(ctx, dt);
142
+ }
143
+ },
144
+ onPlayerLeave(ctx, player) {
145
+ loop?.onPlayerLeave?.(ctx, player);
146
+ },
147
+ onReset(ctx) {
148
+ installed?.reset(ctx);
149
+ loop?.onReset?.(ctx);
150
+ },
151
+ onDispose(ctx) {
152
+ installed?.dispose(ctx);
153
+ installedByCtx.delete(ctx);
154
+ loop?.onDispose?.(ctx);
155
+ },
156
+ };
157
+ }
@@ -0,0 +1,72 @@
1
+ import type { SystemDefinition } from "./defineSystem.js";
2
+ /** Default fixed-sim stage order — systems pick a stage; most need only this. */
3
+ export declare const DEFAULT_FIXED_STAGES: readonly ["input", "movement", "combat", "ai", "activities", "cleanup"];
4
+ /**
5
+ * Default frame stage order. Gameplay stages mirror the fixed table so once-per-frame systems
6
+ * (`type: "frame"`) can pick `combat`/`ai`/… without falling into the unknown-stage bucket;
7
+ * presentation stages follow.
8
+ */
9
+ export declare const DEFAULT_FRAME_STAGES: readonly ["input", "movement", "combat", "ai", "activities", "cleanup", "animation", "camera", "effects"];
10
+ /** @internal */
11
+ export type TimingChannel = "fixed" | "frame" | "interval" | "manual" | "event";
12
+ /** @internal */
13
+ export interface ScheduledSystem {
14
+ readonly id: string;
15
+ readonly channel: TimingChannel;
16
+ readonly stage: string;
17
+ readonly rate?: number;
18
+ readonly every?: number;
19
+ readonly after: readonly string[];
20
+ readonly before: readonly string[];
21
+ readonly dependsOn: readonly string[];
22
+ }
23
+ /** @internal */
24
+ export interface StageBucket {
25
+ readonly stage: string;
26
+ /** System ids in deterministic order within this stage. */
27
+ readonly systems: readonly string[];
28
+ }
29
+ /** @internal */
30
+ export interface FixedRateGroup {
31
+ readonly rate: number;
32
+ readonly stages: readonly StageBucket[];
33
+ /** Flat ordered ids for this rate (all stages). */
34
+ readonly order: readonly string[];
35
+ }
36
+ /**
37
+ * Deterministic compiled schedule: stage buckets, multi-subscribe channels, dependency validation.
38
+ * Order never depends on import order — only stage tables + explicit before/after constraints.
39
+ */
40
+ export interface CompiledSystemSchedule {
41
+ readonly systemsById: ReadonlyMap<string, SystemDefinition>;
42
+ readonly scheduled: readonly ScheduledSystem[];
43
+ /** Fixed-sim groups keyed by rate (Hz); multiple systems may share a rate. */
44
+ readonly fixed: readonly FixedRateGroup[];
45
+ readonly frame: readonly StageBucket[];
46
+ readonly frameOrder: readonly string[];
47
+ /** Interval systems — each keeps its own period; multi-subscribe is per-system. */
48
+ readonly intervals: readonly ScheduledSystem[];
49
+ readonly manual: readonly string[];
50
+ readonly eventOnly: readonly string[];
51
+ /** All auto-ticking systems in a diagnostic flat order (fixed rates → frame → intervals). */
52
+ readonly tickOrder: readonly string[];
53
+ }
54
+ /** @internal */
55
+ export interface CompileSystemScheduleOptions {
56
+ fixedStages?: readonly string[];
57
+ frameStages?: readonly string[];
58
+ defaultFixedRate?: number;
59
+ }
60
+ /**
61
+ * Topological sort with a stable tie-break on original declaration index, then id.
62
+ * Edges: `after: "x"` means this runs after x (x → this); `before: "y"` means this → y.
63
+ * @internal
64
+ */
65
+ export declare function orderWithConstraints(ids: readonly string[], after: ReadonlyMap<string, readonly string[]>, before: ReadonlyMap<string, readonly string[]>, indexOf: ReadonlyMap<string, number>): string[];
66
+ /**
67
+ * Compile system definitions into a deterministic schedule.
68
+ * Validates unique ids, `dependsOn`, and before/after cycles.
69
+ *
70
+ * @capability system-schedule compile fixed/frame/interval system ticks into deterministic ordered stages
71
+ */
72
+ export declare function compileSystemSchedule(systems: readonly SystemDefinition[], options?: CompileSystemScheduleOptions): CompiledSystemSchedule;
@@ -0,0 +1,242 @@
1
+ /** Default fixed-sim stage order — systems pick a stage; most need only this. */
2
+ export const DEFAULT_FIXED_STAGES = [
3
+ "input",
4
+ "movement",
5
+ "combat",
6
+ "ai",
7
+ "activities",
8
+ "cleanup",
9
+ ];
10
+ /**
11
+ * Default frame stage order. Gameplay stages mirror the fixed table so once-per-frame systems
12
+ * (`type: "frame"`) can pick `combat`/`ai`/… without falling into the unknown-stage bucket;
13
+ * presentation stages follow.
14
+ */
15
+ export const DEFAULT_FRAME_STAGES = [
16
+ "input",
17
+ "movement",
18
+ "combat",
19
+ "ai",
20
+ "activities",
21
+ "cleanup",
22
+ "animation",
23
+ "camera",
24
+ "effects",
25
+ ];
26
+ const DEFAULT_FIXED_RATE = 60;
27
+ function asList(value) {
28
+ if (value === undefined)
29
+ return [];
30
+ return typeof value === "string" ? [value] : value;
31
+ }
32
+ function channelOf(tick) {
33
+ if (tick === undefined)
34
+ return "event";
35
+ return tick.type;
36
+ }
37
+ function stageOf(tick, channel) {
38
+ if (tick === undefined || tick.type === "manual")
39
+ return "";
40
+ if (tick.type === "fixed" || tick.type === "frame" || tick.type === "interval") {
41
+ return tick.stage ?? defaultStage(channel);
42
+ }
43
+ return "";
44
+ }
45
+ function defaultStage(channel) {
46
+ if (channel === "fixed")
47
+ return "combat";
48
+ if (channel === "frame")
49
+ return "effects";
50
+ if (channel === "interval")
51
+ return "activities";
52
+ return "";
53
+ }
54
+ function rateOf(tick, defaultFixedRate) {
55
+ if (tick?.type === "fixed")
56
+ return tick.rate ?? defaultFixedRate;
57
+ return undefined;
58
+ }
59
+ function everyOf(tick) {
60
+ if (tick?.type === "interval")
61
+ return tick.every;
62
+ return undefined;
63
+ }
64
+ function afterOf(tick) {
65
+ if (tick === undefined || tick.type === "manual")
66
+ return [];
67
+ if (tick.type === "fixed" || tick.type === "frame" || tick.type === "interval") {
68
+ return asList(tick.after);
69
+ }
70
+ return [];
71
+ }
72
+ function beforeOf(tick) {
73
+ if (tick === undefined || tick.type === "manual")
74
+ return [];
75
+ if (tick.type === "fixed" || tick.type === "frame" || tick.type === "interval") {
76
+ return asList(tick.before);
77
+ }
78
+ return [];
79
+ }
80
+ /**
81
+ * Topological sort with a stable tie-break on original declaration index, then id.
82
+ * Edges: `after: "x"` means this runs after x (x → this); `before: "y"` means this → y.
83
+ * @internal
84
+ */
85
+ export function orderWithConstraints(ids, after, before, indexOf) {
86
+ const idSet = new Set(ids);
87
+ const preds = new Map();
88
+ const succs = new Map();
89
+ for (const id of ids) {
90
+ preds.set(id, new Set());
91
+ succs.set(id, new Set());
92
+ }
93
+ const addEdge = (from, to) => {
94
+ if (!idSet.has(from) || !idSet.has(to) || from === to)
95
+ return;
96
+ succs.get(from).add(to);
97
+ preds.get(to).add(from);
98
+ };
99
+ for (const id of ids) {
100
+ for (const a of after.get(id) ?? [])
101
+ addEdge(a, id);
102
+ for (const b of before.get(id) ?? [])
103
+ addEdge(id, b);
104
+ }
105
+ const ready = ids
106
+ .filter((id) => preds.get(id).size === 0)
107
+ .sort((a, b) => {
108
+ const ia = indexOf.get(a) ?? 0;
109
+ const ib = indexOf.get(b) ?? 0;
110
+ if (ia !== ib)
111
+ return ia - ib;
112
+ return a < b ? -1 : a > b ? 1 : 0;
113
+ });
114
+ const ordered = [];
115
+ while (ready.length > 0) {
116
+ const next = ready.shift();
117
+ ordered.push(next);
118
+ for (const succ of succs.get(next) ?? []) {
119
+ const set = preds.get(succ);
120
+ set.delete(next);
121
+ if (set.size === 0) {
122
+ ready.push(succ);
123
+ ready.sort((a, b) => {
124
+ const ia = indexOf.get(a) ?? 0;
125
+ const ib = indexOf.get(b) ?? 0;
126
+ if (ia !== ib)
127
+ return ia - ib;
128
+ return a < b ? -1 : a > b ? 1 : 0;
129
+ });
130
+ }
131
+ }
132
+ }
133
+ if (ordered.length !== ids.length) {
134
+ const leftover = ids.filter((id) => !ordered.includes(id));
135
+ throw new Error(`system schedule: cyclic before/after constraints among: ${leftover.join(", ")}`);
136
+ }
137
+ return ordered;
138
+ }
139
+ function bucketByStage(items, stageOrder, indexOf) {
140
+ const stageIndex = new Map();
141
+ stageOrder.forEach((s, i) => stageIndex.set(s, i));
142
+ const unknownStages = new Set();
143
+ for (const item of items) {
144
+ if (item.stage !== "" && !stageIndex.has(item.stage))
145
+ unknownStages.add(item.stage);
146
+ }
147
+ const stages = [...stageOrder, ...[...unknownStages].sort()];
148
+ const buckets = [];
149
+ for (const stage of stages) {
150
+ const inStage = items.filter((s) => s.stage === stage);
151
+ if (inStage.length === 0)
152
+ continue;
153
+ const after = new Map();
154
+ const before = new Map();
155
+ for (const s of inStage) {
156
+ after.set(s.id, s.after);
157
+ before.set(s.id, s.before);
158
+ }
159
+ const order = orderWithConstraints(inStage.map((s) => s.id), after, before, indexOf);
160
+ buckets.push({ stage, systems: order });
161
+ }
162
+ return buckets;
163
+ }
164
+ /**
165
+ * Compile system definitions into a deterministic schedule.
166
+ * Validates unique ids, `dependsOn`, and before/after cycles.
167
+ *
168
+ * @capability system-schedule compile fixed/frame/interval system ticks into deterministic ordered stages
169
+ */
170
+ export function compileSystemSchedule(systems, options) {
171
+ const fixedStages = options?.fixedStages ?? DEFAULT_FIXED_STAGES;
172
+ const frameStages = options?.frameStages ?? DEFAULT_FRAME_STAGES;
173
+ const defaultFixedRate = options?.defaultFixedRate ?? DEFAULT_FIXED_RATE;
174
+ const systemsById = new Map();
175
+ const indexOf = new Map();
176
+ systems.forEach((system, index) => {
177
+ if (systemsById.has(system.id)) {
178
+ throw new Error(`system schedule: duplicate system id "${system.id}"`);
179
+ }
180
+ systemsById.set(system.id, system);
181
+ indexOf.set(system.id, index);
182
+ });
183
+ for (const system of systems) {
184
+ for (const dep of system.dependsOn ?? []) {
185
+ if (!systemsById.has(dep)) {
186
+ throw new Error(`system schedule: "${system.id}" dependsOn unknown system "${dep}"`);
187
+ }
188
+ }
189
+ }
190
+ const scheduled = systems.map((system) => {
191
+ const channel = channelOf(system.tick);
192
+ return {
193
+ id: system.id,
194
+ channel,
195
+ stage: stageOf(system.tick, channel),
196
+ rate: rateOf(system.tick, defaultFixedRate),
197
+ every: everyOf(system.tick),
198
+ after: afterOf(system.tick),
199
+ before: beforeOf(system.tick),
200
+ dependsOn: system.dependsOn ?? [],
201
+ };
202
+ });
203
+ const fixedItems = scheduled.filter((s) => s.channel === "fixed");
204
+ const rates = [...new Set(fixedItems.map((s) => s.rate ?? defaultFixedRate))].sort((a, b) => b - a);
205
+ const fixed = rates.map((rate) => {
206
+ const group = fixedItems.filter((s) => (s.rate ?? defaultFixedRate) === rate);
207
+ const stages = bucketByStage(group, fixedStages, indexOf);
208
+ return {
209
+ rate,
210
+ stages,
211
+ order: stages.flatMap((b) => b.systems),
212
+ };
213
+ });
214
+ const frameItems = scheduled.filter((s) => s.channel === "frame");
215
+ const frame = bucketByStage(frameItems, frameStages, indexOf);
216
+ const frameOrder = frame.flatMap((b) => b.systems);
217
+ const intervals = scheduled.filter((s) => s.channel === "interval");
218
+ // Stable order for intervals: stage buckets then constraints across all interval systems
219
+ const intervalBuckets = bucketByStage(intervals, fixedStages, indexOf);
220
+ const intervalOrder = intervalBuckets.flatMap((b) => b.systems);
221
+ const intervalsOrdered = intervalOrder.map((id) => intervals.find((s) => s.id === id));
222
+ const manual = scheduled.filter((s) => s.channel === "manual").map((s) => s.id);
223
+ const eventOnly = scheduled
224
+ .filter((s) => s.channel === "event")
225
+ .map((s) => s.id);
226
+ const tickOrder = [
227
+ ...fixed.flatMap((g) => g.order),
228
+ ...frameOrder,
229
+ ...intervalOrder,
230
+ ];
231
+ return {
232
+ systemsById,
233
+ scheduled,
234
+ fixed,
235
+ frame,
236
+ frameOrder,
237
+ intervals: intervalsOrdered,
238
+ manual,
239
+ eventOnly,
240
+ tickOrder,
241
+ };
242
+ }
@@ -0,0 +1,43 @@
1
+ /** A transient HUD message that expires on its own — banner, pickup note, alert. */
2
+ export interface Toast<T = string> {
3
+ /** Stable id for keying in a UI list. */
4
+ id: string;
5
+ /** Message payload (a string, or any structured content the HUD renders). */
6
+ body: T;
7
+ /** Wall-clock time (seconds) after which the toast should be dropped. */
8
+ expiresAt: number;
9
+ }
10
+ /**
11
+ * Append `toast`, keeping only the newest `cap` entries.
12
+ *
13
+ * @capability toast-feed queue of transient self-expiring on-screen messages (toasts, announcer, kill-feed)
14
+ */
15
+ export declare function appendToast<T>(toasts: readonly Toast<T>[], toast: Toast<T>, cap: number): readonly Toast<T>[];
16
+ /** Drop every toast whose `expiresAt` is at or before `now`. Returns the same array when nothing expired. */
17
+ export declare function pruneToasts<T>(toasts: readonly Toast<T>[], now: number): readonly Toast<T>[];
18
+ /** Stateful transient-toast list with a size cap and time-to-live eviction. */
19
+ export interface ToastQueue<T = string> {
20
+ /** Raise a toast at `now` living `ttlSeconds` (falling back to the queue default); returns it. */
21
+ push(body: T, now: number, ttlSeconds?: number): Toast<T>;
22
+ /** Evict toasts that have expired as of `now`. */
23
+ prune(now: number): void;
24
+ /** Current live toasts, oldest first. */
25
+ list(): readonly Toast<T>[];
26
+ /** Remove all toasts. */
27
+ clear(): void;
28
+ }
29
+ /** Options for {@link createToastQueue}. */
30
+ export interface ToastQueueOptions {
31
+ /** Maximum toasts retained; older ones fall off. Defaults to 4. */
32
+ cap?: number;
33
+ /** Default lifetime in seconds when `push` is not given one. Defaults to 3. */
34
+ ttlSeconds?: number;
35
+ }
36
+ /**
37
+ * A capped, self-expiring toast queue — the append-with-limit plus TTL-prune list every HUD hand-rolled
38
+ * on top of a plain array. Feed it game time: `push` raises a message, `prune(now)` drops expired ones,
39
+ * `list()` is what the HUD renders. Unlike the append-only event feed, toasts evict themselves.
40
+ *
41
+ * @capability toast-feed queue of transient self-expiring on-screen messages (toasts, announcer, kill-feed)
42
+ */
43
+ export declare function createToastQueue<T = string>(options?: ToastQueueOptions): ToastQueue<T>;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Append `toast`, keeping only the newest `cap` entries.
3
+ *
4
+ * @capability toast-feed queue of transient self-expiring on-screen messages (toasts, announcer, kill-feed)
5
+ */
6
+ export function appendToast(toasts, toast, cap) {
7
+ const next = [...toasts, toast];
8
+ return cap > 0 && next.length > cap ? next.slice(next.length - cap) : next;
9
+ }
10
+ /** Drop every toast whose `expiresAt` is at or before `now`. Returns the same array when nothing expired. */
11
+ export function pruneToasts(toasts, now) {
12
+ const kept = toasts.filter((toast) => toast.expiresAt > now);
13
+ return kept.length === toasts.length ? toasts : kept;
14
+ }
15
+ /**
16
+ * A capped, self-expiring toast queue — the append-with-limit plus TTL-prune list every HUD hand-rolled
17
+ * on top of a plain array. Feed it game time: `push` raises a message, `prune(now)` drops expired ones,
18
+ * `list()` is what the HUD renders. Unlike the append-only event feed, toasts evict themselves.
19
+ *
20
+ * @capability toast-feed queue of transient self-expiring on-screen messages (toasts, announcer, kill-feed)
21
+ */
22
+ export function createToastQueue(options = {}) {
23
+ const cap = options.cap ?? 4;
24
+ const defaultTtl = options.ttlSeconds ?? 3;
25
+ let toasts = [];
26
+ let counter = 0;
27
+ return {
28
+ push(body, now, ttlSeconds) {
29
+ const toast = { id: `toast-${counter}`, body, expiresAt: now + (ttlSeconds ?? defaultTtl) };
30
+ counter += 1;
31
+ toasts = appendToast(toasts, toast, cap);
32
+ return toast;
33
+ },
34
+ prune(now) {
35
+ toasts = pruneToasts(toasts, now);
36
+ },
37
+ list() {
38
+ return toasts;
39
+ },
40
+ clear() {
41
+ toasts = [];
42
+ },
43
+ };
44
+ }
@@ -32,6 +32,7 @@ export interface TradeSystem {
32
32
  sell(itemId: string, count: number | undefined, party: TradeParty): TradeRejection | null;
33
33
  tradableAt(shopId: string, allItemIds: string[]): string[];
34
34
  }
35
+ /** @internal */
35
36
  export declare function canAffordCosts(balances: Record<string, number>, costs: Record<string, number>): string | null;
36
37
  export interface TradeOutcome {
37
38
  itemId: string;
@@ -45,8 +46,11 @@ export type TradeResolution = {
45
46
  status: "rejected";
46
47
  reason: string;
47
48
  };
49
+ /** @internal */
48
50
  export declare function resolveBuy(itemId: string, trade: TradeField | null | undefined, shopId: string, count: number, balances: Record<string, number>): TradeResolution;
51
+ /** @internal */
49
52
  export declare function resolveSell(itemId: string, trade: TradeField | null | undefined, count: number): TradeResolution;
53
+ /** @internal */
50
54
  export declare function applyTradeOutcome(outcome: TradeOutcome, appliers: {
51
55
  adjustItem(itemId: string, count: number): {
52
56
  reason: string;
@@ -55,4 +59,10 @@ export declare function applyTradeOutcome(outcome: TradeOutcome, appliers: {
55
59
  }): {
56
60
  reason: string;
57
61
  } | null;
62
+ /**
63
+ * Buy and sell goods against player currency balances, resolving affordability and price.
64
+ *
65
+ * @capability shop-trade buy and sell goods against player currency balances
66
+ * @internal
67
+ */
58
68
  export declare function createTradeSystem(deps: TradeSystemDeps): TradeSystem;
@@ -10,6 +10,7 @@ function negate(amounts) {
10
10
  out[currency] = -amount;
11
11
  return out;
12
12
  }
13
+ /** @internal */
13
14
  export function canAffordCosts(balances, costs) {
14
15
  for (const [currency, amount] of Object.entries(costs)) {
15
16
  if ((balances[currency] ?? 0) < amount)
@@ -27,6 +28,7 @@ function buyEligibility(trade, shopId) {
27
28
  function sellEligibility(trade) {
28
29
  return trade?.sell ? null : "not-sellable";
29
30
  }
31
+ /** @internal */
30
32
  export function resolveBuy(itemId, trade, shopId, count, balances) {
31
33
  const ineligible = buyEligibility(trade, shopId);
32
34
  if (ineligible)
@@ -37,12 +39,14 @@ export function resolveBuy(itemId, trade, shopId, count, balances) {
37
39
  return { status: "rejected", reason: unaffordable };
38
40
  return { status: "ok", outcome: { itemId, count, currency: negate(costs) } };
39
41
  }
42
+ /** @internal */
40
43
  export function resolveSell(itemId, trade, count) {
41
44
  const ineligible = sellEligibility(trade);
42
45
  if (ineligible)
43
46
  return { status: "rejected", reason: ineligible };
44
47
  return { status: "ok", outcome: { itemId, count: -count, currency: scale(trade.sell, count) } };
45
48
  }
49
+ /** @internal */
46
50
  export function applyTradeOutcome(outcome, appliers) {
47
51
  const itemResult = appliers.adjustItem(outcome.itemId, outcome.count);
48
52
  if (itemResult)
@@ -50,6 +54,12 @@ export function applyTradeOutcome(outcome, appliers) {
50
54
  appliers.adjustCurrency(outcome.currency);
51
55
  return null;
52
56
  }
57
+ /**
58
+ * Buy and sell goods against player currency balances, resolving affordability and price.
59
+ *
60
+ * @capability shop-trade buy and sell goods against player currency balances
61
+ * @internal
62
+ */
53
63
  export function createTradeSystem(deps) {
54
64
  const { resolveTrade, wallet, inventory } = deps;
55
65
  function canBuy(itemId, shopId, count = 1) {
@@ -10,6 +10,11 @@ export interface UnlockCatalog {
10
10
  has(unlockId: string): boolean;
11
11
  tree(categoryId: string): UnlockDef[];
12
12
  }
13
+ /**
14
+ * A catalog of unlockable content gated behind conditions the player earns, tracking what is unlocked.
15
+ *
16
+ * @capability unlockables gate content behind unlock conditions the player earns
17
+ */
13
18
  export declare function createUnlockCatalog(defs?: readonly UnlockDef[]): UnlockCatalog;
14
19
  export interface Unlocks {
15
20
  has(userId: string, unlockId: string): boolean;
@@ -18,5 +23,8 @@ export interface Unlocks {
18
23
  tree(categoryId: string): UnlockDef[];
19
24
  snapshot(userId: string): string[];
20
25
  hydrate(userId: string, ids: string[]): void;
26
+ /** Whole-store capture across every user — the world-save/replication seam (per-user `snapshot` can't enumerate users). */
27
+ snapshotAll(): Record<string, string[]>;
28
+ hydrateAll(data: Record<string, string[]>): void;
21
29
  }
22
30
  export declare function createUnlocks(defs?: UnlockDef[]): Unlocks;
@@ -7,6 +7,11 @@ export function grantUnlock(granted, unlockId) {
7
7
  export function unlockTree(defs, categoryId) {
8
8
  return defs.filter((def) => def.category === categoryId);
9
9
  }
10
+ /**
11
+ * A catalog of unlockable content gated behind conditions the player earns, tracking what is unlocked.
12
+ *
13
+ * @capability unlockables gate content behind unlock conditions the player earns
14
+ */
10
15
  export function createUnlockCatalog(defs = []) {
11
16
  const byId = new Map();
12
17
  for (const def of defs)
@@ -48,5 +53,16 @@ export function createUnlocks(defs = []) {
48
53
  hydrate(userId, ids) {
49
54
  granted.set(userId, new Set(ids));
50
55
  },
56
+ snapshotAll() {
57
+ const out = {};
58
+ for (const [userId, ids] of granted)
59
+ out[userId] = Array.from(ids);
60
+ return out;
61
+ },
62
+ hydrateAll(data) {
63
+ granted.clear();
64
+ for (const [userId, ids] of Object.entries(data))
65
+ granted.set(userId, new Set(ids));
66
+ },
51
67
  };
52
68
  }