@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
package/dist/game/feed.js CHANGED
@@ -1,11 +1,44 @@
1
+ /**
2
+ * Append `entry` to a flat, serializable feed list, then bound it by age (`ttl`, relative to the
3
+ * appended entry's `at`) and/or count (`limit`, newest kept). Works on the game's own flat entry
4
+ * shape — anything with an `at` stamp — so `{ id, text, tone, at }`-style notice lists and event
5
+ * logs drop into serialized state with no `{ at, data }` envelope. Returns a new array.
6
+ *
7
+ * @capability notice-feed serializable tone-tagged notice/event feed bounded by count and age (toasts, life events, killfeed)
8
+ */
9
+ export function appendFeed(list, entry, options) {
10
+ let next = [...list, entry];
11
+ if (options?.ttl !== undefined) {
12
+ const cutoff = entry.at - options.ttl;
13
+ next = next.filter((item) => item.at > cutoff);
14
+ }
15
+ const limit = options?.limit;
16
+ return limit !== undefined && next.length > limit ? next.slice(next.length - limit) : next;
17
+ }
18
+ /**
19
+ * Drop feed entries older than `ttl` game-seconds before `now`. Returns the same array reference
20
+ * when nothing expired, so equality checks skip a redundant state write. The tick-time counterpart
21
+ * to {@link appendFeed}'s age bound.
22
+ *
23
+ * @capability notice-feed serializable tone-tagged notice/event feed bounded by count and age (toasts, life events, killfeed)
24
+ */
25
+ export function pruneFeed(list, now, ttl) {
26
+ const cutoff = now - ttl;
27
+ const kept = list.filter((item) => item.at > cutoff);
28
+ return kept.length === list.length ? list : kept;
29
+ }
1
30
  export function appendFeedEntry(buffer, entry, limit) {
2
- const next = [...buffer, entry];
3
- return next.length > limit ? next.slice(next.length - limit) : next;
31
+ return appendFeed(buffer, entry, { limit });
4
32
  }
5
33
  export function recentFeedEntries(buffer, limit) {
6
34
  const count = limit ?? buffer.length;
7
35
  return buffer.slice(Math.max(0, buffer.length - count));
8
36
  }
