@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
@@ -1,18 +1,8 @@
1
+ import type { DeathReason } from "../combat/deathReason.js";
1
2
  import type { TelegraphShape } from "../combat/telegraph.js";
2
3
  import type { CameraShake } from "../combat/hitReaction.js";
3
- export type DeathReason = {
4
- kind: "player_kill";
5
- killerUserId: string;
6
- via?: {
7
- item?: string;
8
- };
9
- } | {
10
- kind: "environment";
11
- source: string;
12
- } | {
13
- kind: "self";
14
- source: string;
15
- };
4
+ import type { CombatVfxInstanceEvent } from "./vfxInstance.js";
5
+ export type { DeathReason };
16
6
  export interface EntityDiedEvent {
17
7
  instanceId: string;
18
8
  catalogId: string;
@@ -22,6 +12,11 @@ export interface EntityDiedEvent {
22
12
  position: [number, number, number];
23
13
  serverId?: string;
24
14
  }
15
+ /** Request that an entity's rig play a one-shot animation clip bound to `event` in its `animation.oneShots` (e.g. an "attack" swing); the shell resolves the clip and plays it once over the locomotion state. */
16
+ export interface EntityAnimationEvent {
17
+ instanceId: string;
18
+ event: string;
19
+ }
25
20
  export interface LootGrantedEvent {
26
21
  userId: string;
27
22
  drops: {
@@ -101,6 +96,29 @@ export interface EntityFloatTextEvent {
101
96
  crit?: boolean;
102
97
  scale?: number;
103
98
  }
99
+ /** The visual archetype of a spell/ability effect burst: a traveling bolt, a connecting beam, an expanding ground nova, a soft aura glow, or a scattering impact spark. */
100
+ export type VfxKind = "projectile" | "beam" | "nova" | "glow" | "spark";
101
+ /** A transient sprite-particle effect the shell renders once and expires — one burst of `kind`, tinted `color`, anchored at `from` (and `to` for travel/beam effects). */
102
+ export interface CombatVfxEvent {
103
+ id: number;
104
+ kind: VfxKind;
105
+ color: number;
106
+ from: [number, number, number];
107
+ to?: [number, number, number];
108
+ radius?: number;
109
+ durationMs: number;
110
+ }
111
+ /**
112
+ * An endpoint of a retained VFX instance: either an entity instance id (a renderer resolves and follows its live
113
+ * pose each frame) or a fixed `[x, y, z]` world point. Kept serializable so the effect replicates as plain data.
114
+ */
115
+ export type VfxRef = string | readonly [number, number, number];
116
+ /**
117
+ * The archetype of a retained (long-lived, updatable) VFX effect — an open string, not a closed union, so a
118
+ * renderer registers new kinds (beam, tether, zone, target line, looping emitter) without a central branch.
119
+ * `"beam"` is the first shipped retained renderer.
120
+ */
121
+ export type RetainedVfxKind = string;
104
122
  export interface CombatTelegraphEvent {
105
123
  id: number;
106
124
  shape: TelegraphShape;
@@ -118,6 +136,8 @@ export interface CombatHitReactionEvent {
118
136
  position: [number, number, number];
119
137
  hitstopMs: number;
120
138
  shake?: CameraShake;
139
+ /** Trauma (0..1) for a trauma² shake channel — set when the reaction resolved from `trauma` instead of `shake`. */
140
+ trauma?: number;
121
141
  }
122
142
  export interface ProjectileSettledEvent {
123
143
  from: string;
@@ -164,10 +184,19 @@ export interface AudioPlayEvent {
164
184
  sound: string;
165
185
  at?: readonly [number, number, number];
166
186
  }
187
+ /** Request that the shell's audio engine resume its (browser-gesture-suspended) context; carries no payload. */
188
+ export type AudioResumeEvent = Record<string, never>;
189
+ /** Crossfade the procedural soundtrack to `theme` (null fades out), optionally transposing the incoming theme by `transpose` semitones. */
190
+ export interface AudioMusicEvent {
191
+ theme: string | null;
192
+ transpose?: number;
193
+ }
167
194
  export interface GameEventMap {
168
195
  "entity.died": EntityDiedEvent;
169
196
  "entity.floatText": EntityFloatTextEvent;
170
197
  "combat.telegraph": CombatTelegraphEvent;
198
+ "combat.vfx": CombatVfxEvent;
199
+ "combat.vfxInstance": CombatVfxInstanceEvent;
171
200
  "combat.telegraphCancelled": CombatTelegraphCancelledEvent;
172
201
  "combat.hitReaction": CombatHitReactionEvent;
173
202
  "loot.granted": LootGrantedEvent;
@@ -190,6 +219,9 @@ export interface GameEventMap {
190
219
  "possession.swapped": PossessionSwappedEvent;
191
220
  "form.changed": FormChangedEvent;
192
221
  "audio.play": AudioPlayEvent;
222
+ "audio.music": AudioMusicEvent;
223
+ "audio.resume": AudioResumeEvent;
224
+ "entity.animation": EntityAnimationEvent;
193
225
  }
194
226
  export type GameEventHandler<TPayload> = (payload: TPayload) => void;
195
227
  export interface GameEvents<TMap extends GameEventMap = GameEventMap> {
@@ -197,4 +229,9 @@ export interface GameEvents<TMap extends GameEventMap = GameEventMap> {
197
229
  subscribe<TName extends keyof TMap>(name: TName, handler: GameEventHandler<TMap[TName]>): () => void;
198
230
  emit<TName extends keyof TMap>(name: TName, payload: TMap[TName]): void;
199
231
  }
232
+ /**
233
+ * A typed publish/subscribe bus for gameplay events that systems and HUDs subscribe to.
234
+ *
235
+ * @capability event-bus typed publish/subscribe bus for gameplay events
236
+ */
200
237
  export declare function createGameEvents<TMap extends GameEventMap = GameEventMap>(): GameEvents<TMap>;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * A typed publish/subscribe bus for gameplay events that systems and HUDs subscribe to.
3
+ *
4
+ * @capability event-bus typed publish/subscribe bus for gameplay events
5
+ */
1
6
  export function createGameEvents() {
2
7
  const listeners = new Map();
3
8
  function on(name, handler) {
@@ -3,9 +3,37 @@ export interface FeedEntry<T = unknown> {
3
3
  at: number;
4
4
  data: T;
5
5
  }
6
+ /** Any feed entry carrying a game-time (or wall-clock) `at` stamp for age-based pruning. */
7
+ export interface TimedFeedEntry {
8
+ at: number;
9
+ }
10
+ /** Bounds for {@link appendFeed} / {@link pruneFeed}: newest-`limit` cap and/or `ttl` age window. */
11
+ export interface FeedWindow {
12
+ /** Keep only the newest `limit` entries. Omit for no count cap. */
13
+ limit?: number;
14
+ /** Drop entries older than `ttl` game-seconds before the newest `at`. Omit for no age cap. */
15
+ ttl?: number;
16
+ }
6
17
  export interface GameFeedOptions {
7
18
  limit?: number;
8
19
  }
20
+ /**
21
+ * Append `entry` to a flat, serializable feed list, then bound it by age (`ttl`, relative to the
22
+ * appended entry's `at`) and/or count (`limit`, newest kept). Works on the game's own flat entry
23
+ * shape — anything with an `at` stamp — so `{ id, text, tone, at }`-style notice lists and event
24
+ * logs drop into serialized state with no `{ at, data }` envelope. Returns a new array.
25
+ *
26
+ * @capability notice-feed serializable tone-tagged notice/event feed bounded by count and age (toasts, life events, killfeed)
27
+ */
28
+ export declare function appendFeed<T extends TimedFeedEntry>(list: readonly T[], entry: T, options?: FeedWindow): T[];
29
+ /**
30
+ * Drop feed entries older than `ttl` game-seconds before `now`. Returns the same array reference
31
+ * when nothing expired, so equality checks skip a redundant state write. The tick-time counterpart
32
+ * to {@link appendFeed}'s age bound.
33
+ *
34
+ * @capability notice-feed serializable tone-tagged notice/event feed bounded by count and age (toasts, life events, killfeed)
35
+ */
36
+ export declare function pruneFeed<T extends TimedFeedEntry>(list: readonly T[], now: number, ttl: number): T[];
9
37
  export declare function appendFeedEntry<T>(buffer: readonly FeedEntry<T>[], entry: FeedEntry<T>, limit: number): FeedEntry<T>[];
10
38
  export declare function recentFeedEntries<T>(buffer: readonly FeedEntry<T>[], limit?: number): FeedEntry<T>[];
11
39
  export interface GameFeed {
@@ -18,4 +46,9 @@ export interface GameFeed {
18
46
  snapshot(): Record<string, FeedEntry[]>;
19
47
  hydrate(data: Record<string, FeedEntry[]>): void;
20
48
  }
49
+ /**
50
+ * A rolling per-action feed of recent gameplay events, bindable to the event bus — the HUD ticker and killfeed history.
51
+ *
52
+ * @capability event-feed a rolling feed of recent gameplay events for a HUD ticker or killfeed
53
+ */
21
54
  export declare function createGameFeed(options?: GameFeedOptions): GameFeed;
package/dist/game/feed.js CHANGED
@@ -1,11 +1,44 @@
1
+ /**
2
+ * Append `entry` to a flat, serializable feed list, then bound it by age (`ttl`, relative to the
3
+ * appended entry's `at`) and/or count (`limit`, newest kept). Works on the game's own flat entry
4
+ * shape — anything with an `at` stamp — so `{ id, text, tone, at }`-style notice lists and event
5
+ * logs drop into serialized state with no `{ at, data }` envelope. Returns a new array.
6
+ *
7
+ * @capability notice-feed serializable tone-tagged notice/event feed bounded by count and age (toasts, life events, killfeed)
8
+ */
9
+ export function appendFeed(list, entry, options) {
10
+ let next = [...list, entry];
11
+ if (options?.ttl !== undefined) {
12
+ const cutoff = entry.at - options.ttl;
13
+ next = next.filter((item) => item.at > cutoff);
14
+ }
15
+ const limit = options?.limit;
16
+ return limit !== undefined && next.length > limit ? next.slice(next.length - limit) : next;
17
+ }
18
+ /**
19
+ * Drop feed entries older than `ttl` game-seconds before `now`. Returns the same array reference
20
+ * when nothing expired, so equality checks skip a redundant state write. The tick-time counterpart
21
+ * to {@link appendFeed}'s age bound.
22
+ *
23
+ * @capability notice-feed serializable tone-tagged notice/event feed bounded by count and age (toasts, life events, killfeed)
24
+ */
25
+ export function pruneFeed(list, now, ttl) {
26
+ const cutoff = now - ttl;
27
+ const kept = list.filter((item) => item.at > cutoff);
28
+ return kept.length === list.length ? list : kept;
29
+ }
1
30
  export function appendFeedEntry(buffer, entry, limit) {
2
- const next = [...buffer, entry];
3
- return next.length > limit ? next.slice(next.length - limit) : next;
31
+ return appendFeed(buffer, entry, { limit });
4
32
  }
5
33
  export function recentFeedEntries(buffer, limit) {
6
34
  const count = limit ?? buffer.length;
7
35
  return buffer.slice(Math.max(0, buffer.length - count));
8
36
  }
37
+ /**
38
+ * A rolling per-action feed of recent gameplay events, bindable to the event bus — the HUD ticker and killfeed history.
39
+ *
40
+ * @capability event-feed a rolling feed of recent gameplay events for a HUD ticker or killfeed
41
+ */
9
42
  export function createGameFeed(options) {
10
43
  const limit = options?.limit ?? 20;
11
44
  const buffers = new Map();
@@ -1,4 +1,5 @@
1
1
  import type { GameContext } from "../runtime/gameContext.js";
2
+ import type { LifecycleConfig } from "./defineGame.js";
2
3
  /**
3
4
  * Canonical run phase every game moves through. `menu` (title/main menu),
4
5
  * `playing` (live), `paused` (mid-run pause), `ended` (win/lose/results).
@@ -18,3 +19,13 @@ export declare function setGamePhase(ctx: GameContext, phase: GamePhase): void;
18
19
  /** Current phase; defaults to `playing` when unset so always-live games need no wiring. */
19
20
  export declare function gamePhase(ctx: GameContext): GamePhase;
20
21
  export declare function isPlaying(ctx: GameContext): boolean;
22
+ /**
23
+ * Derive the canonical phase from a game's own run state via its {@link LifecycleConfig.phaseOf} and
24
+ * publish it when it changed — the runtime calls this after every loop hook so a game never hand-writes
25
+ * a per-tick `setGamePhase(ctx, state.phase === … ? … : …)` ternary or its own previous-phase diff. The
26
+ * guard makes it idempotent: the phase store is only rewritten (and touch controls re-gated) on an actual
27
+ * transition, so a busy `onTick` costs one `phaseOf` read, not a store write per frame.
28
+ *
29
+ * @internal
30
+ */
31
+ export declare function syncLifecyclePhase(ctx: GameContext, lifecycle: LifecycleConfig | undefined): void;
@@ -19,3 +19,19 @@ export function gamePhase(ctx) {
19
19
  export function isPlaying(ctx) {
20
20
  return gamePhase(ctx) === "playing";
21
21
  }
22
+ /**
23
+ * Derive the canonical phase from a game's own run state via its {@link LifecycleConfig.phaseOf} and
24
+ * publish it when it changed — the runtime calls this after every loop hook so a game never hand-writes
25
+ * a per-tick `setGamePhase(ctx, state.phase === … ? … : …)` ternary or its own previous-phase diff. The
26
+ * guard makes it idempotent: the phase store is only rewritten (and touch controls re-gated) on an actual
27
+ * transition, so a busy `onTick` costs one `phaseOf` read, not a store write per frame.
28
+ *
29
+ * @internal
30
+ */
31
+ export function syncLifecyclePhase(ctx, lifecycle) {
32
+ if (lifecycle === undefined)
33
+ return;
34
+ const desired = lifecycle.phaseOf(lifecycle.store.read(ctx));
35
+ if (gamePhase(ctx) !== desired)
36
+ setGamePhase(ctx, desired);
37
+ }
@@ -0,0 +1,25 @@
1
+ /** Structural, DOM-free storage backend: the browser `localStorage` satisfies it, as does a test stub or `null`. The one storage seam core primitives target so persistence code never needs the DOM `Storage` lib. */
2
+ export interface KeyValueStorage {
3
+ getItem(key: string): string | null;
4
+ setItem(key: string, value: string): void;
5
+ removeItem(key: string): void;
6
+ }
7
+ /** The ambient `localStorage` as a {@link KeyValueStorage} when one exists (browser), otherwise `null` (server/tests) — never references the DOM `Storage` type, so it is safe in core. */
8
+ export declare function defaultKeyValueStorage(): KeyValueStorage | null;
9
+ /** A single persisted, mutable cell: read the current value, overwrite it, or read-modify-write with {@link KeyValueStore.update}. Unlike a record book it has no monotonic guard — the value goes wherever you set it. */
10
+ export interface KeyValueStore<T> {
11
+ get(): T;
12
+ set(value: T): void;
13
+ update(mutate: (previous: T) => T): T;
14
+ clear(): void;
15
+ }
16
+ /** Config for {@link createKeyValueStore}: the storage `key`, the `initial` value used before anything is saved, an optional `storage` backend (defaults to `localStorage`, pass `null` for memory-only), and optional custom `serialize`/`deserialize` (default JSON). */
17
+ export interface KeyValueStoreConfig<T> {
18
+ readonly key: string;
19
+ readonly initial: T;
20
+ readonly storage?: KeyValueStorage | null;
21
+ readonly serialize?: (value: T) => string;
22
+ readonly deserialize?: (raw: string) => T;
23
+ }
24
+ /** A lightweight mutable local save cell for single-player state (a credit bank, a settings blob, level progress) — the read-modify-write counterpart to the monotonic `recordBook`. Persists through a {@link KeyValueStorage} (browser `localStorage` by default); corrupt or unavailable storage degrades to in-memory and never throws into a game tick. */
25
+ export declare function createKeyValueStore<T>(config: KeyValueStoreConfig<T>): KeyValueStore<T>;
@@ -0,0 +1,61 @@
1
+ /** The ambient `localStorage` as a {@link KeyValueStorage} when one exists (browser), otherwise `null` (server/tests) — never references the DOM `Storage` type, so it is safe in core. */
2
+ export function defaultKeyValueStorage() {
3
+ try {
4
+ if (typeof globalThis !== "undefined" && "localStorage" in globalThis) {
5
+ return globalThis.localStorage ?? null;
6
+ }
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ return null;
12
+ }
13
+ /** A lightweight mutable local save cell for single-player state (a credit bank, a settings blob, level progress) — the read-modify-write counterpart to the monotonic `recordBook`. Persists through a {@link KeyValueStorage} (browser `localStorage` by default); corrupt or unavailable storage degrades to in-memory and never throws into a game tick. */
14
+ export function createKeyValueStore(config) {
15
+ const storage = config.storage === undefined ? defaultKeyValueStorage() : config.storage;
16
+ const serialize = config.serialize ?? ((value) => JSON.stringify(value));
17
+ const deserialize = config.deserialize ?? ((raw) => JSON.parse(raw));
18
+ const read = () => {
19
+ if (storage === null)
20
+ return config.initial;
21
+ try {
22
+ const raw = storage.getItem(config.key);
23
+ return raw === null ? config.initial : deserialize(raw);
24
+ }
25
+ catch {
26
+ return config.initial;
27
+ }
28
+ };
29
+ let current = read();
30
+ const write = (value) => {
31
+ current = value;
32
+ if (storage === null)
33
+ return;
34
+ try {
35
+ storage.setItem(config.key, serialize(value));
36
+ }
37
+ catch {
38
+ // storage rejected the write; keep the value in memory for this session
39
+ }
40
+ };
41
+ return {
42
+ get: () => current,
43
+ set: (value) => write(value),
44
+ update: (mutate) => {
45
+ const next = mutate(current);
46
+ write(next);
47
+ return next;
48
+ },
49
+ clear: () => {
50
+ current = config.initial;
51
+ if (storage === null)
52
+ return;
53
+ try {
54
+ storage.removeItem(config.key);
55
+ }
56
+ catch {
57
+ // ignore removal failure; in-memory value already reset
58
+ }
59
+ },
60
+ };
61
+ }
@@ -41,6 +41,11 @@ export interface Leaderboard {
41
41
  snapshot(): LeaderboardRow[];
42
42
  hydrate(rows: LeaderboardRow[]): void;
43
43
  }
44
+ /**
45
+ * Ranked score tracking across global, server, and per-profile scopes, with top-N queries and per-profile lookups.
46
+ *
47
+ * @capability leaderboard ranked score tracking across global, server, and per-profile scopes
48
+ */
44
49
  export declare function createLeaderboard(sink?: {
45
50
  onIncrement?(row: LeaderboardRow): void;
46
51
  }): Leaderboard;
@@ -11,6 +11,11 @@ function trackKey(stat, scope) {
11
11
  function rowKey(stat, scope, serverId, userId) {
12
12
  return `${scope}:${stat}:${serverId ?? ""}:${userId}`;
13
13
  }
14
+ /**
15
+ * Ranked score tracking across global, server, and per-profile scopes, with top-N queries and per-profile lookups.
16
+ *
17
+ * @capability leaderboard ranked score tracking across global, server, and per-profile scopes
18
+ */
14
19
  export function createLeaderboard(sink) {
15
20
  const trackedPairs = new Map();
16
21
  const rows = new Map();
@@ -1,11 +1,23 @@
1
+ import { type KeyValueStorage } from "./keyValueStore.js";
1
2
  export interface LevelDescriptor<TLevelConfig> {
2
3
  id: string;
3
4
  config: TLevelConfig;
4
5
  }
6
+ /** A level's star rating, 0 (cleared, no stars) to 3. */
7
+ export type LevelStars = 0 | 1 | 2 | 3;
8
+ /** Persisted per-level outcome: whether it has ever been cleared and the best star rating achieved. */
9
+ export interface LevelRecord {
10
+ cleared: boolean;
11
+ stars: LevelStars;
12
+ }
5
13
  export interface LevelSequenceConfig<TLevelConfig> {
6
14
  levels: readonly LevelDescriptor<TLevelConfig>[];
7
15
  /** Extra attempts granted after the first per level. Defaults to 0 (a single attempt, no retries). */
8
16
  retriesPerLevel?: number;
17
+ /** Persistence key for per-level completion/stars. Omit to keep records in-memory only. */
18
+ key?: string;
19
+ /** Storage backend for the records (browser `localStorage` by default when `key` is set); pass `null` for memory-only. */
20
+ storage?: KeyValueStorage | null;
9
21
  }
10
22
  export type LevelSequenceStatus = "idle" | "playing" | "cleared" | "failed" | "complete";
11
23
  export interface CurrentLevel<TLevelConfig> {
@@ -24,15 +36,25 @@ export interface LevelSequence<TLevelConfig> {
24
36
  status(): LevelSequenceStatus;
25
37
  /** Enters level 0. A no-op on an empty level list, which leaves `status()` at "idle" forever. */
26
38
  start(): void;
27
- /** Marks the current level cleared; call `advance()` to move to the next one. */
28
- clear(): void;
39
+ /** Marks the current level cleared, recording its best star rating; call `advance()` to move to the next one. */
40
+ clear(stars?: LevelStars): void;
29
41
  /** Consumes an attempt on the current level. Returns "retry" while attempts remain, else "failed". */
30
42
  fail(): "retry" | "failed";
31
43
  /** Restarts the current level after a "retry"-eligible failure. Returns false if there was nothing to retry. */
32
44
  retry(): boolean;
33
45
  /** Moves past a cleared level, or to "complete" if it was the last one. Returns false unless status is "cleared". */
34
46
  advance(): boolean;
47
+ /** Jumps directly to an unlocked level and starts it. Returns false for an unknown or still-locked level. */
48
+ select(level: string): boolean;
49
+ /** Whether a level can be entered: the first level always, later ones once the preceding level has a cleared record. */
50
+ isUnlocked(level: string): boolean;
51
+ /** The persisted record for a level, or `null` if it has never been cleared. */
52
+ record(level: string): LevelRecord | null;
53
+ /** A snapshot of every persisted level record, keyed by level id. */
54
+ records(): Readonly<Record<string, LevelRecord>>;
35
55
  reset(): void;
56
+ /** Wipes all persisted completion/star records (and the frontier), returning to a fresh campaign. */
57
+ clearRecords(): void;
36
58
  progress(): LevelSequenceProgress;
37
59
  }
38
60
  /**
@@ -1,3 +1,4 @@
1
+ import { createKeyValueStore } from "./keyValueStore.js";
1
2
  /**
2
3
  * A pure, deterministic level campaign: an ordered list of levels, each with its own opaque config, played
3
4
  * through a `start` → (`clear` → `advance`)* → `complete` happy path, with `fail`/`retry` handling per-level
@@ -7,10 +8,32 @@
7
8
  export function createLevelSequence(config) {
8
9
  const levels = config.levels;
9
10
  const maxAttempts = 1 + Math.max(0, Math.floor(config.retriesPerLevel ?? 0));
11
+ const store = config.key === undefined
12
+ ? null
13
+ : createKeyValueStore({
14
+ key: config.key,
15
+ initial: {},
16
+ storage: config.storage,
17
+ });
10
18
  let index = 0;
11
19
  let attempt = 1;
12
20
  let status = "idle";
13
21
  const clearedIds = [];
22
+ const levelRecords = store === null ? {} : { ...store.get() };
23
+ function persistRecords() {
24
+ store?.set({ ...levelRecords });
25
+ }
26
+ function indexOfLevel(id) {
27
+ return levels.findIndex((level) => level.id === id);
28
+ }
29
+ function isUnlocked(id) {
30
+ const idx = indexOfLevel(id);
31
+ if (idx < 0)
32
+ return false;
33
+ if (idx === 0)
34
+ return true;
35
+ return levelRecords[levels[idx - 1].id]?.cleared === true;
36
+ }
14
37
  function current() {
15
38
  if (status === "idle" || status === "complete")
16
39
  return null;
@@ -30,12 +53,38 @@ export function createLevelSequence(config) {
30
53
  clearedIds.length = 0;
31
54
  status = "playing";
32
55
  },
33
- clear() {
56
+ clear(stars) {
34
57
  if (status !== "playing" || current() === null)
35
58
  return;
36
- clearedIds.push(levels[index].id);
59
+ const id = levels[index].id;
60
+ clearedIds.push(id);
61
+ const previousStars = levelRecords[id]?.stars ?? 0;
62
+ const bestStars = Math.max(previousStars, stars ?? 0);
63
+ levelRecords[id] = { cleared: true, stars: bestStars };
64
+ persistRecords();
37
65
  status = "cleared";
38
66
  },
67
+ select(level) {
68
+ const idx = indexOfLevel(level);
69
+ if (idx < 0 || !isUnlocked(level))
70
+ return false;
71
+ index = idx;
72
+ attempt = 1;
73
+ status = "playing";
74
+ return true;
75
+ },
76
+ isUnlocked,
77
+ record: (level) => levelRecords[level] ?? null,
78
+ records: () => ({ ...levelRecords }),
79
+ clearRecords() {
80
+ for (const id of Object.keys(levelRecords))
81
+ delete levelRecords[id];
82
+ store?.clear();
83
+ index = 0;
84
+ attempt = 1;
85
+ clearedIds.length = 0;
86
+ status = "idle";
87
+ },
39
88
  fail() {
40
89
  if (status !== "playing" || current() === null)
41
90
  return "failed";
@@ -44,4 +44,9 @@ export interface Loadouts {
44
44
  reason: string;
45
45
  } | null;
46
46
  }
47
+ /**
48
+ * Save, name, and swap equipment loadouts.
49
+ *
50
+ * @capability loadouts save and swap named equipment loadouts
51
+ */
47
52
  export declare function createLoadouts(deps: LoadoutDeps): Loadouts;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Save, name, and swap equipment loadouts.
3
+ *
4
+ * @capability loadouts save and swap named equipment loadouts
5
+ */
1
6
  export function createLoadouts(deps) {
2
7
  const definitions = new Map();
3
8
  return {
@@ -27,6 +27,8 @@ export interface LootFilterOverride {
27
27
  * First matching rule wins (PoE/Last Epoch block semantics) — later rules
28
28
  * never override an earlier match. Returns overrides only; fields the rule
29
29
  * doesn't set are left for the caller's baseline (rarity style) to fill in.
30
+ *
31
+ * @capability loot-filter filter and highlight drops by rarity/name rules
30
32
  */
31
33
  export declare function evaluateLootFilter(rules: readonly LootFilterRule[], item: LootFilterItem): LootFilterOverride;
32
34
  /** Validating factory — rule ids must be unique so authoring mistakes fail loudly. */
@@ -18,6 +18,8 @@ function matchesCondition(when, item) {
18
18
  * First matching rule wins (PoE/Last Epoch block semantics) — later rules
19
19
  * never override an earlier match. Returns overrides only; fields the rule
20
20
  * doesn't set are left for the caller's baseline (rarity style) to fill in.
21
+ *
22
+ * @capability loot-filter filter and highlight drops by rarity/name rules
21
23
  */
22
24
  export function evaluateLootFilter(rules, item) {
23
25
  for (const rule of rules) {