@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,194 @@
1
+ /**
2
+ * Group destination assignment: slot a moving group into a formation around a
3
+ * target point, then match members to slots. Shape is caller data — a
4
+ * {@link FormationSlotGenerator} emits slot offsets in the group's local frame
5
+ * ("right" = +x, "forward" = +y) and the engine ships line/box/wedge/circle
6
+ * only as samples; a custom generator needs no engine change. Placement and
7
+ * matching are pure and deterministic so the same inputs always yield the same
8
+ * world slots and the same assignment, which keeps them replay- and
9
+ * network-safe. Route planning and local collision avoidance are deliberately
10
+ * separate seams (`movement/avoidance`, `nav/pathFollow`): this module answers
11
+ * only "where should each member stand", not "how does it get there".
12
+ */
13
+ import { yawForward, yawRight } from "./steering.js";
14
+ /**
15
+ * Engine yaw (`rotationY`, radians) that faces from `from` toward `to` on the
16
+ * XZ plane, matching the `forward = (sin yaw, cos yaw)` convention. Feed the
17
+ * result as the `facing` of {@link placeFormation} to orient a formation along
18
+ * its travel direction. Returns `0` when the points coincide.
19
+ *
20
+ * @capability formation-facing group facing yaw from a travel direction on the XZ plane
21
+ * @consumer squad and crowd movement — orient a destination formation along its heading
22
+ */
23
+ export function facingYaw(from, to) {
24
+ const dx = to[0] - from[0];
25
+ const dz = to[1] - from[1];
26
+ if (dx * dx + dz * dz <= 1e-18)
27
+ return 0;
28
+ return Math.atan2(dx, dz);
29
+ }
30
+ /**
31
+ * Transform a generator's local slot offsets into world XZ positions around a
32
+ * `destination`, rotated by `facing` (engine yaw). Slot `i` in the returned
33
+ * array is `generator(count)[i]` mapped through the group frame, so it stays
34
+ * aligned with {@link assignFormationSlots}' slot indices. Pure and allocation-
35
+ * light: one array of `count` points, no per-call closures retained.
36
+ *
37
+ * @capability formation-placement place a group formation's world slots around a destination
38
+ * @consumer squad/party/convoy movement — generate per-member destination slots around a target
39
+ */
40
+ export function placeFormation(destination, facing, count, generator) {
41
+ if (count <= 0)
42
+ return [];
43
+ const forward = yawForward(facing);
44
+ const right = yawRight(facing);
45
+ const local = generator(count);
46
+ const slots = [];
47
+ for (let i = 0; i < count; i += 1) {
48
+ const offset = local[i] ?? ZERO;
49
+ const r = offset[0];
50
+ const f = offset[1];
51
+ slots.push([
52
+ destination[0] + right[0] * r + forward[0] * f,
53
+ destination[1] + right[1] * r + forward[1] * f,
54
+ ]);
55
+ }
56
+ return slots;
57
+ }
58
+ /**
59
+ * Match `members` to `slots` by a deterministic greedy nearest assignment:
60
+ * every (member, slot) pair is ranked by squared travel distance (minus a
61
+ * stickiness bonus for a member's previous slot) and assigned in order while
62
+ * both ends are free. Returns `assignment[member] = slot`, or `-1` for members
63
+ * left unmatched when there are fewer slots than members. Ties break by member
64
+ * then slot index, so the result is stable across runs and independent of input
65
+ * ordering — the property replay and lockstep multiplayer rely on. Groups are
66
+ * bounded, so the `O(members·slots·log)` sort is fine; this is not a per-frame
67
+ * whole-world pass.
68
+ *
69
+ * @capability formation-assignment stable deterministic member-to-slot matching for a group formation
70
+ * @consumer squad/party movement — assign each member a destination slot with low reshuffle churn
71
+ */
72
+ export function assignFormationSlots(members, slots, options = {}) {
73
+ const memberCount = members.length;
74
+ const slotCount = slots.length;
75
+ const assignment = new Array(memberCount).fill(-1);
76
+ if (memberCount === 0 || slotCount === 0)
77
+ return assignment;
78
+ const previous = options.previous;
79
+ const stickiness = options.stickiness ?? 0;
80
+ const pairs = [];
81
+ for (let m = 0; m < memberCount; m += 1) {
82
+ const member = members[m];
83
+ const keepSlot = previous?.[m];
84
+ for (let s = 0; s < slotCount; s += 1) {
85
+ const slot = slots[s];
86
+ const dx = slot[0] - member[0];
87
+ const dz = slot[1] - member[1];
88
+ let cost = dx * dx + dz * dz;
89
+ if (stickiness > 0 && keepSlot === s)
90
+ cost -= stickiness;
91
+ pairs.push({ member: m, slot: s, cost });
92
+ }
93
+ }
94
+ pairs.sort((a, b) => a.cost !== b.cost ? a.cost - b.cost : a.member !== b.member ? a.member - b.member : a.slot - b.slot);
95
+ const slotTaken = new Array(slotCount).fill(false);
96
+ let filled = 0;
97
+ const need = Math.min(memberCount, slotCount);
98
+ for (let p = 0; p < pairs.length && filled < need; p += 1) {
99
+ const pair = pairs[p];
100
+ if (assignment[pair.member] !== -1 || slotTaken[pair.slot])
101
+ continue;
102
+ assignment[pair.member] = pair.slot;
103
+ slotTaken[pair.slot] = true;
104
+ filled += 1;
105
+ }
106
+ return assignment;
107
+ }
108
+ const ZERO = [0, 0];
109
+ /**
110
+ * A single rank abreast, centered on the destination and facing forward — a
111
+ * skirmish line or a chorus row. Slots run left→right along the group's right
112
+ * axis.
113
+ *
114
+ * @capability formation-line line (abreast) slot generator for group destinations
115
+ * @consumer squad movement — line formation sample policy for {@link placeFormation}
116
+ */
117
+ export function lineFormation(options) {
118
+ const spacing = options.spacing;
119
+ return (count) => {
120
+ const slots = [];
121
+ const mid = (count - 1) / 2;
122
+ for (let i = 0; i < count; i += 1)
123
+ slots.push([(i - mid) * spacing, 0]);
124
+ return slots;
125
+ };
126
+ }
127
+ /**
128
+ * A rectangular grid centered on the destination, front row toward `+forward` —
129
+ * a marching block or a phalanx. Rows fill front-to-back, left-to-right.
130
+ *
131
+ * @capability formation-box box/grid slot generator for group destinations
132
+ * @consumer squad movement — box formation sample policy for {@link placeFormation}
133
+ */
134
+ export function boxFormation(options) {
135
+ const spacing = options.spacing;
136
+ const fixedColumns = options.columns;
137
+ return (count) => {
138
+ const columns = Math.max(1, fixedColumns ?? Math.ceil(Math.sqrt(count)));
139
+ const rows = Math.ceil(count / columns);
140
+ const midCol = (columns - 1) / 2;
141
+ const midRow = (rows - 1) / 2;
142
+ const slots = [];
143
+ for (let i = 0; i < count; i += 1) {
144
+ const row = Math.floor(i / columns);
145
+ const col = i % columns;
146
+ slots.push([(col - midCol) * spacing, (midRow - row) * spacing]);
147
+ }
148
+ return slots;
149
+ };
150
+ }
151
+ /**
152
+ * A "V"/arrowhead with the apex at the destination and arms trailing back — a
153
+ * flying-wedge charge or a goose skein. Slot 0 is the tip; later slots alternate
154
+ * right then left, each rank stepping one `spacing` outward and backward.
155
+ *
156
+ * @capability formation-wedge wedge/arrowhead slot generator for group destinations
157
+ * @consumer squad movement — wedge formation sample policy for {@link placeFormation}
158
+ */
159
+ export function wedgeFormation(options) {
160
+ const spacing = options.spacing;
161
+ return (count) => {
162
+ const slots = [];
163
+ for (let i = 0; i < count; i += 1) {
164
+ if (i === 0) {
165
+ slots.push([0, 0]);
166
+ continue;
167
+ }
168
+ const rank = Math.ceil(i / 2);
169
+ const side = i % 2 === 1 ? 1 : -1;
170
+ slots.push([side * rank * spacing, -rank * spacing]);
171
+ }
172
+ return slots;
173
+ };
174
+ }
175
+ /**
176
+ * An evenly spaced ring around the destination — a guard cordon, a huddle, or a
177
+ * surround. Slot 0 sits `startAngle` from forward; slots advance evenly around
178
+ * the circle.
179
+ *
180
+ * @capability formation-circle ring/cordon slot generator for group destinations
181
+ * @consumer squad/crowd movement — circle formation sample policy for {@link placeFormation}
182
+ */
183
+ export function circleFormation(options) {
184
+ const radius = options.radius;
185
+ const startAngle = options.startAngle ?? 0;
186
+ return (count) => {
187
+ const slots = [];
188
+ for (let i = 0; i < count; i += 1) {
189
+ const angle = startAngle + (2 * Math.PI * i) / count;
190
+ slots.push([radius * Math.sin(angle), radius * Math.cos(angle)]);
191
+ }
192
+ return slots;
193
+ };
194
+ }
@@ -41,4 +41,9 @@ export interface GlideModel {
41
41
  pose(): GlideStep;
42
42
  launch(position: GlideVec3, heading: number, initialSpeed?: number): void;
43
43
  }
