@jgengine/core 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/spawnDirector.d.ts +7 -2
  21. package/dist/ai/spawnDirector.js +18 -15
  22. package/dist/ai/spawnPoint.d.ts +3 -1
  23. package/dist/ai/spawnPoint.js +3 -1
  24. package/dist/ai/targetAcquisition.d.ts +84 -0
  25. package/dist/ai/targetAcquisition.js +92 -0
  26. package/dist/anim/easing.d.ts +19 -0
  27. package/dist/anim/easing.js +19 -0
  28. package/dist/anim/oscillator.d.ts +12 -0
  29. package/dist/anim/oscillator.js +25 -0
  30. package/dist/area/areaEffectField.d.ts +127 -0
  31. package/dist/area/areaEffectField.js +175 -0
  32. package/dist/area/stackPolicy.d.ts +47 -0
  33. package/dist/area/stackPolicy.js +99 -0
  34. package/dist/authoring.d.ts +1 -0
  35. package/dist/authoring.js +1 -0
  36. package/dist/board/laneBoard.d.ts +13 -0
  37. package/dist/board/laneBoard.js +13 -0
  38. package/dist/board/timelineBoard.d.ts +10 -0
  39. package/dist/board/timelineBoard.js +10 -0
  40. package/dist/combat/abilityKit.d.ts +18 -0
  41. package/dist/combat/abilityKit.js +24 -9
  42. package/dist/combat/animationState.d.ts +5 -0
  43. package/dist/combat/animationState.js +5 -0
  44. package/dist/combat/breakMeters.d.ts +10 -0
  45. package/dist/combat/breakMeters.js +10 -0
  46. package/dist/combat/castRunner.d.ts +5 -0
  47. package/dist/combat/castRunner.js +5 -0
  48. package/dist/combat/comboPoints.d.ts +5 -0
  49. package/dist/combat/comboPoints.js +5 -0
  50. package/dist/combat/comboString.d.ts +5 -0
  51. package/dist/combat/comboString.js +5 -0
  52. package/dist/combat/damageInterceptors.d.ts +192 -0
  53. package/dist/combat/damageInterceptors.js +251 -0
  54. package/dist/combat/damageMatchup.d.ts +68 -0
  55. package/dist/combat/damageMatchup.js +42 -0
  56. package/dist/combat/damageResolution.d.ts +63 -0
  57. package/dist/combat/damageResolution.js +50 -0
  58. package/dist/combat/death.d.ts +7 -1
  59. package/dist/combat/death.js +5 -0
  60. package/dist/combat/deathReason.d.ts +14 -0
  61. package/dist/combat/deathReason.js +1 -0
  62. package/dist/combat/defensiveWindow.d.ts +5 -0
  63. package/dist/combat/defensiveWindow.js +5 -0
  64. package/dist/combat/dotField.d.ts +5 -1
  65. package/dist/combat/dotField.js +5 -1
  66. package/dist/combat/downed.d.ts +5 -0
  67. package/dist/combat/downed.js +5 -0
  68. package/dist/combat/effects.d.ts +5 -0
  69. package/dist/combat/effects.js +5 -0
  70. package/dist/combat/encounterSequence.d.ts +258 -0
  71. package/dist/combat/encounterSequence.js +426 -0
  72. package/dist/combat/hitReaction.d.ts +57 -1
  73. package/dist/combat/hitReaction.js +45 -5
  74. package/dist/combat/magazine.d.ts +54 -0
  75. package/dist/combat/magazine.js +96 -0
  76. package/dist/combat/projectiles.d.ts +5 -0
  77. package/dist/combat/projectiles.js +32 -14
  78. package/dist/combat/receivedDamage.d.ts +117 -0
  79. package/dist/combat/receivedDamage.js +92 -0
  80. package/dist/combat/regenShield.d.ts +5 -1
  81. package/dist/combat/regenShield.js +5 -1
  82. package/dist/combat/renderCues.d.ts +51 -0
  83. package/dist/combat/renderCues.js +44 -0
  84. package/dist/combat/resourcePool.d.ts +5 -0
  85. package/dist/combat/resourcePool.js +5 -0
  86. package/dist/combat/rewardAllocation.d.ts +121 -0
  87. package/dist/combat/rewardAllocation.js +251 -0
  88. package/dist/combat/shotOrigin.d.ts +18 -1
  89. package/dist/combat/shotOrigin.js +39 -0
  90. package/dist/combat/statusApplication.d.ts +96 -0
  91. package/dist/combat/statusApplication.js +81 -0
  92. package/dist/combat/telegraph.d.ts +11 -2
  93. package/dist/combat/telegraph.js +11 -2
  94. package/dist/combat/thresholdCrossings.d.ts +85 -0
  95. package/dist/combat/thresholdCrossings.js +116 -0
  96. package/dist/combat.d.ts +34 -0
  97. package/dist/combat.js +34 -0
  98. package/dist/commands/commandRegistry.d.ts +11 -0
  99. package/dist/commands/commandRegistry.js +9 -2
  100. package/dist/crafting/crop.d.ts +18 -0
  101. package/dist/crafting/crop.js +18 -0
  102. package/dist/crafting/production.d.ts +5 -0
  103. package/dist/crafting/production.js +5 -0
  104. package/dist/devtools/rewriteTunables.d.ts +17 -0
  105. package/dist/devtools/rewriteTunables.js +276 -0
  106. package/dist/devtools/saveEndpoint.d.ts +46 -0
  107. package/dist/devtools/saveEndpoint.js +48 -0
  108. package/dist/devtools/transformTunables.d.ts +3 -0
  109. package/dist/devtools/transformTunables.js +3 -0
  110. package/dist/devtools/tunableSchema.d.ts +31 -0
  111. package/dist/devtools/tunableSchema.js +31 -0
  112. package/dist/economy/currency.d.ts +12 -1
  113. package/dist/economy/currency.js +12 -1
  114. package/dist/economy/listingBook.d.ts +91 -0
  115. package/dist/economy/listingBook.js +144 -0
  116. package/dist/economy/resourceLedger.d.ts +222 -0
  117. package/dist/economy/resourceLedger.js +353 -0
  118. package/dist/economy/sharedWallet.d.ts +14 -0
  119. package/dist/economy/sharedWallet.js +14 -0
  120. package/dist/economy/techTree.d.ts +12 -0
  121. package/dist/economy/techTree.js +12 -0
  122. package/dist/economy/wallet.d.ts +26 -2
  123. package/dist/economy/wallet.js +35 -6
  124. package/dist/editor/commands.d.ts +190 -7
  125. package/dist/editor/commands.js +727 -55
  126. package/dist/editor/document.d.ts +159 -13
  127. package/dist/editor/document.js +750 -19
  128. package/dist/editor/grid.d.ts +229 -0
  129. package/dist/editor/grid.js +366 -0
  130. package/dist/editor/gridAdapters.d.ts +80 -0
  131. package/dist/editor/gridAdapters.js +134 -0
  132. package/dist/editor/index.d.ts +73 -6
  133. package/dist/editor/index.js +6 -2
  134. package/dist/editor/liveSync.d.ts +127 -0
  135. package/dist/editor/liveSync.js +249 -0
  136. package/dist/editor/runtimeInspector.d.ts +88 -0
  137. package/dist/editor/runtimeInspector.js +239 -0
  138. package/dist/editor/types.d.ts +107 -1
  139. package/dist/faction/reputation.d.ts +5 -0
  140. package/dist/faction/reputation.js +5 -0
  141. package/dist/format/distance.d.ts +17 -0
  142. package/dist/format/distance.js +18 -0
  143. package/dist/format/duration.d.ts +27 -0
  144. package/dist/format/duration.js +45 -0
  145. package/dist/format/speed.d.ts +17 -0
  146. package/dist/format/speed.js +25 -0
  147. package/dist/game/connectedPlayers.d.ts +6 -4
  148. package/dist/game/connectedPlayers.js +2 -2
  149. package/dist/game/cosmetics.d.ts +9 -0
  150. package/dist/game/cosmetics.js +16 -0
  151. package/dist/game/defineGame.d.ts +100 -2
  152. package/dist/game/defineGame.js +39 -2
  153. package/dist/game/defineSystem.d.ts +88 -0
  154. package/dist/game/defineSystem.js +45 -0
  155. package/dist/game/dialogue.d.ts +33 -0
  156. package/dist/game/dialogue.js +21 -0
  157. package/dist/game/events.d.ts +35 -13
  158. package/dist/game/events.js +5 -0
  159. package/dist/game/feed.d.ts +33 -0
  160. package/dist/game/feed.js +35 -2
  161. package/dist/game/gamePhase.d.ts +11 -0
  162. package/dist/game/gamePhase.js +16 -0
  163. package/dist/game/leaderboard.d.ts +5 -0
  164. package/dist/game/leaderboard.js +5 -0
  165. package/dist/game/loadout.d.ts +5 -0
  166. package/dist/game/loadout.js +5 -0
  167. package/dist/game/lootFilter.d.ts +2 -0
  168. package/dist/game/lootFilter.js +2 -0
  169. package/dist/game/lootPipeline.d.ts +164 -0
  170. package/dist/game/lootPipeline.js +216 -0
  171. package/dist/game/lootTable.d.ts +19 -2
  172. package/dist/game/lootTable.js +15 -5
  173. package/dist/game/objectives.d.ts +43 -0
  174. package/dist/game/objectives.js +36 -0
  175. package/dist/game/paramLayers.d.ts +148 -0
  176. package/dist/game/paramLayers.js +185 -0
  177. package/dist/game/ping.d.ts +5 -0
  178. package/dist/game/ping.js +5 -0
  179. package/dist/game/playableGame.d.ts +92 -7
  180. package/dist/game/quest.d.ts +8 -0
  181. package/dist/game/quest.js +29 -0
  182. package/dist/game/race.d.ts +141 -0
  183. package/dist/game/race.js +169 -0
  184. package/dist/game/recordBook.d.ts +3 -1
  185. package/dist/game/recordBook.js +4 -1
  186. package/dist/game/ruleSelection.d.ts +75 -0
  187. package/dist/game/ruleSelection.js +127 -0
  188. package/dist/game/runDraft.d.ts +5 -0
  189. package/dist/game/runDraft.js +5 -0
  190. package/dist/game/saveStore.d.ts +111 -0
  191. package/dist/game/saveStore.js +312 -0
  192. package/dist/game/snapshotHistory.d.ts +67 -0
  193. package/dist/game/snapshotHistory.js +95 -0
  194. package/dist/game/social.d.ts +38 -1
  195. package/dist/game/social.js +71 -0
  196. package/dist/game/spawnPoints.d.ts +5 -0
  197. package/dist/game/spawnPoints.js +5 -0
  198. package/dist/game/systemRuntime.d.ts +50 -0
  199. package/dist/game/systemRuntime.js +157 -0
  200. package/dist/game/systemSchedule.d.ts +72 -0
  201. package/dist/game/systemSchedule.js +242 -0
  202. package/dist/game/toasts.d.ts +43 -0
  203. package/dist/game/toasts.js +44 -0
  204. package/dist/game/trade.d.ts +10 -0
  205. package/dist/game/trade.js +10 -0
  206. package/dist/game/unlocks.d.ts +8 -0
  207. package/dist/game/unlocks.js +16 -0
  208. package/dist/game/vfxInstance.d.ts +138 -0
  209. package/dist/game/vfxInstance.js +96 -0
  210. package/dist/game/worldItem.d.ts +17 -4
  211. package/dist/game/worldItem.js +17 -4
  212. package/dist/gameplay.d.ts +91 -0
  213. package/dist/gameplay.js +91 -0
  214. package/dist/index.d.ts +5 -14
  215. package/dist/index.js +5 -14
  216. package/dist/input/actionBindings.d.ts +23 -6
  217. package/dist/input/actionBindings.js +23 -6
  218. package/dist/input/axisInput.d.ts +7 -2
  219. package/dist/input/axisInput.js +7 -2
  220. package/dist/input/controlGroups.d.ts +67 -0
  221. package/dist/input/controlGroups.js +41 -0
  222. package/dist/input/touchScheme.d.ts +82 -6
  223. package/dist/input/touchScheme.js +123 -10
  224. package/dist/interaction/lockpick.d.ts +61 -0
  225. package/dist/interaction/lockpick.js +168 -0
  226. package/dist/interaction/proximityPrompt.d.ts +2 -0
  227. package/dist/interaction/proximityPrompt.js +2 -0
  228. package/dist/interaction/qte.d.ts +5 -0
  229. package/dist/interaction/qte.js +5 -0
  230. package/dist/interaction/skillCheck.d.ts +5 -0
  231. package/dist/interaction/skillCheck.js +5 -0
  232. package/dist/inventory/inventoryModel.d.ts +12 -0
  233. package/dist/inventory/inventoryModel.js +12 -0
  234. package/dist/inventory/shapedGrid.d.ts +16 -0
  235. package/dist/inventory/shapedGrid.js +16 -0
  236. package/dist/inventory/slotModel.d.ts +10 -0
  237. package/dist/inventory/slotModel.js +10 -0
  238. package/dist/item/durability.d.ts +5 -0
  239. package/dist/item/durability.js +5 -0
  240. package/dist/item/itemIdentity.d.ts +171 -0
  241. package/dist/item/itemIdentity.js +138 -0
  242. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  243. package/dist/item/itemInstanceRegistry.js +34 -0
  244. package/dist/item/itemgen.d.ts +163 -0
  245. package/dist/item/itemgen.js +151 -0
  246. package/dist/item/modularItem.d.ts +5 -0
  247. package/dist/item/modularItem.js +5 -0
  248. package/dist/item/use.d.ts +5 -0
  249. package/dist/item/use.js +5 -0
  250. package/dist/item/useBehavior.d.ts +142 -0
  251. package/dist/item/useBehavior.js +105 -0
  252. package/dist/item/weapon.d.ts +5 -0
  253. package/dist/item/weapon.js +5 -0
  254. package/dist/math/scalar.d.ts +25 -0
  255. package/dist/math/scalar.js +47 -0
  256. package/dist/meta/changelog.d.ts +4 -1
  257. package/dist/meta/changelog.js +16 -2
  258. package/dist/movement/avoidance.d.ts +45 -0
  259. package/dist/movement/avoidance.js +123 -0
  260. package/dist/movement/cameraRig.d.ts +8 -0
  261. package/dist/movement/cameraRig.js +8 -0
  262. package/dist/movement/dash.d.ts +11 -0
  263. package/dist/movement/dash.js +11 -0
  264. package/dist/movement/formation.d.ts +135 -0
  265. package/dist/movement/formation.js +194 -0
  266. package/dist/movement/glideModel.d.ts +5 -0
  267. package/dist/movement/glideModel.js +5 -0
  268. package/dist/movement/grappleSwing.d.ts +5 -0
  269. package/dist/movement/grappleSwing.js +5 -0
  270. package/dist/movement/leaderTrail.d.ts +5 -0
  271. package/dist/movement/leaderTrail.js +5 -0
  272. package/dist/movement/movementModel.d.ts +35 -8
  273. package/dist/movement/movementModel.js +42 -14
  274. package/dist/movement/playerMovement.js +65 -10
  275. package/dist/movement/poseState.d.ts +13 -0
  276. package/dist/movement/poseState.js +16 -0
  277. package/dist/movement/steering.d.ts +8 -0
  278. package/dist/movement/steering.js +18 -0
  279. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  280. package/dist/multiplayer/combatSnapshot.js +3 -0
  281. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  282. package/dist/multiplayer/lagCompensation.js +5 -0
  283. package/dist/multiplayer/presenceModel.d.ts +9 -1
  284. package/dist/multiplayer/presenceModel.js +9 -1
  285. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  286. package/dist/multiplayer/simultaneousCommit.js +3 -0
  287. package/dist/multiplayer.d.ts +11 -0
  288. package/dist/multiplayer.js +11 -0
  289. package/dist/nav/pathFollow.d.ts +57 -0
  290. package/dist/nav/pathFollow.js +109 -0
  291. package/dist/orders/orderKinds.d.ts +156 -0
  292. package/dist/orders/orderKinds.js +197 -0
  293. package/dist/orders/orderQueue.d.ts +208 -0
  294. package/dist/orders/orderQueue.js +211 -0
  295. package/dist/physics/drivableVehicle.d.ts +29 -0
  296. package/dist/physics/drivableVehicle.js +16 -0
  297. package/dist/physics/kinematicVehicle.d.ts +21 -1
  298. package/dist/physics/kinematicVehicle.js +23 -8
  299. package/dist/physics/physicsWorld.d.ts +24 -12
  300. package/dist/physics/physicsWorld.js +11 -5
  301. package/dist/physics/radialImpulse.d.ts +25 -0
  302. package/dist/physics/radialImpulse.js +27 -0
  303. package/dist/procedural.d.ts +3 -0
  304. package/dist/procedural.js +3 -0
  305. package/dist/progression/statGraph.d.ts +116 -0
  306. package/dist/progression/statGraph.js +318 -0
  307. package/dist/puzzle/cellGrid.d.ts +9 -0
  308. package/dist/puzzle/cellGrid.js +9 -0
  309. package/dist/puzzle/fallingPiece.d.ts +9 -0
  310. package/dist/puzzle/fallingPiece.js +9 -0
  311. package/dist/puzzle/nonogram.d.ts +39 -0
  312. package/dist/puzzle/nonogram.js +136 -0
  313. package/dist/random/nameGen.d.ts +5 -0
  314. package/dist/random/nameGen.js +5 -0
  315. package/dist/random/pick.d.ts +8 -0
  316. package/dist/random/pick.js +31 -0
  317. package/dist/random/rng.d.ts +22 -0
  318. package/dist/random/rng.js +28 -8
  319. package/dist/random/seedLink.d.ts +4 -0
  320. package/dist/random/seedLink.js +4 -0
  321. package/dist/relation/keyedValues.d.ts +54 -0
  322. package/dist/relation/keyedValues.js +115 -0
  323. package/dist/relation/thresholds.d.ts +62 -0
  324. package/dist/relation/thresholds.js +62 -0
  325. package/dist/render/color.d.ts +12 -0
  326. package/dist/render/color.js +26 -0
  327. package/dist/render/lookPreset.d.ts +41 -0
  328. package/dist/render/lookPreset.js +29 -0
  329. package/dist/render/postProcessing.d.ts +20 -0
  330. package/dist/render/postProcessing.js +21 -1
  331. package/dist/rules/predicate.d.ts +53 -0
  332. package/dist/rules/predicate.js +64 -0
  333. package/dist/rules/ruleEffects.d.ts +38 -0
  334. package/dist/rules/ruleEffects.js +37 -0
  335. package/dist/rules/triggeredRules.d.ts +160 -0
  336. package/dist/rules/triggeredRules.js +241 -0
  337. package/dist/runtime/adapter.d.ts +42 -3
  338. package/dist/runtime/adapter.js +44 -1
  339. package/dist/runtime/cameraDirector.d.ts +1 -0
  340. package/dist/runtime/cameraDirector.js +1 -0
  341. package/dist/runtime/commandRunner.d.ts +1 -0
  342. package/dist/runtime/commandRunner.js +1 -0
  343. package/dist/runtime/context/combatFx.d.ts +23 -0
  344. package/dist/runtime/context/combatFx.js +161 -0
  345. package/dist/runtime/context/registries.d.ts +13 -0
  346. package/dist/runtime/context/registries.js +84 -0
  347. package/dist/runtime/context/worldItems.d.ts +21 -0
  348. package/dist/runtime/context/worldItems.js +37 -0
  349. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  350. package/dist/runtime/descriptors/baseline.js +134 -0
  351. package/dist/runtime/descriptors/features.d.ts +74 -0
  352. package/dist/runtime/descriptors/features.js +281 -0
  353. package/dist/runtime/gameContext.d.ts +114 -13
  354. package/dist/runtime/gameContext.js +303 -395
  355. package/dist/runtime/gameRuntime.d.ts +1 -0
  356. package/dist/runtime/gameRuntime.js +1 -0
  357. package/dist/runtime/headlessRunner.d.ts +60 -0
  358. package/dist/runtime/headlessRunner.js +44 -0
  359. package/dist/runtime/hostPersistence.d.ts +12 -0
  360. package/dist/runtime/hostPersistence.js +12 -0
  361. package/dist/runtime/hostedGameRunner.d.ts +8 -3
  362. package/dist/runtime/hostedGameRunner.js +26 -3
  363. package/dist/runtime/hostedWorldSession.d.ts +12 -4
  364. package/dist/runtime/hostedWorldSession.js +11 -4
  365. package/dist/runtime/inputSnapshot.d.ts +8 -3
  366. package/dist/runtime/inputSnapshot.js +6 -2
  367. package/dist/runtime/motionIntents.d.ts +11 -2
  368. package/dist/runtime/motionIntents.js +16 -2
  369. package/dist/runtime/perContext.d.ts +15 -0
  370. package/dist/runtime/perContext.js +21 -0
  371. package/dist/runtime/runtimeSave.d.ts +79 -0
  372. package/dist/runtime/runtimeSave.js +105 -0
  373. package/dist/runtime/save.d.ts +4 -0
  374. package/dist/runtime/save.js +4 -0
  375. package/dist/runtime/snapshot.d.ts +7 -0
  376. package/dist/runtime/snapshot.js +7 -0
  377. package/dist/runtime/visibility.d.ts +2 -1
  378. package/dist/runtime/visibility.js +2 -1
  379. package/dist/runtime/worldChannel.d.ts +7 -3
  380. package/dist/runtime/worldChannel.js +51 -6
  381. package/dist/runtime/worldMirror.d.ts +14 -2
  382. package/dist/runtime/worldMirror.js +15 -2
  383. package/dist/runtime/worldProjection.d.ts +47 -0
  384. package/dist/runtime/worldProjection.js +52 -0
  385. package/dist/runtime/worldReplication.d.ts +30 -7
  386. package/dist/runtime/worldReplication.js +41 -9
  387. package/dist/runtime/worldSnapshot.d.ts +30 -3
  388. package/dist/runtime/worldSnapshot.js +20 -5
  389. package/dist/scene/assetCatalog.d.ts +21 -0
  390. package/dist/scene/assetCatalog.js +4 -0
  391. package/dist/scene/assetDiagnostics.d.ts +69 -0
  392. package/dist/scene/assetDiagnostics.js +110 -0
  393. package/dist/scene/assetGenerator.d.ts +65 -0
  394. package/dist/scene/assetGenerator.js +64 -0
  395. package/dist/scene/assetSpace.d.ts +137 -0
  396. package/dist/scene/assetSpace.js +259 -0
  397. package/dist/scene/authoredTriggers.d.ts +169 -0
  398. package/dist/scene/authoredTriggers.js +340 -0
  399. package/dist/scene/behaviorRuntime.d.ts +75 -0
  400. package/dist/scene/behaviorRuntime.js +217 -0
  401. package/dist/scene/behaviors.d.ts +14 -2
  402. package/dist/scene/behaviors.js +7 -2
  403. package/dist/scene/bodyBind.d.ts +60 -0
  404. package/dist/scene/bodyBind.js +51 -0
  405. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  406. package/dist/scene/builtinSceneKinds.js +62 -0
  407. package/dist/scene/colliders.d.ts +13 -1
  408. package/dist/scene/colliders.js +37 -1
  409. package/dist/scene/entityStats.d.ts +11 -2
  410. package/dist/scene/entityStats.js +11 -2
  411. package/dist/scene/entityStore.d.ts +12 -1
  412. package/dist/scene/entityStore.js +15 -0
  413. package/dist/scene/facing.d.ts +18 -0
  414. package/dist/scene/facing.js +26 -0
  415. package/dist/scene/modelSockets.d.ts +33 -0
  416. package/dist/scene/modelSockets.js +29 -0
  417. package/dist/scene/objectQuery.d.ts +2 -0
  418. package/dist/scene/objectQuery.js +2 -0
  419. package/dist/scene/objectStore.d.ts +4 -0
  420. package/dist/scene/objectStore.js +6 -0
  421. package/dist/scene/possession.d.ts +8 -0
  422. package/dist/scene/possession.js +14 -0
  423. package/dist/scene/roster.d.ts +3 -0
  424. package/dist/scene/roster.js +12 -0
  425. package/dist/scene/sceneKinds.d.ts +240 -0
  426. package/dist/scene/sceneKinds.js +214 -0
  427. package/dist/scene/sceneOwnership.d.ts +169 -0
  428. package/dist/scene/sceneOwnership.js +179 -0
  429. package/dist/scene/selectionBookmarks.d.ts +93 -0
  430. package/dist/scene/selectionBookmarks.js +122 -0
  431. package/dist/scene/vehicleSeat.d.ts +68 -0
  432. package/dist/scene/vehicleSeat.js +59 -0
  433. package/dist/sensor/concealment.d.ts +3 -0
  434. package/dist/sensor/concealment.js +3 -0
  435. package/dist/sensor/freezeMonitor.d.ts +1 -0
  436. package/dist/sensor/freezeMonitor.js +1 -0
  437. package/dist/sensor/frustumSensor.d.ts +7 -3
  438. package/dist/sensor/frustumSensor.js +7 -3
  439. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  440. package/dist/sensor/hiddenStateProbe.js +5 -2
  441. package/dist/sensor/recordingBuffer.d.ts +2 -1
  442. package/dist/sensor/recordingBuffer.js +2 -1
  443. package/dist/sensor/replayLoop.d.ts +6 -2
  444. package/dist/sensor/replayLoop.js +6 -2
  445. package/dist/sensor/revealQuery.d.ts +2 -1
  446. package/dist/sensor/revealQuery.js +2 -1
  447. package/dist/sensor/visionCone.d.ts +10 -3
  448. package/dist/sensor/visionCone.js +10 -3
  449. package/dist/session/contestedChannel.d.ts +1 -0
  450. package/dist/session/contestedChannel.js +1 -0
  451. package/dist/session/extraction.d.ts +1 -0
  452. package/dist/session/extraction.js +1 -0
  453. package/dist/session/roles.d.ts +6 -0
  454. package/dist/session/roles.js +6 -0
  455. package/dist/session/roundState.d.ts +8 -0
  456. package/dist/session/roundState.js +2 -0
  457. package/dist/settings/settingsModel.d.ts +1 -0
  458. package/dist/settings/settingsModel.js +1 -0
  459. package/dist/stats/accumulatorMeter.d.ts +6 -0
  460. package/dist/stats/accumulatorMeter.js +6 -0
  461. package/dist/stats/eventMeter.d.ts +5 -0
  462. package/dist/stats/eventMeter.js +5 -0
  463. package/dist/stats/rollCheck.d.ts +5 -0
  464. package/dist/stats/rollCheck.js +5 -0
  465. package/dist/stats/statModifiers.d.ts +5 -0
  466. package/dist/stats/statModifiers.js +5 -0
  467. package/dist/store/defineKeyedStore.d.ts +38 -0
  468. package/dist/store/defineKeyedStore.js +42 -0
  469. package/dist/store/defineStore.d.ts +33 -0
  470. package/dist/store/defineStore.js +35 -0
  471. package/dist/store/observableKeyedStore.d.ts +5 -0
  472. package/dist/store/observableKeyedStore.js +34 -2
  473. package/dist/survival/decayMeter.d.ts +55 -0
  474. package/dist/survival/decayMeter.js +130 -55
  475. package/dist/survival/moodle.d.ts +2 -0
  476. package/dist/survival/regionHealth.d.ts +6 -0
  477. package/dist/survival/regionHealth.js +5 -0
  478. package/dist/tactics/fallingGrid.d.ts +4 -2
  479. package/dist/tactics/fallingGrid.js +4 -2
  480. package/dist/tactics/predictiveQuery.d.ts +3 -0
  481. package/dist/tactics/predictiveQuery.js +3 -0
  482. package/dist/tactics/snapshot.d.ts +2 -0
  483. package/dist/tactics/snapshot.js +2 -0
  484. package/dist/tactics/surface.d.ts +1 -0
  485. package/dist/tactics/surface.js +1 -0
  486. package/dist/tactics/tacticalGrid.d.ts +1 -0
  487. package/dist/tactics/tacticalGrid.js +1 -0
  488. package/dist/time/beatClock.d.ts +14 -4
  489. package/dist/time/beatClock.js +14 -4
  490. package/dist/time/calendarClock.d.ts +3 -0
  491. package/dist/time/calendarClock.js +3 -0
  492. package/dist/time/idleProgress.d.ts +4 -0
  493. package/dist/time/idleProgress.js +4 -0
  494. package/dist/time/simClock.d.ts +2 -0
  495. package/dist/time/simClock.js +20 -5
  496. package/dist/ui/actionModel.d.ts +110 -0
  497. package/dist/ui/actionModel.js +159 -0
  498. package/dist/ui/gameLayout.d.ts +30 -11
  499. package/dist/ui/gameLayout.js +30 -11
  500. package/dist/ui/hudDocument.d.ts +114 -0
  501. package/dist/ui/hudDocument.js +220 -0
  502. package/dist/ui/hudLayout.d.ts +33 -1
  503. package/dist/ui/hudLayout.js +204 -17
  504. package/dist/ui/selectionModel.d.ts +92 -0
  505. package/dist/ui/selectionModel.js +88 -0
  506. package/dist/ui/tooltipModel.d.ts +63 -0
  507. package/dist/ui/tooltipModel.js +82 -0
  508. package/dist/ui.d.ts +15 -0
  509. package/dist/ui.js +15 -0
  510. package/dist/visibility/bounds.d.ts +8 -1
  511. package/dist/visibility/bounds.js +8 -1
  512. package/dist/visibility/frustum.d.ts +12 -3
  513. package/dist/visibility/frustum.js +12 -3
  514. package/dist/work/jobQueue.d.ts +201 -0
  515. package/dist/work/jobQueue.js +253 -0
  516. package/dist/work/unitTraining.d.ts +58 -0
  517. package/dist/work/unitTraining.js +52 -0
  518. package/dist/world/authoredObjects.d.ts +58 -0
  519. package/dist/world/authoredObjects.js +69 -0
  520. package/dist/world/buildingGenerator.d.ts +18 -0
  521. package/dist/world/buildingGenerator.js +62 -0
  522. package/dist/world/buildings.d.ts +5 -0
  523. package/dist/world/buildings.js +5 -0
  524. package/dist/world/catenary.d.ts +22 -0
  525. package/dist/world/catenary.js +69 -0
  526. package/dist/world/features.d.ts +115 -7
  527. package/dist/world/features.js +56 -5
  528. package/dist/world/footprintGrid.d.ts +59 -0
  529. package/dist/world/footprintGrid.js +141 -0
  530. package/dist/world/geometry.d.ts +64 -0
  531. package/dist/world/geometry.js +94 -0
  532. package/dist/world/grassKind.d.ts +51 -0
  533. package/dist/world/grassKind.js +101 -0
  534. package/dist/world/pathInstances.d.ts +27 -0
  535. package/dist/world/pathInstances.js +27 -0
  536. package/dist/world/pathTerrain.d.ts +80 -0
  537. package/dist/world/pathTerrain.js +142 -0
  538. package/dist/world/placeAsset.d.ts +81 -0
  539. package/dist/world/placeAsset.js +77 -0
  540. package/dist/world/placement.d.ts +4 -0
  541. package/dist/world/placement.js +4 -0
  542. package/dist/world/placementController.d.ts +6 -0
  543. package/dist/world/placementController.js +6 -0
  544. package/dist/world/polyline.d.ts +34 -0
  545. package/dist/world/polyline.js +81 -0
  546. package/dist/world/roads.d.ts +8 -0
  547. package/dist/world/roads.js +38 -0
  548. package/dist/world/scatterRegion.d.ts +164 -0
  549. package/dist/world/scatterRegion.js +409 -0
  550. package/dist/world/sceneShapes.d.ts +43 -0
  551. package/dist/world/sceneShapes.js +1 -0
  552. package/dist/world/segment.d.ts +27 -0
  553. package/dist/world/segment.js +43 -0
  554. package/dist/world/soilKind.d.ts +48 -0
  555. package/dist/world/soilKind.js +92 -0
  556. package/dist/world/spatialSample.d.ts +241 -0
  557. package/dist/world/spatialSample.js +465 -0
  558. package/dist/world/terraform.d.ts +213 -1
  559. package/dist/world/terraform.js +655 -20
  560. package/dist/world/terrain.d.ts +119 -20
  561. package/dist/world/terrain.js +247 -41
  562. package/dist/world/terrainGuides.d.ts +182 -0
  563. package/dist/world/terrainGuides.js +343 -0
  564. package/dist/world/vec2.d.ts +81 -0
  565. package/dist/world/vec2.js +128 -0
  566. package/dist/world/vec3.d.ts +49 -0
  567. package/dist/world/vec3.js +76 -0
  568. package/dist/world/vegetation.d.ts +71 -0
  569. package/dist/world/vegetation.js +151 -0
  570. package/dist/world/visibilityField.d.ts +154 -0
  571. package/dist/world/visibilityField.js +271 -0
  572. package/dist/world/volumetricClouds.d.ts +52 -0
  573. package/dist/world/volumetricClouds.js +43 -0
  574. package/dist/world/walls.d.ts +9 -0
  575. package/dist/world/walls.js +9 -0
  576. package/dist/world/waterKind.d.ts +55 -0
  577. package/dist/world/waterKind.js +99 -0
  578. package/dist/world.d.ts +132 -0
  579. package/dist/world.js +132 -0
  580. package/package.json +32 -8
  581. package/skills/jgengine/SKILL.md +51 -0
  582. package/skills/jgengine/api.md +434 -0
  583. package/skills/jgengine/capabilities.md +29 -0
  584. package/skills/jgengine/reference-cartridge.md +72 -0
  585. package/skills/jgengine-combat/SKILL.md +34 -0
  586. package/skills/jgengine-combat/api.md +549 -0
  587. package/skills/jgengine-combat/capabilities.md +169 -0
  588. package/skills/jgengine-combat/reference.md +98 -0
  589. package/skills/jgengine-gameplay/SKILL.md +39 -0
  590. package/skills/jgengine-gameplay/api.md +1794 -0
  591. package/skills/jgengine-gameplay/capabilities.md +378 -0
  592. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  593. package/skills/jgengine-world/SKILL.md +38 -0
  594. package/skills/jgengine-world/api.md +2652 -0
  595. package/skills/jgengine-world/capabilities.md +370 -0
  596. package/skills/jgengine-world/reference.md +222 -0
  597. package/dist/cartridge/runtime.d.ts +0 -15
  598. package/dist/cartridge/runtime.js +0 -556
  599. package/dist/cartridge/spec.d.ts +0 -188
  600. package/dist/cartridge/spec.js +0 -19
  601. package/dist/cartridge/validate.d.ts +0 -2
  602. package/dist/cartridge/validate.js +0 -78
  603. package/dist/store/engineStore.d.ts +0 -22
  604. package/dist/store/engineStore.js +0 -50
  605. package/dist/store/features.d.ts +0 -10
  606. package/dist/store/features.js +0 -23
  607. package/llms.txt +0 -5389
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Pick one item uniformly at random from `items` using `rng` (a `() => number` in `[0, 1)`); returns undefined when empty.
3
+ *
4
+ * @capability weighted-pick pick one item from a set with an injected random source
5
+ */
6
+ export declare function pickUniform<T>(rng: () => number, items: readonly T[]): T | undefined;
7
+ /** Pick one item with probability proportional to `weightOf(item)`; skips non-positive weights, returns undefined when nothing is eligible. */
8
+ export declare function pickWeighted<T>(rng: () => number, items: readonly T[], weightOf: (item: T) => number): T | undefined;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Pick one item uniformly at random from `items` using `rng` (a `() => number` in `[0, 1)`); returns undefined when empty.
3
+ *
4
+ * @capability weighted-pick pick one item from a set with an injected random source
5
+ */
6
+ export function pickUniform(rng, items) {
7
+ if (items.length === 0)
8
+ return undefined;
9
+ return items[Math.min(items.length - 1, Math.floor(rng() * items.length))];
10
+ }
11
+ /** Pick one item with probability proportional to `weightOf(item)`; skips non-positive weights, returns undefined when nothing is eligible. */
12
+ export function pickWeighted(rng, items, weightOf) {
13
+ let total = 0;
14
+ for (const item of items) {
15
+ const weight = weightOf(item);
16
+ if (weight > 0)
17
+ total += weight;
18
+ }
19
+ if (total <= 0)
20
+ return undefined;
21
+ let roll = rng() * total;
22
+ for (const item of items) {
23
+ const weight = weightOf(item);
24
+ if (weight <= 0)
25
+ continue;
26
+ roll -= weight;
27
+ if (roll <= 0)
28
+ return item;
29
+ }
30
+ return items[items.length - 1];
31
+ }
@@ -1,3 +1,25 @@
1
+ /**
2
+ * Deterministic 32-bit FNV-1a hash of a string → unsigned int. Same text, same number, on every
3
+ * platform — the stable seed behind per-id jitter, spread offsets, and content-addressed variation.
4
+ */
5
+ export declare function hashString(text: string): number;
6
+ /**
7
+ * Opaque, serializable PRNG cursor for state machines that must persist their own random stream
8
+ * (a spawn director, a heat/pursuit meter) instead of holding a closure — the state round-trips
9
+ * through save/load and multiplayer sync, so it can't carry a function. Never read or do
10
+ * arithmetic on the raw value directly; thread it through {@link stepRandomSeed} only.
11
+ */
12
+ export type RandomSeed = number & {
13
+ readonly __randomSeed: unique symbol;
14
+ };
15
+ /** Wraps an already-integer seed (e.g. a `config.seed`) as a {@link RandomSeed} — no hashing. */
16
+ export declare function randomSeedFrom(seed: number): RandomSeed;
17
+ /**
18
+ * One step of the {@link seededRng} recurrence in pure (seed in, seed out) form — the same
19
+ * mulberry32-style generator, shared by every state machine that persists its own PRNG cursor
20
+ * instead of closing over a generator.
21
+ */
22
+ export declare function stepRandomSeed(seed: RandomSeed): readonly [value: number, next: RandomSeed];
1
23
  /** Deterministic pseudo-random generator seeded from a string or number — same seed, same sequence. */
