@jgengine/core 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/spawnDirector.d.ts +7 -2
  21. package/dist/ai/spawnDirector.js +18 -15
  22. package/dist/ai/spawnPoint.d.ts +3 -1
  23. package/dist/ai/spawnPoint.js +3 -1
  24. package/dist/ai/targetAcquisition.d.ts +84 -0
  25. package/dist/ai/targetAcquisition.js +92 -0
  26. package/dist/anim/easing.d.ts +19 -0
  27. package/dist/anim/easing.js +19 -0
  28. package/dist/anim/oscillator.d.ts +12 -0
  29. package/dist/anim/oscillator.js +25 -0
  30. package/dist/area/areaEffectField.d.ts +127 -0
  31. package/dist/area/areaEffectField.js +175 -0
  32. package/dist/area/stackPolicy.d.ts +47 -0
  33. package/dist/area/stackPolicy.js +99 -0
  34. package/dist/authoring.d.ts +1 -0
  35. package/dist/authoring.js +1 -0
  36. package/dist/board/laneBoard.d.ts +13 -0
  37. package/dist/board/laneBoard.js +13 -0
  38. package/dist/board/timelineBoard.d.ts +10 -0
  39. package/dist/board/timelineBoard.js +10 -0
  40. package/dist/combat/abilityKit.d.ts +18 -0
  41. package/dist/combat/abilityKit.js +24 -9
  42. package/dist/combat/animationState.d.ts +5 -0
  43. package/dist/combat/animationState.js +5 -0
  44. package/dist/combat/breakMeters.d.ts +10 -0
  45. package/dist/combat/breakMeters.js +10 -0
  46. package/dist/combat/castRunner.d.ts +5 -0
  47. package/dist/combat/castRunner.js +5 -0
  48. package/dist/combat/comboPoints.d.ts +5 -0
  49. package/dist/combat/comboPoints.js +5 -0
  50. package/dist/combat/comboString.d.ts +5 -0
  51. package/dist/combat/comboString.js +5 -0
  52. package/dist/combat/damageInterceptors.d.ts +192 -0
  53. package/dist/combat/damageInterceptors.js +251 -0
  54. package/dist/combat/damageMatchup.d.ts +68 -0
  55. package/dist/combat/damageMatchup.js +42 -0
  56. package/dist/combat/damageResolution.d.ts +63 -0
  57. package/dist/combat/damageResolution.js +50 -0
  58. package/dist/combat/death.d.ts +7 -1
  59. package/dist/combat/death.js +5 -0
  60. package/dist/combat/deathReason.d.ts +14 -0
  61. package/dist/combat/deathReason.js +1 -0
  62. package/dist/combat/defensiveWindow.d.ts +5 -0
  63. package/dist/combat/defensiveWindow.js +5 -0
  64. package/dist/combat/dotField.d.ts +5 -1
  65. package/dist/combat/dotField.js +5 -1
  66. package/dist/combat/downed.d.ts +5 -0
  67. package/dist/combat/downed.js +5 -0
  68. package/dist/combat/effects.d.ts +5 -0
  69. package/dist/combat/effects.js +5 -0
  70. package/dist/combat/encounterSequence.d.ts +258 -0
  71. package/dist/combat/encounterSequence.js +426 -0
  72. package/dist/combat/hitReaction.d.ts +57 -1
  73. package/dist/combat/hitReaction.js +45 -5
  74. package/dist/combat/magazine.d.ts +54 -0
  75. package/dist/combat/magazine.js +96 -0
  76. package/dist/combat/projectiles.d.ts +5 -0
  77. package/dist/combat/projectiles.js +32 -14
  78. package/dist/combat/receivedDamage.d.ts +117 -0
  79. package/dist/combat/receivedDamage.js +92 -0
  80. package/dist/combat/regenShield.d.ts +5 -1
  81. package/dist/combat/regenShield.js +5 -1
  82. package/dist/combat/renderCues.d.ts +51 -0
  83. package/dist/combat/renderCues.js +44 -0
  84. package/dist/combat/resourcePool.d.ts +5 -0
  85. package/dist/combat/resourcePool.js +5 -0
  86. package/dist/combat/rewardAllocation.d.ts +121 -0
  87. package/dist/combat/rewardAllocation.js +251 -0
  88. package/dist/combat/shotOrigin.d.ts +18 -1
  89. package/dist/combat/shotOrigin.js +39 -0
  90. package/dist/combat/statusApplication.d.ts +96 -0
  91. package/dist/combat/statusApplication.js +81 -0
  92. package/dist/combat/telegraph.d.ts +11 -2
  93. package/dist/combat/telegraph.js +11 -2
  94. package/dist/combat/thresholdCrossings.d.ts +85 -0
  95. package/dist/combat/thresholdCrossings.js +116 -0
  96. package/dist/combat.d.ts +34 -0
  97. package/dist/combat.js +34 -0
  98. package/dist/commands/commandRegistry.d.ts +11 -0
  99. package/dist/commands/commandRegistry.js +9 -2
  100. package/dist/crafting/crop.d.ts +18 -0
  101. package/dist/crafting/crop.js +18 -0
  102. package/dist/crafting/production.d.ts +5 -0
  103. package/dist/crafting/production.js +5 -0
  104. package/dist/devtools/rewriteTunables.d.ts +17 -0
  105. package/dist/devtools/rewriteTunables.js +276 -0
  106. package/dist/devtools/saveEndpoint.d.ts +46 -0
  107. package/dist/devtools/saveEndpoint.js +48 -0
  108. package/dist/devtools/transformTunables.d.ts +3 -0
  109. package/dist/devtools/transformTunables.js +3 -0
  110. package/dist/devtools/tunableSchema.d.ts +31 -0
  111. package/dist/devtools/tunableSchema.js +31 -0
  112. package/dist/economy/currency.d.ts +12 -1
  113. package/dist/economy/currency.js +12 -1
  114. package/dist/economy/listingBook.d.ts +91 -0
  115. package/dist/economy/listingBook.js +144 -0
  116. package/dist/economy/resourceLedger.d.ts +222 -0
  117. package/dist/economy/resourceLedger.js +353 -0
  118. package/dist/economy/sharedWallet.d.ts +14 -0
  119. package/dist/economy/sharedWallet.js +14 -0
  120. package/dist/economy/techTree.d.ts +12 -0
  121. package/dist/economy/techTree.js +12 -0
  122. package/dist/economy/wallet.d.ts +26 -2
  123. package/dist/economy/wallet.js +35 -6
  124. package/dist/editor/commands.d.ts +190 -7
  125. package/dist/editor/commands.js +727 -55
  126. package/dist/editor/document.d.ts +159 -13
  127. package/dist/editor/document.js +750 -19
  128. package/dist/editor/grid.d.ts +229 -0
  129. package/dist/editor/grid.js +366 -0
  130. package/dist/editor/gridAdapters.d.ts +80 -0
  131. package/dist/editor/gridAdapters.js +134 -0
  132. package/dist/editor/index.d.ts +73 -6
  133. package/dist/editor/index.js +6 -2
  134. package/dist/editor/liveSync.d.ts +127 -0
  135. package/dist/editor/liveSync.js +249 -0
  136. package/dist/editor/runtimeInspector.d.ts +88 -0
  137. package/dist/editor/runtimeInspector.js +239 -0
  138. package/dist/editor/types.d.ts +107 -1
  139. package/dist/faction/reputation.d.ts +5 -0
  140. package/dist/faction/reputation.js +5 -0
  141. package/dist/format/distance.d.ts +17 -0
  142. package/dist/format/distance.js +18 -0
  143. package/dist/format/duration.d.ts +27 -0
  144. package/dist/format/duration.js +45 -0
  145. package/dist/format/speed.d.ts +17 -0
  146. package/dist/format/speed.js +25 -0
  147. package/dist/game/connectedPlayers.d.ts +6 -4
  148. package/dist/game/connectedPlayers.js +2 -2
  149. package/dist/game/cosmetics.d.ts +9 -0
  150. package/dist/game/cosmetics.js +16 -0
  151. package/dist/game/defineGame.d.ts +100 -2
  152. package/dist/game/defineGame.js +39 -2
  153. package/dist/game/defineSystem.d.ts +88 -0
  154. package/dist/game/defineSystem.js +45 -0
  155. package/dist/game/dialogue.d.ts +33 -0
  156. package/dist/game/dialogue.js +21 -0
  157. package/dist/game/events.d.ts +35 -13
  158. package/dist/game/events.js +5 -0
  159. package/dist/game/feed.d.ts +33 -0
  160. package/dist/game/feed.js +35 -2
  161. package/dist/game/gamePhase.d.ts +11 -0
  162. package/dist/game/gamePhase.js +16 -0
  163. package/dist/game/leaderboard.d.ts +5 -0
  164. package/dist/game/leaderboard.js +5 -0
  165. package/dist/game/loadout.d.ts +5 -0
  166. package/dist/game/loadout.js +5 -0
  167. package/dist/game/lootFilter.d.ts +2 -0
  168. package/dist/game/lootFilter.js +2 -0
  169. package/dist/game/lootPipeline.d.ts +164 -0
  170. package/dist/game/lootPipeline.js +216 -0
  171. package/dist/game/lootTable.d.ts +19 -2
  172. package/dist/game/lootTable.js +15 -5
  173. package/dist/game/objectives.d.ts +43 -0
  174. package/dist/game/objectives.js +36 -0
  175. package/dist/game/paramLayers.d.ts +148 -0
  176. package/dist/game/paramLayers.js +185 -0
  177. package/dist/game/ping.d.ts +5 -0
  178. package/dist/game/ping.js +5 -0
  179. package/dist/game/playableGame.d.ts +92 -7
  180. package/dist/game/quest.d.ts +8 -0
  181. package/dist/game/quest.js +29 -0
  182. package/dist/game/race.d.ts +141 -0
  183. package/dist/game/race.js +169 -0
  184. package/dist/game/recordBook.d.ts +3 -1
  185. package/dist/game/recordBook.js +4 -1
  186. package/dist/game/ruleSelection.d.ts +75 -0
  187. package/dist/game/ruleSelection.js +127 -0
  188. package/dist/game/runDraft.d.ts +5 -0
  189. package/dist/game/runDraft.js +5 -0
  190. package/dist/game/saveStore.d.ts +111 -0
  191. package/dist/game/saveStore.js +312 -0
  192. package/dist/game/snapshotHistory.d.ts +67 -0
  193. package/dist/game/snapshotHistory.js +95 -0
  194. package/dist/game/social.d.ts +38 -1
  195. package/dist/game/social.js +71 -0
  196. package/dist/game/spawnPoints.d.ts +5 -0
  197. package/dist/game/spawnPoints.js +5 -0
  198. package/dist/game/systemRuntime.d.ts +50 -0
  199. package/dist/game/systemRuntime.js +157 -0
  200. package/dist/game/systemSchedule.d.ts +72 -0
  201. package/dist/game/systemSchedule.js +242 -0
  202. package/dist/game/toasts.d.ts +43 -0
  203. package/dist/game/toasts.js +44 -0
  204. package/dist/game/trade.d.ts +10 -0
  205. package/dist/game/trade.js +10 -0
  206. package/dist/game/unlocks.d.ts +8 -0
  207. package/dist/game/unlocks.js +16 -0
  208. package/dist/game/vfxInstance.d.ts +138 -0
  209. package/dist/game/vfxInstance.js +96 -0
  210. package/dist/game/worldItem.d.ts +17 -4
  211. package/dist/game/worldItem.js +17 -4
  212. package/dist/gameplay.d.ts +91 -0
  213. package/dist/gameplay.js +91 -0
  214. package/dist/index.d.ts +5 -14
  215. package/dist/index.js +5 -14
  216. package/dist/input/actionBindings.d.ts +23 -6
  217. package/dist/input/actionBindings.js +23 -6
  218. package/dist/input/axisInput.d.ts +7 -2
  219. package/dist/input/axisInput.js +7 -2
  220. package/dist/input/controlGroups.d.ts +67 -0
  221. package/dist/input/controlGroups.js +41 -0
  222. package/dist/input/touchScheme.d.ts +82 -6
  223. package/dist/input/touchScheme.js +123 -10
  224. package/dist/interaction/lockpick.d.ts +61 -0
  225. package/dist/interaction/lockpick.js +168 -0
  226. package/dist/interaction/proximityPrompt.d.ts +2 -0
  227. package/dist/interaction/proximityPrompt.js +2 -0
  228. package/dist/interaction/qte.d.ts +5 -0
  229. package/dist/interaction/qte.js +5 -0
  230. package/dist/interaction/skillCheck.d.ts +5 -0
  231. package/dist/interaction/skillCheck.js +5 -0
  232. package/dist/inventory/inventoryModel.d.ts +12 -0
  233. package/dist/inventory/inventoryModel.js +12 -0
  234. package/dist/inventory/shapedGrid.d.ts +16 -0
  235. package/dist/inventory/shapedGrid.js +16 -0
  236. package/dist/inventory/slotModel.d.ts +10 -0
  237. package/dist/inventory/slotModel.js +10 -0
  238. package/dist/item/durability.d.ts +5 -0
  239. package/dist/item/durability.js +5 -0
  240. package/dist/item/itemIdentity.d.ts +171 -0
  241. package/dist/item/itemIdentity.js +138 -0
  242. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  243. package/dist/item/itemInstanceRegistry.js +34 -0
  244. package/dist/item/itemgen.d.ts +163 -0
  245. package/dist/item/itemgen.js +151 -0
  246. package/dist/item/modularItem.d.ts +5 -0
  247. package/dist/item/modularItem.js +5 -0
  248. package/dist/item/use.d.ts +5 -0
  249. package/dist/item/use.js +5 -0
  250. package/dist/item/useBehavior.d.ts +142 -0
  251. package/dist/item/useBehavior.js +105 -0
  252. package/dist/item/weapon.d.ts +5 -0
  253. package/dist/item/weapon.js +5 -0
  254. package/dist/math/scalar.d.ts +25 -0
  255. package/dist/math/scalar.js +47 -0
  256. package/dist/meta/changelog.d.ts +4 -1
  257. package/dist/meta/changelog.js +16 -2
  258. package/dist/movement/avoidance.d.ts +45 -0
  259. package/dist/movement/avoidance.js +123 -0
  260. package/dist/movement/cameraRig.d.ts +8 -0
  261. package/dist/movement/cameraRig.js +8 -0
  262. package/dist/movement/dash.d.ts +11 -0
  263. package/dist/movement/dash.js +11 -0
  264. package/dist/movement/formation.d.ts +135 -0
  265. package/dist/movement/formation.js +194 -0
  266. package/dist/movement/glideModel.d.ts +5 -0
  267. package/dist/movement/glideModel.js +5 -0
  268. package/dist/movement/grappleSwing.d.ts +5 -0
  269. package/dist/movement/grappleSwing.js +5 -0
  270. package/dist/movement/leaderTrail.d.ts +5 -0
  271. package/dist/movement/leaderTrail.js +5 -0
  272. package/dist/movement/movementModel.d.ts +35 -8
  273. package/dist/movement/movementModel.js +42 -14
  274. package/dist/movement/playerMovement.js +65 -10
  275. package/dist/movement/poseState.d.ts +13 -0
  276. package/dist/movement/poseState.js +16 -0
  277. package/dist/movement/steering.d.ts +8 -0
  278. package/dist/movement/steering.js +18 -0
  279. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  280. package/dist/multiplayer/combatSnapshot.js +3 -0
  281. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  282. package/dist/multiplayer/lagCompensation.js +5 -0
  283. package/dist/multiplayer/presenceModel.d.ts +9 -1
  284. package/dist/multiplayer/presenceModel.js +9 -1
  285. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  286. package/dist/multiplayer/simultaneousCommit.js +3 -0
  287. package/dist/multiplayer.d.ts +11 -0
  288. package/dist/multiplayer.js +11 -0
  289. package/dist/nav/pathFollow.d.ts +57 -0
  290. package/dist/nav/pathFollow.js +109 -0
  291. package/dist/orders/orderKinds.d.ts +156 -0
  292. package/dist/orders/orderKinds.js +197 -0
  293. package/dist/orders/orderQueue.d.ts +208 -0
  294. package/dist/orders/orderQueue.js +211 -0
  295. package/dist/physics/drivableVehicle.d.ts +29 -0
  296. package/dist/physics/drivableVehicle.js +16 -0
  297. package/dist/physics/kinematicVehicle.d.ts +21 -1
  298. package/dist/physics/kinematicVehicle.js +23 -8
  299. package/dist/physics/physicsWorld.d.ts +24 -12
  300. package/dist/physics/physicsWorld.js +11 -5
  301. package/dist/physics/radialImpulse.d.ts +25 -0
  302. package/dist/physics/radialImpulse.js +27 -0
  303. package/dist/procedural.d.ts +3 -0
  304. package/dist/procedural.js +3 -0
  305. package/dist/progression/statGraph.d.ts +116 -0
  306. package/dist/progression/statGraph.js +318 -0
  307. package/dist/puzzle/cellGrid.d.ts +9 -0
  308. package/dist/puzzle/cellGrid.js +9 -0
  309. package/dist/puzzle/fallingPiece.d.ts +9 -0
  310. package/dist/puzzle/fallingPiece.js +9 -0
  311. package/dist/puzzle/nonogram.d.ts +39 -0
  312. package/dist/puzzle/nonogram.js +136 -0
  313. package/dist/random/nameGen.d.ts +5 -0
  314. package/dist/random/nameGen.js +5 -0
  315. package/dist/random/pick.d.ts +8 -0
  316. package/dist/random/pick.js +31 -0
  317. package/dist/random/rng.d.ts +22 -0
  318. package/dist/random/rng.js +28 -8
  319. package/dist/random/seedLink.d.ts +4 -0
  320. package/dist/random/seedLink.js +4 -0
  321. package/dist/relation/keyedValues.d.ts +54 -0
  322. package/dist/relation/keyedValues.js +115 -0
  323. package/dist/relation/thresholds.d.ts +62 -0
  324. package/dist/relation/thresholds.js +62 -0
  325. package/dist/render/color.d.ts +12 -0
  326. package/dist/render/color.js +26 -0
  327. package/dist/render/lookPreset.d.ts +41 -0
  328. package/dist/render/lookPreset.js +29 -0
  329. package/dist/render/postProcessing.d.ts +20 -0
  330. package/dist/render/postProcessing.js +21 -1
  331. package/dist/rules/predicate.d.ts +53 -0
  332. package/dist/rules/predicate.js +64 -0
  333. package/dist/rules/ruleEffects.d.ts +38 -0
  334. package/dist/rules/ruleEffects.js +37 -0
  335. package/dist/rules/triggeredRules.d.ts +160 -0
  336. package/dist/rules/triggeredRules.js +241 -0
  337. package/dist/runtime/adapter.d.ts +42 -3
  338. package/dist/runtime/adapter.js +44 -1
  339. package/dist/runtime/cameraDirector.d.ts +1 -0
  340. package/dist/runtime/cameraDirector.js +1 -0
  341. package/dist/runtime/commandRunner.d.ts +1 -0
  342. package/dist/runtime/commandRunner.js +1 -0
  343. package/dist/runtime/context/combatFx.d.ts +23 -0
  344. package/dist/runtime/context/combatFx.js +161 -0
  345. package/dist/runtime/context/registries.d.ts +13 -0
  346. package/dist/runtime/context/registries.js +84 -0
  347. package/dist/runtime/context/worldItems.d.ts +21 -0
  348. package/dist/runtime/context/worldItems.js +37 -0
  349. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  350. package/dist/runtime/descriptors/baseline.js +134 -0
  351. package/dist/runtime/descriptors/features.d.ts +74 -0
  352. package/dist/runtime/descriptors/features.js +281 -0
  353. package/dist/runtime/gameContext.d.ts +114 -13
  354. package/dist/runtime/gameContext.js +303 -395
  355. package/dist/runtime/gameRuntime.d.ts +1 -0
  356. package/dist/runtime/gameRuntime.js +1 -0
  357. package/dist/runtime/headlessRunner.d.ts +60 -0
  358. package/dist/runtime/headlessRunner.js +44 -0
  359. package/dist/runtime/hostPersistence.d.ts +12 -0
  360. package/dist/runtime/hostPersistence.js +12 -0
  361. package/dist/runtime/hostedGameRunner.d.ts +8 -3
  362. package/dist/runtime/hostedGameRunner.js +26 -3
  363. package/dist/runtime/hostedWorldSession.d.ts +12 -4
  364. package/dist/runtime/hostedWorldSession.js +11 -4
  365. package/dist/runtime/inputSnapshot.d.ts +8 -3
  366. package/dist/runtime/inputSnapshot.js +6 -2
  367. package/dist/runtime/motionIntents.d.ts +11 -2
  368. package/dist/runtime/motionIntents.js +16 -2
  369. package/dist/runtime/perContext.d.ts +15 -0
  370. package/dist/runtime/perContext.js +21 -0
  371. package/dist/runtime/runtimeSave.d.ts +79 -0
  372. package/dist/runtime/runtimeSave.js +105 -0
  373. package/dist/runtime/save.d.ts +4 -0
  374. package/dist/runtime/save.js +4 -0
  375. package/dist/runtime/snapshot.d.ts +7 -0
  376. package/dist/runtime/snapshot.js +7 -0
  377. package/dist/runtime/visibility.d.ts +2 -1
  378. package/dist/runtime/visibility.js +2 -1
  379. package/dist/runtime/worldChannel.d.ts +7 -3
  380. package/dist/runtime/worldChannel.js +51 -6
  381. package/dist/runtime/worldMirror.d.ts +14 -2
  382. package/dist/runtime/worldMirror.js +15 -2
  383. package/dist/runtime/worldProjection.d.ts +47 -0
  384. package/dist/runtime/worldProjection.js +52 -0
  385. package/dist/runtime/worldReplication.d.ts +30 -7
  386. package/dist/runtime/worldReplication.js +41 -9
  387. package/dist/runtime/worldSnapshot.d.ts +30 -3
  388. package/dist/runtime/worldSnapshot.js +20 -5
  389. package/dist/scene/assetCatalog.d.ts +21 -0
  390. package/dist/scene/assetCatalog.js +4 -0
  391. package/dist/scene/assetDiagnostics.d.ts +69 -0
  392. package/dist/scene/assetDiagnostics.js +110 -0
  393. package/dist/scene/assetGenerator.d.ts +65 -0
  394. package/dist/scene/assetGenerator.js +64 -0
  395. package/dist/scene/assetSpace.d.ts +137 -0
  396. package/dist/scene/assetSpace.js +259 -0
  397. package/dist/scene/authoredTriggers.d.ts +169 -0
  398. package/dist/scene/authoredTriggers.js +340 -0
  399. package/dist/scene/behaviorRuntime.d.ts +75 -0
  400. package/dist/scene/behaviorRuntime.js +217 -0
  401. package/dist/scene/behaviors.d.ts +14 -2
  402. package/dist/scene/behaviors.js +7 -2
  403. package/dist/scene/bodyBind.d.ts +60 -0
  404. package/dist/scene/bodyBind.js +51 -0
  405. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  406. package/dist/scene/builtinSceneKinds.js +62 -0
  407. package/dist/scene/colliders.d.ts +13 -1
  408. package/dist/scene/colliders.js +37 -1
  409. package/dist/scene/entityStats.d.ts +11 -2
  410. package/dist/scene/entityStats.js +11 -2
  411. package/dist/scene/entityStore.d.ts +12 -1
  412. package/dist/scene/entityStore.js +15 -0
  413. package/dist/scene/facing.d.ts +18 -0
  414. package/dist/scene/facing.js +26 -0
  415. package/dist/scene/modelSockets.d.ts +33 -0
  416. package/dist/scene/modelSockets.js +29 -0
  417. package/dist/scene/objectQuery.d.ts +2 -0
  418. package/dist/scene/objectQuery.js +2 -0
  419. package/dist/scene/objectStore.d.ts +4 -0
  420. package/dist/scene/objectStore.js +6 -0
  421. package/dist/scene/possession.d.ts +8 -0
  422. package/dist/scene/possession.js +14 -0
  423. package/dist/scene/roster.d.ts +3 -0
  424. package/dist/scene/roster.js +12 -0
  425. package/dist/scene/sceneKinds.d.ts +240 -0
  426. package/dist/scene/sceneKinds.js +214 -0
  427. package/dist/scene/sceneOwnership.d.ts +169 -0
  428. package/dist/scene/sceneOwnership.js +179 -0
  429. package/dist/scene/selectionBookmarks.d.ts +93 -0
  430. package/dist/scene/selectionBookmarks.js +122 -0
  431. package/dist/scene/vehicleSeat.d.ts +68 -0
  432. package/dist/scene/vehicleSeat.js +59 -0
  433. package/dist/sensor/concealment.d.ts +3 -0
  434. package/dist/sensor/concealment.js +3 -0
  435. package/dist/sensor/freezeMonitor.d.ts +1 -0
  436. package/dist/sensor/freezeMonitor.js +1 -0
  437. package/dist/sensor/frustumSensor.d.ts +7 -3
  438. package/dist/sensor/frustumSensor.js +7 -3
  439. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  440. package/dist/sensor/hiddenStateProbe.js +5 -2
  441. package/dist/sensor/recordingBuffer.d.ts +2 -1
  442. package/dist/sensor/recordingBuffer.js +2 -1
  443. package/dist/sensor/replayLoop.d.ts +6 -2
  444. package/dist/sensor/replayLoop.js +6 -2
  445. package/dist/sensor/revealQuery.d.ts +2 -1
  446. package/dist/sensor/revealQuery.js +2 -1
  447. package/dist/sensor/visionCone.d.ts +10 -3
  448. package/dist/sensor/visionCone.js +10 -3
  449. package/dist/session/contestedChannel.d.ts +1 -0
  450. package/dist/session/contestedChannel.js +1 -0
  451. package/dist/session/extraction.d.ts +1 -0
  452. package/dist/session/extraction.js +1 -0
  453. package/dist/session/roles.d.ts +6 -0
  454. package/dist/session/roles.js +6 -0
  455. package/dist/session/roundState.d.ts +8 -0
  456. package/dist/session/roundState.js +2 -0
  457. package/dist/settings/settingsModel.d.ts +1 -0
  458. package/dist/settings/settingsModel.js +1 -0
  459. package/dist/stats/accumulatorMeter.d.ts +6 -0
  460. package/dist/stats/accumulatorMeter.js +6 -0
  461. package/dist/stats/eventMeter.d.ts +5 -0
  462. package/dist/stats/eventMeter.js +5 -0
  463. package/dist/stats/rollCheck.d.ts +5 -0
  464. package/dist/stats/rollCheck.js +5 -0
  465. package/dist/stats/statModifiers.d.ts +5 -0
  466. package/dist/stats/statModifiers.js +5 -0
  467. package/dist/store/defineKeyedStore.d.ts +38 -0
  468. package/dist/store/defineKeyedStore.js +42 -0
  469. package/dist/store/defineStore.d.ts +33 -0
  470. package/dist/store/defineStore.js +35 -0
  471. package/dist/store/observableKeyedStore.d.ts +5 -0
  472. package/dist/store/observableKeyedStore.js +34 -2
  473. package/dist/survival/decayMeter.d.ts +55 -0
  474. package/dist/survival/decayMeter.js +130 -55
  475. package/dist/survival/moodle.d.ts +2 -0
  476. package/dist/survival/regionHealth.d.ts +6 -0
  477. package/dist/survival/regionHealth.js +5 -0
  478. package/dist/tactics/fallingGrid.d.ts +4 -2
  479. package/dist/tactics/fallingGrid.js +4 -2
  480. package/dist/tactics/predictiveQuery.d.ts +3 -0
  481. package/dist/tactics/predictiveQuery.js +3 -0
  482. package/dist/tactics/snapshot.d.ts +2 -0
  483. package/dist/tactics/snapshot.js +2 -0
  484. package/dist/tactics/surface.d.ts +1 -0
  485. package/dist/tactics/surface.js +1 -0
  486. package/dist/tactics/tacticalGrid.d.ts +1 -0
  487. package/dist/tactics/tacticalGrid.js +1 -0
  488. package/dist/time/beatClock.d.ts +14 -4
  489. package/dist/time/beatClock.js +14 -4
  490. package/dist/time/calendarClock.d.ts +3 -0
  491. package/dist/time/calendarClock.js +3 -0
  492. package/dist/time/idleProgress.d.ts +4 -0
  493. package/dist/time/idleProgress.js +4 -0
  494. package/dist/time/simClock.d.ts +2 -0
  495. package/dist/time/simClock.js +20 -5
  496. package/dist/ui/actionModel.d.ts +110 -0
  497. package/dist/ui/actionModel.js +159 -0
  498. package/dist/ui/gameLayout.d.ts +30 -11
  499. package/dist/ui/gameLayout.js +30 -11
  500. package/dist/ui/hudDocument.d.ts +114 -0
  501. package/dist/ui/hudDocument.js +220 -0
  502. package/dist/ui/hudLayout.d.ts +33 -1
  503. package/dist/ui/hudLayout.js +204 -17
  504. package/dist/ui/selectionModel.d.ts +92 -0
  505. package/dist/ui/selectionModel.js +88 -0
  506. package/dist/ui/tooltipModel.d.ts +63 -0
  507. package/dist/ui/tooltipModel.js +82 -0
  508. package/dist/ui.d.ts +15 -0
  509. package/dist/ui.js +15 -0
  510. package/dist/visibility/bounds.d.ts +8 -1
  511. package/dist/visibility/bounds.js +8 -1
  512. package/dist/visibility/frustum.d.ts +12 -3
  513. package/dist/visibility/frustum.js +12 -3
  514. package/dist/work/jobQueue.d.ts +201 -0
  515. package/dist/work/jobQueue.js +253 -0
  516. package/dist/work/unitTraining.d.ts +58 -0
  517. package/dist/work/unitTraining.js +52 -0
  518. package/dist/world/authoredObjects.d.ts +58 -0
  519. package/dist/world/authoredObjects.js +69 -0
  520. package/dist/world/buildingGenerator.d.ts +18 -0
  521. package/dist/world/buildingGenerator.js +62 -0
  522. package/dist/world/buildings.d.ts +5 -0
  523. package/dist/world/buildings.js +5 -0
  524. package/dist/world/catenary.d.ts +22 -0
  525. package/dist/world/catenary.js +69 -0
  526. package/dist/world/features.d.ts +115 -7
  527. package/dist/world/features.js +56 -5
  528. package/dist/world/footprintGrid.d.ts +59 -0
  529. package/dist/world/footprintGrid.js +141 -0
  530. package/dist/world/geometry.d.ts +64 -0
  531. package/dist/world/geometry.js +94 -0
  532. package/dist/world/grassKind.d.ts +51 -0
  533. package/dist/world/grassKind.js +101 -0
  534. package/dist/world/pathInstances.d.ts +27 -0
  535. package/dist/world/pathInstances.js +27 -0
  536. package/dist/world/pathTerrain.d.ts +80 -0
  537. package/dist/world/pathTerrain.js +142 -0
  538. package/dist/world/placeAsset.d.ts +81 -0
  539. package/dist/world/placeAsset.js +77 -0
  540. package/dist/world/placement.d.ts +4 -0
  541. package/dist/world/placement.js +4 -0
  542. package/dist/world/placementController.d.ts +6 -0
  543. package/dist/world/placementController.js +6 -0
  544. package/dist/world/polyline.d.ts +34 -0
  545. package/dist/world/polyline.js +81 -0
  546. package/dist/world/roads.d.ts +8 -0
  547. package/dist/world/roads.js +38 -0
  548. package/dist/world/scatterRegion.d.ts +164 -0
  549. package/dist/world/scatterRegion.js +409 -0
  550. package/dist/world/sceneShapes.d.ts +43 -0
  551. package/dist/world/sceneShapes.js +1 -0
  552. package/dist/world/segment.d.ts +27 -0
  553. package/dist/world/segment.js +43 -0
  554. package/dist/world/soilKind.d.ts +48 -0
  555. package/dist/world/soilKind.js +92 -0
  556. package/dist/world/spatialSample.d.ts +241 -0
  557. package/dist/world/spatialSample.js +465 -0
  558. package/dist/world/terraform.d.ts +213 -1
  559. package/dist/world/terraform.js +655 -20
  560. package/dist/world/terrain.d.ts +119 -20
  561. package/dist/world/terrain.js +247 -41
  562. package/dist/world/terrainGuides.d.ts +182 -0
  563. package/dist/world/terrainGuides.js +343 -0
  564. package/dist/world/vec2.d.ts +81 -0
  565. package/dist/world/vec2.js +128 -0
  566. package/dist/world/vec3.d.ts +49 -0
  567. package/dist/world/vec3.js +76 -0
  568. package/dist/world/vegetation.d.ts +71 -0
  569. package/dist/world/vegetation.js +151 -0
  570. package/dist/world/visibilityField.d.ts +154 -0
  571. package/dist/world/visibilityField.js +271 -0
  572. package/dist/world/volumetricClouds.d.ts +52 -0
  573. package/dist/world/volumetricClouds.js +43 -0
  574. package/dist/world/walls.d.ts +9 -0
  575. package/dist/world/walls.js +9 -0
  576. package/dist/world/waterKind.d.ts +55 -0
  577. package/dist/world/waterKind.js +99 -0
  578. package/dist/world.d.ts +132 -0
  579. package/dist/world.js +132 -0
  580. package/package.json +32 -8
  581. package/skills/jgengine/SKILL.md +51 -0
  582. package/skills/jgengine/api.md +434 -0
  583. package/skills/jgengine/capabilities.md +29 -0
  584. package/skills/jgengine/reference-cartridge.md +72 -0
  585. package/skills/jgengine-combat/SKILL.md +34 -0
  586. package/skills/jgengine-combat/api.md +549 -0
  587. package/skills/jgengine-combat/capabilities.md +169 -0
  588. package/skills/jgengine-combat/reference.md +98 -0
  589. package/skills/jgengine-gameplay/SKILL.md +39 -0
  590. package/skills/jgengine-gameplay/api.md +1794 -0
  591. package/skills/jgengine-gameplay/capabilities.md +378 -0
  592. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  593. package/skills/jgengine-world/SKILL.md +38 -0
  594. package/skills/jgengine-world/api.md +2652 -0
  595. package/skills/jgengine-world/capabilities.md +370 -0
  596. package/skills/jgengine-world/reference.md +222 -0
  597. package/dist/cartridge/runtime.d.ts +0 -15
  598. package/dist/cartridge/runtime.js +0 -556
  599. package/dist/cartridge/spec.d.ts +0 -188
  600. package/dist/cartridge/spec.js +0 -19
  601. package/dist/cartridge/validate.d.ts +0 -2
  602. package/dist/cartridge/validate.js +0 -78
  603. package/dist/store/engineStore.d.ts +0 -22
  604. package/dist/store/engineStore.js +0 -50
  605. package/dist/store/features.d.ts +0 -10
  606. package/dist/store/features.js +0 -23
  607. package/llms.txt +0 -5389
