@jgengine/core 0.10.0 → 0.12.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 (727) hide show
  1. package/CHANGELOG.md +39 -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/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -0,0 +1,467 @@
1
+ import type { CardPile, CardPileConfig } from "../cards/cardPile.js";
2
+ import type { EffectInput, EffectResult, EffectVia, ReceiveMap, SingleTargetEffectInput } from "../combat/effects.js";
3
+ import type { ProjectileSystem } from "../combat/projectiles.js";
4
+ import type { HitReaction, HitReactionConfig, ImpactPresetName } from "../combat/hitReaction.js";
5
+ import type { TelegraphShape } from "../combat/telegraph.js";
6
+ import type { CommandDefinition, CommandResult } from "../commands/commandRegistry.js";
7
+ import type { ChargeOptions as WalletChargeOptions } from "../economy/wallet.js";
8
+ import type { Cosmetics } from "../game/cosmetics.js";
9
+ import type { GameDefinition } from "../game/defineGame.js";
10
+ import type { TerrainField } from "../world/terrain.js";
11
+ import type { GameEventMap, GameEvents, VfxKind } from "../game/events.js";
12
+ import type { VfxInstanceStore } from "../game/vfxInstance.js";
13
+ import type { GameFeed } from "../game/feed.js";
14
+ import type { Leaderboard } from "../game/leaderboard.js";
15
+ import type { Loadouts } from "../game/loadout.js";
16
+ import type { Drop, LootTableDef } from "../game/lootTable.js";
17
+ import type { GameDialogue } from "../game/dialogue.js";
18
+ import type { QuestJournal } from "../game/quest.js";
19
+ import type { WorldItemRecord, WorldItemSpawnInput } from "../game/worldItem.js";
20
+ import type { Chat } from "../game/chat.js";
21
+ import type { Social } from "../game/social.js";
22
+ import type { TradeField, TradeSystem } from "../game/trade.js";
23
+ import type { Unlocks } from "../game/unlocks.js";
24
+ import type { InventoryLayout, InventorySet } from "../inventory/inventoryModel.js";
25
+ import type { ContextVerb } from "../interaction/contextMenu.js";
26
+ import type { ProximityPrompt } from "../interaction/proximityPrompt.js";
27
+ import type { ItemUseHandler, ItemUseInput, ItemUseRejection, ItemUseResult } from "../item/use.js";
28
+ import type { WeaponStats } from "../item/weapon.js";
29
+ import type { PoseAllowedStates, PoseState } from "../movement/poseState.js";
30
+ import type { ModelAssetRef } from "../scene/assetCatalog.js";
31
+ import type { BodyBind } from "../scene/bodyBind.js";
32
+ import type { PaintLayer } from "../scene/paintLayer.js";
33
+ import type { EntityStatsApi, StatCatalog } from "../scene/entityStats.js";
34
+ import type { EntityBlackboard, EntityPose, EntityPosition, EntityStore, SceneEntity, SpawnOptions, SpawnPose } from "../scene/entityStore.js";
35
+ import type { Forms } from "../scene/form.js";
36
+ import type { EntityColliderSet, ModelBodySource } from "../scene/colliders.js";
37
+ import type { ObjectRaycastHit, ObjectRaycastInput } from "../scene/objectQuery.js";
38
+ import type { ObjectStore } from "../scene/objectStore.js";
39
+ import type { Roster } from "../scene/roster.js";
40
+ import type { SelectionSet } from "../scene/selection.js";
41
+ import type { ConnectedPlayers } from "../game/connectedPlayers.js";
42
+ import type { Possession } from "../scene/possession.js";
43
+ import type { SceneRaycastHit, SceneRaycastInput } from "../scene/sceneRaycast.js";
44
+ import type { MoveTowardOptions, SpatialApi } from "../scene/spatial.js";
45
+ import type { CycleTargetOptions } from "../scene/targeting.js";
46
+ import type { Stats } from "../stats/statModifiers.js";
47
+ import type { ObservableKeyedStore } from "../store/observableKeyedStore.js";
48
+ import type { SnapshotModule, SnapshotViewer, WorldSnapshot } from "./worldSnapshot.js";
49
+ import type { ReplicationPolicy } from "./worldProjection.js";
50
+ import type { RuntimeSave, RuntimeSaveOptions } from "./runtimeSave.js";
51
+ import type { SimClock } from "../time/simClock.js";
52
+ import type { TurnLoop, TurnLoopConfig } from "../turn/turnLoop.js";
53
+ import type { RaceState, RaceStateConfig } from "../game/race.js";
54
+ import type { CameraDirector } from "./cameraDirector.js";
55
+ import type { InputSnapshot } from "./inputSnapshot.js";
56
+ import type { MotionIntents } from "./motionIntents.js";
57
+ import type { OnDeathSpec } from "../combat/death.js";
58
+ export interface GameContextItemEntry {
59
+ use?: string;
60
+ weapon?: Record<string, unknown>;
61
+ trade?: TradeField;
62
+ /** Rarity id read by the `worldItem` loot-filter/render binding when this item drops to the ground (#32/#33). */
63
+ rarity?: string;
64
+ /** Base item type read by the loot-filter rule evaluator (#33); defaults to the item id when absent. */
65
+ baseType?: string;
66
+ }
67
+ export type CatalogEntityRole = "player" | "enemy" | "hostile" | "npc" | "vehicle";
68
+ export interface GameContextEntityEntry {
69
+ stats?: StatCatalog;
70
+ receive?: ReceiveMap;
71
+ onDeath?: OnDeathSpec;
72
+ movement?: PoseAllowedStates & {
73
+ walkSpeed?: number;
74
+ };
75
+ role?: CatalogEntityRole;
76
+ /** Right-click context-menu verbs for this entity (#31). */
77
+ verbs?: readonly ContextVerb[];
78
+ /** Purpose-specific colliders (physical body + named damage hitboxes). */
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;
82
+ }
83
+ export interface GameContextObjectEntry {
84
+ proximityPrompt?: ProximityPrompt;
85
+ breakable?: false | {
86
+ baseBreakTime: number;
87
+ };
88
+ slotInventory?: InventoryLayout;
89
+ /** Right-click context-menu verbs for this object (#31). */
90
+ verbs?: readonly ContextVerb[];
91
+ colliders?: EntityColliderSet;
92
+ halfExtents?: readonly [number, number, number];
93
+ }
94
+ export interface GameContextContent {
95
+ itemById?(itemId: string): GameContextItemEntry | null | undefined;
96
+ entityById?(catalogId: string): GameContextEntityEntry | null | undefined;
97
+ objectById?(catalogId: string): GameContextObjectEntry | null | undefined;
98
+ }
99
+ export interface GameContextOptions<TAssetRef extends ModelAssetRef = ModelAssetRef, TMultiplayer = unknown> {
100
+ definition: GameDefinition<TAssetRef, TMultiplayer>;
101
+ content: GameContextContent;
102
+ player: {
103
+ userId: string;
104
+ isNew: boolean;
105
+ };
106
+ now?: () => number;
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;
116
+ /**
117
+ * Render-model lookup feeding collider auto-fit: what each entity kind / object catalog id renders as
118
+ * (resolved `entityModels`/`objectModels` — the shell wires this automatically). When set, entities and
119
+ * objects without authored `colliders` get hitboxes fitted to their model's measured bounds instead of
120
+ * the humanoid/unit-cube defaults. A multiplayer host should receive the same lookup as its clients so
121
+ * both resolve identical colliders.
122
+ */
123
+ models?: GameContextModels;
124
+ }
125
+ /** Per-kind render-model lookup for {@link GameContextOptions.models}; a resolved `ModelConfig` satisfies {@link ModelBodySource} structurally.
126
+ * @capability collider-autofit hitboxes and physical bodies fit each kind's rendered model bounds automatically — no hand-tuned sizes
127
+ */
128
+ export interface GameContextModels {
129
+ entity?(kind: string): ModelBodySource | null | undefined;
130
+ object?(catalogId: string): ModelBodySource | null | undefined;
131
+ }
132
+ export interface SceneObjectContext extends ObjectStore {
133
+ catalog(instanceId: string): GameContextObjectEntry | null;
134
+ raycast(input: ObjectRaycastInput): ObjectRaycastHit | null;
135
+ raycastAll(input: ObjectRaycastInput): readonly ObjectRaycastHit[];
136
+ setColliders(instanceId: string, colliders: EntityColliderSet | null): void;
137
+ collidersOf(instanceId: string): EntityColliderSet | null;
138
+ /**
139
+ * Per-instance selection/highlight state for placed objects — the reactive counterpart to
140
+ * `worldHealthBars`/`nameplates` (entities), so a build-mode or RTS selection ring reads
141
+ * `ctx.scene.object.selection` instead of hand-rolling one through `WorldOverlay` against external
142
+ * state. Mutations (`add`/`remove`/`toggle`/`replace`/`clear`) bump `ctx.version()`/notify
143
+ * `ctx.subscribe` like every other `ctx` surface. Render it with `WorldObjectHighlights`
144
+ * (`@jgengine/shell/world/WorldHud`).
145
+ */
146
+ selection: SelectionSet;
147
+ }
148
+ export interface FloatTextInput {
149
+ instanceId?: string;
150
+ position?: [number, number, number];
151
+ text?: string;
152
+ kind?: string;
153
+ amount?: number;
154
+ hitType?: string;
155
+ element?: string;
156
+ crit?: boolean;
157
+ scale?: number;
158
+ }
159
+ /** 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`. */
160
+ export interface VfxInput {
161
+ kind: VfxKind;
162
+ color: number;
163
+ from?: string | readonly [number, number, number];
164
+ to?: string | readonly [number, number, number];
165
+ radius?: number;
166
+ durationMs?: number;
167
+ }
168
+ export interface TelegraphInput {
169
+ from: string;
170
+ shape: TelegraphShape;
171
+ at: [number, number, number];
172
+ dir?: number;
173
+ windupMs: number;
174
+ kind?: string;
175
+ effect?: {
176
+ effect: string;
177
+ via?: EffectVia;
178
+ radius?: number;
179
+ falloff?: "linear" | "none";
180
+ los?: boolean;
181
+ };
182
+ }
183
+ export interface HitReactionInput {
184
+ from: string;
185
+ to: string;
186
+ config: HitReactionConfig | ImpactPresetName;
187
+ power?: number;
188
+ }
189
+ /** Options for {@link SceneEntityContext.moveTowardCommit}: {@link MoveTowardOptions} plus an optional facing turn. */
190
+ export interface MoveTowardCommitOptions extends MoveTowardOptions {
191
+ /** Rotate the entity to face its direction of travel instead of preserving its current `rotationY`. Default false. */
192
+ face?: boolean;
193
+ }
194
+ export interface SceneEntityContext {
195
+ spawn(name: string, options?: SpawnOptions): string;
196
+ despawn(instanceId: string): boolean;
197
+ update: EntityStore["update"];
198
+ setPose(instanceId: string, pose: EntityPose): boolean;
199
+ setPoseConstraint: EntityStore["setPoseConstraint"];
200
+ get(instanceId: string): SceneEntity | null;
201
+ list(): readonly SceneEntity[];
202
+ ids: EntityStore["ids"];
203
+ subscribeMembership: EntityStore["subscribeMembership"];
204
+ spawnPoseOf(instanceId: string): SpawnPose | null;
205
+ resetToSpawn(instanceId: string): boolean;
206
+ resetAllToSpawn(filter?: (entity: SceneEntity) => boolean): number;
207
+ blackboard: EntityBlackboard;
208
+ stats: EntityStatsApi;
209
+ floatText(input: FloatTextInput): void;
210
+ vfx(input: VfxInput): void;
211
+ /**
212
+ * Retained VFX registry for long-lived, updatable effects (held beams, tethers, zones, target lines) whose
213
+ * endpoints and params change over time — the persistent complement to the one-shot {@link SceneEntityContext.vfx}
214
+ * burst. `upsert` creates/replaces by stable id, `update` nudges dynamic params, `stop` disposes with an optional
215
+ * fade; endpoints given as an entity instance id are followed live by the renderer without per-frame commands.
216
+ */
217
+ vfxInstance: VfxInstanceStore;
218
+ telegraph(input: TelegraphInput): () => void;
219
+ hitReaction(input: HitReactionInput): HitReaction | null;
220
+ setTarget(fromId: string, toId: string | null): void;
221
+ getTarget(fromId: string): string | null;
222
+ cycleTarget(fromId: string, options?: CycleTargetOptions): string | null;
223
+ canReceive(instanceId: string, effect: string, magnitude?: number): string | null;
224
+ preview(input: SingleTargetEffectInput): number;
225
+ effect(input: EffectInput): EffectResult[];
226
+ willHitProjectile: ProjectileSystem["willHitProjectile"];
227
+ fireProjectile: ProjectileSystem["fireProjectile"];
228
+ settleProjectile: ProjectileSystem["settleProjectile"];
229
+ distance: SpatialApi["distance"];
230
+ inRadius: SpatialApi["inRadius"];
231
+ hasLineOfSight: SpatialApi["hasLineOfSight"];
232
+ queryArc: SpatialApi["queryArc"];
233
+ moveToward: SpatialApi["moveToward"];
234
+ /**
235
+ * `moveToward` plus commit: steps `instanceId` toward `target` and immediately `setPose`s the
236
+ * result, so a per-tick mover no longer pairs `moveToward` with a hand-written `setPose`.
237
+ * `options.face` turns the entity to its direction of travel; omitted preserves the current
238
+ * `rotationY`. Returns the committed position (`null`, committing nothing, when `moveToward` would
239
+ * — unknown instance/target).
240
+ */
241
+ moveTowardCommit(instanceId: string, target: EntityPosition | string, options: MoveTowardCommitOptions): EntityPosition | null;
242
+ invalidateSpatial: SpatialApi["invalidate"];
243
+ setColliders(instanceId: string, colliders: EntityColliderSet | null): void;
244
+ collidersOf(instanceId: string): EntityColliderSet | null;
245
+ /** Uniform visual scale from the entity's catalog entry (1 when unscaled). */
246
+ visualScaleOf(instanceId: string): number;
247
+ form: Forms;
248
+ paint: PaintLayer;
249
+ /**
250
+ * Lazily creates (on first call) or returns the existing declarative bind for `key` — the sim-snapshot →
251
+ * scene-entity pose mirror (#673). Call `bind(key).sync(bodies, dt)` once per tick with every sim body's
252
+ * current snapshot instead of hand-writing `setPose` per body: an id seen for the first time is spawned
253
+ * from its `kind`, an id already bound is posed, and a previously-bound id absent from this tick's
254
+ * `bodies` is despawned — no per-game spawn/despawn dance.
255
+ */
256
+ bind(key: string): BodyBind;
257
+ }
258
+ export type WorldItemPickupResult = {
259
+ status: "ok";
260
+ record: WorldItemRecord;
261
+ } | {
262
+ status: "rejected";
263
+ reason: string;
264
+ };
265
+ export interface SceneWorldItemContext {
266
+ spawn(input: WorldItemSpawnInput): WorldItemRecord;
267
+ get(instanceId: string): WorldItemRecord | null;
268
+ list(): readonly WorldItemRecord[];
269
+ nearestInRadius(from: EntityPosition, radius: number, filter?: (record: WorldItemRecord) => boolean): string | null;
270
+ pickup(instanceId: string, userId: string): WorldItemPickupResult;
271
+ consume(instanceId: string): WorldItemRecord | null;
272
+ }
273
+ export interface GameContextCommands {
274
+ define<TInput>(name: string, definition: CommandDefinition<GameContext, TInput>): void;
275
+ has(name: string): boolean;
276
+ names(): string[];
277
+ run(name: string, input: unknown): CommandResult<GameContext>;
278
+ /** Run a command attributed to `actorUserId` — a shared-world host routes each client's command through this so the handler can read {@link actor}. */
279
+ runAs(actorUserId: string, name: string, input: unknown): CommandResult<GameContext>;
280
+ /** The user a command is running on behalf of, or `null` outside a {@link runAs} call — commands default to `ctx.player.userId` when this is `null`. */
281
+ actor(): string | null;
282
+ }
283
+ export interface GameContextFeed extends Omit<GameFeed, "bind"> {
284
+ bind(action: keyof GameEventMap): () => void;
285
+ }
286
+ export interface GameContextLoot {
287
+ register(def: LootTableDef): void;
288
+ has(id: string): boolean;
289
+ roll(id: string, rng?: () => number): Drop[];
290
+ grantToPlayer(userId: string, drops: Drop[], source?: string): void;
291
+ }
292
+ export interface GameContextEconomy {
293
+ balance(userId: string, currencyId: string): number;
294
+ grant(userId: string, currencyId: string, amount: number): void;
295
+ /** `options.overdraft` opts this charge into carrying a negative balance (`true` unlimited, `{ max }` capped) — omitted keeps the strict no-debt default. */
296
+ charge(userId: string, currencyId: string, amount: number, options?: WalletChargeOptions): {
297
+ reason: string;
298
+ } | null;
299
+ /** True once `balance(userId, currencyId)` has gone negative under an overdraft-enabled charge. */
300
+ isOverdrawn(userId: string, currencyId: string): boolean;
301
+ }
302
+ export interface GameContextItemUse {
303
+ register(handlers: Record<string, ItemUseHandler<GameContext>>): void;
304
+ registered(): string[];
305
+ can(input: ItemUseInput): ItemUseRejection | null;
306
+ use(input: ItemUseInput): ItemUseResult<GameContext>;
307
+ }
308
+ export interface GameContextWorld {
309
+ ground: TerrainField;
310
+ groundHeightAt(x: number, z: number): number;
311
+ }
312
+ export interface GameContextCards {
313
+ /** Lazily creates (on first call, `config` required) or returns the existing notify-wrapped pile for `id`. */
314
+ pile(id: string, config?: CardPileConfig): CardPile;
315
+ }
316
+ export interface GameContextTurn {
317
+ /** Lazily creates (on first call, `config` required) or returns the existing notify-wrapped turn loop for `id`. */
318
+ loop(id: string, config?: TurnLoopConfig): TurnLoop;
319
+ }
320
+ export interface GameContextRace {
321
+ /** Lazily creates (on first call, `config` required) or returns the existing reactive race for `id` — discrete mutations and eventful `update` calls bump `ctx.version()`, so HUDs stop hand-managing `store.set` (#286.2). */
322
+ state(id: string, config?: RaceStateConfig): RaceState;
323
+ }
324
+ /** Reachable audio seam on `ctx.game`: `play`, `music`, and `resume` route through the `audio.play`/`audio.music`/`audio.resume` events the shell's audio engine listens on, so game code triggers sound without importing the shell. Retained `loop`/`setLoop`/`stopLoop` add id-keyed loops with live pitch/gain control over `audio.loopStart`/`audio.loopSet`/`audio.loopStop` (#1051). */
325
+ export interface GameAudio {
326
+ play(sound: string, at?: readonly [number, number, number]): void;
327
+ /** Crossfade the procedural soundtrack to `theme` (null fades out); `transpose` shifts the incoming theme's key in semitones. */
328
+ music(theme: string | null, transpose?: number): void;
329
+ resume(): void;
330
+ /**
331
+ * Start — or idempotently keep — the retained, id-keyed loop `id` playing catalog `sound`, emitting
332
+ * `audio.loopStart`. Re-calling with the same `sound` does not restart it (no click); a different `sound`
333
+ * replaces the source. Pair with {@link GameAudio.setLoop} to track a live signal — an RPM-pitched engine
334
+ * loop, a slip-scaled tire squeal (#1051) — and {@link GameAudio.stopLoop} to end it.
335
+ */
336
+ loop(id: string, sound: string, options?: {
337
+ at?: readonly [number, number, number];
338
+ }): void;
339
+ /**
340
+ * Live-update retained loop `id` via `audio.loopSet`: `rate` re-pitches it (1 = authored pitch, clamped
341
+ * 0.25–4 by the shell), `gain` rescales volume (0–1), `at` repositions its emitter. Cheap to call every
342
+ * tick (~60 Hz) — the shell ramps rate/gain over ~20 ms to avoid zipper noise. A no-op when `id` is not a
343
+ * live loop (an update may race a stop) (#1051).
344
+ */
345
+ setLoop(id: string, params: {
346
+ rate?: number;
347
+ gain?: number;
348
+ at?: readonly [number, number, number];
349
+ }): void;
350
+ /** Stop and dispose retained loop `id` (emits `audio.loopStop`); an unknown `id` is ignored (#1051). */
351
+ stopLoop(id: string): void;
352
+ }
353
+ /** The live engine handle a game's loop, systems, commands, and UI read and mutate — entities, objects, the reactive store, opted-in `game.*` subsystems, world queries, and the sim clock. One context = one running world. */
354
+ export interface GameContext {
355
+ scene: {
356
+ object: SceneObjectContext;
357
+ entity: SceneEntityContext;
358
+ worldItem: SceneWorldItemContext;
359
+ raycast(input: SceneRaycastInput): SceneRaycastHit | null;
360
+ raycastAll(input: SceneRaycastInput): readonly SceneRaycastHit[];
361
+ };
362
+ world: GameContextWorld;
363
+ game: {
364
+ commands: GameContextCommands;
365
+ events: GameEvents;
366
+ audio: GameAudio;
367
+ /** Play a model's one-shot animation clip bound to `event` in its `animation.oneShots` (e.g. an attack swing) — emits `entity.animation` for the shell to pick up. */
368
+ playEntityAnimation(instanceId: string, event: string): void;
369
+ feed: GameContextFeed;
370
+ loot: GameContextLoot;
371
+ /** Shop/vendor barter — present only when `features.trade` is set. */
372
+ trade?: TradeSystem;
373
+ /** Quest/mission journal — present only when `features.quest` is set. */
374
+ quest?: QuestJournal;
375
+ /** Talkable-NPC dialogue open/close bridge — present only when `features.dialogue` is set. */
376
+ dialogue?: GameDialogue;
377
+ /** Friends/party/presence/emotes/world-invites — present only when `features.social` is set. */
378
+ social?: Social;
379
+ /** Channels + messages — present only when `features.chat` is set (implies `social`). */
380
+ chat?: Chat;
381
+ /** Earned unlockable content — present only when `features.unlocks` is set. */
382
+ unlocks?: Unlocks;
383
+ economy: GameContextEconomy;
384
+ /** Competitive score tracking — present only when `features.leaderboard` is set. */
385
+ leaderboard?: Leaderboard;
386
+ /** Owned-entity roster — present only when `features.roster` is set. */
387
+ roster?: Roster;
388
+ /** Game-defined keyed reactive store slot (#163.1); mutations bump `ctx.version()`/notify `ctx.subscribe`. */
389
+ store: ObservableKeyedStore<unknown>;
390
+ /** Card pile zones — present only when `features.cards` is set. */
391
+ cards?: GameContextCards;
392
+ /** Turn/phase loop — present only when `features.turn` is set. */
393
+ turn?: GameContextTurn;
394
+ /** Lap/checkpoint race state — present only when `features.race` is set. */
395
+ race?: GameContextRace;
396
+ /** Connected-player set for a shared world — present only when `features.players` is set. */
397
+ players?: ConnectedPlayers;
398
+ /** 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()`. */
399
+ save?: RuntimeSave;
400
+ /**
401
+ * Register a save-only snapshot module after boot (system-owned persistence).
402
+ * Used by `composeGameLoop` / `installSystems` when a system declares `save`.
403
+ */
404
+ registerSave?(module: SnapshotModule): void;
405
+ /**
406
+ * Register a host→client replication module after boot (system-owned replication).
407
+ * Used by `composeGameLoop` / `installSystems` when a system declares `replicate`.
408
+ */
409
+ registerReplicate?(module: SnapshotModule): void;
410
+ };
411
+ player: {
412
+ /** The acting player's id — the command actor inside `runAs`, the local player everywhere else. */
413
+ userId: string;
414
+ isNew: boolean;
415
+ /** The acting player's inventory set — the command actor's bags inside `runAs`, the local player's everywhere else. */
416
+ inventory: InventorySet<string>;
417
+ /** A specific player's inventory set — how a host reads or grants into any connected player's bags. */
418
+ inventoryFor(userId: string): InventorySet<string>;
419
+ /** The acting player's stat modifiers — the command actor's inside `runAs`, the local player's everywhere else. */
420
+ stats: Stats<string>;
421
+ /** A specific player's stat modifiers — how a host reads or buffs any connected player's stats. */
422
+ statsFor(userId: string): Stats<string>;
423
+ loadout: Loadouts;
424
+ applyLoadout(userId: string, loadoutId: string): {
425
+ reason: string;
426
+ } | null;
427
+ movement: PoseState;
428
+ possession: Possession;
429
+ /** Cosmetic skins/customization — present only when `features.cosmetics` is set. */
430
+ cosmetics?: Cosmetics;
431
+ /** 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`. */
432
+ motion: MotionIntents;
433
+ /** A specific player's motion queue — how the host-side per-player movement integrator drains each connected player's impulses. */
434
+ motionFor(userId: string): MotionIntents;
435
+ };
436
+ item: {
437
+ use: GameContextItemUse;
438
+ weapon: WeaponStats;
439
+ };
440
+ time: SimClock;
441
+ /** Runtime camera-follow/cinematic override (#196.2); the shell reads `followedEntityId()` each frame. */
442
+ camera: CameraDirector;
443
+ /** Held-input snapshot published by the shell each frame before `onTick` (#164.1). */
444
+ input: InputSnapshot;
445
+ subscribe(listener: () => void): () => void;
446
+ version(): number;
447
+ /**
448
+ * Bump {@link version}/notify {@link subscribe} directly — the escape hatch for a command that only
449
+ * mutates game-owned state outside the entity/object/economy/store layers (an external session map,
450
+ * a plain closure variable) and needs to force a reactive HUD refresh without faking a `ctx.game.store.set`.
451
+ */
452
+ touch(): void;
453
+ /**
454
+ * Gather every opted-in live subsystem into one {@link WorldSnapshot} — entities, entity stats, the
455
+ * keyed store, the action feed, plus leaderboard/chat when those features are on. The full-world
456
+ * baseline a host sends a joining client; {@link hydrate} is its inverse. Pass a `viewer` and the host
457
+ * projects the snapshot to only what that viewer may see (private state, area of interest) when a
458
+ * {@link GameContextOptions.replication} policy is set; without one the viewer argument is a no-op.
459
+ */
460
+ snapshot(viewer?: SnapshotViewer): WorldSnapshot;
461
+ /** Apply a {@link WorldSnapshot} from an authoritative host, hydrating each subsystem key present in it. */
462
+ hydrate(snapshot: WorldSnapshot): void;
463
+ /** Aggregate world-dirty version summed across replicated modules; the host replicator skips an unchanged commit. @internal */
464
+ replicationVersion(): number;
465
+ /** True when a {@link GameContextOptions.replication} policy makes {@link snapshot} viewer-dependent (private/AOI projection is active). @internal */
466
+ replicatesPerViewer(): boolean;
467
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -43,4 +43,5 @@ export type GameRuntime = {
43
43
  joinPlayer: (snapshot: GameRuntimeSnapshot, userId: string, isNew: boolean) => GameRuntimeSnapshot;
44
44
  toProfileRow: (snapshot: GameRuntimeSnapshot, userId: string) => RuntimeProfileRow | null;
45
45
  };
46
+ /** @internal */
46
47
  export declare function createGameRuntime(definition: GameRuntimeDefinition): GameRuntime;
@@ -1,5 +1,6 @@
1
1
  import { runCommand } from "./commandRunner.js";
2
2
  import { createEmptyPlayerRow, createRuntimeSnapshot, } from "./snapshot.js";
3
+ /** @internal */
3
4
  export function createGameRuntime(definition) {
4
5
  const loop = definition.loop;
5
6
  let initialized = false;
@@ -0,0 +1,62 @@
1
+ import type { GameDefinition, GameLoop } from "../game/defineGame.js";
2
+ import type { PointerAxisState } from "../input/pointerAxis.js";
3
+ import type { ModelAssetRef } from "../scene/assetCatalog.js";
4
+ import { type GameContext, type GameContextContent, type GameContextModels } from "./gameContext.js";
5
+ import type { InputSnapshot } from "./inputSnapshot.js";
6
+ /** One step's worth of player intent handed to {@link HeadlessRunner.step} — the held-action set and pointer state the shell would otherwise publish from the browser each frame. */
7
+ export interface HeadlessInput {
8
+ /** Replaces the held-action set for this step; edge detection (`justPressed`/`justReleased`) rolls the previous set forward. Omit to keep the last published set. */
9
+ held?: readonly string[];
10
+ /** Replaces the normalized pointer state; omit to leave the last pointer unchanged (pass `null` to clear it). */
11
+ pointer?: PointerAxisState | null;
12
+ }
13
+ export interface HeadlessRunnerOptions<TAssetRef extends ModelAssetRef, TMultiplayer> {
14
+ definition: GameDefinition<TAssetRef, TMultiplayer>;
15
+ /** Catalog resolvers (`entityById`/`objectById`) the context uses; defaults to an empty catalog. */
16
+ content?: GameContextContent;
17
+ /** Lifecycle hooks — `onInit`/`onNewPlayer` fire at construction, `onTick` on every {@link HeadlessRunner.step}. The shell keeps this separate from `definition` (presentation wraps it); a headless caller passes it directly. */
18
+ loop?: GameLoop<GameContext>;
19
+ /** The single local player; defaults to `{ userId: "player", isNew: true }`. */
20
+ player?: {
21
+ userId: string;
22
+ isNew: boolean;
23
+ };
24
+ /** Wall-clock source for the sim clock — inject a deterministic counter for reproducible runs. */
25
+ now?: () => number;
26
+ /** Per-step real-dt clamp in seconds, matching the shell's frame cap so one long stall can't fast-forward the sim. Default `0.05`. */
27
+ maxStepSeconds?: number;
28
+ /**
29
+ * Drive the built-in keyboard player-movement controller from the held-action set each step, exactly as the shell's
30
+ * FrameDriver does for pose-driven games. Off by default — tick-driven games move their own entities inside
31
+ * `onTick` and don't need it.
32
+ */
33
+ playerMovement?: boolean;
34
+ /** Yaw heading (radians) fed to the movement controller when `playerMovement` is on; the shell supplies its camera yaw. */
35
+ heading?: number;
36
+ /** Render-model lookup for collider auto-fit — pass what the shell would derive from `entityModels`/`objectModels` so headless raycasts hit the same boxes as play. */
37
+ models?: GameContextModels;
38
+ }
39
+ /**
40
+ * A renderer-free driver for a game loop: builds a {@link GameContext} from a {@link GameDefinition}, runs the init
41
+ * hooks, then advances the simulation one step at a time from injected input. No React, R3F, or three.js — the whole
42
+ * play path (time, input, `onTick`, behaviour nav, optional player movement) runs from `core` primitives alone, so a
43
+ * non-React host (a server tick, a test, a CLI replay) can play a real game and read its world snapshot. The shell's
44
+ * FrameDriver is one such driver bolted to `useFrame`; this is the same step distilled out of the render tree.
45
+ *
46
+ * @capability headless-runner play a real game loop with no renderer — tick, feed input, read the world snapshot
47
+ */
48
+ export interface HeadlessRunner {
49
+ /** The live game context — read `ctx.scene.entity.list()`, `ctx.game.store`, `ctx.subscribe`/`ctx.version()` for the world snapshot. */
50
+ readonly ctx: GameContext;
51
+ /** The per-frame input the loop reads; the same object exposed as `ctx.input`. */
52
+ readonly input: InputSnapshot;
53
+ readonly userId: string;
54
+ /**
55
+ * Advance the simulation one step. Publishes `input` (if given), advances the sim clock by the clamped real dt,
56
+ * runs optional player movement, then `loop.onTick` and behaviour nav. Returns the scaled game dt `onTick` saw.
57
+ */
58
+ step(dtSeconds: number, input?: HeadlessInput): number;
59
+ /** Publish input without advancing — for pre-seeding the held set before the first {@link step}. */
60
+ publishInput(input: HeadlessInput): void;
61
+ }
62
+ export declare function createHeadlessRunner<TAssetRef extends ModelAssetRef, TMultiplayer>(options: HeadlessRunnerOptions<TAssetRef, TMultiplayer>): HeadlessRunner;
@@ -0,0 +1,45 @@
1
+ import { resolvePlayerMovementTuning, stepPlayerMovement, } from "../movement/playerMovement.js";
2
+ import { advanceBehaviors } from "../scene/behaviorRuntime.js";
3
+ import { createGameContext } from "./gameContext.js";
4
+ export function createHeadlessRunner(options) {
5
+ const { definition, loop } = options;
6
+ const content = options.content ?? {};
7
+ const player = options.player ?? { userId: "player", isNew: true };
8
+ const maxStep = options.maxStepSeconds ?? 0.05;
9
+ const ctx = createGameContext({
10
+ definition,
11
+ content,
12
+ player,
13
+ ...(options.now === undefined ? {} : { now: options.now }),
14
+ ...(options.models === undefined ? {} : { models: options.models }),
15
+ });
16
+ loop?.onInit?.(ctx);
17
+ loop?.onNewPlayer?.(ctx);
18
+ const tuning = options.playerMovement === true
19
+ ? resolvePlayerMovementTuning({ physics: definition.physics, world: definition.world })
20
+ : null;
21
+ function publishInput(input) {
22
+ if (input.held !== undefined)
23
+ ctx.input.publish(input.held);
24
+ if (input.pointer !== undefined)
25
+ ctx.input.publishPointer(input.pointer);
26
+ }
27
+ return {
28
+ ctx,
29
+ input: ctx.input,
30
+ userId: player.userId,
31
+ publishInput,
32
+ step(dtSeconds, input) {
33
+ if (input !== undefined)
34
+ publishInput(input);
35
+ const dt = Math.min(dtSeconds, maxStep);
36
+ const gameDt = ctx.time.advance(dt);
37
+ if (tuning !== null) {
38
+ stepPlayerMovement(ctx, player.userId, { held: ctx.input.held(), pointer: ctx.input.pointer() }, dt, tuning, options.heading);
39
+ }
40
+ loop?.onTick?.(ctx, gameDt);
41
+ advanceBehaviors(ctx, gameDt);
42
+ return gameDt;
43
+ },
44
+ };
45
+ }
@@ -58,11 +58,13 @@ export type LeaderboardEntry = {
58
58
  value: number;
59
59
  };
60
60
  export declare const LEADERBOARD_PENDING_KEY = "leaderboardPending";
61
+ /** @internal */
61
62
  export declare function drainPendingLeaderboardIncrements(session: Record<string, unknown>): {
62
63
  increments: LeaderboardIncrement[];
63
64
  session: Record<string, unknown>;
64
65
  };
65
66
  export declare const LEADERBOARD_TOP_LIMIT = 100;
67
+ /** @internal */
66
68
  export declare function clampLimit(value: number | undefined, fallback: number, max: number): number;
67
69
  export type LeaderboardRow = {
68
70
  gameId: string;
@@ -73,8 +75,11 @@ export type LeaderboardRow = {
73
75
  value: number;
74
76
  updatedAt: number;
75
77
  };
78
+ /** @internal */
76
79
  export declare function leaderboardRowKey(row: Omit<LeaderboardRow, "value" | "updatedAt">): string;
80
+ /** @internal */
77
81
  export declare function applyLeaderboardRows(rows: Map<string, LeaderboardRow>, gameId: string, entries: LeaderboardIncrement[], now: number): void;
82
+ /** @internal */
78
83
  export declare function topLeaderboardRows(rows: Iterable<LeaderboardRow>, args: {
79
84
  gameId: string;
80
85
  stat: string;
@@ -82,9 +87,12 @@ export declare function topLeaderboardRows(rows: Iterable<LeaderboardRow>, args:
82
87
  serverId?: string;
83
88
  limit?: number;
84
89
  }): LeaderboardEntry[];
90
+ /** @internal */
85
91
  export declare function profileLeaderboardStats(rows: Iterable<LeaderboardRow>, gameId: string, userId: string): Record<string, number>;
86
92
  export declare const FEED_RING_LIMIT = 20;
93
+ /** @internal */
87
94
  export declare function trimFeedEntries<T>(entries: T[], limit?: number): T[];
95
+ /** @internal */
88
96
  export declare function shouldAutoSave(save: SaveConfig, dirtyAt: number | undefined, lastSavedAt: number | undefined, now: number): boolean;
89
97
  export type ServerListing = {
90
98
  serverId: string;
@@ -101,9 +109,11 @@ export type ServerListing = {
101
109
  export type ToServerListingOptions = {
102
110
  includeJoinCode?: boolean;
103
111
  };
112
+ /** @internal */
104
113
  export declare function toServerListing(record: GameServerRecord, options?: ToServerListingOptions): ServerListing;
105
114
  export declare const OPEN_SERVER_LISTING_LIMIT = 20;
106
115
  export declare const OPEN_SERVER_LISTING_MAX = 100;
116
+ /** @internal */
107
117
  export declare function toOpenServerListings(listings: Iterable<ServerListing>, limit?: number): ServerListing[];
108
118
  export type HostPersistence = {
109
119
  savePlan?: (plan: ServerPersistPlan) => Promise<void>;
@@ -141,6 +151,7 @@ export type HostPersistence = {
141
151
  userId: string;
142
152
  }) => Promise<Record<string, number>>;
143
153
  };
154
+ /** @internal */
144
155
  export declare function buildHydratePlayers(server: GameServerRecord, profiles: Record<string, PlayerProfileRecord | null>): Record<string, RuntimePlayerRow>;
145
156
  export type ServerPersistPlan = {
146
157
  server: GameServerRecord;
@@ -149,4 +160,5 @@ export type ServerPersistPlan = {
149
160
  deletedChunks: string[];
150
161
  leaderboard: LeaderboardIncrement[];
151
162
  };
163
+ /** @internal */
152
164
  export declare function planServerPersist(server: GameServerRecord, snapshot: GameRuntimeSnapshot, save: SaveConfig, now: number): ServerPersistPlan;