@jgengine/core 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Timed-bid auctions in the WoW/BDO auction-house mold: post an item with a start price, minimum
3
+ * increment, and optional buyout; bids escrow currency, outbid players are refunded into their
4
+ * collection box, bids near the close extend it (anti-snipe), and settlement pays the seller minus
5
+ * the house cut while the item lands in the winner's collection box. Unsold auctions return the
6
+ * goods to the seller's box. Wallet and inventory movement is the caller's job (mirrors
7
+ * `economy/listingBook`) — this primitive owns the auction lifecycle and the escrowed
8
+ * collection-box bookkeeping behind it.
9
+ *
10
+ * @capability auction-book timed bid auctions with escrowed bids, buyout, anti-snipe close extension, and collection-box settlement
11
+ */
12
+ export function createAuctionBook(config) {
13
+ const auctions = new Map();
14
+ const boxes = new Map();
15
+ let counter = 0;
16
+ function boxOf(playerId) {
17
+ let box = boxes.get(playerId);
18
+ if (box === undefined) {
19
+ box = { currency: {}, items: [] };
20
+ boxes.set(playerId, box);
21
+ }
22
+ return box;
23
+ }
24
+ function creditCurrency(playerId, currency, amount) {
25
+ const box = boxOf(playerId);
26
+ box.currency[currency] = (box.currency[currency] ?? 0) + amount;
27
+ }
28
+ function creditItem(playerId, itemId, count) {
29
+ const box = boxOf(playerId);
30
+ const existing = box.items.find((stack) => stack.itemId === itemId);
31
+ if (existing !== undefined)
32
+ existing.count += count;
33
+ else
34
+ box.items.push({ itemId, count });
35
+ }
36
+ function countOf(sellerId) {
37
+ let total = 0;
38
+ for (const auction of auctions.values())
39
+ if (auction.sellerId === sellerId)
40
+ total += 1;
41
+ return total;
42
+ }
43
+ function snapshot(state) {
44
+ return { ...state, highBid: state.highBid };
45
+ }
46
+ function minimumBid(state) {
47
+ return state.highBid === null ? state.startPrice : state.highBid.amount + state.minIncrement;
48
+ }
49
+ function settle(state, winnerId, price) {
50
+ auctions.delete(state.id);
51
+ const houseCut = Math.floor(price * config.cutRate);
52
+ const sellerProceeds = price - houseCut;
53
+ creditCurrency(state.sellerId, state.currency, sellerProceeds);
54
+ creditItem(winnerId, state.itemId, state.count);
55
+ return { status: "sold", auction: snapshot(state), winnerId, price, houseCut, sellerProceeds };
56
+ }
57
+ function acceptBid(state, bidderId, amount, now) {
58
+ if (state.highBid !== null) {
59
+ creditCurrency(state.highBid.bidderId, state.currency, state.highBid.amount);
60
+ }
61
+ if (state.buyoutPrice !== null && amount >= state.buyoutPrice) {
62
+ state.highBid = { bidderId, amount: state.buyoutPrice, at: now };
63
+ const settlement = settle(state, bidderId, state.buyoutPrice);
64
+ if (settlement.status !== "sold")
65
+ throw new Error("unreachable");
66
+ return { status: "ok", auction: settlement.auction, escrowed: state.buyoutPrice, won: true };
67
+ }
68
+ state.highBid = { bidderId, amount, at: now };
69
+ const window = config.antiSnipeWindowSeconds ?? 0;
70
+ const extension = config.antiSnipeExtensionSeconds ?? 0;
71
+ if (window > 0 && extension > 0 && state.endsAt - now < window) {
72
+ state.endsAt = Math.max(state.endsAt, now + extension);
73
+ }
74
+ return { status: "ok", auction: snapshot(state), escrowed: amount, won: false };
75
+ }
76
+ return {
77
+ post(input) {
78
+ if (!Number.isInteger(input.count) || input.count < 1) {
79
+ return { status: "rejected", reason: "invalid-count" };
80
+ }
81
+ if (!Number.isFinite(input.startPrice) || input.startPrice <= 0) {
82
+ return { status: "rejected", reason: "invalid-price" };
83
+ }
84
+ if (!Number.isFinite(input.minIncrement) || input.minIncrement <= 0) {
85
+ return { status: "rejected", reason: "invalid-increment" };
86
+ }
87
+ if (input.buyoutPrice !== undefined) {
88
+ if (!Number.isFinite(input.buyoutPrice) || input.buyoutPrice < input.startPrice) {
89
+ return { status: "rejected", reason: "invalid-buyout" };
90
+ }
91
+ }
92
+ if (countOf(input.sellerId) >= config.maxAuctionsPerSeller) {
93
+ return { status: "rejected", reason: "auction-cap-reached" };
94
+ }
95
+ const id = input.id ?? `auction_${(counter += 1)}`;
96
+ const state = {
97
+ id,
98
+ sellerId: input.sellerId,
99
+ itemId: input.itemId,
100
+ count: input.count,
101
+ currency: input.currency,
102
+ startPrice: input.startPrice,
103
+ minIncrement: input.minIncrement,
104
+ buyoutPrice: input.buyoutPrice ?? null,
105
+ listedAt: input.now,
106
+ endsAt: input.now + config.durationSeconds,
107
+ highBid: null,
108
+ };
109
+ auctions.set(id, state);
110
+ return { status: "ok", auction: snapshot(state) };
111
+ },
112
+ bid(auctionId, bidderId, amount, now) {
113
+ const state = auctions.get(auctionId);
114
+ if (state === undefined)
115
+ return { status: "rejected", reason: "not-found" };
116
+ if (state.endsAt <= now)
117
+ return { status: "rejected", reason: "ended" };
118
+ if (state.sellerId === bidderId)
119
+ return { status: "rejected", reason: "own-auction" };
120
+ if (!Number.isFinite(amount) || amount <= 0) {
121
+ return { status: "rejected", reason: "invalid-amount" };
122
+ }
123
+ if (state.highBid?.bidderId === bidderId) {
124
+ return { status: "rejected", reason: "already-leading" };
125
+ }
126
+ if (amount < minimumBid(state))
127
+ return { status: "rejected", reason: "bid-too-low" };
128
+ return acceptBid(state, bidderId, amount, now);
129
+ },
130
+ buyout(auctionId, buyerId, now) {
131
+ const state = auctions.get(auctionId);
132
+ if (state === undefined)
133
+ return { status: "rejected", reason: "not-found" };
134
+ if (state.endsAt <= now)
135
+ return { status: "rejected", reason: "ended" };
136
+ if (state.sellerId === buyerId)
137
+ return { status: "rejected", reason: "own-auction" };
138
+ if (state.buyoutPrice === null)
139
+ return { status: "rejected", reason: "no-buyout" };
140
+ if (state.highBid?.bidderId === buyerId) {
141
+ creditCurrency(buyerId, state.currency, state.highBid.amount);
142
+ state.highBid = null;
143
+ }
144
+ return acceptBid(state, buyerId, state.buyoutPrice, now);
145
+ },
146
+ cancel(auctionId, sellerId) {
147
+ const state = auctions.get(auctionId);
148
+ if (state === undefined)
149
+ return { status: "rejected", reason: "not-found" };
150
+ if (state.sellerId !== sellerId)
151
+ return { status: "rejected", reason: "not-owner" };
152
+ if (state.highBid !== null)
153
+ return { status: "rejected", reason: "has-bids" };
154
+ auctions.delete(auctionId);
155
+ return { status: "ok", auction: snapshot(state) };
156
+ },
157
+ settleExpired(now) {
158
+ const ended = [];
159
+ for (const state of auctions.values())
160
+ if (state.endsAt <= now)
161
+ ended.push(state);
162
+ const settlements = [];
163
+ for (const state of ended) {
164
+ if (state.highBid === null) {
165
+ auctions.delete(state.id);
166
+ creditItem(state.sellerId, state.itemId, state.count);
167
+ settlements.push({ status: "returned", auction: snapshot(state) });
168
+ }
169
+ else {
170
+ settlements.push(settle(state, state.highBid.bidderId, state.highBid.amount));
171
+ }
172
+ }
173
+ return settlements;
174
+ },
175
+ get(auctionId) {
176
+ const state = auctions.get(auctionId);
177
+ return state === undefined ? null : snapshot(state);
178
+ },
179
+ active() {
180
+ return [...auctions.values()].map(snapshot);
181
+ },
182
+ auctionsOf(sellerId) {
183
+ return [...auctions.values()].filter((a) => a.sellerId === sellerId).map(snapshot);
184
+ },
185
+ countOf,
186
+ collectionOf(playerId) {
187
+ const box = boxes.get(playerId);
188
+ if (box === undefined)
189
+ return { currency: {}, items: [] };
190
+ return { currency: { ...box.currency }, items: box.items.map((stack) => ({ ...stack })) };
191
+ },
192
+ claimCurrency(playerId) {
193
+ const box = boxOf(playerId);
194
+ const claimed = box.currency;
195
+ box.currency = {};
196
+ return claimed;
197
+ },
198
+ claimItem(playerId, itemId, count) {
199
+ const box = boxOf(playerId);
200
+ const index = box.items.findIndex((stack) => stack.itemId === itemId);
201
+ if (index === -1)
202
+ return false;
203
+ const stack = box.items[index];
204
+ if (stack.count < count)
205
+ return false;
206
+ if (stack.count === count)
207
+ box.items.splice(index, 1);
208
+ else
209
+ box.items[index] = { ...stack, count: stack.count - count };
210
+ return true;
211
+ },
212
+ };
213
+ }
@@ -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
+ }
@@ -0,0 +1,44 @@
1
+ /** One completed sale recorded into a {@link PriceHistory}. */
2
+ export interface SaleRecord {
3
+ readonly itemId: string;
4
+ readonly count: number;
5
+ readonly unitPrice: number;
6
+ readonly currency: string;
7
+ readonly at: number;
8
+ }
9
+ /**
10
+ * Tunables for {@link createPriceHistory} — the per-item sample cap bounds memory; the optional
11
+ * window drops samples older than `windowSeconds` whenever the history is written or read with a
12
+ * newer timestamp.
13
+ */
14
+ export interface PriceHistoryConfig {
15
+ maxSamplesPerItem: number;
16
+ windowSeconds?: number;
17
+ }
18
+ /** Aggregated market stats for one item over the retained samples. */
19
+ export interface PriceStats {
20
+ readonly sampleCount: number;
21
+ readonly volume: number;
22
+ readonly minUnitPrice: number;
23
+ readonly maxUnitPrice: number;
24
+ readonly averageUnitPrice: number;
25
+ readonly latestUnitPrice: number;
26
+ }
27
+ /** A bounded rolling record of completed sales per item. See {@link createPriceHistory}. */
28
+ export interface PriceHistory {
29
+ record(sale: SaleRecord): void;
30
+ statsOf(itemId: string, now?: number): PriceStats | null;
31
+ samplesOf(itemId: string, now?: number): readonly SaleRecord[];
32
+ itemIds(): readonly string[];
33
+ clear(itemId?: string): void;
34
+ }
35
+ /**
36
+ * The "market price" readout behind every auction house: a bounded rolling record of completed
37
+ * sales per item, aggregated into min/max/volume-weighted-average/latest unit-price stats so games
38
+ * can show current value and recent trends. Memory is bounded by `maxSamplesPerItem` (oldest
39
+ * samples drop first) and optionally by a sliding time window; timestamps are injected by the
40
+ * caller so the history stays deterministic.
41
+ *
42
+ * @capability price-history rolling per-item sale records aggregated into market price stats
43
+ */
44
+ export declare function createPriceHistory(config: PriceHistoryConfig): PriceHistory;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * The "market price" readout behind every auction house: a bounded rolling record of completed
3
+ * sales per item, aggregated into min/max/volume-weighted-average/latest unit-price stats so games
4
+ * can show current value and recent trends. Memory is bounded by `maxSamplesPerItem` (oldest
5
+ * samples drop first) and optionally by a sliding time window; timestamps are injected by the
6
+ * caller so the history stays deterministic.
7
+ *
8
+ * @capability price-history rolling per-item sale records aggregated into market price stats
9
+ */
10
+ export function createPriceHistory(config) {
11
+ const samples = new Map();
12
+ function trim(list, now) {
13
+ if (config.windowSeconds !== undefined && now !== undefined) {
14
+ const cutoff = now - config.windowSeconds;
15
+ let drop = 0;
16
+ while (drop < list.length && list[drop].at < cutoff)
17
+ drop += 1;
18
+ if (drop > 0)
19
+ list.splice(0, drop);
20
+ }
21
+ if (list.length > config.maxSamplesPerItem) {
22
+ list.splice(0, list.length - config.maxSamplesPerItem);
23
+ }
24
+ }
25
+ function retained(itemId, now) {
26
+ const list = samples.get(itemId);
27
+ if (list === undefined)
28
+ return null;
29
+ trim(list, now);
30
+ if (list.length === 0) {
31
+ samples.delete(itemId);
32
+ return null;
33
+ }
34
+ return list;
35
+ }
36
+ return {
37
+ record(sale) {
38
+ if (!Number.isFinite(sale.unitPrice) || sale.unitPrice < 0)
39
+ return;
40
+ if (!Number.isInteger(sale.count) || sale.count < 1)
41
+ return;
42
+ let list = samples.get(sale.itemId);
43
+ if (list === undefined) {
44
+ list = [];
45
+ samples.set(sale.itemId, list);
46
+ }
47
+ list.push(sale);
48
+ trim(list, sale.at);
49
+ },
50
+ statsOf(itemId, now) {
51
+ const list = retained(itemId, now);
52
+ if (list === null)
53
+ return null;
54
+ let volume = 0;
55
+ let spend = 0;
56
+ let min = Number.POSITIVE_INFINITY;
57
+ let max = Number.NEGATIVE_INFINITY;
58
+ for (const sale of list) {
59
+ volume += sale.count;
60
+ spend += sale.unitPrice * sale.count;
61
+ if (sale.unitPrice < min)
62
+ min = sale.unitPrice;
63
+ if (sale.unitPrice > max)
64
+ max = sale.unitPrice;
65
+ }
66
+ return {
67
+ sampleCount: list.length,
68
+ volume,
69
+ minUnitPrice: min,
70
+ maxUnitPrice: max,
71
+ averageUnitPrice: spend / volume,
72
+ latestUnitPrice: list[list.length - 1].unitPrice,
73
+ };
74
+ },
75
+ samplesOf(itemId, now) {
76
+ const list = retained(itemId, now);
77
+ return list === null ? [] : [...list];
78
+ },
79
+ itemIds() {
80
+ return [...samples.keys()];
81
+ },
82
+ clear(itemId) {
83
+ if (itemId === undefined)
84
+ samples.clear();
85
+ else
86
+ samples.delete(itemId);
87
+ },
88
+ };
89
+ }