@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,79 @@
1
+ import { type SaveBackend, type SaveStatus, type SaveTimers } from "../game/saveStore.js";
2
+ import type { WorldSnapshot } from "./worldSnapshot.js";
3
+ /**
4
+ * The narrow slice of a live `GameContext` a runtime save reads and writes — a
5
+ * `GameContext` satisfies it directly (`ctx.snapshot`/`ctx.hydrate`/`ctx.subscribe`).
6
+ * Depending on this instead of the full context keeps the save controller a deep,
7
+ * decoupled module: it captures and restores the *whole* opted-in world without
8
+ * knowing any subsystem.
9
+ */
10
+ export interface RuntimeSaveTarget {
11
+ snapshot(): WorldSnapshot;
12
+ hydrate(snapshot: WorldSnapshot): void;
13
+ subscribe(listener: () => void): () => void;
14
+ }
15
+ /** `"autosave"` writes a fresh capture on a debounce after any world change; `"manual"` writes only on an explicit `save()`/`checkpoint()` — the save-point / quest-trigger model. */
16
+ export type RuntimeSaveMode = "autosave" | "manual";
17
+ /** How {@link createRuntimeSave} is wired — the live world `target`, the `backend` it persists through, and optional mode/slot/versioning/cadence knobs. */
18
+ export interface RuntimeSaveConfig {
19
+ /** The live world to capture from and restore into — pass the `GameContext`. */
20
+ target: RuntimeSaveTarget;
21
+ /** Where the save lives — `localSaveBackend()` (offline) or a cloud/Convex backend; the only thing that changes between offline and cloud. */
22
+ backend: SaveBackend;
23
+ /** `"autosave"` (default) persists on world change; `"manual"` only when the game calls `save()`/`checkpoint()`. */
24
+ mode?: RuntimeSaveMode;
25
+ /** Storage namespace. Default `"runtime"`. */
26
+ key?: string;
27
+ /** Active save slot. Default `"default"`. */
28
+ slot?: string;
29
+ /** Save-format version; bump + pass {@link migrate} on a breaking world-shape change. */
30
+ version?: number;
31
+ migrate?: (data: unknown, fromVersion: number) => WorldSnapshot;
32
+ /** Debounce for `autosave` mode. Default `3000`. */
33
+ autosaveMs?: number;
34
+ now?: () => number;
35
+ timers?: SaveTimers;
36
+ onError?: (error: unknown) => void;
37
+ }
38
+ /** {@link RuntimeSaveConfig} without `target` — what a host (`createGameContext`) accepts to build `ctx.game.save` and bind it to the context itself. */
39
+ export type RuntimeSaveOptions = Omit<RuntimeSaveConfig, "target">;
40
+ /**
41
+ * Whole-world save/load bound to a live world and a pluggable backend. `save()`
42
+ * captures `target.snapshot()` and writes it; `load()` reads it back and
43
+ * `target.hydrate()`s the whole world. In `autosave` mode it also writes on a
44
+ * debounce after any change. Named slots, versioned migration, and offline↔cloud
45
+ * (backend swap) all come for free from the underlying save store.
46
+ */
47
+ export interface RuntimeSave {
48
+ status(): SaveStatus;
49
+ slot(): string;
50
+ /** Capture the live world and persist it now (serialized against any in-flight write). */
51
+ save(): Promise<void>;
52
+ /** Semantic alias for `save()` — call it from a save point, a quest-complete or area-enter handler. */
53
+ checkpoint(): Promise<void>;
54
+ /** Load the active slot and hydrate the whole world; resolves `true` when a real save was applied, `false` for an empty slot. */
55
+ load(): Promise<boolean>;
56
+ /** Whether the active slot holds a saved world — gate a title-screen "Continue" on it. */
57
+ hasSave(): Promise<boolean>;
58
+ /** Delete the active slot's save. */
59
+ clear(): Promise<void>;
60
+ /** Switch slot and load it, hydrating the world when that slot has a save. */
61
+ switchSlot(slot: string): Promise<boolean>;
62
+ /** The slots this game has written — back a load/save menu. */
63
+ slots(): Promise<string[]>;
64
+ subscribe(listener: () => void): () => void;
65
+ /** Stop autosave and release the world subscription. */
66
+ dispose(): void;
67
+ }
68
+ /**
69
+ * Bridge a live world to a pluggable save backend: whole-state capture/restore
70
+ * with autosave, save points, named slots, and versioned migration — the same
71
+ * call for offline (localStorage) and cloud (Convex), only the `backend`
72
+ * differs. The game keeps control of *when* it saves (the `mode` plus explicit
73
+ * `checkpoint()` calls from quests/areas) and *when* it restores (`load()` on
74
+ * boot), so any save mechanic — continuous autosave, manual save points,
75
+ * checkpoint triggers — is expressible without new engine code.
76
+ *
77
+ * @capability runtime-save save/load the whole game world through a pluggable backend, autosave or save points
78
+ */
79
+ export declare function createRuntimeSave(config: RuntimeSaveConfig): RuntimeSave;
@@ -0,0 +1,105 @@
1
+ import { createSaveStore, } from "../game/saveStore.js";
2
+ function defaultTimers() {
3
+ return {
4
+ set: (handler, ms) => globalThis.setTimeout(handler, ms),
5
+ clear: (handle) => globalThis.clearTimeout(handle),
6
+ };
7
+ }
8
+ function hasContent(snapshot) {
9
+ for (const _key in snapshot)
10
+ return true;
11
+ return false;
12
+ }
13
+ /**
14
+ * Bridge a live world to a pluggable save backend: whole-state capture/restore
15
+ * with autosave, save points, named slots, and versioned migration — the same
16
+ * call for offline (localStorage) and cloud (Convex), only the `backend`
17
+ * differs. The game keeps control of *when* it saves (the `mode` plus explicit
18
+ * `checkpoint()` calls from quests/areas) and *when* it restores (`load()` on
19
+ * boot), so any save mechanic — continuous autosave, manual save points,
20
+ * checkpoint triggers — is expressible without new engine code.
21
+ *
22
+ * @capability runtime-save save/load the whole game world through a pluggable backend, autosave or save points
23
+ */
24
+ export function createRuntimeSave(config) {
25
+ const mode = config.mode ?? "autosave";
26
+ const autosaveMs = config.autosaveMs ?? 3000;
27
+ const timers = config.timers ?? defaultTimers();
28
+ const store = createSaveStore({
29
+ backend: config.backend,
30
+ initial: {},
31
+ key: config.key ?? "runtime",
32
+ slot: config.slot,
33
+ version: config.version,
34
+ migrate: config.migrate,
35
+ autosave: false,
36
+ now: config.now,
37
+ onError: config.onError,
38
+ });
39
+ let pendingTimer = null;
40
+ let unsubscribe = null;
41
+ let disposed = false;
42
+ let restoring = false;
43
+ function clearTimer() {
44
+ if (pendingTimer !== null) {
45
+ timers.clear(pendingTimer);
46
+ pendingTimer = null;
47
+ }
48
+ }
49
+ function persist() {
50
+ clearTimer();
51
+ store.set(config.target.snapshot());
52
+ return store.save();
53
+ }
54
+ function scheduleAutosave() {
55
+ if (disposed || restoring)
56
+ return;
57
+ clearTimer();
58
+ pendingTimer = timers.set(() => {
59
+ pendingTimer = null;
60
+ void persist();
61
+ }, autosaveMs);
62
+ }
63
+ if (mode === "autosave") {
64
+ unsubscribe = config.target.subscribe(scheduleAutosave);
65
+ }
66
+ function applyLoaded(snapshot) {
67
+ if (!hasContent(snapshot))
68
+ return false;
69
+ restoring = true;
70
+ try {
71
+ config.target.hydrate(snapshot);
72
+ }
73
+ finally {
74
+ restoring = false;
75
+ }
76
+ return true;
77
+ }
78
+ const save = () => persist();
79
+ return {
80
+ status: () => store.status(),
81
+ slot: () => store.slot(),
82
+ save,
83
+ checkpoint: save,
84
+ async load() {
85
+ return applyLoaded(await store.load());
86
+ },
87
+ async hasSave() {
88
+ return hasContent(await store.load());
89
+ },
90
+ clear: () => store.clear(),
91
+ async switchSlot(slot) {
92
+ clearTimer();
93
+ return applyLoaded(await store.switchSlot(slot));
94
+ },
95
+ slots: () => store.slots(),
96
+ subscribe: (listener) => store.subscribe(listener),
97
+ dispose() {
98
+ disposed = true;
99
+ clearTimer();
100
+ if (unsubscribe !== null)
101
+ unsubscribe();
102
+ store.dispose();
103
+ },
104
+ };
105
+ }
@@ -3,7 +3,11 @@ export type SaveConfig = "none" | {
3
3
  auto: string;
4
4
  scope: SaveScope;
5
5
  };