44
+ /**
45
+ * Gliding/wingsuit descent control — lift, drag, and steering from a launch.
46
+ *
47
+ * @capability glide gliding/wingsuit descent control from a launch
48
+ */
44
49
  export declare function createGlideModel(config?: GlideModelConfig): GlideModel;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Gliding/wingsuit descent control — lift, drag, and steering from a launch.
3
+ *
4
+ * @capability glide gliding/wingsuit descent control from a launch
5
+ */
1
6
  export function createGlideModel(config = {}) {
2
7
  const gravity = (config.gravity ?? 20) * (config.gravityScale ?? 0.25);
3
8
  const thrustAccel = config.thrustAccel ?? 10;
@@ -31,4 +31,9 @@ export interface GrappleSwing {
31
31
  /** Constrain one frame. `reeling` shortens the rope; returns the corrected position/velocity. */
32
32
  step(position: SwingVec3, velocity: SwingVec3, dt: number, reeling?: boolean): GrappleSwingStep;
33
33
  }
34
+ /**
35
+ * Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.
36
+ *
37
+ * @capability grapple-swing grappling-hook rope swing physics with reel-in
38
+ */
34
39
  export declare function createGrappleSwing(config?: GrappleSwingConfig): GrappleSwing;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Grappling-hook rope swing physics with anchor, pendulum motion, and reel-in.
3
+ *
4
+ * @capability grapple-swing grappling-hook rope swing physics with reel-in
5
+ */
1
6
  export function createGrappleSwing(config = {}) {
2
7
  const reelSpeed = config.reelSpeed ?? 0;
3
8
  const minLength = config.minLength ?? 1;
@@ -26,4 +26,9 @@ export interface LeaderTrail {
26
26
  /** Drop all history (teleport, respawn) and optionally restart from a position. */
27
27
  reset(position?: TrailPoint): void;
28
28
  }
29
+ /**
30
+ * A trailing follower formation that chases a leader along its past path — snake/convoy trails.
31
+ *
32
+ * @capability follow-trail trailing follower/snake formation that chases a leader
33
+ */
29
34
  export declare function createLeaderTrail(config: LeaderTrailConfig): LeaderTrail;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * A trailing follower formation that chases a leader along its past path — snake/convoy trails.
3
+ *
4
+ * @capability follow-trail trailing follower/snake formation that chases a leader
5
+ */
1
6
  export function createLeaderTrail(config) {
2
7
  if (!(config.spacing > 0))
3
8
  throw new Error(`leader trail spacing must be positive, got ${config.spacing}`);
@@ -12,6 +12,7 @@
12
12
  */
13
13
  export type MovementKey = "w" | "a" | "s" | "d" | "shift" | "control" | "c" | "space";
14
14
  export type MovementKeysState = Record<MovementKey, boolean>;
15
+ /** @internal */
15
16
  export declare function createEmptyMovementKeys(): MovementKeysState;
16
17
  /**
17
18
  * Frame-independent description of what the player is asking the avatar to do.
@@ -31,7 +32,8 @@ export interface MovementIntent {
31
32
  * Translate the set of held keys into an intent. When `canMove` is false (a
32
33
  * menu is open, the world is paused) the avatar is fully idle so it never
33
34
  * drifts behind an overlay.
34
- */
35
+ * @internal
36
+ */
35
37
  export declare function resolveMovementIntent(keys: MovementKeysState, canMove: boolean): MovementIntent;
36
38
  /**
37
39
  * Kinematics + feel tuning for the first-person controller. Centralised here so
@@ -43,6 +45,8 @@ export declare const MOVEMENT_TUNING: {
43
45
  readonly walkSpeedMultiplier: 1.75;
44
46
  readonly runSpeedMultiplier: 2.25;
45
47
  readonly crouchSpeedMultiplier: 0.45;
48
+ /** Backward (S) travels this fraction of walk speed so retreating reads slower than advancing. */
49
+ readonly backpedalSpeedMultiplier: 0.65;
46
50
  readonly groundAcceleration: 26;
47
51
  readonly airAcceleration: 12;
48
52
  readonly groundFriction: 18;
@@ -74,6 +78,7 @@ export interface PlayerMotionState {
74
78
  grounded: boolean;
75
79
  jumpHeld: boolean;
76
80
  }
81
+ /** @internal */
77
82
  export declare function createPlayerMotionState(): PlayerMotionState;
78
83
  /** Horizontal step (world units) the avatar should commit this frame. */
79
84
  export interface MovementFrameStep {
@@ -87,6 +92,19 @@ export interface MovementFrameStep {
87
92
  export interface MovementTuningOverrides {
88
93
  gravityAcceleration?: number;
89
94
  jumpVelocity?: number;
95
+ /** Fraction of walk speed while backpedalling; overrides {@link MOVEMENT_TUNING.backpedalSpeedMultiplier}. */
96
+ backpedalSpeedMultiplier?: number;
97
+ }
98
+ /**
99
+ * Per-frame dynamic modifiers for {@link advancePlayerMotion} — state the caller
100
+ * recomputes each tick (unlike the static {@link MovementTuningOverrides}). Omitted
101
+ * fields leave the integrator at its default behavior.
102
+ */
103
+ export interface MotionFrameOptions {
104
+ /** Extra multiplier applied on top of the resolved target speed (e.g. swimming). Default 1. */
105
+ speedScale?: number;
106
+ /** Suppress gravity/jump integration and hold the avatar afloat this frame (e.g. swimming). Default false. */
107
+ floating?: boolean;
90
108
  }
91
109
  /**
92
110
  * Advance one frame of avatar kinematics. Mutates `motion` (velocity, jump,
@@ -97,8 +115,9 @@ export interface MovementTuningOverrides {
97
115
  * (need not be normalized); the avatar's right axis is derived from it. Pulling
98
116
  * this out of the render loop is what lets us assert "held forward for N frames
99
117
  * crosses the room" in a unit test instead of only in the live game.
100
- */
101
- export declare function advancePlayerMotion(motion: PlayerMotionState, intent: MovementIntent, forwardX: number, forwardZ: number, baseSpeed: number, rawDeltaSeconds: number, tuning?: MovementTuningOverrides): MovementFrameStep;
118
+ * @internal
119
+ */
120
+ export declare function advancePlayerMotion(motion: PlayerMotionState, intent: MovementIntent, forwardX: number, forwardZ: number, baseSpeed: number, rawDeltaSeconds: number, tuning?: MovementTuningOverrides, options?: MotionFrameOptions): MovementFrameStep;
102
121
  /** A placed scene object the walking player collides against as a circle-vs-AABB obstacle. */
103
122
  export interface CollisionObstacle {
104
123
  position: readonly [number, number, number];
@@ -113,21 +132,29 @@ export interface CollisionObstacle {
113
132
  * by `playerRadius`; an obstacle whose vertical span misses the player's
114
133
  * feet-to-head span is skipped entirely. Callers should pre-filter to nearby
115
134
  * objects — this also early-exits per obstacle on horizontal distance.
116
- */
135
+ * @internal
136
+ */
117
137
  export declare function resolveObstacleStep(current: readonly [number, number, number], stepX: number, stepZ: number, obstacles: readonly CollisionObstacle[], playerRadius?: number): MovementFrameStep;
118
- /** Placed objects within `radius` (XZ) of `center`, as {@link CollisionObstacle}s to pre-filter for {@link resolveObstacleStep}. */
138
+ /** Placed objects within `radius` (XZ) of `center`, as {@link CollisionObstacle}s to pre-filter for {@link resolveObstacleStep}.
139
+ * @internal
140
+ */
119
141
  export declare function nearbyObstacles(objects: readonly {
120
142
  position: readonly [number, number, number];
121
143
  }[], center: readonly [number, number, number], radius?: number): CollisionObstacle[];
122
- /** Zeroes the off-axis component so travel is locked to a single world axis (`PlayerMovementConfig.mode: "axis"`). */
144
+ /** Zeroes the off-axis component so travel is locked to a single world axis (`PlayerMovementConfig.mode: "axis"`).
145
+ * @internal
146
+ */
123
147
  export declare function constrainStepToAxis(stepX: number, stepZ: number, axis: "x" | "z"): MovementFrameStep;
124
148
  /**
125
149
  * Snap a world position to its containing cell's center, matching the
126
150
  * bounds-free form of `navGrid`'s and `tacticalGrid`'s `floor` + half-cell
127
151
  * convention (`PlayerMovementConfig.mode: "grid"`).
128
- */
152
+ * @internal
153
+ */
129
154
  export declare function snapPositionToGrid(x: number, z: number, cellSize: number): [number, number];
130
155
  /** Peak jump height from MOVEMENT_TUNING.jumpVelocity + gravity, with small buffer. */
131
156
  export declare const MAX_JUMP_OFFSET = 1.15;
132
- /** Camera yaw looks along -Z; character mesh faces +Z at body rotation.y = 0. */
157
+ /** Camera yaw looks along -Z; character mesh faces +Z at body rotation.y = 0.
158
+ * @internal
159
+ */
133
160
  export declare function cameraYawToAvatarBodyYaw(cameraYaw: number): number;
@@ -10,6 +10,7 @@
10
10
  * touch controls) and its camera rigs (pointer lock, the per-frame look
11
11
  * channel).
12
12
  */
13
+ /** @internal */
13
14
  export function createEmptyMovementKeys() {
14
15
  return { w: false, a: false, s: false, d: false, shift: false, control: false, c: false, space: false };
15
16
  }
@@ -25,7 +26,8 @@ const IDLE_INTENT = {
25
26
  * Translate the set of held keys into an intent. When `canMove` is false (a
26
27
  * menu is open, the world is paused) the avatar is fully idle so it never
27
28
  * drifts behind an overlay.
28
- */
29
+ * @internal
30
+ */
29
31
  export function resolveMovementIntent(keys, canMove) {
30
32
  if (!canMove)
31
33
  return IDLE_INTENT;
@@ -52,6 +54,8 @@ export const MOVEMENT_TUNING = {
52
54
  walkSpeedMultiplier: 1.75,
53
55
  runSpeedMultiplier: 2.25,
54
56
  crouchSpeedMultiplier: 0.45,
57
+ /** Backward (S) travels this fraction of walk speed so retreating reads slower than advancing. */
58
+ backpedalSpeedMultiplier: 0.65,
55
59
  groundAcceleration: 26,
56
60
  airAcceleration: 12,
57
61
  groundFriction: 18,
@@ -70,15 +74,24 @@ export const MOVEMENT_TUNING = {
70
74
  /** Largest physics step we integrate so a stalled tab can't teleport the player. */
71
75
  maxFrameSeconds: 0.05,
72
76
  };
73
- /** Speed (units/s) the avatar should target given the active intent. */
74
- function resolveTargetSpeed(intent, baseSpeed) {
77
+ /**
78
+ * Speed (units/s) the avatar should target given the active intent. Crouch and run
79
+ * take precedence over backpedal; a plain backward intent (`forward < 0`) slows to
80
+ * {@link MOVEMENT_TUNING.backpedalSpeedMultiplier} (overridable via `tuning`), while a
81
+ * pure strafe keeps full speed.
82
+ */
83
+ function resolveTargetSpeed(intent, baseSpeed, tuning) {
84
+ const backpedal = tuning?.backpedalSpeedMultiplier ?? MOVEMENT_TUNING.backpedalSpeedMultiplier;
75
85
  const speedMultiplier = intent.crouching
76
86
  ? MOVEMENT_TUNING.crouchSpeedMultiplier
77
87
  : intent.running
78
88
  ? MOVEMENT_TUNING.runSpeedMultiplier
79
- : 1;
89
+ : intent.forward < 0
90
+ ? backpedal
91
+ : 1;
80
92
  return baseSpeed * MOVEMENT_TUNING.walkSpeedMultiplier * speedMultiplier;
81
93
  }
94
+ /** @internal */
82
95
  export function createPlayerMotionState() {
83
96
  return {
84
97
  horizontalVelocityX: 0,
@@ -98,10 +111,11 @@ export function createPlayerMotionState() {
98
111
  * (need not be normalized); the avatar's right axis is derived from it. Pulling
99
112
  * this out of the render loop is what lets us assert "held forward for N frames
100
113
  * crosses the room" in a unit test instead of only in the live game.
101
- */
102
- export function advancePlayerMotion(motion, intent, forwardX, forwardZ, baseSpeed, rawDeltaSeconds, tuning) {
114
+ * @internal
115
+ */
116
+ export function advancePlayerMotion(motion, intent, forwardX, forwardZ, baseSpeed, rawDeltaSeconds, tuning, options) {
103
117
  const deltaSeconds = Math.min(rawDeltaSeconds, MOVEMENT_TUNING.maxFrameSeconds);
104
- const targetSpeed = resolveTargetSpeed(intent, baseSpeed);
118
+ const targetSpeed = resolveTargetSpeed(intent, baseSpeed, tuning) * (options?.speedScale ?? 1);
105
119
  const gravityAcceleration = tuning?.gravityAcceleration ?? MOVEMENT_TUNING.gravityAcceleration;
106
120
  const jumpVelocity = tuning?.jumpVelocity ?? MOVEMENT_TUNING.jumpVelocity;
107
121
  let targetVelocityX = 0;
@@ -146,13 +160,19 @@ export function advancePlayerMotion(motion, intent, forwardX, forwardZ, baseSpee
146
160
  motion.horizontalVelocityX *= friction;
147
161
  motion.horizontalVelocityZ *= friction;
148
162
  }
163
+ const floating = options?.floating === true;
149
164
  const jumpPressed = intent.jumping;
150
- if (jumpPressed && !motion.jumpHeld && motion.grounded && !intent.crouching) {
165
+ if (jumpPressed && !motion.jumpHeld && motion.grounded && !intent.crouching && !floating) {
151
166
  motion.verticalVelocity = jumpVelocity;
152
167
  motion.grounded = false;
153
168
  }
154
169
  motion.jumpHeld = jumpPressed;
155
- if (!motion.grounded || motion.verticalVelocity > 0) {
170
+ if (floating) {
171
+ motion.verticalVelocity = 0;
172
+ motion.jumpOffset = 0;
173
+ motion.grounded = true;
174
+ }
175
+ else if (!motion.grounded || motion.verticalVelocity > 0) {
156
176
  motion.verticalVelocity -= gravityAcceleration * deltaSeconds;
157
177
  motion.jumpOffset += motion.verticalVelocity * deltaSeconds;
158
178
  if (motion.jumpOffset <= 0) {
@@ -188,7 +208,8 @@ function clampAxisStep(originalCoord, step, min, max) {
188
208
  * by `playerRadius`; an obstacle whose vertical span misses the player's
189
209
  * feet-to-head span is skipped entirely. Callers should pre-filter to nearby
190
210
  * objects — this also early-exits per obstacle on horizontal distance.
191
- */
211
+ * @internal
212
+ */
192
213
  export function resolveObstacleStep(current, stepX, stepZ, obstacles, playerRadius = DEFAULT_OBSTACLE_PLAYER_RADIUS) {
193
214
  const feetY = current[1];
194
215
  const headY = feetY + OBSTACLE_PLAYER_HEIGHT;
@@ -228,7 +249,9 @@ export function resolveObstacleStep(current, stepX, stepZ, obstacles, playerRadi
228
249
  return { stepX: resultX, stepZ: resultZ };
229
250
  }
230
251
  const OBSTACLE_GATHER_RADIUS = 3;
231
- /** Placed objects within `radius` (XZ) of `center`, as {@link CollisionObstacle}s to pre-filter for {@link resolveObstacleStep}. */
252
+ /** Placed objects within `radius` (XZ) of `center`, as {@link CollisionObstacle}s to pre-filter for {@link resolveObstacleStep}.
253
+ * @internal
254
+ */
232
255
  export function nearbyObstacles(objects, center, radius = OBSTACLE_GATHER_RADIUS) {
233
256
  const radiusSq = radius * radius;
234
257
  const result = [];
@@ -240,7 +263,9 @@ export function nearbyObstacles(objects, center, radius = OBSTACLE_GATHER_RADIUS
240
263
  }
241
264
  return result;
242
265
  }
243
- /** Zeroes the off-axis component so travel is locked to a single world axis (`PlayerMovementConfig.mode: "axis"`). */
266
+ /** Zeroes the off-axis component so travel is locked to a single world axis (`PlayerMovementConfig.mode: "axis"`).
267
+ * @internal
268
+ */
244
269
  export function constrainStepToAxis(stepX, stepZ, axis) {
245
270
  return axis === "x" ? { stepX, stepZ: 0 } : { stepX: 0, stepZ };
246
271
  }
@@ -248,13 +273,16 @@ export function constrainStepToAxis(stepX, stepZ, axis) {
248
273
  * Snap a world position to its containing cell's center, matching the
249
274
  * bounds-free form of `navGrid`'s and `tacticalGrid`'s `floor` + half-cell
250
275
  * convention (`PlayerMovementConfig.mode: "grid"`).
251
- */
276
+ * @internal
277
+ */
252
278
  export function snapPositionToGrid(x, z, cellSize) {
253
279
  return [(Math.floor(x / cellSize) + 0.5) * cellSize, (Math.floor(z / cellSize) + 0.5) * cellSize];
254
280
  }
255
281
  /** Peak jump height from MOVEMENT_TUNING.jumpVelocity + gravity, with small buffer. */
256
282
  export const MAX_JUMP_OFFSET = 1.15;
257
- /** Camera yaw looks along -Z; character mesh faces +Z at body rotation.y = 0. */
283
+ /** Camera yaw looks along -Z; character mesh faces +Z at body rotation.y = 0.
284
+ * @internal
285
+ */
258
286
  export function cameraYawToAvatarBodyYaw(cameraYaw) {
259
287
  return cameraYaw + Math.PI;
260
288
  }
@@ -1,10 +1,15 @@
1
1
  import { applyHorizontalImpulses, applyMotionImpulses } from "../runtime/motionIntents.js";
2
- import { groundFieldFor, hasEnvironmentTerrain } from "../world/terrain.js";
2
+ import { groundFieldFor, hasEnvironmentTerrain, sampleSlope } from "../world/terrain.js";
3
3
  import { advancePlayerMotion, constrainStepToAxis, createEmptyMovementKeys, createPlayerMotionState, nearbyObstacles, resolveMovementIntent, resolveObstacleStep, snapPositionToGrid, } from "./movementModel.js";
4
- import { steerYaw } from "./steering.js";
4
+ import { approachYaw, steerYaw } from "./steering.js";
5
5
  import { advanceVoxelPlayer, createVoxelPlayerBody, } from "./voxelController.js";
6
6
  const DEFAULT_TURN_SPEED = 2.4;
7
7
  const DEFAULT_WALK_SPEED = 2;
8
+ const DEFAULT_SWIM_SPEED_MULTIPLIER = 0.65;
9
+ /** Minimum ground-normal `y` the player can stand on before slope-slide kicks in — cos(50°) ≈ 0.643. */
10
+ const DEFAULT_MAX_CLIMB_NORMAL_Y = Math.cos((50 * Math.PI) / 180);
11
+ /** Downhill slide speed (units/s) per unit of slope steepness while on too-steep ground. */
12
+ const SLOPE_SLIDE_SPEED = 4;
8
13
  /**
9
14
  * Maps a game's declared `physics` onto the movement controllers' tuning. `PhysicsConfig.gravity` is a signed
10
15
  * world acceleration (negative points down), but the controllers integrate `velocityY -= gravityAcceleration * dt`
@@ -25,10 +30,12 @@ export function resolvePhysicsTuning(physics) {
25
30
  /** Gather a game's collision/movement/physics/world config into a {@link PlayerMovementTuning} — call once per world; both the shell and a host pass the result to {@link stepPlayerMovement}. */
26
31
  export function resolvePlayerMovementTuning(opts) {
27
32
  const physics = resolvePhysicsTuning(opts.physics);
33
+ const backpedal = opts.movement?.backpedalMult;
34
+ const overrides = backpedal === undefined ? physics : { ...(physics ?? {}), backpedalSpeedMultiplier: backpedal };
28
35
  return {
29
36
  ...(opts.collision === undefined ? {} : { collision: opts.collision }),
30
37
  ...(opts.movement === undefined ? {} : { movement: opts.movement }),
31
- ...(physics === undefined ? {} : { physics }),
38
+ ...(overrides === undefined ? {} : { physics: overrides }),
32
39
  ground: groundFieldFor(opts.world),
33
40
  hasTerrain: hasEnvironmentTerrain(opts.world),
34
41
  };
@@ -45,7 +52,7 @@ function storeFor(ctx) {
45
52
  function stateFor(store, userId) {
46
53
  let state = store.players.get(userId);
47
54
  if (state === undefined) {
48
- state = { heading: 0, voxelBody: null, motion: null };
55
+ state = { heading: 0, facing: null, voxelBody: null, motion: null };
49
56
  store.players.set(userId, state);
50
57
  }
51
58
  return state;
@@ -58,6 +65,25 @@ export function playerMovementHeading(ctx, userId) {
58
65
  export function forgetPlayerMovement(ctx, userId) {
59
66
  stores.get(ctx)?.players.delete(userId);
60
67
  }
68
+ /**
69
+ * Rendered body yaw to commit this frame. With `turnSpeed` unset the body snaps
70
+ * to its movement heading exactly as before (no opt-in, no behavior change); with
71
+ * `turnSpeed` set it rotates toward that heading at `turnSpeed` rad/s along the
72
+ * shortest arc, so strafing and backpedalling read as a turning body rather than
73
+ * an instant flip. Retained per player so the smoothing is continuous across frames.
74
+ */
75
+ function resolveBodyFacing(state, moving, velocityX, velocityZ, fallbackYaw, turnSpeed, dt) {
76
+ if (turnSpeed === undefined) {
77
+ const snapped = moving ? Math.atan2(velocityX, velocityZ) : fallbackYaw;
78
+ state.facing = snapped;
79
+ return snapped;
80
+ }
81
+ const from = state.facing ?? fallbackYaw;
82
+ const target = moving ? Math.atan2(velocityX, velocityZ) : from;
83
+ const next = approachYaw(from, target, turnSpeed, dt);
84
+ state.facing = next;
85
+ return next;
86
+ }
61
87
  /**
62
88
  * Integrate one player's movement for a tick from their held-input frame and commit the pose — the single
63
89
  * genre-agnostic controller both the shell (its local player) and a host (each connected player in `onTick`) call,
@@ -80,8 +106,9 @@ export function stepPlayerMovement(ctx, userId, input, dt, tuning, heading) {
80
106
  }
81
107
  else {
82
108
  const turnInput = (isDown("turnRight") ? 1 : 0) - (isDown("turnLeft") ? 1 : 0);
109
+ const turnSpeed = tuning.movement?.turnSpeed ?? DEFAULT_TURN_SPEED;
83
110
  if (turnInput !== 0)
84
- state.heading = steerYaw(state.heading, turnInput, DEFAULT_TURN_SPEED, dt);
111
+ state.heading = steerYaw(state.heading, turnInput, turnSpeed, dt);
85
112
  }
86
113
  const forwardX = Math.sin(state.heading);
87
114
  const forwardZ = Math.cos(state.heading);
@@ -120,7 +147,7 @@ export function stepPlayerMovement(ctx, userId, input, dt, tuning, heading) {
120
147
  body.y = motionBatch.y;
121
148
  ctx.scene.entity.setPose(playerId, {
122
149
  position: [body.x, body.y, body.z],
123
- rotationY: intent.moving ? Math.atan2(body.velocityX, body.velocityZ) : player.rotationY,
150
+ rotationY: resolveBodyFacing(state, intent.moving, body.velocityX, body.velocityZ, player.rotationY, tuning.movement?.turnSpeed, dt),
124
151
  dt,
125
152
  });
126
153
  return;
@@ -132,7 +159,19 @@ export function stepPlayerMovement(ctx, userId, input, dt, tuning, heading) {
132
159
  }
133
160
  motion.verticalVelocity = applyMotionImpulses(motion.verticalVelocity, motionBatch);
134
161
  [motion.horizontalVelocityX, motion.horizontalVelocityZ] = applyHorizontalImpulses(motion.horizontalVelocityX, motion.horizontalVelocityZ, motionBatch);
135
- const step = advancePlayerMotion(motion, intent, forwardX, forwardZ, walkSpeed, dt, tuning.physics);
162
+ const swimCfg = tuning.movement?.swim;
163
+ const swimEnabled = swimCfg === true || (typeof swimCfg === "object" && swimCfg !== null);
164
+ const swimSpeedMultiplier = typeof swimCfg === "object" && swimCfg !== null
165
+ ? swimCfg.speedMultiplier ?? DEFAULT_SWIM_SPEED_MULTIPLIER
166
+ : DEFAULT_SWIM_SPEED_MULTIPLIER;
167
+ const waterLevel = tuning.ground.waterLevel;
168
+ const submerged = swimEnabled &&
169
+ waterLevel !== undefined &&
170
+ tuning.ground.sampleHeight(player.position[0], player.position[2]) < waterLevel;
171
+ const motionOptions = submerged
172
+ ? { speedScale: swimSpeedMultiplier, floating: true }
173
+ : undefined;
174
+ const step = advancePlayerMotion(motion, intent, forwardX, forwardZ, walkSpeed, dt, tuning.physics, motionOptions);
136
175
  let stepX = step.stepX;
137
176
  let stepZ = step.stepZ;
138
177
  if (tuning.movement?.mode === "axis") {
@@ -153,10 +192,26 @@ export function stepPlayerMovement(ctx, userId, input, dt, tuning, heading) {
153
192
  nextX = snapped[0];
154
193
  nextZ = snapped[1];
155
194
  }
156
- let nextY = tuning.ground.sampleHeight(nextX, nextZ) + motion.jumpOffset;
195
+ const slideCfg = tuning.movement?.slopeSlide;
196
+ if (slideCfg === true || (typeof slideCfg === "object" && slideCfg !== null)) {
197
+ const maxClimbNormalY = typeof slideCfg === "object" && slideCfg.maxClimbSlope !== undefined
198
+ ? slideCfg.maxClimbSlope
199
+ : DEFAULT_MAX_CLIMB_NORMAL_Y;
200
+ if (tuning.ground.sampleNormal(nextX, nextZ)[1] < maxClimbNormalY) {
201
+ const slope = sampleSlope(tuning.ground, nextX, nextZ);
202
+ const slide = SLOPE_SLIDE_SPEED * slope.steepness * dt;
203
+ nextX += slope.downhill[0] * slide;
204
+ nextZ += slope.downhill[1] * slide;
205
+ }
206
+ }
207
+ const groundAtNext = tuning.ground.sampleHeight(nextX, nextZ);
208
+ let nextY = groundAtNext + motion.jumpOffset;
157
209
  if (motionBatch !== null && motionBatch.y !== null) {
158
210
  nextY = motionBatch.y;
159
- motion.jumpOffset = motionBatch.y - tuning.ground.sampleHeight(nextX, nextZ);
211
+ motion.jumpOffset = motionBatch.y - groundAtNext;
212
+ }
213
+ else if (swimEnabled && waterLevel !== undefined && groundAtNext < waterLevel) {
214
+ nextY = waterLevel;
160
215
  }
161
216
  if (tuning.movement?.beforeCommit !== undefined) {
162
217
  const frame = {
@@ -175,7 +230,7 @@ export function stepPlayerMovement(ctx, userId, input, dt, tuning, heading) {
175
230
  }
176
231
  ctx.scene.entity.setPose(playerId, {
177
232
  position: [nextX, nextY, nextZ],
178
- rotationY: intent.moving ? Math.atan2(motion.horizontalVelocityX, motion.horizontalVelocityZ) : player.rotationY,
233
+ rotationY: resolveBodyFacing(state, intent.moving, motion.horizontalVelocityX, motion.horizontalVelocityZ, player.rotationY, tuning.movement?.turnSpeed, dt),
179
234
  dt,
180
235
  });
181
236
  }
@@ -13,11 +13,24 @@ export interface PoseAllowedStates {
13
13
  export interface PoseRejection {
14
14
  reason: string;
15
15
  }
16
+ export interface PoseSnapshot {
17
+ poses: Record<string, MovementPose>;
18
+ aims: Record<string, AimMode>;
19
+ }
16
20
  export interface PoseState {
17
21
  getPose(instanceId: string): MovementPose;
18
22
  setPose(instanceId: string, pose: MovementPose): PoseRejection | null;
19
23
  getAim(instanceId: string): AimMode;
20
24
  setAim(instanceId: string, mode: AimMode): PoseRejection | null;
21
25
  clear(instanceId: string): void;
26
+ /** Snapshot every entity's pose and aim for a whole-world save. */
27
+ snapshotAll(): PoseSnapshot;
28
+ /** Restore every entity's pose and aim from a {@link snapshotAll} payload. */
29
+ hydrateAll(state: PoseSnapshot): void;
22
30
  }
31
+ /**
32
+ * Stance/pose transitions — stand, crouch, prone — that change the hitbox and movement.
33
+ *
34
+ * @capability crouch-prone stance/pose transitions that change the hitbox
35
+ */
23
36
  export declare function createPoseState(resolveAllowed: (instanceId: string) => PoseAllowedStates | null | undefined): PoseState;