37
+ /**
38
+ * A rolling per-action feed of recent gameplay events, bindable to the event bus — the HUD ticker and killfeed history.
39
+ *
40
+ * @capability event-feed a rolling feed of recent gameplay events for a HUD ticker or killfeed
41
+ */
9
42
  export function createGameFeed(options) {
10
43
  const limit = options?.limit ?? 20;
11
44
  const buffers = new Map();
@@ -1,4 +1,5 @@
1
1
  import type { GameContext } from "../runtime/gameContext.js";
2
+ import type { LifecycleConfig } from "./defineGame.js";
2
3
  /**
3
4
  * Canonical run phase every game moves through. `menu` (title/main menu),
4
5
  * `playing` (live), `paused` (mid-run pause), `ended` (win/lose/results).
@@ -18,3 +19,13 @@ export declare function setGamePhase(ctx: GameContext, phase: GamePhase): void;
18
19
  /** Current phase; defaults to `playing` when unset so always-live games need no wiring. */
19
20
  export declare function gamePhase(ctx: GameContext): GamePhase;
20
21
  export declare function isPlaying(ctx: GameContext): boolean;
22
+ /**
23
+ * Derive the canonical phase from a game's own run state via its {@link LifecycleConfig.phaseOf} and
24
+ * publish it when it changed — the runtime calls this after every loop hook so a game never hand-writes
25
+ * a per-tick `setGamePhase(ctx, state.phase === … ? … : …)` ternary or its own previous-phase diff. The
26
+ * guard makes it idempotent: the phase store is only rewritten (and touch controls re-gated) on an actual
27
+ * transition, so a busy `onTick` costs one `phaseOf` read, not a store write per frame.
28
+ *
29
+ * @internal
30
+ */
31
+ export declare function syncLifecyclePhase(ctx: GameContext, lifecycle: LifecycleConfig | undefined): void;
@@ -19,3 +19,19 @@ export function gamePhase(ctx) {
19
19
  export function isPlaying(ctx) {
20
20
  return gamePhase(ctx) === "playing";
21
21
  }
22
+ /**
23
+ * Derive the canonical phase from a game's own run state via its {@link LifecycleConfig.phaseOf} and
24
+ * publish it when it changed — the runtime calls this after every loop hook so a game never hand-writes
25
+ * a per-tick `setGamePhase(ctx, state.phase === … ? … : …)` ternary or its own previous-phase diff. The
26
+ * guard makes it idempotent: the phase store is only rewritten (and touch controls re-gated) on an actual
27
+ * transition, so a busy `onTick` costs one `phaseOf` read, not a store write per frame.
28
+ *
29
+ * @internal
30
+ */
31
+ export function syncLifecyclePhase(ctx, lifecycle) {
32
+ if (lifecycle === undefined)
33
+ return;
34
+ const desired = lifecycle.phaseOf(lifecycle.store.read(ctx));
35
+ if (gamePhase(ctx) !== desired)
36
+ setGamePhase(ctx, desired);
37
+ }
@@ -41,6 +41,11 @@ export interface Leaderboard {
41
41
  snapshot(): LeaderboardRow[];
42
42
  hydrate(rows: LeaderboardRow[]): void;
43
43
  }
44
+ /**
45
+ * Ranked score tracking across global, server, and per-profile scopes, with top-N queries and per-profile lookups.
46
+ *
47
+ * @capability leaderboard ranked score tracking across global, server, and per-profile scopes
48
+ */
44
49
  export declare function createLeaderboard(sink?: {
45
50
  onIncrement?(row: LeaderboardRow): void;
46
51
  }): Leaderboard;
@@ -11,6 +11,11 @@ function trackKey(stat, scope) {
11
11
  function rowKey(stat, scope, serverId, userId) {
12
12
  return `${scope}:${stat}:${serverId ?? ""}:${userId}`;
13
13
  }
14
+ /**
15
+ * Ranked score tracking across global, server, and per-profile scopes, with top-N queries and per-profile lookups.
16
+ *
17
+ * @capability leaderboard ranked score tracking across global, server, and per-profile scopes
18
+ */
14
19
  export function createLeaderboard(sink) {
15
20
  const trackedPairs = new Map();
16
21
  const rows = new Map();
@@ -44,4 +44,9 @@ export interface Loadouts {
44
44
  reason: string;
45
45
  } | null;
46
46
  }
47
+ /**
48
+ * Save, name, and swap equipment loadouts.
49
+ *
50
+ * @capability loadouts save and swap named equipment loadouts
51
+ */
47
52
  export declare function createLoadouts(deps: LoadoutDeps): Loadouts;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Save, name, and swap equipment loadouts.
3
+ *
4
+ * @capability loadouts save and swap named equipment loadouts
5
+ */
1
6
  export function createLoadouts(deps) {
2
7
  const definitions = new Map();
3
8
  return {
@@ -27,6 +27,8 @@ export interface LootFilterOverride {
27
27
  * First matching rule wins (PoE/Last Epoch block semantics) — later rules
28
28
  * never override an earlier match. Returns overrides only; fields the rule
29
29
  * doesn't set are left for the caller's baseline (rarity style) to fill in.
30
+ *
31
+ * @capability loot-filter filter and highlight drops by rarity/name rules
30
32
  */
31
33
  export declare function evaluateLootFilter(rules: readonly LootFilterRule[], item: LootFilterItem): LootFilterOverride;
32
34
  /** Validating factory — rule ids must be unique so authoring mistakes fail loudly. */
@@ -18,6 +18,8 @@ function matchesCondition(when, item) {
18
18
  * First matching rule wins (PoE/Last Epoch block semantics) — later rules
19
19
  * never override an earlier match. Returns overrides only; fields the rule
20
20
  * doesn't set are left for the caller's baseline (rarity style) to fill in.
21
+ *
22
+ * @capability loot-filter filter and highlight drops by rarity/name rules
21
23
  */
22
24
  export function evaluateLootFilter(rules, item) {
23
25
  for (const rule of rules) {
@@ -0,0 +1,164 @@
1
+ import type { Drop, LootEntry, LootTableDef } from "./lootTable.js";
2
+ /**
3
+ * One eligible entry inside a {@link LootRollPlan}: the original table entry plus its live
4
+ * eligibility and effective weight/chance. Modifiers rewrite these fields; the source `entry`
5
+ * object is never mutated, so table definitions stay shared and reusable.
6
+ */
7
+ export interface LootPlanEntry {
8
+ /** The untouched source entry from the table this stage rolls. */
9
+ entry: LootEntry;
10
+ /** Position of `entry` in the source table, carried through to provenance. */
11
+ index: number;
12
+ /** Effective relative pick weight (weighted mode). Starts at the entry's declared weight. */
13
+ weight: number;
14
+ /** Effective per-entry drop probability (independent mode). Starts at the entry's declared chance. */
15
+ chance?: number;
16
+ /** When `false`, the entry is gated out of this roll — excluded from the weighted total or the independent pass. */
17
+ eligible: boolean;
18
+ }
19
+ /**
20
+ * The mutable roll plan a stage derives from its table before rolling. Modifiers transform this —
21
+ * gating entries, reweighting them, or changing the roll count — instead of touching table defs.
22
+ */
23
+ export interface LootRollPlan {
24
+ /** Source table id (for provenance) or `null` when the stage rolled an inline, unnamed table. */
25
+ tableId: string | null;
26
+ /** Weighted vs independent roll mode, inherited from the source table. */
27
+ mode: "weighted" | "independent";
28
+ /** Number of rolls to perform; a quantity modifier can raise or lower this. */
29
+ rolls: number;
30
+ /** The candidate entries with their live eligibility and effective weights/chances. */
31
+ entries: LootPlanEntry[];
32
+ }
33
+ /**
34
+ * A registered, id-tagged loot policy applied to one stage. `plan` transforms eligibility, weights,
35
+ * and roll counts before rolling (luck, difficulty, gating); `drops` post-processes the rolled drops
36
+ * (quantity multipliers, dedupe, caps). Neither hook mutates table definitions, and the id is recorded
37
+ * in provenance so a resolved drop can be traced back to the policies that shaped it.
38
+ */
39
+ export interface LootModifier<TCtx = unknown> {
40
+ /** Stable identifier recorded in {@link LootDropProvenance.modifiers} and stage traces. */
41
+ id: string;
42
+ /** Rewrite the roll plan (eligibility, effective weights, roll count). Return the plan to apply. */
43
+ plan?: (plan: LootRollPlan, ctx: TCtx) => LootRollPlan;
44
+ /** Post-process this stage's rolled drops (scale counts, dedupe, cap). Return the drops to keep. */
45
+ drops?: (drops: Drop[], ctx: TCtx) => Drop[];
46
+ }
47
+ /**
48
+ * How a stage folds its rolled drops into the accumulating result: `"contribute"` appends,
49
+ * `"fallback"` rolls only when nothing has dropped yet, `"replace"` discards prior drops and
50
+ * overrides with its own (quest/boss overrides).
51
+ */
52
+ export type LootStageKind = "contribute" | "fallback" | "replace";
53
+ /**
54
+ * One ordered step in a {@link LootPipelineDef}: a source pool (a table id or inline table), an
55
+ * optional context gate, a fold mode, and the modifiers that reshape its roll. Stages compose the
56
+ * genre concepts — world pool, dedicated pool, luck, pity — without any of them living in core.
57
+ */
58
+ export interface LootStage<TCtx = unknown> {
59
+ /** Stable stage identifier recorded in provenance and traces. */
60
+ id: string;
61
+ /** Source pool: a table id resolved against the pipeline's resolver, or an inline table definition. */
62
+ table: string | LootTableDef;
63
+ /** Fold mode; defaults to `"contribute"`. */
64
+ kind?: LootStageKind;
65
+ /** Context gate — when it returns `false` the stage is skipped and traced with reason `"gate-false"`. */
66
+ when?: (ctx: TCtx) => boolean;
67
+ /** Modifiers applied in order to this stage's roll. */
68
+ modifiers?: LootModifier<TCtx>[];
69
+ }
70
+ /**
71
+ * A named, ordered loot-resolution pipeline: the stages to run plus result-shaping policy
72
+ * (duplicate stacking, a total drop cap). Serializable except for its stage gate/modifier functions,
73
+ * mirroring how {@link LootTableDef} entries may carry a `generate` function.
74
+ */
75
+ export interface LootPipelineDef<TCtx = unknown> {
76
+ id: string;
77
+ /** Stages run in array order — the deterministic resolution order. */
78
+ stages: LootStage<TCtx>[];
79
+ /** When `true`, drops of the same item/currency are merged into one entry with summed counts. */
80
+ stack?: boolean;
81
+ /** Optional hard cap on the number of resolved drops; extras are trimmed and the cap is traced. */
82
+ maxDrops?: number;
83
+ }
84
+ /** The caller-owned context, injected RNG, and optional seed threaded through a single resolution. */
85
+ export interface LootResolveContext<TCtx = unknown> {
86
+ /** Caller-owned, typed resolution context read by stage gates and modifiers. */
87
+ ctx: TCtx;
88
+ /** Injected randomness — seed it for deterministic, server-authoritative replay. */
89
+ rng: () => number;
90
+ /** Optional seed value recorded verbatim in {@link LootResolution.seed} for replay bookkeeping. */
91
+ seed?: number | string;
92
+ }
93
+ /** Why one drop is in the result: the stage/table/entry that produced it, its weights, and the modifiers that shaped it. */
94
+ export interface LootDropProvenance {
95
+ /** Stage that produced the drop. */
96
+ stageId: string;
97
+ /** Source table id, or `null` for an inline table. */
98
+ tableId: string | null;
99
+ /** Index of the winning entry in its source table. */
100
+ entryIndex: number;
101
+ /** The granted item id, when the drop is an item. */
102
+ item?: string;
103
+ /** The granted currency id, when the drop is currency. */
104
+ currency?: string;
105
+ /** The entry's declared weight before modifiers (weighted mode). */
106
+ originalWeight?: number;
107
+ /** The entry's effective weight after modifiers (weighted mode). */
108
+ effectiveWeight?: number;
109
+ /** The entry's declared chance before modifiers (independent mode). */
110
+ originalChance?: number;
111
+ /** The entry's effective chance after modifiers (independent mode). */
112
+ effectiveChance?: number;
113
+ /** Ids of the modifiers that ran on the producing stage, in application order. */
114
+ modifiers: string[];
115
+ }
116
+ /** The disposition of a stage after resolution — did it roll, get gated, fall through, override, or find nothing. */
117
+ export type LootStageStatus = "rolled" | "skipped" | "empty" | "replaced" | "fell-through";
118
+ /** Per-stage record of what happened during resolution, for debugging and replay auditing. */
119
+ export interface LootStageTrace {
120
+ stageId: string;
121
+ tableId: string | null;
122
+ kind: LootStageKind;
123
+ status: LootStageStatus;
124
+ /** Human-readable reason for a non-`"rolled"` status (e.g. `"gate-false"`, `"empty-pool"`, `"prior-drops-present"`). */
125
+ reason?: string;
126
+ /** Ids of modifiers applied on this stage. */
127
+ modifiers: string[];
128
+ /** Drops this stage contributed to the final result. */
129
+ dropCount: number;
130
+ }
131
+ /** The fully serializable outcome of a resolution: the drops, their provenance, per-stage traces, and the replay seed. */
132
+ export interface LootResolution {
133
+ drops: Drop[];
134
+ provenance: LootDropProvenance[];
135
+ stages: LootStageTrace[];
136
+ seed?: number | string;
137
+ }
138
+ /** A resolved, reusable loot pipeline. Call {@link LootPipeline.resolve} with a per-drop context and RNG. */
139
+ export interface LootPipeline<TCtx = unknown> {
140
+ readonly id: string;
141
+ resolve(context: LootResolveContext<TCtx>): LootResolution;
142
+ }
143
+ /** Dependencies a pipeline needs at build time — chiefly how to turn a table id into its definition. */
144
+ export interface LootPipelineDeps {
145
+ /** Resolve a table id to its definition. Required only when stages reference tables by id. */
146
+ resolveTable?: (id: string) => LootTableDef | undefined;
147
+ }
148
+ /**
149
+ * Validate a loot pipeline definition and return it unchanged, for use with {@link createLootPipeline}.
150
+ *
151
+ * @capability loot-pipeline validate a composable loot-resolution pipeline definition
152
+ */
153
+ export declare function defineLootPipeline<TCtx = unknown>(def: LootPipelineDef<TCtx>): LootPipelineDef<TCtx>;
154
+ /**
155
+ * Build a composable loot-resolution pipeline: ordered source pools, context gates, fallbacks when a
156
+ * pool yields nothing, roll modifiers (luck, quantity, difficulty) applied as registered policies, and
157
+ * full provenance for every drop (stage, table, entry, original vs effective weights, modifier ids, seed).
158
+ * Rolling consumes the injected RNG in the same order as the base loot table, so a seeded resolution is
159
+ * deterministic and server-authoritatively replayable. Genre concepts (world, dedicated, boss, luck,
160
+ * rarity, pity) stay out of core and ship as stage/modifier compositions.
161
+ *
162
+ * @capability loot-pipeline compose ordered loot pools with fallbacks, roll modifiers, and provenance
163
+ */
164
+ export declare function createLootPipeline<TCtx = unknown>(def: LootPipelineDef<TCtx>, deps?: LootPipelineDeps): LootPipeline<TCtx>;
@@ -0,0 +1,216 @@
1
+ function tableModeOf(def) {
2
+ return def.mode ?? "weighted";
3
+ }
4
+ function buildPlan(def) {
5
+ return {
6
+ tableId: def.id,
7
+ mode: tableModeOf(def),
8
+ rolls: def.rolls ?? 1,
9
+ entries: def.entries.map((entry, index) => {
10
+ const planEntry = { entry, index, weight: entry.weight ?? 0, eligible: true };
11
+ if (entry.chance !== undefined)
12
+ planEntry.chance = entry.chance;
13
+ return planEntry;
14
+ }),
15
+ };
16
+ }
17
+ function resolveCount(count, rng) {
18
+ if (typeof count === "number")
19
+ return count;
20
+ const [min, max] = count;
21
+ return min + Math.floor(rng() * (max - min + 1));
22
+ }
23
+ function dropFromEntry(entry, count, rng) {
24
+ if (entry.generate !== undefined)
25
+ return { item: entry.generate(rng), count };
26
+ return entry.item !== undefined ? { item: entry.item, count } : { currency: entry.currency, count };
27
+ }
28
+ /** Pick one eligible plan entry by effective weight, mirroring `createLootRegistry`'s weighted algorithm and RNG order. */
29
+ function pickWeighted(entries, rng) {
30
+ const eligible = entries.filter((candidate) => candidate.eligible && candidate.weight > 0);
31
+ if (eligible.length === 0)
32
+ return null;
33
+ const total = eligible.reduce((sum, candidate) => sum + candidate.weight, 0);
34
+ let roll = rng() * total;
35
+ for (const candidate of eligible) {
36
+ roll -= candidate.weight;
37
+ if (roll < 0)
38
+ return candidate;
39
+ }
40
+ return eligible[eligible.length - 1] ?? null;
41
+ }
42
+ /** Roll a prepared plan into drops, consuming `rng` in the same order as the base loot table primitive. */
43
+ function rollPlan(plan, rng) {
44
+ const rolled = [];
45
+ for (let roll = 0; roll < plan.rolls; roll += 1) {
46
+ if (plan.mode === "independent") {
47
+ for (const planEntry of plan.entries) {
48
+ if (!planEntry.eligible)
49
+ continue;
50
+ if (rng() < (planEntry.chance ?? 0)) {
51
+ const count = resolveCount(planEntry.entry.count, rng);
52
+ rolled.push({ drop: dropFromEntry(planEntry.entry, count, rng), planEntry });
53
+ }
54
+ }
55
+ }
56
+ else {
57
+ const picked = pickWeighted(plan.entries, rng);
58
+ if (picked === null)
59
+ continue;
60
+ const count = resolveCount(picked.entry.count, rng);
61
+ rolled.push({ drop: dropFromEntry(picked.entry, count, rng), planEntry: picked });
62
+ }
63
+ }
64
+ return rolled;
65
+ }
66
+ function stackDrops(drops) {
67
+ const order = [];
68
+ const byKey = new Map();
69
+ for (const drop of drops) {
70
+ const key = drop.item !== undefined ? `item:${drop.item}` : `currency:${drop.currency}`;
71
+ const existing = byKey.get(key);
72
+ if (existing === undefined) {
73
+ byKey.set(key, { ...drop });
74
+ order.push(key);
75
+ }
76
+ else {
77
+ existing.count += drop.count;
78
+ }
79
+ }
80
+ return order.map((key) => byKey.get(key));
81
+ }
82
+ function assertValidPipeline(def) {
83
+ if (def.stages.length === 0) {
84
+ throw new Error(`loot pipeline "${def.id}" must have at least one stage`);
85
+ }
86
+ const seen = new Set();
87
+ for (const stage of def.stages) {
88
+ if (seen.has(stage.id)) {
89
+ throw new Error(`loot pipeline "${def.id}" has duplicate stage id "${stage.id}"`);
90
+ }
91
+ seen.add(stage.id);
92
+ }
93
+ if (def.maxDrops !== undefined && (!Number.isInteger(def.maxDrops) || def.maxDrops < 0)) {
94
+ throw new Error(`loot pipeline "${def.id}" maxDrops must be a non-negative integer`);
95
+ }
96
+ }
97
+ /**
98
+ * Validate a loot pipeline definition and return it unchanged, for use with {@link createLootPipeline}.
99
+ *
100
+ * @capability loot-pipeline validate a composable loot-resolution pipeline definition
101
+ */
102
+ export function defineLootPipeline(def) {
103
+ assertValidPipeline(def);
104
+ return def;
105
+ }
106
+ /**
107
+ * Build a composable loot-resolution pipeline: ordered source pools, context gates, fallbacks when a
108
+ * pool yields nothing, roll modifiers (luck, quantity, difficulty) applied as registered policies, and
109
+ * full provenance for every drop (stage, table, entry, original vs effective weights, modifier ids, seed).
110
+ * Rolling consumes the injected RNG in the same order as the base loot table, so a seeded resolution is
111
+ * deterministic and server-authoritatively replayable. Genre concepts (world, dedicated, boss, luck,
112
+ * rarity, pity) stay out of core and ship as stage/modifier compositions.
113
+ *
114
+ * @capability loot-pipeline compose ordered loot pools with fallbacks, roll modifiers, and provenance
115
+ */
116
+ export function createLootPipeline(def, deps = {}) {
117
+ assertValidPipeline(def);
118
+ function resolveStageTable(stage) {
119
+ if (typeof stage.table !== "string")
120
+ return stage.table;
121
+ const resolved = deps.resolveTable?.(stage.table);
122
+ if (resolved === undefined) {
123
+ throw new Error(`loot pipeline "${def.id}" stage "${stage.id}" references unknown table "${stage.table}"`);
124
+ }
125
+ return resolved;
126
+ }
127
+ return {
128
+ id: def.id,
129
+ resolve({ ctx, rng, seed }) {
130
+ let drops = [];
131
+ let provenance = [];
132
+ const traces = [];
133
+ for (const stage of def.stages) {
134
+ const kind = stage.kind ?? "contribute";
135
+ const modifierIds = (stage.modifiers ?? []).map((modifier) => modifier.id);
136
+ if (stage.when !== undefined && !stage.when(ctx)) {
137
+ traces.push({ stageId: stage.id, tableId: null, kind, status: "skipped", reason: "gate-false", modifiers: modifierIds, dropCount: 0 });
138
+ continue;
139
+ }
140
+ if (kind === "fallback" && drops.length > 0) {
141
+ traces.push({ stageId: stage.id, tableId: null, kind, status: "fell-through", reason: "prior-drops-present", modifiers: modifierIds, dropCount: 0 });
142
+ continue;
143
+ }
144
+ const tableDef = resolveStageTable(stage);
145
+ let plan = buildPlan(tableDef);
146
+ for (const modifier of stage.modifiers ?? []) {
147
+ if (modifier.plan !== undefined)
148
+ plan = modifier.plan(plan, ctx);
149
+ }
150
+ const rolled = rollPlan(plan, rng);
151
+ let stageDrops = rolled.map((entry) => entry.drop);
152
+ for (const modifier of stage.modifiers ?? []) {
153
+ if (modifier.drops !== undefined)
154
+ stageDrops = modifier.drops(stageDrops, ctx);
155
+ }
156
+ // Provenance tracks the rolled entries and their lineage; drop-only modifiers (dedupe/cap) may
157
+ // reshape counts, so provenance is emitted from the rolls that still carry entry indices.
158
+ const stageProvenance = rolled.map((entry) => {
159
+ const record = {
160
+ stageId: stage.id,
161
+ tableId: plan.tableId,
162
+ entryIndex: entry.planEntry.index,
163
+ modifiers: modifierIds,
164
+ };
165
+ if (entry.drop.item !== undefined)
166
+ record.item = entry.drop.item;
167
+ if (entry.drop.currency !== undefined)
168
+ record.currency = entry.drop.currency;
169
+ const source = entry.planEntry.entry;
170
+ if (plan.mode === "weighted") {
171
+ record.originalWeight = source.weight ?? 0;
172
+ record.effectiveWeight = entry.planEntry.weight;
173
+ }
174
+ else {
175
+ record.originalChance = source.chance ?? 0;
176
+ record.effectiveChance = entry.planEntry.chance ?? 0;
177
+ }
178
+ return record;
179
+ });
180
+ const status = stageDrops.length === 0 ? "empty" : kind === "replace" ? "replaced" : "rolled";
181
+ const trace = {
182
+ stageId: stage.id,
183
+ tableId: plan.tableId,
184
+ kind,
185
+ status,
186
+ modifiers: modifierIds,
187
+ dropCount: stageDrops.length,
188
+ };
189
+ if (status === "empty")
190
+ trace.reason = "empty-pool";
191
+ traces.push(trace);
192
+ if (stageDrops.length === 0)
193
+ continue;
194
+ if (kind === "replace") {
195
+ drops = stageDrops;
196
+ provenance = stageProvenance;
197
+ }
198
+ else {
199
+ drops = [...drops, ...stageDrops];
200
+ provenance = [...provenance, ...stageProvenance];
201
+ }
202
+ }
203
+ if (def.stack === true)
204
+ drops = stackDrops(drops);
205
+ if (def.maxDrops !== undefined && drops.length > def.maxDrops) {
206
+ drops = drops.slice(0, def.maxDrops);
207
+ provenance = provenance.slice(0, def.maxDrops);
208
+ traces.push({ stageId: "@cap", tableId: null, kind: "contribute", status: "skipped", reason: `capped-at-${def.maxDrops}`, modifiers: [], dropCount: 0 });
209
+ }
210
+ const resolution = { drops, provenance, stages: traces };
211
+ if (seed !== undefined)
212
+ resolution.seed = seed;
213
+ return resolution;
214
+ },
215
+ };
216
+ }
@@ -1,7 +1,15 @@
1
- /** One possible drop in a {@link LootTableDef} — an item or currency, its count range, and its odds. */
1
+ /** One possible drop in a {@link LootTableDef} — an item, currency, or generated item, its count range, and its odds. */
2
2
  export interface LootEntry {
3
3
  item?: string;
4
4
  currency?: string;
5
+ /**
6
+ * Roll a procedurally generated item instead of a static catalog id (a rolled unique gun, an
7
+ * affixed relic) — invoked with the roll's rng and returning the generated item's runtime id, the
8
+ * one `content.itemById` and inventories treat exactly like a static id (#536.1). Compose it with
9
+ * `item/itemInstanceRegistry`'s `proceduralLootEntry` over any procedural roller (e.g. `item/affix`'s
10
+ * `createAffixRoller`).
11
+ */
12
+ generate?: (rng: () => number) => string;
5
13
  count: number | [number, number];
6
14
  /** Relative pick weight — required in `"weighted"` mode, forbidden in `"independent"` mode. */
7
15
  weight?: number;
@@ -31,8 +39,17 @@ export interface LootRegistry {
31
39
  has(id: string): boolean;
32
40
  roll(id: string, rng?: () => number): Drop[];
33
41
  }
42
+ /**
43
+ * Register named loot tables and roll weighted randomized drops from them.
44
+ *
45
+ * @capability loot-table register loot tables and roll weighted randomized drops
46
+ */
34
47
  export declare function createLootRegistry(): LootRegistry;
35
- /** Validates a loot table definition and returns it unchanged, for use with {@link createLootRegistry}. */
48
+ /**
49
+ * Validates a loot table definition and returns it unchanged, for use with {@link createLootRegistry}.
50
+ *
51
+ * @capability loot-table validate a loot table definition for use with the registry
52
+ */
36
53
  export declare function lootTable(def: LootTableDef): LootTableDef;
37
54
  export declare function grantDrops(drops: Drop[], appliers: {
38
55
  putItem: (itemId: string, count: number) => unknown;
@@ -1,8 +1,7 @@
1
1
  function assertValidEntry(entry, mode) {
2
- const hasItem = entry.item !== undefined;
3
- const hasCurrency = entry.currency !== undefined;
4
- if (hasItem === hasCurrency) {
5
- throw new Error("loot entry must have exactly one of item or currency");
2
+ const kinds = [entry.item !== undefined, entry.currency !== undefined, entry.generate !== undefined].filter(Boolean).length;
3
+ if (kinds !== 1) {
4
+ throw new Error("loot entry must have exactly one of item, currency, or generate");
6
5
  }
7
6
  if (mode === "weighted") {
8
7
  if (entry.chance !== undefined) {
@@ -45,8 +44,15 @@ function pickEntry(entries, rng) {
45
44
  }
46
45
  function rollEntry(entry, rng) {
47
46
  const count = resolveCount(entry.count, rng);
47
+ if (entry.generate !== undefined)
48
+ return { item: entry.generate(rng), count };
48
49
  return entry.item !== undefined ? { item: entry.item, count } : { currency: entry.currency, count };
49
50
  }
51
+ /**
52
+ * Register named loot tables and roll weighted randomized drops from them.
53
+ *
54
+ * @capability loot-table register loot tables and roll weighted randomized drops
55
+ */
50
56
  export function createLootRegistry() {
51
57
  const tables = new Map();
52
58
  return {
@@ -82,7 +88,11 @@ export function createLootRegistry() {
82
88
  },
83
89
  };
84
90
  }
85
- /** Validates a loot table definition and returns it unchanged, for use with {@link createLootRegistry}. */
91
+ /**
92
+ * Validates a loot table definition and returns it unchanged, for use with {@link createLootRegistry}.
93
+ *
94
+ * @capability loot-table validate a loot table definition for use with the registry
95
+ */
86
96
  export function lootTable(def) {
87
97
  assertValidDef(def);
88
98
  return def;
@@ -0,0 +1,43 @@
1
+ /** Whether a metric must reach up to a target or stay down under it. */
2
+ export type ThresholdDirection = "atLeast" | "atMost";
3
+ /** A live-metric goal: hit `target` from the required `direction` (defaults to `atLeast`). */
4
+ export interface ThresholdObjective {
5
+ id: string;
6
+ target: number;
7
+ direction?: ThresholdDirection;
8
+ }
9
+ /** Evaluated state of one {@link ThresholdObjective} against a current metric value. */
10
+ export interface ObjectiveStatus {
11
+ id: string;
12
+ value: number;
13
+ target: number;
14
+ direction: ThresholdDirection;
15
+ /** True when the value satisfies the target from the required direction. */
16
+ met: boolean;
17
+ /** Fraction toward the target, 0..1 (1 once met). */
18
+ progress: number;
19
+ }
20
+ /**
21
+ * Evaluate a single live-metric objective: is `value` at least (or at most) the target, and how far along.
22
+ * Unlike an event counter, this reads a continuously-changing metric — population, approval, pollution —
23
+ * the objective shape city-builders and management sims track every tick.
24
+ *
25
+ * @capability objectives check progress of a threshold objective against a live metric
26
+ */
27
+ export declare function evaluateObjective(objective: ThresholdObjective, value: number): ObjectiveStatus;
28
+ /** Rolled-up state across a set of objectives. */
29
+ export interface ObjectiveSummary {
30
+ statuses: ObjectiveStatus[];
31
+ /** How many objectives are met. */
32
+ met: number;
33
+ total: number;
34
+ /** True when every objective is met. */
35
+ complete: boolean;
36
+ /** Mean progress across all objectives, 0..1. */
37
+ progress: number;
38
+ }
39
+ /**
40
+ * Evaluate every objective against current metric values (a lookup map or function) and roll them up into
41
+ * a met-count, completion flag, and mean progress — the brief/charter panel every sim renders.
42
+ */
43
+ export declare function evaluateObjectives(objectives: readonly ThresholdObjective[], values: Readonly<Record<string, number>> | ((id: string) => number)): ObjectiveSummary;