6
+ /** @internal */
6
7
  export declare function parseSaveAutoMs(auto: string): number;
8
+ /** @internal */
7
9
  export declare function saveScopeIncludesPlayer(scope: SaveScope): boolean;
10
+ /** @internal */
8
11
  export declare function saveScopeIncludesChunks(scope: SaveScope): boolean;
12
+ /** @internal */
9
13
  export declare function isSaveEnabled(config: SaveConfig): config is Exclude<SaveConfig, "none">;
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function parseSaveAutoMs(auto) {
2
3
  const match = /^(\d+(?:\.\d+)?)(ms|s|m|h)$/.exec(auto.trim());
3
4
  if (!match) {
@@ -18,12 +19,15 @@ export function parseSaveAutoMs(auto) {
18
19
  throw new Error(`Invalid save.auto unit: ${unit}`);
19
20
  }
20
21
  }
22
+ /** @internal */
21
23
  export function saveScopeIncludesPlayer(scope) {
22
24
  return scope === "player" || scope === "player+chunks";
23
25
  }
26
+ /** @internal */
24
27
  export function saveScopeIncludesChunks(scope) {
25
28
  return scope === "chunks" || scope === "player+chunks";
26
29
  }
30
+ /** @internal */
27
31
  export function isSaveEnabled(config) {
28
32
  return config !== "none";
29
33
  }
@@ -69,8 +69,11 @@ export type GameRuntimeSnapshot = {
69
69
  chunks: string[];
70
70
  };
71
71
  };
