@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,74 @@
1
+ import type { CardPile, CardPileConfig } from "../../cards/cardPile.js";
2
+ import type { CommandRegistry } from "../../commands/commandRegistry.js";
3
+ import { type WalletState } from "../../economy/wallet.js";
4
+ import type { GameFeatures } from "../../game/defineGame.js";
5
+ import type { GameEvents } from "../../game/events.js";
6
+ import { type Social } from "../../game/social.js";
7
+ import type { InventoryLayout, InventorySet } from "../../inventory/inventoryModel.js";
8
+ import type { StatValueMap } from "../../scene/entityStats.js";
9
+ import type { EntityStore } from "../../scene/entityStore.js";
10
+ import type { SpatialApi } from "../../scene/spatial.js";
11
+ import type { ObservableKeyedStore } from "../../store/observableKeyedStore.js";
12
+ import type { SnapshotModule } from "../worldSnapshot.js";
13
+ import type { TurnLoop, TurnLoopConfig } from "../../turn/turnLoop.js";
14
+ import type { RaceState, RaceStateConfig } from "../../game/race.js";
15
+ import type { GameContext, GameContextContent, GameContextEconomy } from "../gameContext.js";
16
+ /**
17
+ * Shared wiring every optional-feature descriptor draws from — the live core subsystems (entities,
18
+ * spatial, economy, inventory) plus reactive plumbing (`signalNotify`) and a `feature` reader for the
19
+ * few features that reference another (quest reads unlocks). Handed to each {@link FeatureDescriptor}'s
20
+ * `create` so a new opt-in subsystem plugs into one registration, never a new `features.x ?` branch.
21
+ * @internal
22
+ */
23
+ export interface FeatureDeps {
24
+ features: GameFeatures;
25
+ signalNotify: () => void;
26
+ events: GameEvents;
27
+ now: () => number;
28
+ entities: EntityStore;
29
+ spatial: SpatialApi;
30
+ store: ObservableKeyedStore<unknown>;
31
+ commandRegistry: CommandRegistry<GameContext>;
32
+ economy: GameContextEconomy;
33
+ content: GameContextContent;
34
+ activeUserId: () => string;
35
+ walletOf: (userId: string) => WalletState;
36
+ setWallet: (userId: string, state: WalletState) => void;
37
+ layouts: Record<string, InventoryLayout>;
38
+ inventoryFor: (userId: string) => InventorySet<string>;
39
+ ensureInstanceStats: (instanceId: string) => StatValueMap;
40
+ seedUserPool: (userId: string, statId: string, pool: {
41
+ current: number;
42
+ max?: number;
43
+ min?: number;
44
+ }) => void;
45
+ sharedSocial: () => Social;
46
+ pile: (id: string, config?: CardPileConfig) => CardPile;
47
+ loop: (id: string, config?: TurnLoopConfig) => TurnLoop;
48
+ cardPiles: ReadonlyMap<string, CardPile>;
49
+ turnLoops: ReadonlyMap<string, TurnLoop>;
50
+ raceState: (id: string, config?: RaceStateConfig) => RaceState;
51
+ feature: <T>(key: keyof GameFeatures) => T | undefined;
52
+ }
53
+ /** @internal What a descriptor produces: the `ctx`-facing value plus its optional replication/save modules. */
54
+ export interface FeatureBuild {
55
+ value: unknown;
56
+ /** Registered into the host→client replication set when present (`ctx.snapshot`/`ctx.hydrate`). */
57
+ replicate?: SnapshotModule;
58
+ /** Registered into the whole-world save-only set when present (`ctx.game.save`). */
59
+ save?: SnapshotModule;
60
+ }
61
+ /**
62
+ * One opt-in subsystem expressed as data: which `features` flag turns it on, how it wires itself from
63
+ * {@link FeatureDeps}, and whether it replicates or persists. `createGameContext` iterates the
64
+ * descriptor list instead of hand-wiring each `features.x ? create : undefined` branch — the seam a
65
+ * new feature extends through.
66
+ * @internal
67
+ */
68
+ export interface FeatureDescriptor {
69
+ readonly key: keyof GameFeatures;
70
+ enabled(features: GameFeatures): boolean;
71
+ create(deps: FeatureDeps): FeatureBuild;
72
+ }
73
+ /** @internal */
74
+ export declare const featureDescriptors: readonly FeatureDescriptor[];
@@ -0,0 +1,281 @@
1
+ import { canAfford as walletCanAfford, chargeAll as walletChargeAll, } from "../../economy/wallet.js";
2
+ import { createCosmetics } from "../../game/cosmetics.js";
3
+ import { createLeaderboard } from "../../game/leaderboard.js";
4
+ import { createGameDialogue } from "../../game/dialogue.js";
5
+ import { createQuestJournal } from "../../game/quest.js";
6
+ import { createChat } from "../../game/chat.js";
7
+ import {} from "../../game/social.js";
8
+ import { createTradeSystem } from "../../game/trade.js";
9
+ import { createUnlocks } from "../../game/unlocks.js";
10
+ import { createRoster } from "../../scene/roster.js";
11
+ import { createConnectedPlayers } from "../../game/connectedPlayers.js";
12
+ import { notifyAfter } from "../../store/changeSignal.js";
13
+ /** @internal */
14
+ export const featureDescriptors = [
15
+ {
16
+ key: "unlocks",
17
+ enabled: (f) => f.unlocks === true,
18
+ create(d) {
19
+ const unlocks = notifyAfter(createUnlocks(), ["grant", "hydrate"], d.signalNotify);
20
+ return {
21
+ value: unlocks,
22
+ save: {
23
+ key: "unlocks",
24
+ snapshot: () => unlocks.snapshotAll(),
25
+ hydrate: (data) => unlocks.hydrateAll(data),
26
+ },
27
+ };
28
+ },
29
+ },
30
+ {
31
+ key: "social",
32
+ enabled: (f) => f.social === true,
33
+ create(d) {
34
+ const raw = d.sharedSocial();
35
+ const social = {
36
+ friends: notifyAfter(raw.friends, ["request", "accept", "decline", "remove", "block", "hydrate"], d.signalNotify),
37
+ party: notifyAfter(raw.party, ["invite", "accept", "decline", "kick", "leave", "promote"], d.signalNotify),
38
+ presence: raw.presence,
39
+ emotes: raw.emotes,
40
+ worldInvites: notifyAfter(raw.worldInvites, ["invite", "accept", "decline"], d.signalNotify),
41
+ snapshot: raw.snapshot,
42
+ hydrate: (data) => {
43
+ raw.hydrate(data);
44
+ d.signalNotify();
45
+ },
46
+ };
47
+ return {
48
+ value: social,
49
+ replicate: {
50
+ key: "social",
51
+ snapshot: () => social.snapshot(),
52
+ hydrate: (data) => social.hydrate(data),
53
+ },
54
+ };
55
+ },
56
+ },
57
+ {
58
+ key: "chat",
59
+ enabled: (f) => f.chat === true,
60
+ create(d) {
61
+ const raw = d.sharedSocial();
62
+ const chat = notifyAfter(createChat({
63
+ events: d.events,
64
+ now: d.now,
65
+ party: raw.party,
66
+ proximity: {
67
+ entities: { get: (id) => d.entities.get(id) },
68
+ spatial: { inRadius: (center, radius, filter) => d.spatial.inRadius(center, radius, filter) },
69
+ },
70
+ blockedBy: (userId) => raw.friends.snapshot(userId).blocked,
71
+ }), ["register", "send", "whisper", "hydrate"], d.signalNotify);
72
+ return {
73
+ value: chat,
74
+ replicate: {
75
+ key: "chat",
76
+ snapshot: () => chat.snapshot(),
77
+ hydrate: (data) => chat.hydrate(data),
78
+ },
79
+ };
80
+ },
81
+ },
82
+ {
83
+ key: "leaderboard",
84
+ enabled: (f) => f.leaderboard === true,
85
+ create(d) {
86
+ const leaderboard = notifyAfter(createLeaderboard(), ["increment", "hydrate"], d.signalNotify);
87
+ return {
88
+ value: leaderboard,
89
+ replicate: {
90
+ key: "leaderboard",
91
+ snapshot: () => leaderboard.snapshot(),
92
+ hydrate: (data) => leaderboard.hydrate(data),
93
+ },
94
+ };
95
+ },
96
+ },
97
+ {
98
+ key: "roster",
99
+ enabled: (f) => f.roster === true,
100
+ create(d) {
101
+ const roster = notifyAfter(createRoster({ now: d.now }), ["capture", "release", "setEquipped", "hydrate"], d.signalNotify);
102
+ return {
103
+ value: roster,
104
+ save: {
105
+ key: "roster",
106
+ snapshot: () => roster.snapshotAll(),
107
+ hydrate: (data) => roster.hydrateAll(data),
108
+ },
109
+ };
110
+ },
111
+ },
112
+ {
113
+ key: "cosmetics",
114
+ enabled: (f) => f.cosmetics === true,
115
+ create(d) {
116
+ const cosmetics = notifyAfter(createCosmetics({ events: d.events }), ["apply", "equip", "hydrate"], d.signalNotify);
117
+ return {
118
+ value: cosmetics,
119
+ save: {
120
+ key: "cosmetics",
121
+ snapshot: () => cosmetics.snapshotAll(),
122
+ hydrate: (data) => cosmetics.hydrateAll(data),
123
+ },
124
+ };
125
+ },
126
+ },
127
+ {
128
+ key: "trade",
129
+ enabled: (f) => f.trade === true,
130
+ create(d) {
131
+ return {
132
+ value: createTradeSystem({
133
+ resolveTrade: (itemId) => d.content.itemById?.(itemId)?.trade,
134
+ wallet: {
135
+ canAfford: (costs) => walletCanAfford(d.walletOf(d.activeUserId()), costs) ? null : "insufficient-funds",
136
+ charge(costs) {
137
+ const result = walletChargeAll(d.walletOf(d.activeUserId()), costs);
138
+ if (result.status === "ok") {
139
+ d.setWallet(d.activeUserId(), result.state);
140
+ d.signalNotify();
141
+ }
142
+ },
143
+ grant(gains) {
144
+ for (const [currencyId, amount] of Object.entries(gains)) {
145
+ d.economy.grant(d.activeUserId(), currencyId, amount);
146
+ }
147
+ },
148
+ },
149
+ inventory: {
150
+ put(inventoryId, itemId, count) {
151
+ if (d.layouts[inventoryId] === undefined)
152
+ return { reason: `unknown inventory "${inventoryId}"` };
153
+ const result = d.inventoryFor(d.activeUserId()).put(inventoryId, itemId, count);
154
+ return result.status === "ok" ? null : { reason: result.reason };
155
+ },
156
+ take(inventoryId, itemId, count) {
157
+ if (d.layouts[inventoryId] === undefined)
158
+ return { reason: `unknown inventory "${inventoryId}"` };
159
+ const result = d.inventoryFor(d.activeUserId()).take(inventoryId, itemId, count);
160
+ return result.status === "ok" ? null : { reason: result.reason };
161
+ },
162
+ count: (inventoryId, itemId) => d.inventoryFor(d.activeUserId()).count(inventoryId, itemId),
163
+ },
164
+ }),
165
+ };
166
+ },
167
+ },
168
+ {
169
+ key: "quest",
170
+ enabled: (f) => f.quest === true,
171
+ create(d) {
172
+ const quest = notifyAfter(createQuestJournal({
173
+ events: d.events,
174
+ rewards: {
175
+ grantXp(userId, amount) {
176
+ const existing = d.ensureInstanceStats(userId)["xp"];
177
+ const current = (existing?.current ?? 0) + amount;
178
+ d.seedUserPool(userId, "xp", { current, max: Math.max(existing?.max ?? 0, current) });
179
+ },
180
+ grantEconomy: (userId, currencyId, amount) => d.economy.grant(userId, currencyId, amount),
181
+ grantItem(userId, inventoryId, itemId, count) {
182
+ if (d.layouts[inventoryId] === undefined)
183
+ return { reason: `unknown inventory "${inventoryId}"` };
184
+ const result = d.inventoryFor(userId).put(inventoryId, itemId, count);
185
+ return result.status === "ok" ? null : { reason: result.reason };
186
+ },
187
+ grantUnlock: (userId, unlockId) => d.feature("unlocks")?.grant(userId, unlockId),
188
+ },
189
+ hasUnlock: (userId, id) => d.feature("unlocks")?.has(userId, id) ?? false,
190
+ }), ["accept", "abandon", "progress", "turnIn", "grant", "revoke", "hydrate"], d.signalNotify);
191
+ return {
192
+ value: quest,
193
+ save: {
194
+ key: "quest",
195
+ snapshot: () => quest.snapshotAll(),
196
+ hydrate: (data) => quest.hydrateAll(data),
197
+ },
198
+ };
199
+ },
200
+ },
201
+ {
202
+ key: "dialogue",
203
+ enabled: (f) => f.dialogue === true,
204
+ create(d) {
205
+ const dialogue = createGameDialogue(d.store);
206
+ d.commandRegistry.define("dialogue.open", {
207
+ apply(state, input) {
208
+ const id = input.id;
209
+ if (id !== undefined)
210
+ state.game.dialogue?.open(id);
211
+ },
212
+ });
213
+ d.commandRegistry.define("dialogue.close", {
214
+ apply(state) {
215
+ state.game.dialogue?.close();
216
+ },
217
+ });
218
+ return { value: dialogue };
219
+ },
220
+ },
221
+ {
222
+ key: "players",
223
+ enabled: (f) => f.players === true,
224
+ create(d) {
225
+ return { value: notifyAfter(createConnectedPlayers(), ["join", "leave"], d.signalNotify) };
226
+ },
227
+ },
228
+ {
229
+ key: "cards",
230
+ enabled: (f) => f.cards === true,
231
+ create(d) {
232
+ return {
233
+ value: { pile: d.pile },
234
+ save: {
235
+ key: "cards",
236
+ snapshot: () => {
237
+ const out = {};
238
+ for (const [id, cardPile] of d.cardPiles)
239
+ out[id] = cardPile.state();
240
+ return out;
241
+ },
242
+ hydrate: (data) => {
243
+ for (const [id, state] of Object.entries(data)) {
244
+ d.cardPiles.get(id)?.reset(state);
245
+ }
246
+ },
247
+ },
248
+ };
249
+ },
250
+ },
251
+ {
252
+ key: "turn",
253
+ enabled: (f) => f.turn === true,
254
+ create(d) {
255
+ return {
256
+ value: { loop: d.loop },
257
+ save: {
258
+ key: "turn",
259
+ snapshot: () => {
260
+ const out = {};
261
+ for (const [id, turnLoop] of d.turnLoops)
262
+ out[id] = turnLoop.capture();
263
+ return out;
264
+ },
265
+ hydrate: (data) => {
266
+ for (const [id, state] of Object.entries(data)) {
267
+ d.turnLoops.get(id)?.restore(state);
268
+ }
269
+ },
270
+ },
271
+ };
272
+ },
273
+ },
274
+ {
275
+ key: "race",
276
+ enabled: (f) => f.race === true,
277
+ create(d) {
278
+ return { value: { state: d.raceState } };
279
+ },
280
+ },
281
+ ];
@@ -2,17 +2,20 @@ import { type CardPile, type CardPileConfig } from "../cards/cardPile.js";
2
2
  import { type OnDeathSpec } from "../combat/death.js";
