@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,179 @@
1
+ /**
2
+ * Scene ownership boundary — gives every editor-visible object an explicit
3
+ * provenance and a single verdict (expose / bake / reject) so the editor never
4
+ * presents unauthored content as broken authored content.
5
+ *
6
+ * The product invariant is "author world content in the editor": the scene
7
+ * document is the source of truth. Runtime code, procedural generators, and
8
+ * simulation still put objects in front of the player that the document never
9
+ * described. This module classifies each such object by where it comes from and
10
+ * decides whether the editor may author it, may offer to bake it into the
11
+ * document, or must reject it as read-only runtime content — with a diagnostic
12
+ * that explains the decision. Genuinely runtime-only content is then declared
13
+ * with a reason rather than silently tolerated or exempted by game name.
14
+ *
15
+ * Everything here is plain serializable data and pure functions, so a
16
+ * {@link SceneOwnershipManifest} round-trips through JSON and the verdict for an
17
+ * object is deterministic given its declaration.
18
+ */
19
+ /** Current {@link SceneOwnershipManifest} schema version. */
20
+ export const SCENE_OWNERSHIP_MANIFEST_VERSION = 1;
21
+ /**
22
+ * Resolve one declaration into a single boundary verdict.
23
+ *
24
+ * - `authored` and `generated` provenance -> **expose** (generated objects are
25
+ * read-only; edit their source document object).
26
+ * - `runtime`/`transient` with a `bake` capability -> **bake** (offer import).
27
+ * - `runtime`/`transient` without `bake` -> **reject** (read-only); a missing
28
+ * `reason` marks it a boundary violation — content bypassing the document with
29
+ * no authored home, no way to bake, and no declared justification.
30
+ *
31
+ * @capability scene-ownership classify an editor-visible object as expose/bake/reject with a diagnostic
32
+ */
33
+ export function classifyOwnership(declaration) {
34
+ const { provenance, capabilities, reason } = declaration;
35
+ const kind = provenance.kind;
36
+ if (kind === "authored") {
37
+ return {
38
+ decision: "expose",
39
+ provenance: kind,
40
+ readOnly: false,
41
+ bakeable: false,
42
+ reason: `authored document object "${provenance.documentId}"`,
43
+ };
44
+ }
45
+ if (kind === "generated") {
46
+ return {
47
+ decision: "expose",
48
+ provenance: kind,
49
+ readOnly: true,
50
+ bakeable: false,
51
+ reason: `generated from authored object "${provenance.sourceDocumentId}"; edit the source`,
52
+ };
53
+ }
54
+ const canBake = capabilities?.bake === true;
55
+ if (canBake) {
56
+ return {
57
+ decision: "bake",
58
+ provenance: kind,
59
+ readOnly: true,
60
+ bakeable: true,
61
+ reason: reason ?? `runtime provider "${provenance.providerId}" can bake this into the document`,
62
+ };
63
+ }
64
+ const hasReason = reason !== undefined && reason.trim() !== "";
65
+ const violation = hasReason
66
+ ? undefined
67
+ : `${kind} object "${provenance.instanceId}" from provider "${provenance.providerId}" has no authored ` +
68
+ `document entry, no bake capability, and no declared reason — it bypasses the scene-ownership boundary`;
69
+ return {
70
+ decision: "reject",
71
+ provenance: kind,
72
+ readOnly: true,
73
+ bakeable: false,
74
+ reason: hasReason ? reason : `runtime-only content owned by provider "${provenance.providerId}"`,
75
+ violation,
76
+ };
77
+ }
78
+ /** Stable id string for a provenance — used to key diagnostics deterministically. */
79
+ function provenanceKey(provenance) {
80
+ switch (provenance.kind) {
81
+ case "authored":
82
+ return `authored:${provenance.documentId}`;
83
+ case "generated":
84
+ return `generated:${provenance.sourceDocumentId}/${provenance.instanceId}`;
85
+ default:
86
+ return `${provenance.kind}:${provenance.providerId}/${provenance.instanceId}`;
87
+ }
88
+ }
89
+ /**
90
+ * Stable identity string for a provenance (e.g. `runtime:town/building-3`), suitable
91
+ * for keying an object in an editor tree or a diagnostics table.
92
+ *
93
+ * @capability scene-ownership derive a stable object key from its provenance
94
+ */
95
+ export function ownershipKey(provenance) {
96
+ return provenanceKey(provenance);
97
+ }
98
+ /**
99
+ * Audit a keyed set of declarations and return one diagnostic per object that
100
+ * breaks the boundary contract (a `reject` verdict carrying a `violation`).
101
+ * Deterministic: diagnostics come back in the iteration order of `entries`.
102
+ *
103
+ * @capability scene-ownership audit editor-visible objects and report boundary violations
104
+ */
105
+ export function collectOwnershipDiagnostics(entries) {
106
+ const out = [];
107
+ for (const [key, declaration] of entries) {
108
+ const verdict = classifyOwnership(declaration);
109
+ if (verdict.violation !== undefined) {
110
+ out.push({
111
+ key,
112
+ provenance: verdict.provenance,
113
+ decision: verdict.decision,
114
+ message: `${key}: ${verdict.violation}`,
115
+ });
116
+ }
117
+ }
118
+ return out;
119
+ }
120
+ /**
121
+ * Audit every declaration in a manifest, keying diagnostics by each object's
122
+ * provenance id. An empty result means the manifest declares all of its content
123
+ * cleanly — every object is authored, generated, bakeable, or a reasoned
124
+ * runtime/transient object.
125
+ *
126
+ * @capability scene-ownership audit a whole ownership manifest for boundary violations
127
+ */
128
+ export function auditManifest(manifest) {
129
+ return collectOwnershipDiagnostics(manifest.declarations.map((declaration) => [provenanceKey(declaration.provenance), declaration]));
130
+ }
131
+ function isProvenance(value) {
132
+ if (typeof value !== "object" || value === null)
133
+ return false;
134
+ const record = value;
135
+ switch (record.kind) {
136
+ case "authored":
137
+ return typeof record.documentId === "string";
138
+ case "generated":
139
+ return typeof record.sourceDocumentId === "string" && typeof record.instanceId === "string";
140
+ case "runtime":
141
+ case "transient":
142
+ return typeof record.providerId === "string" && typeof record.instanceId === "string";
143
+ default:
144
+ return false;
145
+ }
146
+ }
147
+ function isDeclaration(value) {
148
+ if (typeof value !== "object" || value === null)
149
+ return false;
150
+ const record = value;
151
+ if (!isProvenance(record.provenance))
152
+ return false;
153
+ if (record.reason !== undefined && typeof record.reason !== "string")
154
+ return false;
155
+ if (record.capabilities !== undefined && (typeof record.capabilities !== "object" || record.capabilities === null)) {
156
+ return false;
157
+ }
158
+ return true;
159
+ }
160
+ /**
161
+ * Narrow unknown parsed JSON to a {@link SceneOwnershipManifest}. Structural only —
162
+ * verifies the version, the declarations array, and each declaration's provenance
163
+ * shape; it does not judge whether declarations satisfy the boundary (use
164
+ * {@link auditManifest} for that).
165
+ *
166
+ * @capability scene-ownership validate a serialized ownership manifest loaded from disk
167
+ */
168
+ export function isSceneOwnershipManifest(value) {
169
+ if (typeof value !== "object" || value === null)
170
+ return false;
171
+ const record = value;
172
+ if (record.version !== SCENE_OWNERSHIP_MANIFEST_VERSION)
173
+ return false;
174
+ if (record.provider !== undefined && typeof record.provider !== "string")
175
+ return false;
176
+ if (!Array.isArray(record.declarations))
177
+ return false;
178
+ return record.declarations.every(isDeclaration);
179
+ }
@@ -0,0 +1,93 @@
1
+ import type { SelectionSet } from "./selection.js";
2
+ /**
3
+ * The serializable shape of a {@link SelectionBookmarks} store: each key maps to
4
+ * its ordered, deduplicated id list. Plain data — safe to persist in a save file
5
+ * or replicate over the wire, and the exact input {@link createSelectionBookmarks}
6
+ * restores.
7
+ */
8
+ export interface SelectionBookmarkSnapshot {
9
+ bookmarks: Record<string, readonly string[]>;
10
+ }
11
+ /** Outcome of a {@link SelectionBookmarks.prune} pass — what the validity predicate removed. */
12
+ export interface SelectionPruneResult {
13
+ /** Ids dropped from at least one bookmark because the predicate rejected them. */
14
+ removedIds: string[];
15
+ /** Bookmark keys deleted because pruning emptied them. */
16
+ clearedKeys: string[];
17
+ }
18
+ /**
19
+ * A generic, keyed store of saved id sets ("bookmarks") over stable string ids —
20
+ * the reusable layer under RTS control groups, camera bookmarks, saved squads,
21
+ * editor selection presets, and accessibility recall. It owns storage only:
22
+ * binding, recall, enumeration, pruning, and serialization. It never touches the
23
+ * active {@link SelectionSet} or the camera — replacement/merge and focus stay
24
+ * caller hooks (see {@link recallSelectionBookmark}) so one store serves any
25
+ * genre, input scheme, or focus policy.
26
+ *
27
+ * Keys are opaque strings, so numbered control groups (`"1"`…`"9"`), named
28
+ * bookmarks (`"home"`, `"base"`), or per-owner namespaces all coexist. Each
29
+ * bookmark preserves insertion order and dedupes, matching {@link SelectionSet}.
30
+ */
31
+ export interface SelectionBookmarks {
32
+ /** Replace the set under `key` with `ids` (ordered, deduped). Binding an empty set removes the key, so `has(key)` is then false and it drops out of {@link serialize}. */
33
+ bind(key: string, ids: Iterable<string>): void;
34
+ /** Add `ids` to the set under `key` (creating it if absent), skipping ones already present so order is stable. */
35
+ append(key: string, ids: Iterable<string>): void;
36
+ /** Remove `ids` from the set under `key`; if that empties the set, the key is deleted. No-op when the key is absent. */
37
+ remove(key: string, ids: Iterable<string>): void;
38
+ /** The ordered ids saved under `key`, or an empty array when the key is absent. The returned array is a fresh copy — mutating it never touches the store. */
39
+ recall(key: string): string[];
40
+ /** True when `key` holds a non-empty set. */
41
+ has(key: string): boolean;
42
+ /** Delete `key`; returns true when a set was removed. */
43
+ clear(key: string): boolean;
44
+ /** Delete every bookmark. */
45
+ clearAll(): void;
46
+ /** All bookmark keys in insertion order. */
47
+ keys(): string[];
48
+ /** Count of ids saved under `key`, or 0 when absent. */
49
+ size(key: string): number;
50
+ /**
51
+ * Drop every id the `isValid` predicate rejects from all bookmarks — the seam
52
+ * for destroyed entities, cross-scene ids, and ownership changes: the caller
53
+ * supplies validity, the store applies it. Bookmarks emptied by pruning are
54
+ * removed. Returns what was removed so callers can surface it.
55
+ */
56
+ prune(isValid: (id: string) => boolean): SelectionPruneResult;
57
+ /** A plain-data copy of every bookmark — the exact input {@link createSelectionBookmarks} restores. */
58
+ serialize(): SelectionBookmarkSnapshot;
59
+ }
60
+ /**
61
+ * Create a keyed bookmark store, optionally restored from a {@link serialize}
62
+ * snapshot. Restoration re-dedupes and drops empty sets, so a hand-authored or
63
+ * migrated snapshot always normalizes to the same invariants a live store holds.
64
+ *
65
+ * @capability selection-bookmarks keyed saved-set store (RTS control groups, camera bookmarks, saved squads) with prune + serialize
66
+ */
67
+ export declare function createSelectionBookmarks(snapshot?: SelectionBookmarkSnapshot): SelectionBookmarks;
68
+ /** How a recalled bookmark folds into the active selection. */
69
+ export type BookmarkRecallMode = "replace" | "merge";
70
+ /** Caller hooks for {@link recallSelectionBookmark} — kept out of the store so focus and validity stay genre-owned. */
71
+ export interface RecallBookmarkOptions {
72
+ /** `"replace"` (default) swaps the active selection for the bookmark; `"merge"` unions it in. */
73
+ mode?: BookmarkRecallMode;
74
+ /**
75
+ * Validity predicate applied to the bookmark before it reaches the selection —
76
+ * stale ids (destroyed entities, wrong scene, lost ownership) are pruned from
77
+ * the stored bookmark in place, so recall self-heals. Omit to recall verbatim.
78
+ */
79
+ isValid?: (id: string) => boolean;
80
+ /** Focus hook fired with the surviving ids (e.g. center/follow the camera). Never called when recall yields nothing. */
81
+ onFocus?: (ids: readonly string[]) => void;
82
+ }
83
+ /**
84
+ * Compose a bookmark recall onto an active {@link SelectionSet}: optionally prune
85
+ * stale ids (updating the stored bookmark), fold the survivors into the selection
86
+ * by `mode`, then fire the caller's focus hook. This is the one place the store,
87
+ * the selection, and the camera meet — kept as an explicit helper, not a store
88
+ * side effect, so games opt into the exact replacement/merge and focus policy
89
+ * they want. Returns the surviving ids that were applied.
90
+ *
91
+ * @capability selection-bookmark-recall fold a saved set into the active selection with stale-ref pruning and a caller focus hook
92
+ */
93
+ export declare function recallSelectionBookmark(bookmarks: SelectionBookmarks, key: string, selection: SelectionSet, options?: RecallBookmarkOptions): string[];
@@ -0,0 +1,122 @@
1
+ function dedupe(ids) {
2
+ const out = [];
3
+ const seen = new Set();
4
+ for (const id of ids) {
5
+ if (seen.has(id))
6
+ continue;
7
+ seen.add(id);
8
+ out.push(id);
9
+ }
10
+ return out;
11
+ }
12
+ /**
13
+ * Create a keyed bookmark store, optionally restored from a {@link serialize}
14
+ * snapshot. Restoration re-dedupes and drops empty sets, so a hand-authored or
15
+ * migrated snapshot always normalizes to the same invariants a live store holds.
16
+ *
17
+ * @capability selection-bookmarks keyed saved-set store (RTS control groups, camera bookmarks, saved squads) with prune + serialize
18
+ */
19
+ export function createSelectionBookmarks(snapshot) {
20
+ const groups = new Map();
21
+ if (snapshot !== undefined) {
22
+ for (const [key, ids] of Object.entries(snapshot.bookmarks)) {
23
+ const list = dedupe(ids);
24
+ if (list.length > 0)
25
+ groups.set(key, list);
26
+ }
27
+ }
28
+ return {
29
+ bind(key, ids) {
30
+ const list = dedupe(ids);
31
+ if (list.length === 0)
32
+ groups.delete(key);
33
+ else
34
+ groups.set(key, list);
35
+ },
36
+ append(key, ids) {
37
+ const existing = groups.get(key);
38
+ if (existing === undefined) {
39
+ const list = dedupe(ids);
40
+ if (list.length > 0)
41
+ groups.set(key, list);
42
+ return;
43
+ }
44
+ const seen = new Set(existing);
45
+ for (const id of ids) {
46
+ if (seen.has(id))
47
+ continue;
48
+ seen.add(id);
49
+ existing.push(id);
50
+ }
51
+ },
52
+ remove(key, ids) {
53
+ const existing = groups.get(key);
54
+ if (existing === undefined)
55
+ return;
56
+ const drop = new Set(ids);
57
+ const next = existing.filter((id) => !drop.has(id));
58
+ if (next.length === 0)
59
+ groups.delete(key);
60
+ else
61
+ groups.set(key, next);
62
+ },
63
+ recall(key) {
64
+ const existing = groups.get(key);
65
+ return existing === undefined ? [] : [...existing];
66
+ },
67
+ has: (key) => (groups.get(key)?.length ?? 0) > 0,
68
+ clear: (key) => groups.delete(key),
69
+ clearAll: () => groups.clear(),
70
+ keys: () => [...groups.keys()],
71
+ size: (key) => groups.get(key)?.length ?? 0,
72
+ prune(isValid) {
73
+ const removedIds = new Set();
74
+ const clearedKeys = [];
75
+ for (const [key, list] of [...groups]) {
76
+ const next = list.filter((id) => {
77
+ const keep = isValid(id);
78
+ if (!keep)
79
+ removedIds.add(id);
80
+ return keep;
81
+ });
82
+ if (next.length === list.length)
83
+ continue;
84
+ if (next.length === 0) {
85
+ groups.delete(key);
86
+ clearedKeys.push(key);
87
+ }
88
+ else {
89
+ groups.set(key, next);
90
+ }
91
+ }
92
+ return { removedIds: [...removedIds], clearedKeys };
93
+ },
94
+ serialize: () => ({
95
+ bookmarks: Object.fromEntries([...groups].map(([key, list]) => [key, [...list]])),
96
+ }),
97
+ };
98
+ }
99
+ /**
100
+ * Compose a bookmark recall onto an active {@link SelectionSet}: optionally prune
101
+ * stale ids (updating the stored bookmark), fold the survivors into the selection
102
+ * by `mode`, then fire the caller's focus hook. This is the one place the store,
103
+ * the selection, and the camera meet — kept as an explicit helper, not a store
104
+ * side effect, so games opt into the exact replacement/merge and focus policy
105
+ * they want. Returns the surviving ids that were applied.
106
+ *
107
+ * @capability selection-bookmark-recall fold a saved set into the active selection with stale-ref pruning and a caller focus hook
108
+ */
109
+ export function recallSelectionBookmark(bookmarks, key, selection, options = {}) {
110
+ const { mode = "replace", isValid, onFocus } = options;
111
+ if (isValid !== undefined)
112
+ bookmarks.prune(isValid);
113
+ const ids = bookmarks.recall(key);
114
+ if (mode === "replace")
115
+ selection.replace(ids);
116
+ else
117
+ for (const id of ids)
118
+ selection.add(id);
119
+ if (ids.length > 0)
120
+ onFocus?.(ids);
121
+ return ids;
122
+ }
@@ -0,0 +1,68 @@
1
+ import { MountController, type MountSeat, type RideableConfig } from "./mount.js";
2
+ /** World-space `[x, y, z]` for a vehicle's current position. */
3
+ export type VehiclePosition = readonly [number, number, number];
4
+ /** A vehicle's world-space position and heading, used for {@link VehicleSeats.exit}'s dismount placement math. */
5
+ export interface VehiclePose {
6
+ position: VehiclePosition;
7
+ rotationY: number;
8
+ }
9
+ /** Options for {@link VehicleSeats.enter}. */
10
+ export interface EnterVehicleOptions {
11
+ /** Specific seat to board; omit to take the first free control seat, else the first free seat. */
12
+ seatId?: string;
13
+ }
14
+ /** Movement-lock patch for `entities.update(riderId, { movement: { ...current, ...patch } })` (#286.gameplay `movement.frozen`). */
15
+ export interface RiderMovementPatch {
16
+ frozen: boolean;
17
+ }
18
+ /** Result of {@link VehicleSeats.enter} — the resolved seat plus the camera/drive/movement patches to apply. */
19
+ export type EnterVehicleResult = {
20
+ ok: true;
21
+ seat: MountSeat;
22
+ /** Feed straight into `ctx.camera.follow(...)` — the vehicle while a control seat is taken, else the rider's own id. */
23
+ cameraTarget: string;
24
+ /** Entity this rider's axis input should now drive (`scene/mount`'s `driveTarget`); `null` for a passenger seat. */
25
+ driveTarget: string | null;
26
+ riderMovementPatch: RiderMovementPatch;
27
+ } | {
28
+ ok: false;
29
+ reason: string;
30
+ };
31
+ /** Result of {@link VehicleSeats.exit} — the side-door placement plus the camera/movement patches to apply. */
32
+ export type ExitVehicleResult = {
33
+ ok: true;
34
+ vehicleId: string;
35
+ /** Where to `setPose` the rider — alongside the vehicle's side door, facing its heading. */
36
+ placement: VehiclePose;
37
+ cameraTarget: string;
38
+ riderMovementPatch: RiderMovementPatch;
39
+ } | {
40
+ ok: false;
41
+ reason: "not_seated";
42
+ };
43
+ /** Where {@link VehicleSeats.exit} steps the rider out, relative to the vehicle's heading. */
44
+ export interface DismountOffset {
45
+ /** Lateral distance from the vehicle's centerline; default 2.2. */
46
+ distance?: number;
47
+ /** Which side of the vehicle to step out on, relative to its heading; default `"right"`. */
48
+ side?: "left" | "right";
49
+ }
50
+ /**
51
+ * Composes `scene/mount`'s control-transfer bookkeeping with the seat/camera/movement-mode transition
52
+ * every enter/exit-vehicle flow needs (#533.2): boarding resolves a free seat and reports the camera
53
+ * target, drive target, and rider movement-lock patch in one call; leaving computes a side-door
54
+ * placement next to the vehicle and reports the same triad in reverse. Pure — no entity/camera side
55
+ * effects — the caller applies `riderMovementPatch`/`placement`/`cameraTarget` via its own `ctx`.
56
+ */
57
+ export declare class VehicleSeats {
58
+ private readonly controller;
59
+ constructor(controller?: MountController);
60
+ register(config: RideableConfig): void;
61
+ enter(riderId: string, vehicleId: string, options?: EnterVehicleOptions): EnterVehicleResult;
62
+ exit(riderId: string, vehiclePose: VehiclePose, offset?: DismountOffset): ExitVehicleResult;
63
+ isSeated(riderId: string): boolean;
64
+ driverOf(vehicleId: string): string | null;
65
+ get mounts(): MountController;
66
+ }
67
+ /** Builds a {@link VehicleSeats}, optionally over an existing `MountController` to share its occupancy. */
68
+ export declare function createVehicleSeats(controller?: MountController): VehicleSeats;
@@ -0,0 +1,59 @@
1
+ import { createMountController, MountController } from "./mount.js";
2
+ /**
3
+ * Composes `scene/mount`'s control-transfer bookkeeping with the seat/camera/movement-mode transition
4
+ * every enter/exit-vehicle flow needs (#533.2): boarding resolves a free seat and reports the camera
5
+ * target, drive target, and rider movement-lock patch in one call; leaving computes a side-door
6
+ * placement next to the vehicle and reports the same triad in reverse. Pure — no entity/camera side
7
+ * effects — the caller applies `riderMovementPatch`/`placement`/`cameraTarget` via its own `ctx`.
8
+ */
9
+ export class VehicleSeats {
10
+ controller;
11
+ constructor(controller) {
12
+ this.controller = controller ?? createMountController();
13
+ }
14
+ register(config) {
15
+ this.controller.register(config);
16
+ }
17
+ enter(riderId, vehicleId, options = {}) {
18
+ const result = this.controller.mount(riderId, vehicleId, options.seatId);
19
+ if (!result.ok)
20
+ return { ok: false, reason: result.reason };
21
+ return {
22
+ ok: true,
23
+ seat: result.seat,
24
+ cameraTarget: this.controller.cameraTarget(riderId),
25
+ driveTarget: this.controller.driveTarget(riderId),
26
+ riderMovementPatch: { frozen: true },
27
+ };
28
+ }
29
+ exit(riderId, vehiclePose, offset = {}) {
30
+ const vehicleId = this.controller.dismount(riderId);
31
+ if (vehicleId === null)
32
+ return { ok: false, reason: "not_seated" };
33
+ const distance = offset.distance ?? 2.2;
34
+ const sign = offset.side === "left" ? -1 : 1;
35
+ const side = vehiclePose.rotationY + (Math.PI / 2) * sign;
36
+ const x = vehiclePose.position[0] + Math.sin(side) * distance;
37
+ const z = vehiclePose.position[2] + Math.cos(side) * distance;
38
+ return {
39
+ ok: true,
40
+ vehicleId,
41
+ placement: { position: [x, vehiclePose.position[1], z], rotationY: vehiclePose.rotationY },
42
+ cameraTarget: riderId,
43
+ riderMovementPatch: { frozen: false },
44
+ };
45
+ }
46
+ isSeated(riderId) {
47
+ return this.controller.isSeated(riderId);
48
+ }
49
+ driverOf(vehicleId) {
50
+ return this.controller.driver(vehicleId);
51
+ }
52
+ get mounts() {
53
+ return this.controller;
54
+ }
55
+ }
56
+ /** Builds a {@link VehicleSeats}, optionally over an existing `MountController` to share its occupancy. */
57
+ export function createVehicleSeats(controller) {
58
+ return new VehicleSeats(controller);
59
+ }
@@ -1,5 +1,7 @@
1
1
  export type ColorHex = string;