2
24
  export declare function seededRng(seed: string | number): () => number;
3
25
  /** Derives independent, deterministic {@link seededRng} streams from one base seed, keyed by stream name. */
@@ -1,5 +1,8 @@
1
- function hashSeed(seed) {
2
- const text = typeof seed === "number" ? seed.toString() : seed;
1
+ /**
2
+ * Deterministic 32-bit FNV-1a hash of a string → unsigned int. Same text, same number, on every
3
+ * platform — the stable seed behind per-id jitter, spread offsets, and content-addressed variation.
4
+ */
5
+ export function hashString(text) {
3
6
  let h = 2166136261 >>> 0;
4
7
  for (let i = 0; i < text.length; i++) {
5
8
  h ^= text.charCodeAt(i);
@@ -7,15 +10,32 @@ function hashSeed(seed) {
7
10
  }
8
11
  return h >>> 0;
9
12
  }
13
+ function hashSeed(seed) {
14
+ return hashString(typeof seed === "number" ? seed.toString() : seed);
15
+ }
16
+ /** Wraps an already-integer seed (e.g. a `config.seed`) as a {@link RandomSeed} — no hashing. */
17
+ export function randomSeedFrom(seed) {
18
+ return (seed | 0);
19
+ }
20
+ /**
21
+ * One step of the {@link seededRng} recurrence in pure (seed in, seed out) form — the same
22
+ * mulberry32-style generator, shared by every state machine that persists its own PRNG cursor
23
+ * instead of closing over a generator.
24
+ */
25
+ export function stepRandomSeed(seed) {
26
+ const next = (seed + 0x6d2b79f5) | 0;
27
+ let t = Math.imul(next ^ (next >>> 15), 1 | next);
28
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
29
+ const value = ((t ^ (t >>> 14)) >>> 0) / 4294967296;
30
+ return [value, next];
31
+ }
10
32
  /** Deterministic pseudo-random generator seeded from a string or number — same seed, same sequence. */
11
33
  export function seededRng(seed) {
12
- let a = hashSeed(seed) >>> 0;
34
+ let cursor = randomSeedFrom(hashSeed(seed));
13
35
  return () => {
14
- a = (a + 0x6d2b79f5) >>> 0;
15
- let t = a;
16
- t = Math.imul(t ^ (t >>> 15), t | 1);
17
- t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
18
- return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
36
+ const [value, next] = stepRandomSeed(cursor);
37
+ cursor = next;
38
+ return value;
19
39
  };
20
40
  }
21
41
  /** Derives independent, deterministic {@link seededRng} streams from one base seed, keyed by stream name. */
@@ -1,5 +1,9 @@
1
1
  export declare const DEFAULT_SEED_PARAM = "seed";
2
+ /** @internal */
2
3
  export declare function withSeedParam(url: string, seed: string | number, param?: string): string;
4
+ /** @internal */
3
5
  export declare function seedFromSearch(search: string, param?: string): string | null;
6
+ /** @internal */
4
7
  export declare function seedFromUrl(url: string, param?: string): string | null;
8
+ /** @internal */
5
9
  export declare function dailySeed(nowMs: number, salt?: string): string;
@@ -8,6 +8,7 @@ function splitUrl(url) {
8
8
  const query = queryIndex === -1 ? "" : rest.slice(queryIndex + 1);
9
9
  return { base, query, hash };
10
10
  }
11
+ /** @internal */
11
12
  export function withSeedParam(url, seed, param = DEFAULT_SEED_PARAM) {
12
13
  const { base, query, hash } = splitUrl(url);
13
14
  const params = new URLSearchParams(query);
@@ -15,16 +16,19 @@ export function withSeedParam(url, seed, param = DEFAULT_SEED_PARAM) {
15
16
  const queryString = params.toString();
16
17
  return `${base}${queryString ? `?${queryString}` : ""}${hash ? `#${hash}` : ""}`;
17
18
  }
19
+ /** @internal */
18
20
  export function seedFromSearch(search, param = DEFAULT_SEED_PARAM) {
19
21
  const normalized = search.startsWith("?") ? search.slice(1) : search;
20
22
  const params = new URLSearchParams(normalized);
21
23
  const value = params.get(param);
22
24
  return value === null || value === "" ? null : value;
23
25
  }
26
+ /** @internal */
24
27
  export function seedFromUrl(url, param = DEFAULT_SEED_PARAM) {
25
28
  const { query } = splitUrl(url);
26
29
  return seedFromSearch(query, param);
27
30
  }
31
+ /** @internal */
28
32
  export function dailySeed(nowMs, salt) {
29
33
  const date = new Date(nowMs);
30
34
  const year = date.getUTCFullYear().toString().padStart(4, "0");
@@ -0,0 +1,54 @@
1
+ /** Optional inclusive `[min, max]` clamp applied after a write. Omit an edge for unbounded. */
2
+ export interface NumericBounds {
3
+ readonly min?: number;
4
+ readonly max?: number;
5
+ }
6
+ /** Clamp a scalar to `bounds` (identity when `bounds` is omitted). Pure — touches no record. */
7
+ export declare function clampValue(value: number, bounds?: NumericBounds): number;
8
+ /** Current value for `key`, or `fallback` (default `0`) when the record has no entry. */
9
+ export declare function getValue(record: Record<string, number>, key: string, fallback?: number): number;
10
+ /**
11
+ * Set `key` to `value` (clamped to `bounds`), writing the record in place. Returns the stored value.
12
+ *
13
+ * @capability set a bounded keyed value in a caller-owned serializable record
14
+ */
15
+ export declare function setValue(record: Record<string, number>, key: string, value: number, bounds?: NumericBounds): number;
16
+ /** Add `delta` to `key` (clamped to `bounds`), writing the record in place. Returns the stored value. */
17
+ export declare function addValue(record: Record<string, number>, key: string, delta: number, bounds?: NumericBounds): number;
18
+ /**
19
+ * Step `key` toward `target` by at most `maxDelta` without overshooting, then clamp
20
+ * to `bounds`. Writes in place and returns the stored value.
21
+ *
22
+ * @capability move a keyed value toward a target by a bounded step
23
+ */
24
+ export declare function towardValue(record: Record<string, number>, key: string, target: number, maxDelta: number, bounds?: NumericBounds): number;
25
+ /**
26
+ * Decay `key` toward a `rest` value (default `0`) by `rate` per call — the common
27
+ * "relationships cool off" / "heat fades" drift. Thin wrapper over {@link towardValue}.
28
+ */
29
+ export declare function driftValue(record: Record<string, number>, key: string, rate: number, rest?: number, bounds?: NumericBounds): number;
30
+ /** Canonicalizes a two-part relation identity into a single delimiter-safe record key. */
31
+ export interface PairKeyCodec {
32
+ /** `true` when order matters (a→b differs from b→a); `false` sorts the pair first. */
33
+ readonly directed: boolean;
34
+ /** Encode a pair into one record key. Undirected codecs canonicalize by sorting the two ids. */
35
+ key(a: string, b: string): string;
36
+ /** Recover the pair from a key. Undirected keys come back in canonical (sorted) order. */
37
+ parse(key: string): [string, string];
38
+ }
39
+ /** Direction and delimiter policy for {@link createPairKeyCodec}. */
40
+ export interface PairKeyOptions {
41
+ /** `true` for ordered relations (rivalry-from, owes-to); default `false` (mutual). */
42
+ readonly directed?: boolean;
43
+ /** Single-character delimiter between encoded ids (default `"|"`). Collisions are escaped, not forbidden. */
44
+ readonly separator?: string;
45
+ }
46
+ /**
47
+ * Build a pair-key codec for keyed relation values. Ids are escaped before joining,
48
+ * so any id (including ones containing the separator or a backslash) round-trips
49
+ * through {@link PairKeyCodec.key} → {@link PairKeyCodec.parse} without collision.
50
+ * Undirected codecs (the default) canonicalize so `key(a, b) === key(b, a)`.
51
+ *
52
+ * @capability build a serializable directed/undirected pair key that resists delimiter collisions
53
+ */
54
+ export declare function createPairKeyCodec(options?: PairKeyOptions): PairKeyCodec;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Pure, serialization-friendly numeric operations over a caller-owned record of
3
+ * keyed values, plus delimiter-safe pair-key codecs for directed and undirected
4
+ * relations.
5
+ *
6
+ * No hidden state and no social semantics: the record, its bounds, drift rates,
7
+ * and keys are all caller data. Operations mutate the passed record in place and
8
+ * return the resulting value, so a game keeps one plain `Record<string, number>`
9
+ * it can serialize with `JSON.stringify` and restore verbatim. Pair keys are the
10
+ * injectable canonicalizer — compose `codec.key(a, b)` into any of the ops below.
11
+ */
12
+ import { clamp, moveTowards } from "../math/scalar.js";
13
+ function applyBounds(value, bounds) {
14
+ return clamp(value, bounds?.min ?? Number.NEGATIVE_INFINITY, bounds?.max ?? Number.POSITIVE_INFINITY);
15
+ }
16
+ /** Clamp a scalar to `bounds` (identity when `bounds` is omitted). Pure — touches no record. */
17
+ export function clampValue(value, bounds) {
18
+ return applyBounds(value, bounds);
19
+ }
20
+ /** Current value for `key`, or `fallback` (default `0`) when the record has no entry. */
21
+ export function getValue(record, key, fallback = 0) {
22
+ const stored = record[key];
23
+ return stored === undefined ? fallback : stored;
24
+ }
25
+ /**
26
+ * Set `key` to `value` (clamped to `bounds`), writing the record in place. Returns the stored value.
27
+ *
28
+ * @capability set a bounded keyed value in a caller-owned serializable record
29
+ */
30
+ export function setValue(record, key, value, bounds) {
31
+ const next = applyBounds(value, bounds);
32
+ record[key] = next;
33
+ return next;
34
+ }
35
+ /** Add `delta` to `key` (clamped to `bounds`), writing the record in place. Returns the stored value. */
36
+ export function addValue(record, key, delta, bounds) {
37
+ return setValue(record, key, getValue(record, key) + delta, bounds);
38
+ }
39
+ /**
40
+ * Step `key` toward `target` by at most `maxDelta` without overshooting, then clamp
41
+ * to `bounds`. Writes in place and returns the stored value.
42
+ *
43
+ * @capability move a keyed value toward a target by a bounded step
44
+ */
45
+ export function towardValue(record, key, target, maxDelta, bounds) {
46
+ const step = maxDelta > 0 ? maxDelta : 0;
47
+ return setValue(record, key, moveTowards(getValue(record, key), target, step), bounds);
48
+ }
49
+ /**
50
+ * Decay `key` toward a `rest` value (default `0`) by `rate` per call — the common
51
+ * "relationships cool off" / "heat fades" drift. Thin wrapper over {@link towardValue}.
52
+ */
53
+ export function driftValue(record, key, rate, rest = 0, bounds) {
54
+ return towardValue(record, key, rest, rate, bounds);
55
+ }
56
+ const ESCAPE = "\\";
57
+ function escapeComponent(value, separator) {
58
+ let out = "";
59
+ for (const ch of value) {
60
+ if (ch === ESCAPE || ch === separator)
61
+ out += ESCAPE;
62
+ out += ch;
63
+ }
64
+ return out;
65
+ }
66
+ function splitEscaped(key, separator) {
67
+ const parts = [];
68
+ let current = "";
69
+ let escaped = false;
70
+ for (const ch of key) {
71
+ if (escaped) {
72
+ current += ch;
73
+ escaped = false;
74
+ }
75
+ else if (ch === ESCAPE) {
76
+ escaped = true;
77
+ }
78
+ else if (ch === separator) {
79
+ parts.push(current);
80
+ current = "";
81
+ }
82
+ else {
83
+ current += ch;
84
+ }
85
+ }
86
+ parts.push(current);
87
+ return [parts[0] ?? "", parts[1] ?? ""];
88
+ }
89
+ /**
90
+ * Build a pair-key codec for keyed relation values. Ids are escaped before joining,
91
+ * so any id (including ones containing the separator or a backslash) round-trips
92
+ * through {@link PairKeyCodec.key} → {@link PairKeyCodec.parse} without collision.
93
+ * Undirected codecs (the default) canonicalize so `key(a, b) === key(b, a)`.
94
+ *
95
+ * @capability build a serializable directed/undirected pair key that resists delimiter collisions
96
+ */
97
+ export function createPairKeyCodec(options = {}) {
98
+ const directed = options.directed ?? false;
99
+ const separator = options.separator ?? "|";
100
+ if (separator.length !== 1) {
101
+ throw new Error(`pair-key separator must be a single character, got ${JSON.stringify(separator)}`);
102
+ }
103
+ if (separator === ESCAPE)
104
+ throw new Error("pair-key separator cannot be the escape character '\\'");
105
+ return {
106
+ directed,
107
+ key(a, b) {
108
+ const [first, second] = directed || a <= b ? [a, b] : [b, a];
109
+ return `${escapeComponent(first, separator)}${separator}${escapeComponent(second, separator)}`;
110
+ },
111
+ parse(key) {
112
+ return splitEscaped(key, separator);
113
+ },
114
+ };
115
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Generic threshold-crossing detection over ordered numeric boundaries.
3
+ *
4
+ * Deliberately relationship-agnostic and stateless: the same helper reports
5
+ * reputation-tier transitions, meter milestones, temperature bands, ecosystem
6
+ * pressure, difficulty ramps, or any value moving across labelled cut points.
7
+ * Callers pass `before`/`after` and receive the crossings between them, so the
8
+ * logic never lives inside a ledger or owns hidden state.
9
+ */
10
+ export type ThresholdDirection = "up" | "down";
11
+ /** A labelled cut point on the value axis. `Id` is caller-owned (string, enum, or a policy object). */
12
+ export interface ThresholdBoundary<Id = string> {
13
+ /** Stable identifier reported when this boundary is crossed. */
14
+ readonly id: Id;
15
+ /** Numeric position of the boundary on the value axis. */
16
+ readonly at: number;
17
+ }
18
+ /** A single boundary transition between a `before` and `after` value. */
19
+ export interface ThresholdCrossing<Id = string> {
20
+ readonly id: Id;
21
+ readonly at: number;
22
+ readonly direction: ThresholdDirection;
23
+ }
24
+ /** Exact-boundary and dead-band policy for {@link crossThresholds}. */
25
+ export interface CrossThresholdsOptions {
26
+ /**
27
+ * When true (default) a boundary is *occupied* at `value >= at`; when false it
28
+ * is occupied only at `value > at`. Controls exact-boundary semantics: with the
29
+ * default, landing exactly on `at` counts as an upward crossing and keeps you
30
+ * above on the way down.
31
+ */
32
+ readonly inclusive?: boolean;
33
+ /**
34
+ * Symmetric dead-band (clamped to `>= 0`). An upward crossing of `at` requires
35
+ * reaching `at + hysteresis`; a downward crossing requires falling below
36
+ * `at - hysteresis`. Suppresses flapping when a value oscillates around a
37
+ * boundary. Defaults to `0` (no dead-band).
38
+ */
39
+ readonly hysteresis?: number;
40
+ }
41
+ /**
42
+ * Report every boundary crossed moving from `before` to `after`.
43
+ *
44
+ * Upward moves yield `up` crossings in ascending `at` order; downward moves yield
45
+ * `down` crossings in descending order. Large jumps report every boundary passed;
46
+ * a zero-width move reports nothing. Boundaries need not be pre-sorted.
47
+ *
48
+ * @capability detect fire-once threshold/milestone/tier crossings when a value moves
49
+ */
50
+ export declare function crossThresholds<Id>(boundaries: readonly ThresholdBoundary<Id>[], before: number, after: number, options?: CrossThresholdsOptions): ThresholdCrossing<Id>[];
51
+ /**
52
+ * The highest boundary at-or-below `value` — the band the value currently sits in.
53
+ * Returns `null` when `value` is below every boundary. Boundaries need not be sorted.
54
+ *
55
+ * Tier labels stay caller policy: pass an `Id` object carrying whatever label,
56
+ * relation, or colour the game needs.
57
+ *
58
+ * @capability resolve the current tier/band label for a keyed or scalar value
59
+ */
60
+ export declare function tierAt<Id>(boundaries: readonly ThresholdBoundary<Id>[], value: number, options?: {
61
+ readonly inclusive?: boolean;
62
+ }): ThresholdBoundary<Id> | null;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Generic threshold-crossing detection over ordered numeric boundaries.
3
+ *
4
+ * Deliberately relationship-agnostic and stateless: the same helper reports
5
+ * reputation-tier transitions, meter milestones, temperature bands, ecosystem
6
+ * pressure, difficulty ramps, or any value moving across labelled cut points.
7
+ * Callers pass `before`/`after` and receive the crossings between them, so the
8
+ * logic never lives inside a ledger or owns hidden state.
9
+ */
10
+ /**
11
+ * Report every boundary crossed moving from `before` to `after`.
12
+ *
13
+ * Upward moves yield `up` crossings in ascending `at` order; downward moves yield
14
+ * `down` crossings in descending order. Large jumps report every boundary passed;
15
+ * a zero-width move reports nothing. Boundaries need not be pre-sorted.
16
+ *
17
+ * @capability detect fire-once threshold/milestone/tier crossings when a value moves
18
+ */
19
+ export function crossThresholds(boundaries, before, after, options = {}) {
20
+ if (after === before)
21
+ return [];
22
+ const inclusive = options.inclusive ?? true;
23
+ const margin = options.hysteresis !== undefined && options.hysteresis > 0 ? options.hysteresis : 0;
24
+ const rising = after > before;
25
+ const occupied = (value, edge) => (inclusive ? value >= edge : value > edge);
26
+ const crossings = [];
27
+ for (const boundary of boundaries) {
28
+ if (rising) {
29
+ const edge = boundary.at + margin;
30
+ if (!occupied(before, edge) && occupied(after, edge)) {
31
+ crossings.push({ id: boundary.id, at: boundary.at, direction: "up" });
32
+ }
33
+ }
34
+ else {
35
+ const edge = boundary.at - margin;
36
+ if (occupied(before, edge) && !occupied(after, edge)) {
37
+ crossings.push({ id: boundary.id, at: boundary.at, direction: "down" });
38
+ }
39
+ }
40
+ }
41
+ crossings.sort((a, b) => (rising ? a.at - b.at : b.at - a.at));
42
+ return crossings;
43
+ }
44
+ /**
45
+ * The highest boundary at-or-below `value` — the band the value currently sits in.
46
+ * Returns `null` when `value` is below every boundary. Boundaries need not be sorted.
47
+ *
48
+ * Tier labels stay caller policy: pass an `Id` object carrying whatever label,
49
+ * relation, or colour the game needs.
50
+ *
51
+ * @capability resolve the current tier/band label for a keyed or scalar value
52
+ */
53
+ export function tierAt(boundaries, value, options = {}) {
54
+ const inclusive = options.inclusive ?? true;
55
+ let match = null;
56
+ for (const boundary of boundaries) {
57
+ const occupied = inclusive ? value >= boundary.at : value > boundary.at;
58
+ if (occupied && (match === null || boundary.at > match.at))
59
+ match = boundary;
60
+ }
61
+ return match;
62
+ }
@@ -0,0 +1,12 @@
1
+ /** Split a `#rrggbb` hex color into its `[r, g, b]` channels (0–255).
2
+ * @internal
3
+ */
4
+ export declare function hexToRgb(hex: string): readonly [number, number, number];
5
+ /** Combine `[r, g, b]` channels (0–255, rounded) into a `#rrggbb` hex string.
6
+ * @internal
7
+ */
8
+ export declare function rgbToHex(r: number, g: number, b: number): string;
9
+ /** Interpolate between two `#rrggbb` colors by fraction `t`, clamped to the endpoints.
10
+ * @internal
11
+ */
12
+ export declare function mixHex(from: string, to: string, t: number): string;
@@ -0,0 +1,26 @@
1
+ /** Split a `#rrggbb` hex color into its `[r, g, b]` channels (0–255).
2
+ * @internal
3
+ */
4
+ export function hexToRgb(hex) {
5
+ const value = Number.parseInt(hex.slice(1), 16);
6
+ return [(value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff];
7
+ }
8
+ /** Combine `[r, g, b]` channels (0–255, rounded) into a `#rrggbb` hex string.
9
+ * @internal
10
+ */
11
+ export function rgbToHex(r, g, b) {
12
+ const value = ((Math.round(r) & 0xff) << 16) | ((Math.round(g) & 0xff) << 8) | (Math.round(b) & 0xff);
13
+ return `#${value.toString(16).padStart(6, "0")}`;
14
+ }
15
+ /** Interpolate between two `#rrggbb` colors by fraction `t`, clamped to the endpoints.
16
+ * @internal
17
+ */
18
+ export function mixHex(from, to, t) {
19
+ if (t <= 0)
20
+ return from;
21
+ if (t >= 1)
22
+ return to;
23
+ const [fr, fg, fb] = hexToRgb(from);
24
+ const [tr, tg, tb] = hexToRgb(to);
25
+ return rgbToHex(fr + (tr - fr) * t, fg + (tg - fg) * t, fb + (tb - fb) * t);
26
+ }
@@ -0,0 +1,41 @@
1
+ import type { BackdropConfig, LightingConfig } from "../game/playableGame.js";
2
+ import type { SkyEnvironmentConfig } from "../world/features.js";
3
+ import type { PostProcessingConfig } from "./postProcessing.js";
4
+ /**
5
+ * Named default-look preset composing the existing lighting/sky/fog/post knobs into one field.
6
+ * `"cinematic"` (the default when unset) draws a scene lit like a shipped game — a real day sky
7
+ * with a view-following shadow-casting sun + hemisphere fill, a network-free image-based-lighting
8
+ * environment so PBR surfaces catch soft reflections, and a tuned tone-map/bloom/AO/vignette post
9
+ * stack. `"flat"` opts out of the sky/IBL/post rig to the bare ambient+directional default (pre-#773).
10
+ * The upgraded default primitive materials — tuned roughness/metalness plus subtle procedural surface
11
+ * detail so un-modeled boxes/capsules stop reading as flat plastic — apply under both presets.
12
+ * @capability default-look one field that lights a scene like a shipped game (opt out with "flat")
13
+ */
14
+ export type LookPreset = "cinematic" | "flat";
15
+ /** Explicit graphics knobs a game may set; the preset only fills the ones left undefined. */
16
+ export interface GameLookInput {
17
+ look?: LookPreset;
18
+ lighting?: LightingConfig;
19
+ backdrop?: BackdropConfig;
20
+ postProcessing?: PostProcessingConfig;
21
+ /** True when the world already declares its own sky — the preset then leaves the sky to the world. */
22
+ hasWorldSky?: boolean;
23
+ }
24
+ /** Concrete lighting/backdrop/post the shell renders after the preset has filled unset knobs. */
25
+ export interface ResolvedGameLook {
26
+ lighting?: LightingConfig;
27
+ backdrop?: BackdropConfig;
28
+ postProcessing?: PostProcessingConfig;
29
+ }
30
+ /** A static day sky: a real dome plus the shell's view-following shadow-casting sun and hemisphere fill. */
31
+ export declare const CINEMATIC_SKY: SkyEnvironmentConfig;
32
+ /** Tuned tone-map + bloom + gentle SSAO + vignette/grade stack — the shipped-game post look. */
33
+ export declare const CINEMATIC_POST_PROCESSING: PostProcessingConfig;
34
+ /**
35
+ * Expand a game's `look` into concrete lighting/backdrop/post. The default is `"cinematic"`, so a
36
+ * scene reads lit-like-a-game out of the box; `"flat"` passes the explicit knobs through untouched.
37
+ * Anything the game authored wins — the preset only fills unset knobs, and it never adds a sky when
38
+ * the world already owns one (so the sky's tuned sun/hemisphere serve as the lighting rig).
39
+ * @capability resolve-game-look expand a look preset into concrete lighting/backdrop/post knobs
40
+ */
41
+ export declare function resolveGameLook(input: GameLookInput): ResolvedGameLook;
@@ -0,0 +1,29 @@
1
+ /** A static day sky: a real dome plus the shell's view-following shadow-casting sun and hemisphere fill. */
2
+ export const CINEMATIC_SKY = { preset: "day" };
3
+ /** Tuned tone-map + bloom + gentle SSAO + vignette/grade stack — the shipped-game post look. */
4
+ export const CINEMATIC_POST_PROCESSING = {
5
+ toneMapping: "aces",
6
+ bloom: {},
7
+ ao: { intensity: 1.4 },
8
+ grade: {},
9
+ };
10
+ /**
11
+ * Expand a game's `look` into concrete lighting/backdrop/post. The default is `"cinematic"`, so a
12
+ * scene reads lit-like-a-game out of the box; `"flat"` passes the explicit knobs through untouched.
13
+ * Anything the game authored wins — the preset only fills unset knobs, and it never adds a sky when
14
+ * the world already owns one (so the sky's tuned sun/hemisphere serve as the lighting rig).
15
+ * @capability resolve-game-look expand a look preset into concrete lighting/backdrop/post knobs
16
+ */
17
+ export function resolveGameLook(input) {
18
+ const look = input.look ?? "cinematic";
19
+ if (look === "flat") {
20
+ return { lighting: input.lighting, backdrop: input.backdrop, postProcessing: input.postProcessing };
21
+ }
22
+ const sky = input.backdrop?.sky ?? (input.hasWorldSky === true ? undefined : CINEMATIC_SKY);
23
+ const backdrop = sky === input.backdrop?.sky ? input.backdrop : { ...input.backdrop, sky };
24
+ return {
25
+ lighting: input.lighting,
26
+ backdrop,
27
+ postProcessing: input.postProcessing ?? CINEMATIC_POST_PROCESSING,
28
+ };
29
+ }
@@ -34,6 +34,17 @@ export interface GradeConfig {
34
34
  vignette?: number;
35
35
  /** Animated film-grain amplitude. Default 0.012. */
36
36
  grain?: number;
37
+ /** Chromatic-aberration RGB split, in fractions of the frame (~0..0.01), scaled toward the edges. Default 0 (off). */
38
+ chromaticAberration?: number;
39
+ }
40
+ /** Depth-of-field (bokeh) stage — throws the fore/background out of focus around a focus distance. */
41
+ export interface DofConfig {
42
+ /** Focus distance from the camera in world units. Default 18. */
43
+ focus?: number;
44
+ /** Aperture — larger blurs a shallower slice more aggressively. Default 0.00025. */
45
+ aperture?: number;
46
+ /** Maximum blur radius, 0..1. Default 0.01. */
47
+ maxBlur?: number;
37
48
  }
38
49
  /**
39
50
  * Declarative post-processing chain (RenderPass → AO → Bloom → tone-map output →
@@ -52,5 +63,14 @@ export interface PostProcessingConfig {
52
63
  bloom?: BloomConfig | false;
53
64
  /** Ambient occlusion. Heavier than the other stages — omit or `false` on low-end targets. Default off (omitted). */
54
65
  ao?: AoConfig | false;
66
+ /** Depth-of-field / bokeh. Heavier stage — omit or `false` to skip. Default off (omitted). */
67
+ dof?: DofConfig | false;
55
68
  grade?: GradeConfig | false;
56
69
  }
70
+ /**
71
+ * A cinematic "product shot" post preset — the full chain on (contact-AO, soft bloom, a warm film
72
+ * grade with vignette + a touch of grain + chromatic aberration). Meant for a `StudioStage` where a
73
+ * single parametric asset is framed on a backdrop, so every studio reads shipped, not intern-tier. DoF
74
+ * is left off by default (it needs a per-scene focus distance); set `dof` to enable it.
75
+ */
76
+ export declare const STUDIO_STAGE_POST: PostProcessingConfig;
@@ -1 +1,21 @@
1
- export {};
1
+ /**
2
+ * A cinematic "product shot" post preset — the full chain on (contact-AO, soft bloom, a warm film
3
+ * grade with vignette + a touch of grain + chromatic aberration). Meant for a `StudioStage` where a
4
+ * single parametric asset is framed on a backdrop, so every studio reads shipped, not intern-tier. DoF
5
+ * is left off by default (it needs a per-scene focus distance); set `dof` to enable it.
6
+ */
7
+ export const STUDIO_STAGE_POST = {
8
+ toneMapping: "aces",
9
+ exposure: 1.05,
10
+ bloom: { strength: 0.28, radius: 0.6, threshold: 0.8 },
11
+ ao: { radius: 1.4, intensity: 2.2, distanceFalloff: 3, blend: 1 },
12
+ grade: {
13
+ lift: [0.008, 0.008, 0.014],
14
+ gain: [1.05, 1.02, 0.98],
15
+ gamma: 0.96,
16
+ saturation: 1.12,
17
+ vignette: 0,
18
+ grain: 0.006,
19
+ chromaticAberration: 0.001,
20
+ },
21
+ };