3
3
  import { type EffectInput, type EffectResult, type EffectVia, type ReceiveMap, type SingleTargetEffectInput } from "../combat/effects.js";
4
4
  import { type ProjectileSystem } from "../combat/projectiles.js";
5
- import { type HitReaction, type HitReactionConfig } from "../combat/hitReaction.js";
5
+ import { type HitReaction, type HitReactionConfig, type ImpactPresetName } from "../combat/hitReaction.js";
6
6
  import { type TelegraphShape } from "../combat/telegraph.js";
7
7
  import { type CommandDefinition, type CommandResult } from "../commands/commandRegistry.js";
8
+ import { type ChargeOptions as WalletChargeOptions } from "../economy/wallet.js";
8
9
  import { type Cosmetics } from "../game/cosmetics.js";
9
10
  import type { GameDefinition } from "../game/defineGame.js";
10
11
  import { type TerrainField } from "../world/terrain.js";
11
- import { type GameEventMap, type GameEvents } from "../game/events.js";
12
+ import { type GameEventMap, type GameEvents, type VfxKind } from "../game/events.js";
13
+ import { type VfxInstanceStore } from "../game/vfxInstance.js";
12
14
  import { type GameFeed } from "../game/feed.js";
13
15
  import { type Leaderboard } from "../game/leaderboard.js";