72
+ /** @internal */
72
73
  export declare function createEmptyServerRow(): RuntimeServerRow;
74
+ /** @internal */
73
75
  export declare function createEmptyPlayerRow(userId: string): RuntimePlayerRow;
76
+ /** @internal */
74
77
  export declare function createRuntimeSnapshot(args: {
75
78
  gameId: string;
76
79
  serverId: string;
@@ -79,9 +82,13 @@ export declare function createRuntimeSnapshot(args: {
79
82
  chunks?: Record<string, RuntimeChunkRow>;
80
83
  revision?: number;
81
84
  }): GameRuntimeSnapshot;
85
+ /** @internal */
82
86
  export declare function markServerDirty(snapshot: GameRuntimeSnapshot): GameRuntimeSnapshot;
87
+ /** @internal */
83
88
  export declare function markPlayerDirty(snapshot: GameRuntimeSnapshot, userId: string): GameRuntimeSnapshot;
89
+ /** @internal */
84
90
  export declare function clearDirtyFlags(snapshot: GameRuntimeSnapshot): GameRuntimeSnapshot;
91
+ /** @internal */
85
92
  export declare function splitProfilePlayer(player: RuntimePlayerRow): {
86
93
  persistent: RuntimePlayerRow;
87
94
  session: Record<string, unknown>;
@@ -1,4 +1,5 @@
1
1
  export const RUNTIME_SNAPSHOT_VERSION = 1;
2
+ /** @internal */
2
3
  export function createEmptyServerRow() {
3
4
  return {
4
5
  entities: [],
@@ -7,6 +8,7 @@ export function createEmptyServerRow() {
7
8
  feeds: {},
8
9
  };
9
10
  }
11
+ /** @internal */
10
12
  export function createEmptyPlayerRow(userId) {
11
13
  return {
12
14
  userId,
@@ -16,6 +18,7 @@ export function createEmptyPlayerRow(userId) {
16
18
  session: {},
17
19
  };
18
20
  }
21
+ /** @internal */
19
22
  export function createRuntimeSnapshot(args) {
20
23
  return {
21
24
  version: RUNTIME_SNAPSHOT_VERSION,
@@ -32,6 +35,7 @@ export function createRuntimeSnapshot(args) {
32
35
  },
33
36
  };
34
37
  }
38
+ /** @internal */
35
39
  export function markServerDirty(snapshot) {
36
40
  return {
37
41
  ...snapshot,
@@ -39,6 +43,7 @@ export function markServerDirty(snapshot) {
39
43
  dirty: { ...snapshot.dirty, server: true },
40
44
  };
41
45
  }
46
+ /** @internal */
42
47
  export function markPlayerDirty(snapshot, userId) {
43
48
  if (snapshot.dirty.players.includes(userId)) {
44
49
  return markServerDirty(snapshot);
@@ -53,6 +58,7 @@ export function markPlayerDirty(snapshot, userId) {
53
58
  },
54
59
  };
55
60
  }
61
+ /** @internal */
56
62
  export function clearDirtyFlags(snapshot) {
57
63
  return {
58
64
  ...snapshot,
@@ -63,6 +69,7 @@ export function clearDirtyFlags(snapshot) {
63
69
  },
64
70
  };
65
71
  }
72
+ /** @internal */
66
73
  export function splitProfilePlayer(player) {
67
74
  const { session = {}, ...persistentFields } = player;
68
75
  return {
@@ -62,7 +62,8 @@ export interface VisibilityDecision {
62
62
  *
63
63
  * Render culling and asset streaming are intentionally separate. This class never
64
64
  * destroys entities or throttles simulation; adapters decide how to apply results.
65
- */
65
+ * @internal
66
+ */
66
67
  export declare class VisibilitySystem {
67
68
  #private;
68
69
  readonly settings: VisibilityDefaults;
@@ -23,7 +23,8 @@ function intersectsRadius(camera, bounds, extraMargin) {
23
23
  *
24
24
  * Render culling and asset streaming are intentionally separate. This class never
25
25
  * destroys entities or throttles simulation; adapters decide how to apply results.
26
- */
26
+ * @internal
27
+ */
27
28
  export class VisibilitySystem {
28
29
  settings;
29
30
  #states = new Map();
@@ -1,7 +1,7 @@
1
1
  import type { GameContext } from "./gameContext.js";
2
2
  import type { InputFrame } from "./hostedGameRunner.js";
3
3
  import type { HostedWorldSession } from "./hostedWorldSession.js";
4
- import type { WorldDiff } from "./worldReplication.js";
4
+ import { type WorldDiff } from "./worldReplication.js";
5
5
  import type { WorldSnapshot } from "./worldSnapshot.js";
6
6
  /** Host→client frame: the full baseline a joiner needs, then per-tick diffs. What a transport marshals downstream. */
7
7
  export type WorldServerFrame = {
@@ -43,7 +43,9 @@ export interface WorldHost {
43
43
  broadcast(): void;
44
44
  session(): HostedWorldSession;
45
45
  }
46
- /** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections. */
46
+ /** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections.
47
+ * @internal
48
+ */
47
49
  export declare function createWorldHost(session: HostedWorldSession): WorldHost;
48
50
  /** The client end of a {@link WorldHost} connection: applies server frames to a local `ctx`, sends session verbs upstream. */
49
51
  export interface WorldClientLink {
@@ -54,5 +56,7 @@ export interface WorldClientLink {
54
56
  input(frame: InputFrame): void;
55
57
  revision(): number;
56
58
  }
57
- /** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream. */
59
+ /** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream.
60
+ * @internal
61
+ */
58
62
  export declare function createWorldClientLink(ctx: Pick<GameContext, "hydrate">, send: (frame: WorldClientFrame) => void): WorldClientLink;
@@ -1,9 +1,31 @@
1
1
  import { createWorldMirror } from "./worldMirror.js";
2
- /** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections. */
2
+ import { diffSnapshots } from "./worldReplication.js";
3
+ /** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections.
4
+ * @internal
5
+ */
3
6
  export function createWorldHost(session) {
4
7
  const connections = new Set();
8
+ const connectionsByUser = new Map();
9
+ const perViewer = session.projectsViewers();
5
10
  function connect(userId, send) {
6
11
  let cursor = 0;
12
+ let released = false;
13
+ let viewerSnapshot = null;
14
+ let viewerRevision = 0;
15
+ function release() {
16
+ if (released)
17
+ return;
18
+ released = true;
19
+ connections.delete(connection);
20
+ const peers = connectionsByUser.get(userId);
21
+ if (peers === undefined)
22
+ return;
23
+ peers.delete(connection);
24
+ if (peers.size === 0) {
25
+ connectionsByUser.delete(userId);
26
+ session.leave(userId);
27
+ }
28
+ }
7
29
  const connection = {
8
30
  receive(frame) {
9
31
  switch (frame.t) {
@@ -11,7 +33,7 @@ export function createWorldHost(session) {
11
33
  session.join(userId, frame.isNew);
12
34
  break;
13
35
  case "leave":
14
- session.leave(userId);
36
+ release();
15
37
  break;
16
38
  case "command":
17
39
  session.command(userId, frame.name, frame.input);
@@ -22,6 +44,23 @@ export function createWorldHost(session) {
22
44
  }
23
45
  },
24
46
  push() {
47
+ if (released)
48
+ return;
49
+ if (perViewer) {
50
+ const revision = session.revision();
51
+ if (viewerSnapshot !== null && revision === viewerRevision)
52
+ return;
53
+ const snapshot = session.snapshotFor({ userId });
54
+ if (viewerSnapshot === null) {
55
+ send({ t: "baseline", revision, snapshot });
56
+ }
57
+ else {
58
+ send({ t: "diff", diff: diffSnapshots(viewerSnapshot, snapshot, revision, viewerRevision) });
59
+ }
60
+ viewerSnapshot = snapshot;
61
+ viewerRevision = revision;
62
+ return;
63
+ }
25
64
  if (cursor !== 0 && cursor === session.revision())
26
65
  return;
27
66
  const sync = session.sync(cursor === 0 ? null : cursor);
@@ -34,11 +73,15 @@ export function createWorldHost(session) {
34
73
  send({ t: "diff", diff: sync.diff });
35
74
  }
36
75
  },
37
- close() {
38
- connections.delete(connection);
39
- },
76
+ close: release,
40
77
  };
41
78
  connections.add(connection);
79
+ let peers = connectionsByUser.get(userId);
80
+ if (peers === undefined) {
81
+ peers = new Set();
82
+ connectionsByUser.set(userId, peers);
83
+ }
84
+ peers.add(connection);
42
85
  return connection;
43
86
  }
44
87
  return {
@@ -50,7 +93,9 @@ export function createWorldHost(session) {
50
93
  session: () => session,
51
94
  };
52
95
  }
53
- /** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream. */
96
+ /** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream.
97
+ * @internal
98
+ */
54
99
  export function createWorldClientLink(ctx, send) {
55
100
  const mirror = createWorldMirror(ctx);
56
101
  return {
@@ -11,14 +11,26 @@ import type { WorldSnapshot } from "./worldSnapshot.js";
11
11
  */
12
12
  export interface WorldMirror {
13
13
  applyBaseline(revision: number, snapshot: WorldSnapshot): void;
14
+ /**
15
+ * Fold one {@link WorldDiff} onto the mirror. A diff whose `revision` doesn't advance past the mirror's own
16
+ * (stale or a duplicate resend) is ignored. A diff carrying `baseRevision` that doesn't match the mirror's
17
+ * current revision means frames were skipped in transit — the diff is ignored and {@link needsResync} flips
18
+ * true until the next {@link applyBaseline} instead of folding a gap onto local state. A diff without
19
+ * `baseRevision` (legacy producer) always applies, matching the pre-revision-checking behavior.
20
+ */
14
21
  applyDiff(diff: WorldDiff): void;
15
22
  revision(): number;
23
+ /** True after `applyDiff` detected a skipped revision; the caller should fetch a fresh baseline instead of more diffs. */
24
+ needsResync(): boolean;
16
25
  }
17
- /** Build a {@link WorldMirror} that replicates a host's baseline + diff stream onto `ctx` via `ctx.hydrate`. */
26
+ /** Build a {@link WorldMirror} that replicates a host's baseline + diff stream onto `ctx` via `ctx.hydrate`.
27
+ * @internal
28
+ */
18
29
  export declare function createWorldMirror(ctx: Pick<GameContext, "hydrate">): WorldMirror;
19
30
  /**
20
31
  * Pull one replication step from a co-located {@link HostedWorldSession} into a {@link WorldMirror} — the
21
32
  * no-network local path (host and client in one process). A fresh mirror pulls a baseline; thereafter it pulls
22
33
  * a diff since its own revision. The same `sync(sinceRevision)` call is what a networked transport marshals.
23
- */
34
+ * @internal
35
+ */
24
36
  export declare function pullWorld(session: HostedWorldSession, mirror: WorldMirror): void;
@@ -1,27 +1,40 @@
1
1
  import { applyWorldDiff } from "./worldReplication.js";
2
- /** Build a {@link WorldMirror} that replicates a host's baseline + diff stream onto `ctx` via `ctx.hydrate`. */
2
+ /** Build a {@link WorldMirror} that replicates a host's baseline + diff stream onto `ctx` via `ctx.hydrate`.
3
+ * @internal
4
+ */
3
5
  export function createWorldMirror(ctx) {
4
6
  let mirror = {};
5
7
  let revision = 0;
8
+ let resyncNeeded = false;
6
9
  return {
7
10
  applyBaseline(nextRevision, snapshot) {
8
11
  mirror = snapshot;
9
12
  revision = nextRevision;
13
+ resyncNeeded = false;
10
14
  ctx.hydrate(snapshot);
11
15
  },
12
16
  applyDiff(diff) {
17
+ if (diff.revision <= revision)
18
+ return;
19
+ if (diff.baseRevision !== undefined && diff.baseRevision !== revision) {
20
+ resyncNeeded = true;
21
+ return;
22
+ }
23
+ resyncNeeded = false;
13
24
  mirror = applyWorldDiff(mirror, diff);
14
25
  revision = diff.revision;
15
26
  ctx.hydrate(mirror);
16
27
  },
17
28
  revision: () => revision,
29
+ needsResync: () => resyncNeeded,
18
30
  };
19
31
  }
20
32
  /**
21
33
  * Pull one replication step from a co-located {@link HostedWorldSession} into a {@link WorldMirror} — the
22
34
  * no-network local path (host and client in one process). A fresh mirror pulls a baseline; thereafter it pulls
23
35
  * a diff since its own revision. The same `sync(sinceRevision)` call is what a networked transport marshals.
24
- */
36
+ * @internal
37
+ */
25
38
  export function pullWorld(session, mirror) {
26
39
  const sync = session.sync(mirror.revision() === 0 ? null : mirror.revision());
27
40
  if (sync.kind === "baseline")
@@ -0,0 +1,47 @@
1
+ import type { SceneEntity } from "../scene/entityStore.js";
2
+ import type { SnapshotViewer } from "./worldSnapshot.js";
3
+ /**
4
+ * Host-side interest/privacy policy — how the authoritative world projects to each viewer over the
5
+ * wire. Unset (the default) means every client receives the whole world, exactly as before. Enabling a
6
+ * field changes only what each client *sees*, never how the host simulates: the game plays identically.
7
+ * The core replication modules read this to attach a {@link SnapshotModule.project} without the engine
8
+ * growing a per-feature branch.
9
+ */
10
+ export interface ReplicationPolicy {
11
+ /**
12
+ * Replicate each player's private per-user state (inventory) only to that player — other viewers
13
+ * receive none of it. Off by default so existing games keep broadcasting every player's state.
14
+ */
15
+ privatePerUser?: boolean;
16
+ /**
17
+ * Area-of-interest radius in world units: an entity replicates to a viewer only when within this
18
+ * distance of the viewer's own entity (the entity whose `id` equals the viewer's `userId`). A viewer
19
+ * always receives its own entity. Omit for no distance culling — every entity to every viewer.
20
+ */
21
+ aoiRadius?: number;
22
+ }
23
+ /** True when at least one field of the policy would change the wire payload. A no-op policy needs no projection.
24
+ * @internal host projection plumbing — games set ReplicationPolicy; the runtime applies it.
25
+ */
26
+ export declare function policyProjectsViewers(policy: ReplicationPolicy | undefined): boolean;
27
+ /**
28
+ * Cull an entity list to a viewer's area of interest: keep the viewer's own entity plus every entity
29
+ * within `radius` of it. When the viewer has no locatable entity the full list is returned (fail-open —
30
+ * a spectator or not-yet-spawned player still sees the world rather than an empty one).
31
+ * @internal host projection plumbing
32
+ */
33
+ export declare function projectEntitiesForViewer(entities: readonly SceneEntity[], viewer: SnapshotViewer, radius: number): readonly SceneEntity[];
34
+ /** The set of entity ids a viewer can see under an area-of-interest radius — the visibility set entity-keyed modules cull against.
35
+ * @internal host projection plumbing
36
+ */
37
+ export declare function visibleEntityIds(entities: readonly SceneEntity[], viewer: SnapshotViewer, radius: number): Set<string>;
38
+ /** Keep only the entries of an entity-id-keyed record whose id is in `visible` — the projection for entity stats under area-of-interest.
39
+ * @internal host projection plumbing
40
+ */
41
+ export declare function projectByVisibleIds<T>(byId: Record<string, T>, visible: Set<string>): Record<string, T>;
42
+ /**
43
+ * Narrow a `userId → state` record to only the viewer's own entry — the projection for private
44
+ * per-user state (inventory, wallets) so one client never receives another player's private data.
45
+ * @internal host projection plumbing
46
+ */
47
+ export declare function projectPerUserForViewer<T>(byUser: Record<string, T>, viewer: SnapshotViewer): Record<string, T>;
@@ -0,0 +1,52 @@
1
+ /** True when at least one field of the policy would change the wire payload. A no-op policy needs no projection.
2
+ * @internal host projection plumbing — games set ReplicationPolicy; the runtime applies it.
3
+ */
4
+ export function policyProjectsViewers(policy) {
5
+ if (policy === undefined)
6
+ return false;
7
+ return policy.privatePerUser === true || policy.aoiRadius !== undefined;
8
+ }
9
+ function distanceSquared(a, b) {
10
+ const dx = a[0] - b[0];
11
+ const dy = a[1] - b[1];
12
+ const dz = a[2] - b[2];
13
+ return dx * dx + dy * dy + dz * dz;
14
+ }
15
+ /**
16
+ * Cull an entity list to a viewer's area of interest: keep the viewer's own entity plus every entity
17
+ * within `radius` of it. When the viewer has no locatable entity the full list is returned (fail-open —
18
+ * a spectator or not-yet-spawned player still sees the world rather than an empty one).
19
+ * @internal host projection plumbing
20
+ */
21
+ export function projectEntitiesForViewer(entities, viewer, radius) {
22
+ const self = entities.find((entity) => entity.id === viewer.userId);
23
+ if (self === undefined)
24
+ return entities;
25
+ const radiusSquared = radius * radius;
26
+ return entities.filter((entity) => entity.id === viewer.userId || distanceSquared(entity.position, self.position) <= radiusSquared);
27
+ }
28
+ /** The set of entity ids a viewer can see under an area-of-interest radius — the visibility set entity-keyed modules cull against.
29
+ * @internal host projection plumbing
30
+ */
31
+ export function visibleEntityIds(entities, viewer, radius) {
32
+ return new Set(projectEntitiesForViewer(entities, viewer, radius).map((entity) => entity.id));
33
+ }
34
+ /** Keep only the entries of an entity-id-keyed record whose id is in `visible` — the projection for entity stats under area-of-interest.
35
+ * @internal host projection plumbing
36
+ */
37
+ export function projectByVisibleIds(byId, visible) {
38
+ const out = {};
39
+ for (const [id, value] of Object.entries(byId))
40
+ if (visible.has(id))
41
+ out[id] = value;
42
+ return out;
43
+ }
44
+ /**
45
+ * Narrow a `userId → state` record to only the viewer's own entry — the projection for private
46
+ * per-user state (inventory, wallets) so one client never receives another player's private data.
47
+ * @internal host projection plumbing
48
+ */
49
+ export function projectPerUserForViewer(byUser, viewer) {
50
+ const own = byUser[viewer.userId];
51
+ return own === undefined ? {} : { [viewer.userId]: own };
52
+ }