@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
@@ -6,12 +6,15 @@ export const MAX_SCAN_TARGETS = 512;
6
6
  const COLOR_PATTERN = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
7
7
  const UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
8
8
  const DEFAULT_AXIS = ["x", "y", "z", "w"];
9
+ /** @internal */
9
10
  export function isFiniteNumber(value) {
10
11
  return typeof value === "number" && Number.isFinite(value);
11
12
  }
13
+ /** @internal */
12
14
  export function escapePathSegment(segment) {
13
15
  return segment.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
14
16
  }
17
+ /** @internal */
15
18
  export function unescapePathSegment(segment) {
16
19
  let out = "";
17
20
  for (let i = 0; i < segment.length; i += 1) {
@@ -25,10 +28,12 @@ export function unescapePathSegment(segment) {
25
28
  }
26
29
  return out;
27
30
  }
31
+ /** @internal */
28
32
  export function joinTunablePath(parent, segment) {
29
33
  const escaped = escapePathSegment(segment);
30
34
  return parent === "" ? escaped : `${parent}.${escaped}`;
31
35
  }
36
+ /** @internal */
32
37
  export function splitTunablePath(path) {
33
38
  const parts = [];
34
39
  let current = "";
@@ -49,6 +54,7 @@ export function splitTunablePath(path) {
49
54
  parts.push(unescapePathSegment(current));
50
55
  return parts;
51
56
  }
57
+ /** @internal */
52
58
  export function parseColor(input) {
53
59
  if (typeof input !== "string" || !COLOR_PATTERN.test(input))
54
60
  return null;
@@ -81,6 +87,7 @@ export function parseColor(input) {
81
87
  const hex = `${rgb}${a.toLowerCase()}`;
82
88
  return { hex, rgb, alpha, hasAlpha: true };
83
89
  }
90
+ /** @internal */
84
91
  export function formatColor(rgb, alpha, withAlpha) {
85
92
  const parsed = parseColor(rgb);
86
93
  const rgbHex = parsed?.rgb ?? (/^#[0-9a-fA-F]{6}$/.test(rgb) ? rgb.toLowerCase() : null);
@@ -94,6 +101,7 @@ export function formatColor(rgb, alpha, withAlpha) {
94
101
  .padStart(2, "0");
95
102
  return `${rgbHex}${a}`;
96
103
  }
104
+ /** @internal */
97
105
  export function normalizeColorValue(input, forceAlpha) {
98
106
  const parsed = parseColor(input);
99
107
  if (parsed === null)
@@ -103,9 +111,11 @@ export function normalizeColorValue(input, forceAlpha) {
103
111
  }
104
112
  return parsed.rgb;
105
113
  }
114
+ /** @internal */
106
115
  export function isColorString(value) {
107
116
  return typeof value === "string" && COLOR_PATTERN.test(value);
108
117
  }
118
+ /** @internal */
109
119
  export function vecLength(kind) {
110
120
  if (kind === "vec2")
111
121
  return 2;
@@ -113,11 +123,13 @@ export function vecLength(kind) {
113
123
  return 3;
114
124
  return 4;
115
125
  }
126
+ /** @internal */
116
127
  export function isNumericTuple(value, length) {
117
128
  if (!Array.isArray(value) || value.length !== length)
118
129
  return false;
119
130
  return value.every(isFiniteNumber);
120
131
  }
132
+ /** @internal */
121
133
  export function isIntervalShape(value) {
122
134
  if (value === null || typeof value !== "object" || Array.isArray(value))
123
135
  return false;
@@ -127,6 +139,7 @@ export function isIntervalShape(value) {
127
139
  return false;
128
140
  return isFiniteNumber(record.min) && isFiniteNumber(record.max);
129
141
  }
142
+ /** @internal */
130
143
  export function expandAxisMeta(length, labels, min, max, step, sample) {
131
144
  const resolvedLabels = Array.from({ length }, (_, i) => labels?.[i] ?? DEFAULT_AXIS[i] ?? `a${i}`);
132
145
  const resolvedMin = Array.from({ length }, (_, i) => {
@@ -154,15 +167,18 @@ export function expandAxisMeta(length, labels, min, max, step, sample) {
154
167
  });
155
168
  return { labels: resolvedLabels, min: resolvedMin, max: resolvedMax, step: resolvedStep };
156
169
  }
170
+ /** @internal */
157
171
  export function clampAxisValue(value, min, max) {
158
172
  return Math.min(max, Math.max(min, value));
159
173
  }
174
+ /** @internal */
160
175
  export function parseVec(kind, raw, bounds) {
161
176
  const length = vecLength(kind);
162
177
  if (!isNumericTuple(raw, length))
163
178
  return null;
164
179
  return raw.map((value, i) => clampAxisValue(value, bounds.min[i], bounds.max[i]));
165
180
  }
181
+ /** @internal */
166
182
  export function parseInterval(raw, options) {
167
183
  if (!isIntervalShape(raw))
168
184
  return null;
@@ -200,6 +216,7 @@ export function parseInterval(raw, options) {
200
216
  }
201
217
  return { min: lo, max: hi };
202
218
  }
219
+ /** @internal */
203
220
  export function convertAngle(value, from, to) {
204
221
  if (from === to)
205
222
  return value;
@@ -207,6 +224,7 @@ export function convertAngle(value, from, to) {
207
224
  return (value * Math.PI) / 180;
208
225
  return (value * 180) / Math.PI;
209
226
  }
227
+ /** @internal */
210
228
  export function normalizeAngle(value, unit, options) {
211
229
  let next = value;
212
230
  if (options.wrap === true) {
@@ -225,6 +243,7 @@ export function normalizeAngle(value, unit, options) {
225
243
  }
226
244
  return next;
227
245
  }
246
+ /** @internal */
228
247
  export function resolveChoices(options, choices) {
229
248
  if (choices !== undefined)
230
249
  return choices;
@@ -232,22 +251,26 @@ export function resolveChoices(options, choices) {
232
251
  return options.map((value) => ({ value }));
233
252
  return undefined;
234
253
  }
254
+ /** @internal */
235
255
  export function choiceValues(choices) {
236
256
  if (choices === undefined)
237
257
  return undefined;
238
258
  return choices.map((choice) => choice.value);
239
259
  }
260
+ /** @internal */
240
261
  export function findChoice(choices, raw) {
241
262
  if (choices === undefined)
242
263
  return undefined;
243
264
  return choices.find((choice) => Object.is(choice.value, raw));
244
265
  }
266
+ /** @internal */
245
267
  export function parseEnumValue(raw, choices) {
246
268
  if (choices === undefined)
247
269
  return null;
248
270
  const match = findChoice(choices, raw);
249
271
  return match === undefined ? null : match.value;
250
272
  }
273
+ /** @internal */
251
274
  export function coerceSelectWrite(raw, choices, options) {
252
275
  if (choices !== undefined) {
253
276
  const byValue = findChoice(choices, raw);
@@ -275,6 +298,7 @@ export function coerceSelectWrite(raw, choices, options) {
275
298
  }
276
299
  return raw;
277
300
  }
301
+ /** @internal */
278
302
  export function inferKind(initial, options) {
279
303
  if (options?.kind !== undefined)
280
304
  return options.kind;
@@ -289,6 +313,7 @@ export function inferKind(initial, options) {
289
313
  return "color";
290
314
  return "text";
291
315
  }
316
+ /** @internal */
292
317
  export function discoverableKind(value, meta) {
293
318
  if (meta?.kind !== undefined) {
294
319
  if (meta.kind === "vec2" || meta.kind === "vec3" || meta.kind === "vec4") {
@@ -320,6 +345,7 @@ export function discoverableKind(value, meta) {
320
345
  return "color";
321
346
  return null;
322
347
  }
348
+ /** @internal */
323
349
  export function isScannableContainer(value) {
324
350
  if (value === null || typeof value !== "object")
325
351
  return false;
@@ -328,6 +354,7 @@ export function isScannableContainer(value) {
328
354
  const proto = Object.getPrototypeOf(value);
329
355
  return proto === Object.prototype || proto === null;
330
356
  }
357
+ /** @internal */
331
358
  export function ownWritableDataKeys(target) {
332
359
  return Object.keys(target).filter((key) => {
333
360
  if (UNSAFE_KEYS.has(key))
@@ -342,12 +369,14 @@ export function ownWritableDataKeys(target) {
342
369
  return true;
343
370
  });
344
371
  }
372
+ /** @internal */
345
373
  export function sliderBounds(initial, options) {
346
374
  const min = options?.min ?? (initial < 0 ? initial * 2 : 0);
347
375
  const max = options?.max ?? (initial > 0 ? initial * 2 : initial < 0 ? 0 : 1);
348
376
  const step = options?.step ?? (max - min) / 100;
349
377
  return { min, max, step };
350
378
  }
379
+ /** @internal */
351
380
  export function validateControlValue(kind, raw, context) {
352
381
  switch (kind) {
353
382
  case "slider": {
@@ -420,6 +449,7 @@ export function validateControlValue(kind, raw, context) {
420
449
  return { ok: false, reason: "unknown kind" };
421
450
  }
422
451
  }
452
+ /** @internal */
423
453
  export function parseOverridesPayload(raw) {
424
454
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
425
455
  return { overrides: null, diagnostics: ["overrides payload is not an object"] };
@@ -467,6 +497,7 @@ export function parseOverridesPayload(raw) {
467
497
  diagnostics: version === 0 ? ["migrated unversioned overrides to v1"] : [],
468
498
  };
469
499
  }
500
+ /** @internal */
470
501
  export function cloneValue(value) {
471
502
  if (Array.isArray(value))
472
503
  return value.slice();
@@ -15,11 +15,22 @@ export type CurrencyAdjustment = {
15
15
  success: false;
16
16
  reason: string;
17
17
  };
18
+ /** @internal */
18
19
  export declare function sanitizeCurrencyAmount(amount: number): number;
20
+ /**
21
+ * Format a currency amount with its symbol and grouping for HUD display.
22
+ *
23
+ * @capability currency-format format a currency amount with its symbol for display
24
+ * @internal
25
+ */
19
26
  export declare function formatCurrencyAmount(currency: CurrencyDefinition, amount: number): string;
27
+ /** @internal */
20
28
  export declare function insufficientCurrencyReason(currency: CurrencyDefinition, needed: number, current: number): string;
29
+ /** @internal */
21
30
  export declare function applyCurrencyOperation(currency: CurrencyDefinition, current: number, operation: CurrencyOperation, amount: number): CurrencyAdjustment;
22
- /** Deducts clamp to the available balance (a delta can never overdraw); adds apply in full. */
31
+ /** Deducts clamp to the available balance (a delta can never overdraw); adds apply in full.
32
+ * @internal
33
+ */
23
34
  export declare function resolveCurrencyDelta(current: number, delta: number): {
24
35
  operation: CurrencyOperation;
25
36
  amount: number;
@@ -1,14 +1,23 @@
1
+ /** @internal */
1
2
  export function sanitizeCurrencyAmount(amount) {
2
3
  return Math.max(0, Math.floor(amount));
3
4
  }
5
+ /**
6
+ * Format a currency amount with its symbol and grouping for HUD display.
7
+ *
8
+ * @capability currency-format format a currency amount with its symbol for display
9
+ * @internal
10
+ */
4
11
  export function formatCurrencyAmount(currency, amount) {
5
12
  const prefix = currency.symbol ?? "";
6
13
  const suffix = currency.unit ? ` ${currency.unit}` : "";
7
14
  return `${prefix}${amount}${suffix}`;
8
15
  }
16
+ /** @internal */
9
17
  export function insufficientCurrencyReason(currency, needed, current) {
10
18
  return `Insufficient ${currency.id}: need ${formatCurrencyAmount(currency, needed)}, have ${formatCurrencyAmount(currency, current)}`;
11
19
  }
20
+ /** @internal */
12
21
  export function applyCurrencyOperation(currency, current, operation, amount) {
13
22
  const safeAmount = sanitizeCurrencyAmount(amount);
14
23
  if (safeAmount === 0)
@@ -19,7 +28,9 @@ export function applyCurrencyOperation(currency, current, operation, amount) {
19
28
  const appliedDelta = operation === "add" ? safeAmount : -safeAmount;
20
29
  return { success: true, newBalance: current + appliedDelta, appliedDelta };
21
30
  }
22
- /** Deducts clamp to the available balance (a delta can never overdraw); adds apply in full. */
31
+ /** Deducts clamp to the available balance (a delta can never overdraw); adds apply in full.
32
+ * @internal
33
+ */
23
34
  export function resolveCurrencyDelta(current, delta) {
24
35
  const safeDelta = Math.floor(delta);
25
36
  if (safeDelta > 0)
@@ -0,0 +1,91 @@
1
+ import type { ItemStack } from "../inventory/storageTier.js";
2
+ /** One active post in a {@link ListingBook}: an item stack a seller offered at a fixed price until it expires. */
3
+ export interface Listing {
4
+ readonly id: string;
5
+ readonly sellerId: string;
6
+ readonly itemId: string;
7
+ readonly count: number;
8
+ readonly price: number;
9
+ readonly currency: string;
10
+ readonly listedAt: number;
11
+ readonly expiresAt: number;
12
+ }
13
+ /** Tunables for {@link createListingBook} — per-seller listing cap, expiry window, house cut, and optional price bounds. */
14
+ export interface ListingBookConfig {
15
+ maxListingsPerSeller: number;
16
+ expirySeconds: number;
17
+ cutRate: number;
18
+ minPrice?: number;
19
+ maxPrice?: number;
20
+ }
21
+ /** Input to {@link ListingBook.post} — the goods, asking price, and current game-time to stamp the listing with. */
22
+ export interface PostListingInput {
23
+ id?: string;
24
+ sellerId: string;
25
+ itemId: string;
26
+ count: number;
27
+ price: number;
28
+ currency: string;
29
+ now: number;
30
+ }
31
+ /** Why {@link ListingBook.post} refused a listing. */
32
+ export type PostListingReason = "invalid-count" | "invalid-price" | "price-too-low" | "price-too-high" | "listing-cap-reached";
33
+ /** Result of {@link ListingBook.post}. */
34
+ export type PostListingResult = {
35
+ status: "ok";
36
+ listing: Listing;
37
+ } | {
38
+ status: "rejected";
39
+ reason: PostListingReason;
40
+ };
41
+ /** Result of {@link ListingBook.cancel}. */
42
+ export type CancelListingResult = {
43
+ status: "ok";
44
+ listing: Listing;
45
+ } | {
46
+ status: "rejected";
47
+ reason: "not-found" | "not-owner";
48
+ };
49
+ /** The financial split of a completed sale: total price, the house's cut, and what the seller's collection box was credited. */
50
+ export interface BuyListingOutcome {
51
+ listing: Listing;
52
+ houseCut: number;
53
+ sellerProceeds: number;
54
+ }
55
+ /** Result of {@link ListingBook.buy}. */
56
+ export type BuyListingResult = {
57
+ status: "ok";
58
+ outcome: BuyListingOutcome;
59
+ } | {
60
+ status: "rejected";
61
+ reason: "not-found" | "expired" | "own-listing";
62
+ };
63
+ /** A read-only view of a seller's collection box — currency and item stacks waiting to be claimed. */
64
+ export interface CollectionBoxSnapshot {
65
+ currency: Readonly<Record<string, number>>;
66
+ items: readonly ItemStack[];
67
+ }
68
+ /** A player-driven marketplace of {@link Listing}s plus the per-seller collection boxes behind it. See {@link createListingBook}. */
69
+ export interface ListingBook {
70
+ post(input: PostListingInput): PostListingResult;
71
+ cancel(listingId: string, sellerId: string): CancelListingResult;
72
+ buy(listingId: string, buyerId: string, now: number): BuyListingResult;
73
+ sweepExpired(now: number): readonly Listing[];
74
+ get(listingId: string): Listing | null;
75
+ active(): readonly Listing[];
76
+ listingsOf(sellerId: string): readonly Listing[];
77
+ countOf(sellerId: string): number;
78
+ collectionOf(sellerId: string): CollectionBoxSnapshot;
79
+ claimCurrency(sellerId: string): Readonly<Record<string, number>>;
80
+ claimItem(sellerId: string, itemId: string, count: number): boolean;
81
+ }
82
+ /**
83
+ * A player-driven listing marketplace: post/cancel/buy against a shared book with a house cut on
84
+ * every sale, an expiry sweep that pulls unsold goods out of circulation, and a per-seller
85
+ * collection box holding sale proceeds and returned items until claimed. Buyer/seller wallet and
86
+ * inventory movement is the caller's job (mirrors `game/trade`'s split) — this primitive owns only
87
+ * the listing lifecycle and the escrowed collection-box bookkeeping behind it.
88
+ *
89
+ * @capability listing-book player-driven marketplace listings with a house cut, expiry sweep, and seller collection box
90
+ */
91
+ export declare function createListingBook(config: ListingBookConfig): ListingBook;
@@ -0,0 +1,144 @@
1
+ /**
2
+ * A player-driven listing marketplace: post/cancel/buy against a shared book with a house cut on
3
+ * every sale, an expiry sweep that pulls unsold goods out of circulation, and a per-seller
4
+ * collection box holding sale proceeds and returned items until claimed. Buyer/seller wallet and
5
+ * inventory movement is the caller's job (mirrors `game/trade`'s split) — this primitive owns only
6
+ * the listing lifecycle and the escrowed collection-box bookkeeping behind it.
7
+ *
8
+ * @capability listing-book player-driven marketplace listings with a house cut, expiry sweep, and seller collection box
9
+ */
10
+ export function createListingBook(config) {
11
+ const listings = new Map();
12
+ const boxes = new Map();
13
+ let counter = 0;
14
+ function boxOf(sellerId) {
15
+ let box = boxes.get(sellerId);
16
+ if (box === undefined) {
17
+ box = { currency: {}, items: [] };
18
+ boxes.set(sellerId, box);
19
+ }
20
+ return box;
21
+ }
22
+ function creditCurrency(sellerId, currency, amount) {
23
+ const box = boxOf(sellerId);
24
+ box.currency[currency] = (box.currency[currency] ?? 0) + amount;
25
+ }
26
+ function creditItem(sellerId, itemId, count) {
27
+ const box = boxOf(sellerId);
28
+ const existing = box.items.find((stack) => stack.itemId === itemId);
29
+ if (existing !== undefined)
30
+ existing.count += count;
31
+ else
32
+ box.items.push({ itemId, count });
33
+ }
34
+ function countOf(sellerId) {
35
+ let total = 0;
36
+ for (const listing of listings.values())
37
+ if (listing.sellerId === sellerId)
38
+ total += 1;
39
+ return total;
40
+ }
41
+ return {
42
+ post(input) {
43
+ if (!Number.isInteger(input.count) || input.count < 1) {
44
+ return { status: "rejected", reason: "invalid-count" };
45
+ }
46
+ if (!Number.isFinite(input.price) || input.price <= 0) {
47
+ return { status: "rejected", reason: "invalid-price" };
48
+ }
49
+ if (config.minPrice !== undefined && input.price < config.minPrice) {
50
+ return { status: "rejected", reason: "price-too-low" };
51
+ }
52
+ if (config.maxPrice !== undefined && input.price > config.maxPrice) {
53
+ return { status: "rejected", reason: "price-too-high" };
54
+ }
55
+ if (countOf(input.sellerId) >= config.maxListingsPerSeller) {
56
+ return { status: "rejected", reason: "listing-cap-reached" };
57
+ }
58
+ const id = input.id ?? `listing_${(counter += 1)}`;
59
+ const listing = {
60
+ id,
61
+ sellerId: input.sellerId,
62
+ itemId: input.itemId,
63
+ count: input.count,
64
+ price: input.price,
65
+ currency: input.currency,
66
+ listedAt: input.now,
67
+ expiresAt: input.now + config.expirySeconds,
68
+ };
69
+ listings.set(id, listing);
70
+ return { status: "ok", listing };
71
+ },
72
+ cancel(listingId, sellerId) {
73
+ const listing = listings.get(listingId);
74
+ if (listing === undefined)
75
+ return { status: "rejected", reason: "not-found" };
76
+ if (listing.sellerId !== sellerId)
77
+ return { status: "rejected", reason: "not-owner" };
78
+ listings.delete(listingId);
79
+ return { status: "ok", listing };
80
+ },
81
+ buy(listingId, buyerId, now) {
82
+ const listing = listings.get(listingId);
83
+ if (listing === undefined)
84
+ return { status: "rejected", reason: "not-found" };
85
+ if (listing.sellerId === buyerId)
86
+ return { status: "rejected", reason: "own-listing" };
87
+ if (listing.expiresAt <= now)
88
+ return { status: "rejected", reason: "expired" };
89
+ listings.delete(listingId);
90
+ const houseCut = Math.floor(listing.price * config.cutRate);
91
+ const sellerProceeds = listing.price - houseCut;
92
+ creditCurrency(listing.sellerId, listing.currency, sellerProceeds);
93
+ return { status: "ok", outcome: { listing, houseCut, sellerProceeds } };
94
+ },
95
+ sweepExpired(now) {
96
+ const expired = [];
97
+ for (const listing of listings.values()) {
98
+ if (listing.expiresAt <= now)
99
+ expired.push(listing);
100
+ }
101
+ for (const listing of expired) {
102
+ listings.delete(listing.id);
103
+ creditItem(listing.sellerId, listing.itemId, listing.count);
104
+ }
105
+ return expired;
106
+ },
107
+ get(listingId) {
108
+ return listings.get(listingId) ?? null;
109
+ },
110
+ active() {
111
+ return [...listings.values()];
112
+ },
113
+ listingsOf(sellerId) {
114
+ return [...listings.values()].filter((listing) => listing.sellerId === sellerId);
115
+ },
116
+ countOf,
117
+ collectionOf(sellerId) {
118
+ const box = boxes.get(sellerId);
119
+ if (box === undefined)
120
+ return { currency: {}, items: [] };
121
+ return { currency: { ...box.currency }, items: box.items.map((stack) => ({ ...stack })) };
122
+ },
123
+ claimCurrency(sellerId) {
124
+ const box = boxOf(sellerId);
125
+ const claimed = box.currency;
126
+ box.currency = {};
127
+ return claimed;
128
+ },
129
+ claimItem(sellerId, itemId, count) {
130
+ const box = boxOf(sellerId);
131
+ const index = box.items.findIndex((stack) => stack.itemId === itemId);
132
+ if (index === -1)
133
+ return false;
134
+ const stack = box.items[index];
135
+ if (stack.count < count)
136
+ return false;
137
+ if (stack.count === count)
138
+ box.items.splice(index, 1);
139
+ else
140
+ box.items[index] = { ...stack, count: stack.count - count };
141
+ return true;
142
+ },
143
+ };
144
+ }