14
16
  import { type Loadouts } from "../game/loadout.js";
15
17
  import { type Drop, type LootTableDef } from "../game/lootTable.js";
18
+ import { type GameDialogue } from "../game/dialogue.js";
16
19
  import { type QuestJournal } from "../game/quest.js";
17
20
  import { type WorldItemRecord, type WorldItemSpawnInput } from "../game/worldItem.js";
18
21
  import { type Chat } from "../game/chat.js";
@@ -26,22 +29,26 @@ import { type ItemUseHandler, type ItemUseInput, type ItemUseRejection, type Ite
26
29
  import { type WeaponStats } from "../item/weapon.js";
27
30
  import { type PoseAllowedStates, type PoseState } from "../movement/poseState.js";
28
31
  import type { ModelAssetRef } from "../scene/assetCatalog.js";
32
+ import { type BodyBind } from "../scene/bodyBind.js";
29
33
  import { type PaintLayer } from "../scene/paintLayer.js";
30
34
  import { type EntityStatsApi, type StatCatalog } from "../scene/entityStats.js";
31
- import type { EntityBlackboard, EntityPose, EntityPosition, EntityStore, SceneEntity, SpawnOptions, SpawnPose } from "../scene/entityStore.js";
35
+ import { type EntityBlackboard, type EntityPose, type EntityPosition, type EntityStore, type SceneEntity, type SpawnOptions, type SpawnPose } from "../scene/entityStore.js";
32
36
  import { type Forms } from "../scene/form.js";
33
37
  import { type EntityColliderSet } from "../scene/colliders.js";
34
38
  import { type ObjectRaycastHit, type ObjectRaycastInput } from "../scene/objectQuery.js";
35
39
  import { type ObjectStore } from "../scene/objectStore.js";
36
40
  import { type Roster } from "../scene/roster.js";
41
+ import { type SelectionSet } from "../scene/selection.js";
37
42
  import { type ConnectedPlayers } from "../game/connectedPlayers.js";
38
43
  import { type Possession } from "../scene/possession.js";
39
44
  import { type SceneRaycastHit, type SceneRaycastInput } from "../scene/sceneRaycast.js";
40
- import { type SpatialApi } from "../scene/spatial.js";
45
+ import { type MoveTowardOptions, type SpatialApi } from "../scene/spatial.js";
41
46
  import { type CycleTargetOptions } from "../scene/targeting.js";
42
47
  import { type Stats } from "../stats/statModifiers.js";
43
48
  import { type ObservableKeyedStore } from "../store/observableKeyedStore.js";
44
- import { type WorldSnapshot } from "./worldSnapshot.js";
49
+ import { type SnapshotModule, type SnapshotViewer, type WorldSnapshot } from "./worldSnapshot.js";
50
+ import { type ReplicationPolicy } from "./worldProjection.js";
51
+ import { type RuntimeSave, type RuntimeSaveOptions } from "./runtimeSave.js";
45
52
  import { type SimClock } from "../time/simClock.js";
46
53
  import { type TurnLoop, type TurnLoopConfig } from "../turn/turnLoop.js";
47
54
  import { RaceState, type RaceStateConfig } from "../game/race.js";
@@ -70,6 +77,8 @@ export interface GameContextEntityEntry {
70
77
  verbs?: readonly ContextVerb[];
71
78
  /** Purpose-specific colliders (physical body + named damage hitboxes). */
72
79
  colliders?: EntityColliderSet;
80
+ /** Uniform visual scale of the rendered mesh; derives a matching hitbox (and eye-height) when no explicit `colliders` are set. */
81
+ scale?: number;
73
82
  }
74
83
  export interface GameContextObjectEntry {
75
84
  proximityPrompt?: ProximityPrompt;
@@ -96,6 +105,14 @@ export interface GameContextOptions<TAssetRef extends ModelAssetRef = ModelAsset
96
105
  };
97
106
  now?: () => number;
98
107
  occluder?: (from: EntityPosition, to: EntityPosition) => boolean;
108
+ /** Bind `ctx.game.save` to a pluggable backend (offline/single-player whole-world save). The shell resolves this from `defineGame({ save })`; multiplayer leaves it off (the host persists). */
109
+ save?: RuntimeSaveOptions;
110
+ /**
111
+ * Host-side per-viewer replication policy — private-state and area-of-interest projection over the
112
+ * wire. Bound on the authoritative host only. Unset (the default) replicates the whole world to every
113
+ * client, exactly as before; the simulation is identical either way, so a game plays the same.
114
+ */
115
+ replication?: ReplicationPolicy;
99
116
  }