@@ -0,0 +1,111 @@
1
+ import { type KeyValueStorage } from "./keyValueStore.js";
2
+ /**
3
+ * The one async storage seam a save store persists through. Every backend
4
+ * satisfies this same three-method shape — the browser's `localStorage`
5
+ * (offline), an in-memory map (tests/SSR), or a database/Convex/HTTP endpoint
6
+ * (cloud) — so a game switches offline saves for cloud saves by swapping the
7
+ * backend and changing nothing else. Keys are opaque namespaced strings; values
8
+ * are already-serialized strings, so a backend never needs to know the save
9
+ * shape.
10
+ */
11
+ export interface SaveBackend {
12
+ read(key: string): Promise<string | null>;
13
+ write(key: string, value: string): Promise<void>;
14
+ remove(key: string): Promise<void>;
15
+ }
16
+ /**
17
+ * A {@link SaveBackend} over a synchronous {@link KeyValueStorage} — the
18
+ * browser's `localStorage` by default (offline, on-device saves), a test stub,
19
+ * or `null` for memory-only. Storage errors (quota exceeded, private mode, no
20
+ * DOM) degrade to no-ops, so a save never throws into a game tick.
21
+ *
22
+ * @capability local-save persist a game to on-device localStorage (offline)
23
+ */
24
+ export declare function localSaveBackend(storage?: KeyValueStorage | null): SaveBackend;
25
+ /** A memory-only {@link SaveBackend} — saves survive a reload only within the same session. For tests, SSR, or a "no persistence" mode that still exercises the same save code path. */
26
+ export declare function memorySaveBackend(): SaveBackend;
27
+ /** Adopt any async `read`/`write`/`remove` trio as a {@link SaveBackend} — the seam for cloud saves backed by a database, an HTTP endpoint, or Convex (see `@jgengine/convex/convexSaveBackend`). Reads/writes may reject; the save store surfaces the failure as `"error"` status instead of throwing. */
28
+ export declare function remoteSaveBackend(backend: SaveBackend): SaveBackend;
29
+ /** Lifecycle of the last save/load — drive a "Saving…"/"Saved" indicator or a loading gate off it. `"error"` means the backend rejected a read or write. */
30
+ export type SaveStatus = "idle" | "loading" | "saving" | "saved" | "error";
31
+ /** Autosave cadence: debounce writes `debounceMs` after the last edit, but never wait longer than `maxWaitMs` while edits keep coming (`0` removes the ceiling). `autosave: true` uses `{ debounceMs: 1000, maxWaitMs: 15000 }`. */
32
+ export interface SaveAutoConfig {
33
+ debounceMs?: number;
34
+ maxWaitMs?: number;
35
+ }
36
+ /** The timer seam autosave schedules through — defaults to the ambient `setTimeout`/`clearTimeout`; inject fakes in tests. */
37
+ export interface SaveTimers {
38
+ set(handler: () => void, ms: number): unknown;
39
+ clear(handle: unknown): void;
40
+ }
41
+ /** The versioned envelope written to the backend — `version` lets a later game build detect and {@link SaveStoreConfig.migrate | migrate} an older payload. */
42
+ export interface SaveEnvelope<T> {
43
+ version: number;
44
+ savedAt: number;
45
+ value: T;
46
+ }
47
+ /** How a {@link createSaveStore} is wired — the backend it persists through, the initial value, and optional slot/versioning/autosave/serialization knobs. */
48
+ export interface SaveStoreConfig<T> {
49
+ /** Where saves live — {@link localSaveBackend}, {@link memorySaveBackend}, or a {@link remoteSaveBackend}. */
50
+ backend: SaveBackend;
51
+ /** The value a fresh save starts from (nothing stored yet, or after `clear`). */
52
+ initial: T;
53
+ /** Storage namespace, joined with the slot into the backend key. Default `"save"`. */
54
+ key?: string;
55
+ /** Active save slot — pass distinct slots for multiple parallel saves. Default `"default"`. */
56
+ slot?: string;
57
+ /** Current save-format version. Default `1`. Bump it on a breaking shape change and pass {@link migrate}. */
58
+ version?: number;
59
+ /** Upgrade an older payload to the current shape. Receives the stored value and the version it was written at (`0` for a pre-versioned/raw payload). */
60
+ migrate?: (data: unknown, fromVersion: number) => T;
61
+ /** Autosave on every `set`/`patch`. `false` (default) saves only on an explicit `save()`. */
62
+ autosave?: boolean | SaveAutoConfig;
63
+ serialize?: (envelope: SaveEnvelope<T>) => string;
64
+ deserialize?: (raw: string) => unknown;
65
+ /** Injectable clock (ms). Default `Date.now`. */
66
+ now?: () => number;
67
+ /** Injectable timers for autosave. Default ambient `setTimeout`/`clearTimeout`. */
68
+ timers?: SaveTimers;
69
+ /** Notified on any backend read/write failure — status is already `"error"` when it runs. */
70
+ onError?: (error: unknown) => void;
71
+ }
72
+ /**
73
+ * A pluggable-backend game save with autosave, named slots, and versioned
74
+ * migration. `value()`/`patch()` hold the live state; `load()` hydrates it from
75
+ * the backend; `save()` (or autosave) writes it back. Backend failures surface
76
+ * as `"error"` status and through `onError` — a save never throws into a tick.
77
+ */
78
+ export interface SaveStore<T> {
79
+ value(): T;
80
+ status(): SaveStatus;
81
+ slot(): string;
82
+ /** Monotonic change counter — bumps on any value or status change; drive `useSyncExternalStore` off it. */
83
+ revision(): number;
84
+ /** Hydrate the active slot from the backend into `value()`; corrupt payloads fall back to `initial`. */
85
+ load(): Promise<T>;
86
+ /** Replace the value and mark it dirty (schedules autosave). */
87
+ set(value: T): void;
88
+ /** Read-modify-write the value and mark it dirty; returns the next value. */
89
+ patch(mutate: (previous: T) => T): T;
90
+ /** Flush the current value to the backend now (serialized against in-flight saves). */
91
+ save(): Promise<void>;
92
+ /** Delete the active slot and reset `value()` to `initial`. */
93
+ clear(): Promise<void>;
94
+ /** Flush any dirty state, switch to `slot`, and load it. */
95
+ switchSlot(slot: string): Promise<T>;
96
+ /** The slots this store has written (for a load/save menu). */
97
+ slots(): Promise<string[]>;
98
+ subscribe(listener: () => void): () => void;
99
+ /** Stop autosave timers and drop listeners. */
100
+ dispose(): void;
101
+ }
102
+ /**
103
+ * Create a {@link SaveStore}. Same call for offline and cloud — only the
104
+ * `backend` differs (localStorage, memory, or an async DB/Convex endpoint). Turn
105
+ * on `autosave` and every `set`/`patch` persists on a debounce; leave it off and
106
+ * call `save()` at checkpoints. Bump `version` + pass `migrate` when the save
107
+ * shape changes so old players keep their progress.
108
+ *
109
+ * @capability game-save save/load game state with a pluggable backend, autosave, slots, and migration
110
+ */
111
+ export declare function createSaveStore<T>(config: SaveStoreConfig<T>): SaveStore<T>;
@@ -0,0 +1,312 @@
1
+ import { defaultKeyValueStorage } from "./keyValueStore.js";
2
+ function readSafe(storage, key) {
3
+ if (storage === null)
4
+ return null;
5
+ try {
6
+ return storage.getItem(key);
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ }
12
+ /**
13
+ * A {@link SaveBackend} over a synchronous {@link KeyValueStorage} — the
14
+ * browser's `localStorage` by default (offline, on-device saves), a test stub,
15
+ * or `null` for memory-only. Storage errors (quota exceeded, private mode, no
16
+ * DOM) degrade to no-ops, so a save never throws into a game tick.
17
+ *
18
+ * @capability local-save persist a game to on-device localStorage (offline)
19
+ */
20
+ export function localSaveBackend(storage) {
21
+ const store = storage === undefined ? defaultKeyValueStorage() : storage;
22
+ return {
23
+ read: (key) => Promise.resolve(readSafe(store, key)),
24
+ write: (key, value) => {
25
+ if (store !== null) {
26
+ try {
27
+ store.setItem(key, value);
28
+ }
29
+ catch {
30
+ // storage rejected the write; the store keeps the value in memory
31
+ }
32
+ }
33
+ return Promise.resolve();
34
+ },
35
+ remove: (key) => {
36
+ if (store !== null) {
37
+ try {
38
+ store.removeItem(key);
39
+ }
40
+ catch {
41
+ // ignore removal failure
42
+ }
43
+ }
44
+ return Promise.resolve();
45
+ },
46
+ };
47
+ }
48
+ /** A memory-only {@link SaveBackend} — saves survive a reload only within the same session. For tests, SSR, or a "no persistence" mode that still exercises the same save code path. */
49
+ export function memorySaveBackend() {
50
+ const map = new Map();
51
+ return {
52
+ read: (key) => Promise.resolve(map.get(key) ?? null),
53
+ write: (key, value) => {
54
+ map.set(key, value);
55
+ return Promise.resolve();
56
+ },
57
+ remove: (key) => {
58
+ map.delete(key);
59
+ return Promise.resolve();
60
+ },
61
+ };
62
+ }
63
+ /** Adopt any async `read`/`write`/`remove` trio as a {@link SaveBackend} — the seam for cloud saves backed by a database, an HTTP endpoint, or Convex (see `@jgengine/convex/convexSaveBackend`). Reads/writes may reject; the save store surfaces the failure as `"error"` status instead of throwing. */
64
+ export function remoteSaveBackend(backend) {
65
+ return backend;
66
+ }
67
+ function defaultTimers() {
68
+ return {
69
+ set: (handler, ms) => globalThis.setTimeout(handler, ms),
70
+ clear: (handle) => globalThis.clearTimeout(handle),
71
+ };
72
+ }
73
+ function normalizeAuto(config) {
74
+ if (config === undefined || config === false)
75
+ return null;
76
+ if (config === true)
77
+ return { debounceMs: 1000, maxWaitMs: 15000 };
78
+ return { debounceMs: config.debounceMs ?? 1000, maxWaitMs: config.maxWaitMs ?? 15000 };
79
+ }
80
+ function isEnvelope(value) {
81
+ return (typeof value === "object" &&
82
+ value !== null &&
83
+ typeof value.version === "number" &&
84
+ "value" in value);
85
+ }
86
+ /**
87
+ * Create a {@link SaveStore}. Same call for offline and cloud — only the
88
+ * `backend` differs (localStorage, memory, or an async DB/Convex endpoint). Turn
89
+ * on `autosave` and every `set`/`patch` persists on a debounce; leave it off and
90
+ * call `save()` at checkpoints. Bump `version` + pass `migrate` when the save
91
+ * shape changes so old players keep their progress.
92
+ *
93
+ * @capability game-save save/load game state with a pluggable backend, autosave, slots, and migration
94
+ */
95
+ export function createSaveStore(config) {
96
+ const namespace = config.key ?? "save";
97
+ const formatVersion = config.version ?? 1;
98
+ const initial = config.initial;
99
+ const backend = config.backend;
100
+ const clock = config.now ?? (() => Date.now());
101
+ const timers = config.timers ?? defaultTimers();
102
+ const auto = normalizeAuto(config.autosave);
103
+ const serialize = config.serialize ?? ((envelope) => JSON.stringify(envelope));
104
+ const deserialize = config.deserialize ?? ((raw) => JSON.parse(raw));
105
+ const onError = config.onError;
106
+ let currentSlot = config.slot ?? "default";
107
+ let current = initial;
108
+ let status = "idle";
109
+ let revision = 0;
110
+ let dirty = false;
111
+ let firstDirtyAt = null;
112
+ let pendingTimer = null;
113
+ let saveChain = Promise.resolve();
114
+ let disposed = false;
115
+ const listeners = new Set();
116
+ function emit() {
117
+ revision += 1;
118
+ for (const listener of listeners)
119
+ listener();
120
+ }
121
+ function setStatus(next) {
122
+ if (status === next)
123
+ return;
124
+ status = next;
125
+ emit();
126
+ }
127
+ function reportError(error) {
128
+ onError?.(error);
129
+ }
130
+ const dataKey = (slot) => `${namespace}:${slot}`;
131
+ const indexKey = () => `${namespace}:__slots__`;
132
+ function decode(raw) {
133
+ const parsed = deserialize(raw);
134
+ if (isEnvelope(parsed)) {
135
+ if (parsed.version === formatVersion)
136
+ return parsed.value;
137
+ if (config.migrate)
138
+ return config.migrate(parsed.value, parsed.version);
139
+ return parsed.value;
140
+ }
141
+ if (config.migrate)
142
+ return config.migrate(parsed, 0);
143
+ return parsed;
144
+ }
145
+ async function readSlots() {
146
+ try {
147
+ const raw = await backend.read(indexKey());
148
+ if (raw === null)
149
+ return [];
150
+ const parsed = JSON.parse(raw);
151
+ return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
152
+ }
153
+ catch {
154
+ return [];
155
+ }
156
+ }
157
+ async function rememberSlot(slot) {
158
+ try {
159
+ const list = await readSlots();
160
+ if (list.includes(slot))
161
+ return;
162
+ await backend.write(indexKey(), JSON.stringify([...list, slot]));
163
+ }
164
+ catch (error) {
165
+ reportError(error);
166
+ }
167
+ }
168
+ async function forgetSlot(slot) {
169
+ try {
170
+ const list = await readSlots();
171
+ if (!list.includes(slot))
172
+ return;
173
+ await backend.write(indexKey(), JSON.stringify(list.filter((entry) => entry !== slot)));
174
+ }
175
+ catch (error) {
176
+ reportError(error);
177
+ }
178
+ }
179
+ function clearTimer() {
180
+ if (pendingTimer !== null) {
181
+ timers.clear(pendingTimer);
182
+ pendingTimer = null;
183
+ }
184
+ }
185
+ function markDirty() {
186
+ dirty = true;
187
+ if (auto === null)
188
+ return;
189
+ const now = clock();
190
+ if (firstDirtyAt === null)
191
+ firstDirtyAt = now;
192
+ if (auto.maxWaitMs > 0 && now - firstDirtyAt >= auto.maxWaitMs) {
193
+ clearTimer();
194
+ void save();
195
+ return;
196
+ }
197
+ clearTimer();
198
+ pendingTimer = timers.set(() => {
199
+ pendingTimer = null;
200
+ void save();
201
+ }, auto.debounceMs);
202
+ }
203
+ async function flush() {
204
+ if (disposed)
205
+ return;
206
+ clearTimer();
207
+ const slot = currentSlot;
208
+ const value = current;
209
+ setStatus("saving");
210
+ try {
211
+ const envelope = { version: formatVersion, savedAt: clock(), value };
212
+ await backend.write(dataKey(slot), serialize(envelope));
213
+ await rememberSlot(slot);
214
+ if (current === value) {
215
+ dirty = false;
216
+ firstDirtyAt = null;
217
+ }
218
+ setStatus("saved");
219
+ }
220
+ catch (error) {
221
+ setStatus("error");
222
+ reportError(error);
223
+ }
224
+ }
225
+ function save() {
226
+ const run = saveChain.then(() => flush());
227
+ saveChain = run.catch(() => undefined);
228
+ return run;
229
+ }
230
+ async function load() {
231
+ setStatus("loading");
232
+ try {
233
+ const raw = await backend.read(dataKey(currentSlot));
234
+ let value;
235
+ try {
236
+ value = raw === null ? initial : decode(raw);
237
+ }
238
+ catch {
239
+ value = initial;
240
+ }
241
+ current = value;
242
+ dirty = false;
243
+ firstDirtyAt = null;
244
+ setStatus("idle");
245
+ emit();
246
+ void rememberSlot(currentSlot);
247
+ return current;
248
+ }
249
+ catch (error) {
250
+ setStatus("error");
251
+ reportError(error);
252
+ return current;
253
+ }
254
+ }
255
+ return {
256
+ value: () => current,
257
+ status: () => status,
258
+ slot: () => currentSlot,
259
+ revision: () => revision,
260
+ load,
261
+ set(value) {
262
+ current = value;
263
+ emit();
264
+ markDirty();
265
+ },
266
+ patch(mutate) {
267
+ current = mutate(current);
268
+ emit();
269
+ markDirty();
270
+ return current;
271
+ },
272
+ save,
273
+ async clear() {
274
+ clearTimer();
275
+ const slot = currentSlot;
276
+ setStatus("saving");
277
+ try {
278
+ await backend.remove(dataKey(slot));
279
+ await forgetSlot(slot);
280
+ current = initial;
281
+ dirty = false;
282
+ firstDirtyAt = null;
283
+ setStatus("idle");
284
+ emit();
285
+ }
286
+ catch (error) {
287
+ setStatus("error");
288
+ reportError(error);
289
+ }
290
+ },
291
+ async switchSlot(slot) {
292
+ if (dirty)
293
+ await save();
294
+ clearTimer();
295
+ currentSlot = slot;
296
+ current = initial;
297
+ dirty = false;
298
+ firstDirtyAt = null;
299
+ return load();
300
+ },
301
+ slots: readSlots,
302
+ subscribe(listener) {
303
+ listeners.add(listener);
304
+ return () => listeners.delete(listener);
305
+ },
306
+ dispose() {
307
+ disposed = true;
308
+ clearTimer();
309
+ listeners.clear();
310
+ },
311
+ };
312
+ }
@@ -0,0 +1,67 @@
1
+ /** Bounded past/future snapshot stacks — a serializable undo/redo record for any state `T`. */
2
+ export interface HistoryStacks<T> {
3
+ /** Prior states, oldest first; the last entry is the step an undo restores. */
4
+ readonly past: readonly T[];
5
+ /** Undone states awaiting redo, oldest first; the last entry is the step a redo restores. */
6
+ readonly future: readonly T[];
7
+ }
8
+ /** The snapshot an undo/redo restores plus the advanced stacks. */
9
+ export interface HistoryStep<T> {
10
+ /** State to apply as the new present. */
11
+ snapshot: T;
12
+ /** Stacks after the step. */
13
+ stacks: HistoryStacks<T>;
14
+ }
15
+ /** Empty history stacks for state `T`.
16
+ * @internal
17
+ */
18
+ export declare function emptyHistory<T>(): HistoryStacks<T>;
19
+ /** True when there is a prior state to undo to.
20
+ * @internal
21
+ */
22
+ export declare function canUndo<T>(stacks: HistoryStacks<T>): boolean;
23
+ /** True when there is an undone state to redo.
24
+ * @internal
25
+ */
26
+ export declare function canRedo<T>(stacks: HistoryStacks<T>): boolean;
27
+ /**
28
+ * Record `present` as the newest undo step and clear the redo future (a fresh action forks history).
29
+ * The oldest past entries beyond `limit` are dropped so the stack stays bounded for save/transport.
30
+ * @internal
31
+ */
32
+ export declare function recordSnapshot<T>(stacks: HistoryStacks<T>, present: T, limit?: number): HistoryStacks<T>;
33
+ /**
34
+ * Step back: pop the newest past snapshot to apply as the new present, and push the given `present`
35
+ * onto the future for a later redo. Returns `null` when there is nothing to undo.
36
+ * @internal
37
+ */
38
+ export declare function undoSnapshot<T>(stacks: HistoryStacks<T>, present: T): HistoryStep<T> | null;
39
+ /**
40
+ * Step forward: pop the newest future snapshot to apply as the new present, and push the given
41
+ * `present` back onto the past. Returns `null` when there is nothing to redo.
42
+ * @internal
43
+ */
44
+ export declare function redoSnapshot<T>(stacks: HistoryStacks<T>, present: T): HistoryStep<T> | null;
45
+ /** Stateful undo/redo handle over {@link HistoryStacks}, holding the stacks in a closure. */
46
+ export interface SnapshotHistory<T> {
47
+ /** Record `present` as a new undo step and clear the redo future. */
48
+ record(present: T): void;
49
+ /** Undo, returning the restored snapshot or `null` if there is nothing to undo. */
50
+ undo(present: T): T | null;
51
+ /** Redo, returning the restored snapshot or `null` if there is nothing to redo. */
52
+ redo(present: T): T | null;
53
+ /** True when an undo is available. */
54
+ canUndo(): boolean;
55
+ /** True when a redo is available. */
56
+ canRedo(): boolean;
57
+ /** Drop all history. */
58
+ clear(): void;
59
+ /** Current immutable stacks (for serialization). */
60
+ stacks(): HistoryStacks<T>;
61
+ }
62
+ /**
63
+ * Stateful undo/redo handle wrapping the pure snapshot functions. Call `record(state)` before each
64
+ * mutation; `undo`/`redo` return the state to apply. `limit` bounds the past stack.
65
+ * @internal
66
+ */
67
+ export declare function createSnapshotHistory<T>(limit?: number): SnapshotHistory<T>;
@@ -0,0 +1,95 @@
1
+ /** Empty history stacks for state `T`.
2
+ * @internal
3
+ */
4
+ export function emptyHistory() {
5
+ return { past: [], future: [] };
6
+ }
7
+ /** True when there is a prior state to undo to.
8
+ * @internal
9
+ */
10
+ export function canUndo(stacks) {
11
+ return stacks.past.length > 0;
12
+ }
13
+ /** True when there is an undone state to redo.
14
+ * @internal
15
+ */
16
+ export function canRedo(stacks) {
17
+ return stacks.future.length > 0;
18
+ }
19
+ /**
20
+ * Record `present` as the newest undo step and clear the redo future (a fresh action forks history).
21
+ * The oldest past entries beyond `limit` are dropped so the stack stays bounded for save/transport.
22
+ * @internal
23
+ */
24
+ export function recordSnapshot(stacks, present, limit = 100) {
25
+ const past = [...stacks.past, present];
26
+ const trimmed = limit > 0 && past.length > limit ? past.slice(past.length - limit) : past;
27
+ return { past: trimmed, future: [] };
28
+ }
29
+ /**
30
+ * Step back: pop the newest past snapshot to apply as the new present, and push the given `present`
31
+ * onto the future for a later redo. Returns `null` when there is nothing to undo.
32
+ * @internal
33
+ */
34
+ export function undoSnapshot(stacks, present) {
35
+ if (stacks.past.length === 0)
36
+ return null;
37
+ const snapshot = stacks.past[stacks.past.length - 1];
38
+ return {
39
+ snapshot,
40
+ stacks: { past: stacks.past.slice(0, -1), future: [...stacks.future, present] },
41
+ };
42
+ }
43
+ /**
44
+ * Step forward: pop the newest future snapshot to apply as the new present, and push the given
45
+ * `present` back onto the past. Returns `null` when there is nothing to redo.
46
+ * @internal
47
+ */
48
+ export function redoSnapshot(stacks, present) {
49
+ if (stacks.future.length === 0)
50
+ return null;
51
+ const snapshot = stacks.future[stacks.future.length - 1];
52
+ return {
53
+ snapshot,
54
+ stacks: { past: [...stacks.past, present], future: stacks.future.slice(0, -1) },
55
+ };
56
+ }
57
+ /**
58
+ * Stateful undo/redo handle wrapping the pure snapshot functions. Call `record(state)` before each
59
+ * mutation; `undo`/`redo` return the state to apply. `limit` bounds the past stack.
60
+ * @internal
61
+ */
62
+ export function createSnapshotHistory(limit = 100) {
63
+ let stacks = emptyHistory();
64
+ return {
65
+ record(present) {
66
+ stacks = recordSnapshot(stacks, present, limit);
67
+ },
68
+ undo(present) {
69
+ const step = undoSnapshot(stacks, present);
70
+ if (step === null)
71
+ return null;
72
+ stacks = step.stacks;
73
+ return step.snapshot;
74
+ },
75
+ redo(present) {
76
+ const step = redoSnapshot(stacks, present);
77
+ if (step === null)
78
+ return null;
79
+ stacks = step.stacks;
80
+ return step.snapshot;
81
+ },
82
+ canUndo() {
83
+ return canUndo(stacks);
84
+ },
85
+ canRedo() {
86
+ return canRedo(stacks);
87
+ },
88
+ clear() {
89
+ stacks = emptyHistory();
90
+ },
91
+ stacks() {
92
+ return stacks;
93
+ },
94
+ };
95
+ }
@@ -135,6 +135,36 @@ export interface WorldInvites {
135
135
  decline(userId: string, inviteId: string): void;
136
136
  listFor(userId: string): WorldInvite[];
137
137
  }
138
+ /** One party's replicated membership — id, current leader, and ordered member ids. */
139
+ export interface SocialPartySnapshot {
140
+ id: string;
141
+ leader: string;
142
+ members: string[];
143
+ }
144
+ /**
145
+ * Full friends/party/world-invite state as one serializable baseline — the host→client replication
146
+ * payload behind the `social` snapshot module. Presence and emotes are derived from live deps, not stored.
147
+ */
148
+ export interface SocialSnapshot {
149
+ friendships: Record<string, string[]>;
150
+ blocked: Record<string, string[]>;
151
+ friendRequests: Record<string, {
152
+ from: string;
153
+ to: string;
154
+ }>;
155
+ requestCounter: number;
156
+ partyConfig: PartyConfig | null;
157
+ parties: SocialPartySnapshot[];
158
+ partyInvites: Record<string, {
159
+ from: string;
160
+ to: string;
161
+ createdAt: number;
162
+ }>;
163
+ partyCounter: number;
164
+ inviteCounter: number;
165
+ worldInvites: WorldInvite[];
166
+ worldInviteCounter: number;
167
+ }
138
168
  export interface Social {
139
169
  friends: Friends;
140
170
  party: Party;
@@ -143,5 +173,12 @@ export interface Social {
143
173
  };
144
174
  emotes: Emotes;
145
175
  worldInvites: WorldInvites;
146
- }
176
+ snapshot(): SocialSnapshot;
177
+ hydrate(data: SocialSnapshot): void;
178
+ }
179
+ /**
180
+ * Emotes and lightweight social interactions between nearby players.
181
+ *
182
+ * @capability social-emotes emotes and social interactions between nearby players
183
+ */
147
184
  export declare function createSocial(deps: SocialDeps): Social;