@jgengine/core 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -1,6 +1,7 @@
1
1
  import { getCurrentGameTimestamp, sanitizeGameTimeScale } from "@jgengine/core/time/gameClock";
2
2
  const MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
3
3
  const MONTH_NAMES_FULL = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
4
+ /** @internal */
4
5
  export function computeGameTime(gameTimestamp) {
5
6
  const d = new Date(gameTimestamp);
6
7
  const year = d.getFullYear();
@@ -33,9 +34,11 @@ export function computeGameTime(gameTimestamp) {
33
34
  formatted,
34
35
  };
35
36
  }
37
+ /** @internal */
36
38
  export function computeClientServerOffset(serverNow, clientNow) {
37
39
  return serverNow - clientNow;
38
40
  }
41
+ /** @internal */
39
42
  export function getGameClockTimestamp(createdAt, serverNow, clientNow, gameTimeScale) {
40
43
  const clientOffsetMs = computeClientServerOffset(serverNow, clientNow);
41
44
  return getCurrentGameTimestamp(createdAt, clientNow + clientOffsetMs, sanitizeGameTimeScale(gameTimeScale));
@@ -7,6 +7,7 @@ export interface IdleWindow {
7
7
  effectiveSeconds: number;
8
8
  capped: boolean;
9
9
  }
10
+ /** @internal */
10
11
  export declare function idleWindow(lastSeenMs: number, nowMs: number, config?: IdleWindowConfig): IdleWindow;
11
12
  export interface LinearCatchUpInput {
12
13
  current: number;
@@ -14,6 +15,7 @@ export interface LinearCatchUpInput {
14
15
  min?: number;
15
16
  max?: number;
16
17
  }
18
+ /** @internal */
17
19
  export declare function linearCatchUp(seconds: number, input: LinearCatchUpInput): number;
18
20
  export interface ExponentialCatchUpInput {
19
21
  current: number;
@@ -21,9 +23,11 @@ export interface ExponentialCatchUpInput {
21
23
  min?: number;
22
24
  max?: number;
23
25
  }
26
+ /** @internal */
24
27
  export declare function exponentialCatchUp(seconds: number, input: ExponentialCatchUpInput): number;
25
28
  export interface SteppedCatchUpResult {
26
29
  steps: number;
27
30
  remainderSeconds: number;
28
31
  }
32
+ /** @internal */
29
33
  export declare function steppedCatchUp(seconds: number, stepSeconds: number, step: (index: number) => void, maxSteps?: number): SteppedCatchUpResult;
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function idleWindow(lastSeenMs, nowMs, config = {}) {
2
3
  const elapsedSeconds = Math.max(0, (nowMs - lastSeenMs) / 1000);
3
4
  const capped = config.maxSeconds !== undefined && elapsedSeconds > config.maxSeconds;
@@ -9,17 +10,20 @@ export function idleWindow(lastSeenMs, nowMs, config = {}) {
9
10
  capped,
10
11
  };
11
12
  }
13
+ /** @internal */
12
14
  export function linearCatchUp(seconds, input) {
13
15
  const clampedSeconds = Math.max(0, seconds);
14
16
  const value = input.current + input.ratePerSecond * clampedSeconds;
15
17
  return Math.min(input.max ?? Number.POSITIVE_INFINITY, Math.max(input.min ?? Number.NEGATIVE_INFINITY, value));
16
18
  }
19
+ /** @internal */
17
20
  export function exponentialCatchUp(seconds, input) {
18
21
  const clampedSeconds = Math.max(0, seconds);
19
22
  const factor = Math.max(0, input.factorPerSecond);
20
23
  const value = input.current * factor ** clampedSeconds;
21
24
  return Math.min(input.max ?? Number.POSITIVE_INFINITY, Math.max(input.min ?? Number.NEGATIVE_INFINITY, value));
22
25
  }
26
+ /** @internal */
23
27
  export function steppedCatchUp(seconds, stepSeconds, step, maxSteps) {
24
28
  if (stepSeconds <= 0 || seconds <= 0) {
25
29
  return { steps: 0, remainderSeconds: Math.max(0, seconds) };
@@ -51,6 +51,8 @@ export interface SimClock {
51
51
  advance(realDt: number): number;
52
52
  now(): number;
53
53
  snapshot(): ClockSnapshot;
54
+ /** Restore clock position — game-time, pause state, and speed multipliers — from a {@link ClockSnapshot} for whole-world save/load. Live timers registered via `after`/`every`/`at` are unaffected. */
55
+ hydrate(snapshot: ClockSnapshot): void;
54
56
  calendar(): CalendarTime;
55
57
  isPaused(): boolean;
56
58
  speed(): number;
@@ -1,5 +1,11 @@
1
1
  import { SECONDS_PER_GAME_DAY } from "./gameClock.js";
2
- const MAX_TIMER_FIRES = 10_000;
2
+ const MAX_TIMER_FIRES_PER_ADVANCE = 10_000;
3
+ function requireFiniteTimerValue(label, value) {
4
+ if (!Number.isFinite(value)) {
5
+ throw new Error(`SimClock ${label} must be finite, got ${value}`);
6
+ }
7
+ return value;
8
+ }
3
9
  export function createSimClock(options = {}) {
4
10
  const config = options.config ?? {};
5
11
  const onChange = options.onChange ?? (() => { });
@@ -62,7 +68,7 @@ export function createSimClock(options = {}) {
62
68
  }
63
69
  timer.callback();
64
70
  fires += 1;
65
- if (fires >= MAX_TIMER_FIRES)
71
+ if (fires >= MAX_TIMER_FIRES_PER_ADVANCE)
66
72
  return;
67
73
  }
68
74
  }
@@ -121,10 +127,19 @@ export function createSimClock(options = {}) {
121
127
  timers.delete(id);
122
128
  };
123
129
  }
130
+ function hydrate(state) {
131
+ now = state.now;
132
+ paused = state.paused;
133
+ playSpeed = state.playSpeed;
134
+ timescale = state.timescale;
135
+ displayMinute = minuteIndex(now, dayLength);
136
+ onChange();
137
+ }
124
138
  return {
125
139
  advance,
126
140
  now: () => now,
127
141
  calendar,
142
+ hydrate,
128
143
  snapshot: () => ({
129
144
  now,
130
145
  paused,
@@ -144,12 +159,12 @@ export function createSimClock(options = {}) {
144
159
  cycleSpeed,
145
160
  timescale: () => timescale,
146
161
  setTimescale,
147
- after: (seconds, callback) => register(now + Math.max(0, seconds), null, callback),
162
+ after: (seconds, callback) => register(now + Math.max(0, requireFiniteTimerValue("after(seconds)", seconds)), null, callback),
148
163
  every: (seconds, callback) => {
149
- const interval = Math.max(Number.EPSILON, seconds);
164
+ const interval = Math.max(Number.EPSILON, requireFiniteTimerValue("every(seconds)", seconds));
150
165
  return register(now + interval, interval, callback);
151
166
  },
152
- at: (time, callback) => register(time, null, callback),
167
+ at: (time, callback) => register(requireFiniteTimerValue("at(time)", time), null, callback),
153
168
  };
154
169
  }
155
170
  function minuteIndex(seconds, dayLength) {
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Headless view model for a contextual action collection — the data layer behind an RTS command
3
+ * card, an ability action bar, a build menu, or a radial. It carries *what the buttons mean*
4
+ * (label, hotkey, cost, cooldown, disabled reasons, toggle state) with zero rendering opinion, so a
5
+ * game keeps layout, dimensions, hotkeys, catalog-id mapping, renderer, and chrome caller-owned. The
6
+ * React renderers in `@jgengine/react/actionHud` consume this; a game can swap either without
7
+ * forking the logic here.
8
+ */
9
+ /** A spendable-resource line on an action (e.g. `40` mana). `met` is false only when `available` is known and short. */
10
+ export interface ActionCost {
11
+ resourceId: string;
12
+ amount: number;
13
+ /** Current pool, when the caller knows it — drives {@link ActionCost.met}. Omit when unknown. */
14
+ available?: number;
15
+ /** True unless `available` is known and below `amount`. */
16
+ met: boolean;
17
+ }
18
+ /** Cooldown state for an action, expressed so a radial sweep or countdown can render directly. */
19
+ export interface ActionCooldown {
20
+ remainingMs: number;
21
+ totalMs: number;
22
+ /** Remaining share of the cooldown, `0..1` — the fraction a radial wipe should still cover. */
23
+ fraction: number;
24
+ ready: boolean;
25
+ }
26
+ /** A single blocking reason: a stable machine `code` plus caller-facing `message`. */
27
+ export interface ActionReason {
28
+ /** Stable tag for styling/branching, e.g. `"cooldown" | "cost" | "range" | "disabled"`. */
29
+ code: string;
30
+ message: string;
31
+ }
32
+ /**
33
+ * A caller-authored contextual action — the DATA input to the model. Every field except `id` is
34
+ * optional so a build button, a stance toggle, and a cooldown ability all use the same shape.
35
+ * Catalog-id mapping (turning `icon`/`label` into art and copy) stays caller-owned.
36
+ */
37
+ export interface ActionDef {
38
+ id: string;
39
+ label?: string;
40
+ description?: string;
41
+ /** Icon id / glyph the caller maps to a catalog; the model only carries it through. */
42
+ icon?: string;
43
+ /** Human hotkey label (e.g. `"Q"`, `"1"`). Matched case-insensitively by {@link actionByHotkey}. */
44
+ hotkey?: string;
45
+ /** Section id for grouping a large card into rows/tabs; caller-owned. */
46
+ group?: string;
47
+ cooldown?: ActionCooldown;
48
+ costs?: readonly ActionCost[];
49
+ /** Toggle/stance state — a mode that is currently on. */
50
+ active?: boolean;
51
+ /** Hard-disable regardless of cost/cooldown (not yet researched, no valid target). */
52
+ disabled?: boolean;
53
+ /** Extra caller reasons (out of range, needs tech). Merged after the derived cost/cooldown ones. */
54
+ reasons?: readonly ActionReason[];
55
+ }
56
+ /**
57
+ * A resolved action view model — availability computed once from cooldown, cost, `disabled`, and any
58
+ * caller reasons. `enabled` is the single truth a renderer gates interaction on; `reasons` is the
59
+ * ordered explanation (cooldown, then unmet costs, then caller reasons, then a generic disable).
60
+ */
61
+ export interface ResolvedAction {
62
+ id: string;
63
+ label: string;
64
+ description?: string;
65
+ icon?: string;
66
+ hotkey?: string;
67
+ group?: string;
68
+ active: boolean;
69
+ enabled: boolean;
70
+ cooldown: ActionCooldown | null;
71
+ costs: readonly ActionCost[];
72
+ reasons: readonly ActionReason[];
73
+ }
74
+ /** Build an {@link ActionCooldown} from remaining/total milliseconds. `ready` when nothing remains. */
75
+ export declare function actionCooldown(remainingMs: number, totalMs: number): ActionCooldown;
76
+ /**
77
+ * Build an {@link ActionCooldown} from remaining milliseconds and a known remaining fraction — the
78
+ * shape adapters get from sources (like an ability snapshot) that report a fraction but not a total.
79
+ */
80
+ export declare function actionCooldownFromFraction(remainingMs: number, fraction: number): ActionCooldown;
81
+ /** Build an {@link ActionCost}. `met` is true unless `available` is provided and below `amount`. */
82
+ export declare function actionCost(resourceId: string, amount: number, available?: number): ActionCost;
83
+ /**
84
+ * Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`,
85
+ * and order the blocking `reasons`. Pure — the same input always yields the same view model.
86
+ */
87
+ export declare function resolveAction(def: ActionDef): ResolvedAction;
88
+ /** Resolve an ordered list of actions, preserving input order. */
89
+ export declare function resolveActionCollection(defs: readonly ActionDef[]): ResolvedAction[];
90
+ /**
91
+ * Find the action whose `hotkey` matches `key`, case-insensitively — the keyboard-shortcut router for
92
+ * an action bar. Returns the first match's id, or null. Matching by hotkey does not consider
93
+ * `enabled`; the caller decides whether to fire a disabled action's feedback.
94
+ */
95
+ export declare function actionByHotkey(actions: readonly ResolvedAction[], key: string): string | null;
96
+ /** A focus move for keyboard/controller grid navigation over an action collection. */
97
+ export type FocusDirection = "left" | "right" | "up" | "down" | "next" | "prev" | "first" | "last";
98
+ /** Options for {@link moveGridFocus}. */
99
+ export interface GridFocusOptions {
100
+ /** Wrap around edges instead of clamping (default false). */
101
+ wrap?: boolean;
102
+ }
103
+ /**
104
+ * Pure grid focus math for keyboard and controller navigation of an action card laid out in
105
+ * `columns`-wide rows. Given the current index (`-1` for none) it returns the next index, clamped to
106
+ * `[0, count)` — or wrapped when `wrap` is set. `left/right` move within/across columns, `up/down`
107
+ * across rows, `next/prev` walk the flat order, `first/last` jump to the ends. Renderer-agnostic:
108
+ * radial and list layouts pass `columns: 1` (or `count`) to get sensible 1-D stepping.
109
+ */
110
+ export declare function moveGridFocus(current: number, count: number, columns: number, dir: FocusDirection, options?: GridFocusOptions): number;
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Headless view model for a contextual action collection — the data layer behind an RTS command
3
+ * card, an ability action bar, a build menu, or a radial. It carries *what the buttons mean*
4
+ * (label, hotkey, cost, cooldown, disabled reasons, toggle state) with zero rendering opinion, so a
5
+ * game keeps layout, dimensions, hotkeys, catalog-id mapping, renderer, and chrome caller-owned. The
6
+ * React renderers in `@jgengine/react/actionHud` consume this; a game can swap either without
7
+ * forking the logic here.
8
+ */
9
+ const clamp01 = (value) => (value < 0 ? 0 : value > 1 ? 1 : value);
10
+ /** Build an {@link ActionCooldown} from remaining/total milliseconds. `ready` when nothing remains. */
11
+ export function actionCooldown(remainingMs, totalMs) {
12
+ const remaining = Math.max(0, remainingMs);
13
+ const total = Math.max(0, totalMs);
14
+ return {
15
+ remainingMs: remaining,
16
+ totalMs: total,
17
+ fraction: total <= 0 ? 0 : clamp01(remaining / total),
18
+ ready: remaining <= 0,
19
+ };
20
+ }
21
+ /**
22
+ * Build an {@link ActionCooldown} from remaining milliseconds and a known remaining fraction — the
23
+ * shape adapters get from sources (like an ability snapshot) that report a fraction but not a total.
24
+ */
25
+ export function actionCooldownFromFraction(remainingMs, fraction) {
26
+ const remaining = Math.max(0, remainingMs);
27
+ const frac = clamp01(fraction);
28
+ return {
29
+ remainingMs: remaining,
30
+ totalMs: frac > 0 ? Math.round(remaining / frac) : remaining,
31
+ fraction: frac,
32
+ ready: remaining <= 0,
33
+ };
34
+ }
35
+ /** Build an {@link ActionCost}. `met` is true unless `available` is provided and below `amount`. */
36
+ export function actionCost(resourceId, amount, available) {
37
+ const cost = {
38
+ resourceId,
39
+ amount,
40
+ met: available === undefined ? true : available >= amount,
41
+ };
42
+ if (available !== undefined)
43
+ cost.available = available;
44
+ return cost;
45
+ }
46
+ /**
47
+ * Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`,
48
+ * and order the blocking `reasons`. Pure — the same input always yields the same view model.
49
+ */
50
+ export function resolveAction(def) {
51
+ const costs = def.costs ?? [];
52
+ const reasons = [];
53
+ const cooldown = def.cooldown ?? null;
54
+ if (cooldown !== null && !cooldown.ready) {
55
+ reasons.push({ code: "cooldown", message: cooldownMessage(cooldown) });
56
+ }
57
+ for (const cost of costs) {
58
+ if (!cost.met)
59
+ reasons.push({ code: "cost", message: costMessage(cost) });
60
+ }
61
+ for (const reason of def.reasons ?? [])
62
+ reasons.push(reason);
63
+ if (def.disabled === true && reasons.length === 0) {
64
+ reasons.push({ code: "disabled", message: "Unavailable" });
65
+ }
66
+ const enabled = def.disabled !== true && reasons.length === 0;
67
+ const resolved = {
68
+ id: def.id,
69
+ label: def.label ?? def.id,
70
+ active: def.active === true,
71
+ enabled,
72
+ cooldown,
73
+ costs,
74
+ reasons,
75
+ };
76
+ if (def.description !== undefined)
77
+ resolved.description = def.description;
78
+ if (def.icon !== undefined)
79
+ resolved.icon = def.icon;
80
+ if (def.hotkey !== undefined)
81
+ resolved.hotkey = def.hotkey;
82
+ if (def.group !== undefined)
83
+ resolved.group = def.group;
84
+ return resolved;
85
+ }
86
+ /** Resolve an ordered list of actions, preserving input order. */
87
+ export function resolveActionCollection(defs) {
88
+ return defs.map(resolveAction);
89
+ }
90
+ /** @internal Default cooldown reason copy: `Ready in 2.4s`. */
91
+ function cooldownMessage(cooldown) {
92
+ return `Ready in ${(cooldown.remainingMs / 1000).toFixed(1)}s`;
93
+ }
94
+ /** @internal Default unmet-cost reason copy: `Needs 40 mana`. */
95
+ function costMessage(cost) {
96
+ return `Needs ${cost.amount} ${cost.resourceId}`;
97
+ }
98
+ /**
99
+ * Find the action whose `hotkey` matches `key`, case-insensitively — the keyboard-shortcut router for
100
+ * an action bar. Returns the first match's id, or null. Matching by hotkey does not consider
101
+ * `enabled`; the caller decides whether to fire a disabled action's feedback.
102
+ */
103
+ export function actionByHotkey(actions, key) {
104
+ const needle = key.toLowerCase();
105
+ for (const action of actions) {
106
+ if (action.hotkey !== undefined && action.hotkey.toLowerCase() === needle)
107
+ return action.id;
108
+ }
109
+ return null;
110
+ }
111
+ /**
112
+ * Pure grid focus math for keyboard and controller navigation of an action card laid out in
113
+ * `columns`-wide rows. Given the current index (`-1` for none) it returns the next index, clamped to
114
+ * `[0, count)` — or wrapped when `wrap` is set. `left/right` move within/across columns, `up/down`
115
+ * across rows, `next/prev` walk the flat order, `first/last` jump to the ends. Renderer-agnostic:
116
+ * radial and list layouts pass `columns: 1` (or `count`) to get sensible 1-D stepping.
117
+ */
118
+ export function moveGridFocus(current, count, columns, dir, options) {
119
+ if (count <= 0)
120
+ return -1;
121
+ const cols = Math.max(1, Math.floor(columns));
122
+ const wrap = options?.wrap === true;
123
+ if (dir === "first")
124
+ return 0;
125
+ if (dir === "last")
126
+ return count - 1;
127
+ if (current < 0) {
128
+ return dir === "prev" || dir === "left" || dir === "up" ? count - 1 : 0;
129
+ }
130
+ const clampIndex = (index) => Math.max(0, Math.min(count - 1, index));
131
+ if (dir === "next")
132
+ return current + 1 >= count ? (wrap ? 0 : count - 1) : current + 1;
133
+ if (dir === "prev")
134
+ return current - 1 < 0 ? (wrap ? count - 1 : 0) : current - 1;
135
+ const row = Math.floor(current / cols);
136
+ const col = current % cols;
137
+ if (dir === "right" || dir === "left") {
138
+ const rowStart = row * cols;
139
+ const rowEnd = Math.min(count - 1, rowStart + cols - 1);
140
+ const width = rowEnd - rowStart + 1;
141
+ if (width <= 1)
142
+ return current;
143
+ const nextCol = dir === "right" ? col + 1 : col - 1;
144
+ if (nextCol < 0)
145
+ return wrap ? rowEnd : current;
146
+ if (nextCol > rowEnd - rowStart)
147
+ return wrap ? rowStart : current;
148
+ return rowStart + nextCol;
149
+ }
150
+ // up / down
151
+ const nextRow = dir === "down" ? row + 1 : row - 1;
152
+ const rowCount = Math.ceil(count / cols);
153
+ if (nextRow < 0)
154
+ return wrap ? clampIndex((rowCount - 1) * cols + col) : current;
155
+ if (nextRow > rowCount - 1)
156
+ return wrap ? col : current;
157
+ const target = nextRow * cols + col;
158
+ return target >= count ? (dir === "down" ? current : clampIndex(target)) : target;
159
+ }
@@ -23,17 +23,29 @@ export interface LayoutRect {
23
23
  right: number;
24
24
  bottom: number;
25
25
  }
26
- /** Width of a rect (clamped to ≥0). */
26
+ /** Width of a rect (clamped to ≥0).
27
+ * @internal
28
+ */
27
29
  export declare function rectWidth(rect: LayoutRect): number;
28
- /** Height of a rect (clamped to ≥0). */
30
+ /** Height of a rect (clamped to ≥0).
31
+ * @internal
32
+ */
29
33
  export declare function rectHeight(rect: LayoutRect): number;
30
- /** Area of a rect in px². */
34
+ /** Area of a rect in px².
35
+ * @internal
36
+ */
31
37
  export declare function rectArea(rect: LayoutRect): number;
32
- /** Do the two rectangles share any interior area? Touching edges do not count. */
38
+ /** Do the two rectangles share any interior area? Touching edges do not count.
39
+ * @internal
40
+ */
33
41
  export declare function intersects(a: LayoutRect, b: LayoutRect): boolean;
34
- /** Overlapping area in px²; 0 when the rectangles don't intersect. */
42
+ /** Overlapping area in px²; 0 when the rectangles don't intersect.
43
+ * @internal
44
+ */
35
45
  export declare function overlapArea(a: LayoutRect, b: LayoutRect): number;
36
- /** Portrait when taller than wide, else landscape. */
46
+ /** Portrait when taller than wide, else landscape.
47
+ * @internal
48
+ */
37
49
  export declare function orientationOf(width: number, height: number): LayoutOrientation;
38
50
  /** Inputs to `resolveLayoutMode`. */
39
51
  export interface LayoutModeInput {
@@ -52,9 +64,12 @@ export interface LayoutModeInput {
52
64
  * desktop layout: a coarse-pointer device on a game that supports mobile is
53
65
  * always a `mobile-*` mode, split by live orientation; everything else is a
54
66
  * desktop mode split by width.
55
- */
67
+ * @internal
68
+ */
56
69
  export declare function resolveLayoutMode(input: LayoutModeInput): GameLayoutMode;
57
- /** Whether a mode is one of the phone modes. */
70
+ /** Whether a mode is one of the phone modes.
71
+ * @internal
72
+ */
58
73
  export declare function isMobileMode(mode: GameLayoutMode): boolean;
59
74
  /** What kind of UI a registered region belongs to. */
60
75
  export type LayoutRegionKind = "hud" | "control" | "system" | "screen";
@@ -97,15 +112,19 @@ export interface DetectCollisionsOptions {
97
112
  * regions. A pair is skipped when either side's policy is `allow`, when either
98
113
  * opts into the other via `allowOverlapWith`, when they share a
99
114
  * `collisionGroup`, or when the overlap is below `minArea`.
100
- */
115
+ * @internal
116
+ */
101
117
  export declare function detectLayoutCollisions(regions: readonly LayoutRegion[], options?: DetectCollisionsOptions): LayoutCollision[];
102
- /** Human-readable diagnostic block for a set of collisions (empty string when there are none). */
118
+ /** Human-readable diagnostic block for a set of collisions (empty string when there are none).
119
+ * @internal
120
+ */
103
121
  export declare function formatLayoutCollisions(collisions: readonly LayoutCollision[]): string;
104
122
  /**
105
123
  * The usable gameplay rectangle after reserving physical zones for touch
106
124
  * controls and system UI. Starts from the safe-area-inset viewport and carves
107
125
  * each reserved zone from whichever edge it hugs.
108
- */
126
+ * @internal
127
+ */
109
128
  export declare function computeGameplayRect(viewport: LayoutRect, safeArea: Insets, reserved: readonly LayoutRect[]): LayoutRect;
110
129
  /** The shared live geometry the engine allocates once and every UI subsystem reads. */
111
130
  export interface GameViewportLayout {
@@ -6,29 +6,41 @@
6
6
  */
7
7
  /** All-zero insets. */
8
8
  export const ZERO_INSETS = { top: 0, right: 0, bottom: 0, left: 0 };
9
- /** Width of a rect (clamped to ≥0). */
9
+ /** Width of a rect (clamped to ≥0).
10
+ * @internal
11
+ */
10
12
  export function rectWidth(rect) {
11
13
  return Math.max(0, rect.right - rect.left);
12
14
  }
13
- /** Height of a rect (clamped to ≥0). */
15
+ /** Height of a rect (clamped to ≥0).
16
+ * @internal
17
+ */
14
18
  export function rectHeight(rect) {
15
19
  return Math.max(0, rect.bottom - rect.top);
16
20
  }
17
- /** Area of a rect in px². */
21
+ /** Area of a rect in px².
22
+ * @internal
23
+ */
18
24
  export function rectArea(rect) {
19
25
  return rectWidth(rect) * rectHeight(rect);
20
26
  }
21
- /** Do the two rectangles share any interior area? Touching edges do not count. */
27
+ /** Do the two rectangles share any interior area? Touching edges do not count.
28
+ * @internal
29
+ */
22
30
  export function intersects(a, b) {
23
31
  return a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top;
24
32
  }
25
- /** Overlapping area in px²; 0 when the rectangles don't intersect. */
33
+ /** Overlapping area in px²; 0 when the rectangles don't intersect.
34
+ * @internal
35
+ */
26
36
  export function overlapArea(a, b) {
27
37
  const w = Math.min(a.right, b.right) - Math.max(a.left, b.left);
28
38
  const h = Math.min(a.bottom, b.bottom) - Math.max(a.top, b.top);
29
39
  return w > 0 && h > 0 ? w * h : 0;
30
40
  }
31
- /** Portrait when taller than wide, else landscape. */
41
+ /** Portrait when taller than wide, else landscape.
42
+ * @internal
43
+ */
32
44
  export function orientationOf(width, height) {
33
45
  return height > width ? "portrait" : "landscape";
34
46
  }
@@ -38,7 +50,8 @@ const DEFAULT_COMPACT_WIDTH = 900;
38
50
  * desktop layout: a coarse-pointer device on a game that supports mobile is
39
51
  * always a `mobile-*` mode, split by live orientation; everything else is a
40
52
  * desktop mode split by width.
41
- */
53
+ * @internal
54
+ */
42
55
  export function resolveLayoutMode(input) {
43
56
  const orientation = orientationOf(input.width, input.height);
44
57
  const mobile = input.coarsePointer && (input.mobileSupported ?? true);
@@ -47,7 +60,9 @@ export function resolveLayoutMode(input) {
47
60
  const compactWidth = input.compactWidth ?? DEFAULT_COMPACT_WIDTH;
48
61
  return input.width < compactWidth ? "desktop-compact" : "desktop-wide";
49
62
  }
50
- /** Whether a mode is one of the phone modes. */
63
+ /** Whether a mode is one of the phone modes.
64
+ * @internal
65
+ */
51
66
  export function isMobileMode(mode) {
52
67
  return mode === "mobile-portrait" || mode === "mobile-landscape";
53
68
  }
@@ -66,7 +81,8 @@ const DEFAULT_MIN_AREA = 64;
66
81
  * regions. A pair is skipped when either side's policy is `allow`, when either
67
82
  * opts into the other via `allowOverlapWith`, when they share a
68
83
  * `collisionGroup`, or when the overlap is below `minArea`.
69
- */
84
+ * @internal
85
+ */
70
86
  export function detectLayoutCollisions(regions, options) {
71
87
  const minArea = options?.minArea ?? DEFAULT_MIN_AREA;
72
88
  const out = [];
@@ -92,7 +108,9 @@ function withThousands(n) {
92
108
  .toString()
93
109
  .replace(/\B(?=(\d{3})+(?!\d))/g, ",");
94
110
  }
95
- /** Human-readable diagnostic block for a set of collisions (empty string when there are none). */
111
+ /** Human-readable diagnostic block for a set of collisions (empty string when there are none).
112
+ * @internal
113
+ */
96
114
  export function formatLayoutCollisions(collisions) {
97
115
  if (collisions.length === 0)
98
116
  return "";
@@ -103,7 +121,8 @@ export function formatLayoutCollisions(collisions) {
103
121
  * The usable gameplay rectangle after reserving physical zones for touch
104
122
  * controls and system UI. Starts from the safe-area-inset viewport and carves
105
123
  * each reserved zone from whichever edge it hugs.
106
- */
124
+ * @internal
125
+ */
107
126
  export function computeGameplayRect(viewport, safeArea, reserved) {
108
127
  let top = viewport.top + safeArea.top;
109
128
  let bottom = viewport.bottom - safeArea.bottom;