2
+ /** @internal */
2
3
  export declare function colorDistance(a: ColorHex, b: ColorHex): number;
4
+ /** @internal */
3
5
  export declare function concealmentScore(entityColors: readonly ColorHex[], backgroundColors: readonly ColorHex[]): number;
4
6
  export interface ConcealmentTarget {
5
7
  id: string;
@@ -16,6 +18,7 @@ export interface ConcealmentSensor {
16
18
  tick(targets: readonly ConcealmentTarget[], dt: number): ConcealmentSample[];
17
19
  reset(id?: string): void;
18
20
  }
21
+ /** @internal */
19
22
  export declare function createConcealmentSensor(config?: {
20
23
  threshold?: number;
21
24
  }): ConcealmentSensor;
@@ -13,10 +13,12 @@ function redmean(a, b) {
13
13
  return Math.sqrt((2 + rmean / 256) * dr * dr + 4 * dg * dg + (2 + (255 - rmean) / 256) * db * db);
14
14
  }
15
15
  const REDMEAN_MAX = redmean([0, 0, 0], [255, 255, 255]);
16
+ /** @internal */
16
17
  export function colorDistance(a, b) {
17
18
  const distance = redmean(parseHex(a), parseHex(b));
18
19
  return REDMEAN_MAX === 0 ? 0 : Math.min(1, distance / REDMEAN_MAX);
19
20
  }
21
+ /** @internal */
20
22
  export function concealmentScore(entityColors, backgroundColors) {
21
23
  if (entityColors.length === 0 || backgroundColors.length === 0)
22
24
  return 0;
@@ -32,6 +34,7 @@ export function concealmentScore(entityColors, backgroundColors) {
32
34
  }
33
35
  return 1 - total / entityColors.length;
34
36
  }
37
+ /** @internal */
35
38
  export function createConcealmentSensor(config) {
36
39
  const threshold = config?.threshold ?? 0.7;
37
40
  const dwell = new Map();
@@ -11,6 +11,7 @@ export interface FreezeMonitor {
11
11
  tick(subjects: readonly FreezeSubject[], frozenIds: ReadonlySet<string>, dt: number): FreezeViolation[];
12
12
  reset(id?: string): void;
13
13
  }
14
+ /** @internal */
14
15
  export declare function createFreezeMonitor(config?: {
15
16
  toleranceSpeed?: number;
16
17
  graceSeconds?: number;
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function createFreezeMonitor(config) {
2
3
  const toleranceSpeed = config?.toleranceSpeed ?? 0.05;
3
4
  const graceSeconds = config?.graceSeconds ?? 0;
@@ -26,7 +26,8 @@ export interface FrustumProjection {
26
26
  * Project a world point into the camera's view. Pure geometry — no three.js —
27
27
  * so a game can run "is this framed?" checks headlessly (photo-mode scoring,
28
28
  * server-side kill-cam validation) as well as from the live render camera.
29
- */
29
+ * @internal
30
+ */
30
31
  export declare function projectToView(camera: FrustumCamera, point: EntityPosition): FrustumProjection;
31
32
  export interface FramingConfig {
32
33
  /** World-unit distance from camera that reads as "ideally framed" size. Default 6. */
@@ -36,7 +37,9 @@ export interface FramingConfig {
36
37
  /** Weight of subject size (distance-to-ideal) in the framing score. Default 0.4. */
37
38
  sizeWeight?: number;
38
39
  }
39
- /** 0 (not framed) .. 1 (dead-center, ideal distance) framing quality for an in-view projection. */
40
+ /** 0 (not framed) .. 1 (dead-center, ideal distance) framing quality for an in-view projection.
41
+ * @internal
42
+ */
40
43
  export declare function framingScore(projection: FrustumProjection, config?: FramingConfig): number;
41
44
  export interface FrustumSample {
42
45
  id: string;
@@ -56,5 +59,6 @@ export interface FrustumSensor {
56
59
  * A view-frustum sensor on a held camera object: which entities are in frame,
57
60
  * how well framed they are, and how long they've stayed on-screen (photo-mode
58
61
  * "is this subject framed", Content Warning-style monster-filming scoring).
59
- */
62
+ * @internal
63
+ */
60
64
  export declare function createFrustumSensor(config?: FramingConfig): FrustumSensor;
@@ -19,7 +19,8 @@ const WORLD_UP = [0, 1, 0];
19
19
  * Project a world point into the camera's view. Pure geometry — no three.js —
20
20
  * so a game can run "is this framed?" checks headlessly (photo-mode scoring,
21
21
  * server-side kill-cam validation) as well as from the live render camera.
22
- */
22
+ * @internal
23
+ */
23
24
  export function projectToView(camera, point) {
24
25
  const forward = normalize(subtract(camera.lookAt, camera.position));
25
26
  const relative = subtract(point, camera.position);
@@ -47,7 +48,9 @@ export function projectToView(camera, point) {
47
48
  const inView = Math.abs(screenX) <= 1 && Math.abs(screenY) <= 1;
48
49
  return { inView, distance, screenX, screenY };
49
50
  }
50
- /** 0 (not framed) .. 1 (dead-center, ideal distance) framing quality for an in-view projection. */
51
+ /** 0 (not framed) .. 1 (dead-center, ideal distance) framing quality for an in-view projection.
52
+ * @internal
53
+ */
51
54
  export function framingScore(projection, config) {
52
55
  if (!projection.inView)
53
56
  return 0;
@@ -65,7 +68,8 @@ export function framingScore(projection, config) {
65
68
  * A view-frustum sensor on a held camera object: which entities are in frame,
66
69
  * how well framed they are, and how long they've stayed on-screen (photo-mode
67
70
  * "is this subject framed", Content Warning-style monster-filming scoring).
68
- */
71
+ * @internal
72
+ */
69
73
  export function createFrustumSensor(config) {
70
74
  const dwell = new Map();
71
75
  return {
@@ -25,7 +25,10 @@ export interface SensorReading {
25
25
  * `proximityPrompt` (a UI affordance), this reads world state the player has no
26
26
  * other way to see — the strongest in-range reading wins, mirroring how a real
27
27
  * handheld sensor needle settles on the loudest nearby source.
28
- */
28
+ * @internal
29
+ */
29
30
  export declare function probeHiddenState(origin: EntityPosition, sources: readonly HiddenStateSource[], options: SensorProbeOptions): SensorReading | null;
30
- /** All in-range readings for `variableId`, strongest first. */
31
+ /** All in-range readings for `variableId`, strongest first.
32
+ * @internal
33
+ */
31
34
  export declare function probeHiddenStateAll(origin: EntityPosition, sources: readonly HiddenStateSource[], options: SensorProbeOptions): SensorReading[];
@@ -12,12 +12,15 @@ function strengthAt(distance, range, falloff) {
12
12
  * `proximityPrompt` (a UI affordance), this reads world state the player has no
13
13
  * other way to see — the strongest in-range reading wins, mirroring how a real
14
14
  * handheld sensor needle settles on the loudest nearby source.
15
- */
15
+ * @internal
16
+ */
16
17
  export function probeHiddenState(origin, sources, options) {
17
18
  const readings = probeHiddenStateAll(origin, sources, options);
18
19
  return readings.length === 0 ? null : readings[0];
19
20
  }
20
- /** All in-range readings for `variableId`, strongest first. */
21
+ /** All in-range readings for `variableId`, strongest first.
22
+ * @internal
23
+ */
21
24
  export function probeHiddenStateAll(origin, sources, options) {
22
25
  const { range, variableId, falloff = "linear" } = options;
23
26
  const readings = [];