100
117
  export interface SceneObjectContext extends ObjectStore {
101
118
  catalog(instanceId: string): GameContextObjectEntry | null;
@@ -103,6 +120,15 @@ export interface SceneObjectContext extends ObjectStore {
103
120
  raycastAll(input: ObjectRaycastInput): readonly ObjectRaycastHit[];
104
121
  setColliders(instanceId: string, colliders: EntityColliderSet | null): void;
105
122
  collidersOf(instanceId: string): EntityColliderSet | null;
123
+ /**
124
+ * Per-instance selection/highlight state for placed objects — the reactive counterpart to
125
+ * `worldHealthBars`/`nameplates` (entities), so a build-mode or RTS selection ring reads
126
+ * `ctx.scene.object.selection` instead of hand-rolling one through `WorldOverlay` against external
127
+ * state. Mutations (`add`/`remove`/`toggle`/`replace`/`clear`) bump `ctx.version()`/notify
128
+ * `ctx.subscribe` like every other `ctx` surface. Render it with `WorldObjectHighlights`
129
+ * (`@jgengine/shell/world/WorldHud`).
130
+ */
131
+ selection: SelectionSet;
106
132
  }
107
133
  export interface FloatTextInput {
108
134
  instanceId?: string;
@@ -115,6 +141,15 @@ export interface FloatTextInput {
115
141
  crit?: boolean;
116
142
  scale?: number;
117
143
  }
144
+ /** Request a transient spell/ability VFX burst; `from`/`to` accept an instance id or a world point, `color` is a `0xRRGGBB` tint, and `durationMs` defaults per `kind`. */
145
+ export interface VfxInput {
146
+ kind: VfxKind;
147
+ color: number;
148
+ from?: string | readonly [number, number, number];
149
+ to?: string | readonly [number, number, number];
150
+ radius?: number;
151
+ durationMs?: number;
152
+ }
118
153
  export interface TelegraphInput {
119
154
  from: string;
120
155
  shape: TelegraphShape;
@@ -133,9 +168,14 @@ export interface TelegraphInput {
133
168
  export interface HitReactionInput {
134
169
  from: string;
135
170
  to: string;
136
- config: HitReactionConfig;
171
+ config: HitReactionConfig | ImpactPresetName;
137
172
  power?: number;
138
173
  }
174
+ /** Options for {@link SceneEntityContext.moveTowardCommit}: {@link MoveTowardOptions} plus an optional facing turn. */
175
+ export interface MoveTowardCommitOptions extends MoveTowardOptions {
176
+ /** Rotate the entity to face its direction of travel instead of preserving its current `rotationY`. Default false. */
177
+ face?: boolean;
178
+ }
139
179
  export interface SceneEntityContext {
140
180
  spawn(name: string, options?: SpawnOptions): string;
141
181
  despawn(instanceId: string): boolean;
@@ -144,12 +184,22 @@ export interface SceneEntityContext {
144
184
  setPoseConstraint: EntityStore["setPoseConstraint"];
145
185
  get(instanceId: string): SceneEntity | null;
146
186
  list(): readonly SceneEntity[];
187
+ ids: EntityStore["ids"];
188
+ subscribeMembership: EntityStore["subscribeMembership"];
147
189
  spawnPoseOf(instanceId: string): SpawnPose | null;
148
190
  resetToSpawn(instanceId: string): boolean;
149
191
  resetAllToSpawn(filter?: (entity: SceneEntity) => boolean): number;
150
192
  blackboard: EntityBlackboard;
151
193
  stats: EntityStatsApi;
152
194
  floatText(input: FloatTextInput): void;
195
+ vfx(input: VfxInput): void;
196
+ /**
197
+ * Retained VFX registry for long-lived, updatable effects (held beams, tethers, zones, target lines) whose
198
+ * endpoints and params change over time — the persistent complement to the one-shot {@link SceneEntityContext.vfx}
199
+ * burst. `upsert` creates/replaces by stable id, `update` nudges dynamic params, `stop` disposes with an optional
200
+ * fade; endpoints given as an entity instance id are followed live by the renderer without per-frame commands.
201
+ */
202
+ vfxInstance: VfxInstanceStore;
153
203
  telegraph(input: TelegraphInput): () => void;
154
204
  hitReaction(input: HitReactionInput): HitReaction | null;
155
205
  setTarget(fromId: string, toId: string | null): void;
@@ -166,11 +216,29 @@ export interface SceneEntityContext {
166
216
  hasLineOfSight: SpatialApi["hasLineOfSight"];
167
217
  queryArc: SpatialApi["queryArc"];
168
218
  moveToward: SpatialApi["moveToward"];
219
+ /**
220
+ * `moveToward` plus commit: steps `instanceId` toward `target` and immediately `setPose`s the
221
+ * result, so a per-tick mover no longer pairs `moveToward` with a hand-written `setPose`.
222
+ * `options.face` turns the entity to its direction of travel; omitted preserves the current
223
+ * `rotationY`. Returns the committed position (`null`, committing nothing, when `moveToward` would
224
+ * — unknown instance/target).
225
+ */
226
+ moveTowardCommit(instanceId: string, target: EntityPosition | string, options: MoveTowardCommitOptions): EntityPosition | null;
169
227
  invalidateSpatial: SpatialApi["invalidate"];
170
228
  setColliders(instanceId: string, colliders: EntityColliderSet | null): void;
171
229
  collidersOf(instanceId: string): EntityColliderSet | null;
230
+ /** Uniform visual scale from the entity's catalog entry (1 when unscaled). */
231
+ visualScaleOf(instanceId: string): number;
172
232
  form: Forms;
173
233
  paint: PaintLayer;
234
+ /**
235
+ * Lazily creates (on first call) or returns the existing declarative bind for `key` — the sim-snapshot →
236
+ * scene-entity pose mirror (#673). Call `bind(key).sync(bodies, dt)` once per tick with every sim body's
237
+ * current snapshot instead of hand-writing `setPose` per body: an id seen for the first time is spawned
238
+ * from its `kind`, an id already bound is posed, and a previously-bound id absent from this tick's
239
+ * `bodies` is despawned — no per-game spawn/despawn dance.
240
+ */
241
+ bind(key: string): BodyBind;
174
242
  }
175
243
  export type WorldItemPickupResult = {
176
244
  status: "ok";
@@ -209,9 +277,12 @@ export interface GameContextLoot {
209
277
  export interface GameContextEconomy {
210
278
  balance(userId: string, currencyId: string): number;
211
279
  grant(userId: string, currencyId: string, amount: number): void;
212
- charge(userId: string, currencyId: string, amount: number): {
280
+ /** `options.overdraft` opts this charge into carrying a negative balance (`true` unlimited, `{ max }` capped) — omitted keeps the strict no-debt default. */
281
+ charge(userId: string, currencyId: string, amount: number, options?: WalletChargeOptions): {
213
282
  reason: string;
214
283
  } | null;
284
+ /** True once `balance(userId, currencyId)` has gone negative under an overdraft-enabled charge. */
285
+ isOverdrawn(userId: string, currencyId: string): boolean;
215
286
  }
216
287
  export interface GameContextItemUse {
217
288
  register(handlers: Record<string, ItemUseHandler<GameContext>>): void;
@@ -259,13 +330,18 @@ export interface GameContext {
259
330
  playEntityAnimation(instanceId: string, event: string): void;
260
331
  feed: GameContextFeed;
261
332
  loot: GameContextLoot;
262
- trade: TradeSystem;
263
- quest: QuestJournal;
333
+ /** Shop/vendor barter — present only when `features.trade` is set. */
334
+ trade?: TradeSystem;
335
+ /** Quest/mission journal — present only when `features.quest` is set. */
336
+ quest?: QuestJournal;
337
+ /** Talkable-NPC dialogue open/close bridge — present only when `features.dialogue` is set. */
338
+ dialogue?: GameDialogue;
264
339
  /** Friends/party/presence/emotes/world-invites — present only when `features.social` is set. */
265
340
  social?: Social;
266
341
  /** Channels + messages — present only when `features.chat` is set (implies `social`). */
267
342
  chat?: Chat;
268
- unlocks: Unlocks;
343
+ /** Earned unlockable content — present only when `features.unlocks` is set. */
344
+ unlocks?: Unlocks;
269
345
  economy: GameContextEconomy;
270
346
  /** Competitive score tracking — present only when `features.leaderboard` is set. */
271
347
  leaderboard?: Leaderboard;
@@ -281,6 +357,18 @@ export interface GameContext {
281
357
  race?: GameContextRace;
282
358
  /** Connected-player set for a shared world — present only when `features.players` is set. */
283
359
  players?: ConnectedPlayers;
360
+ /** Whole-world save/load bound to a pluggable backend — present only when `defineGame({ save })` is set (offline/single-player). Drive save points and quest/area checkpoints with `checkpoint()`, restore on boot with `load()`. */
361
+ save?: RuntimeSave;
362
+ /**
363
+ * Register a save-only snapshot module after boot (system-owned persistence).
364
+ * Used by `composeGameLoop` / `installSystems` when a system declares `save`.
365
+ */
366
+ registerSave?(module: SnapshotModule): void;
367
+ /**
368
+ * Register a host→client replication module after boot (system-owned replication).
369
+ * Used by `composeGameLoop` / `installSystems` when a system declares `replicate`.
370
+ */
371
+ registerReplicate?(module: SnapshotModule): void;
284
372
  };
285
373
  player: {
286
374
  /** The acting player's id — the command actor inside `runAs`, the local player everywhere else. */
@@ -300,7 +388,8 @@ export interface GameContext {
300
388
  } | null;
301
389
  movement: PoseState;
302
390
  possession: Possession;
303
- cosmetics: Cosmetics;
391
+ /** Cosmetic skins/customization — present only when `features.cosmetics` is set. */
392
+ cosmetics?: Cosmetics;
304
393
  /** Motion seam into the movement integrator (#162.4); routes to the command actor's queue (or the local player outside a command), so a command's impulse lands on whoever ran it. See `MotionIntents`. */
305
394
  motion: MotionIntents;
306
395
  /** A specific player's motion queue — how the host-side per-player movement integrator drains each connected player's impulses. */
@@ -317,13 +406,25 @@ export interface GameContext {
317
406
  input: InputSnapshot;
318
407
  subscribe(listener: () => void): () => void;
319
408
  version(): number;
409
+ /**
410
+ * Bump {@link version}/notify {@link subscribe} directly — the escape hatch for a command that only
411
+ * mutates game-owned state outside the entity/object/economy/store layers (an external session map,
412
+ * a plain closure variable) and needs to force a reactive HUD refresh without faking a `ctx.game.store.set`.
413
+ */
414
+ touch(): void;
320
415
  /**
321
416
  * Gather every opted-in live subsystem into one {@link WorldSnapshot} — entities, entity stats, the
322
417
  * keyed store, the action feed, plus leaderboard/chat when those features are on. The full-world
323
- * baseline a host sends a joining client; {@link hydrate} is its inverse.
418
+ * baseline a host sends a joining client; {@link hydrate} is its inverse. Pass a `viewer` and the host
419
+ * projects the snapshot to only what that viewer may see (private state, area of interest) when a
420
+ * {@link GameContextOptions.replication} policy is set; without one the viewer argument is a no-op.
324
421
  */
325
- snapshot(): WorldSnapshot;
422
+ snapshot(viewer?: SnapshotViewer): WorldSnapshot;
326
423
  /** Apply a {@link WorldSnapshot} from an authoritative host, hydrating each subsystem key present in it. */
327
424
  hydrate(snapshot: WorldSnapshot): void;
425
+ /** Aggregate world-dirty version summed across replicated modules; the host replicator skips an unchanged commit. @internal */
426
+ replicationVersion(): number;
427
+ /** True when a {@link GameContextOptions.replication} policy makes {@link snapshot} viewer-dependent (private/AOI projection is active). @internal */
428
+ replicatesPerViewer(): boolean;
328
429
  }
329
430
  export declare function createGameContext<TAssetRef extends ModelAssetRef, TMultiplayer>(options: GameContextOptions<TAssetRef, TMultiplayer>): GameContext;