@jgengine/core 0.9.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 (631) hide show
  1. package/CHANGELOG.md +34 -3
  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 +19 -1
  21. package/dist/ai/spawnDirector.js +53 -26
  22. package/dist/ai/spawnPoint.d.ts +7 -0
  23. package/dist/ai/spawnPoint.js +7 -0
  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/audio/audioFalloff.d.ts +5 -2
  35. package/dist/audio/music.d.ts +53 -0
  36. package/dist/audio/music.js +34 -0
  37. package/dist/audio/synth.d.ts +60 -0
  38. package/dist/audio/synth.js +8 -0
  39. package/dist/authoring.d.ts +15 -0
  40. package/dist/authoring.js +15 -0
  41. package/dist/board/laneBoard.d.ts +13 -0
  42. package/dist/board/laneBoard.js +13 -0
  43. package/dist/board/timelineBoard.d.ts +10 -0
  44. package/dist/board/timelineBoard.js +10 -0
  45. package/dist/combat/abilityKit.d.ts +18 -0
  46. package/dist/combat/abilityKit.js +24 -9
  47. package/dist/combat/animationState.d.ts +5 -0
  48. package/dist/combat/animationState.js +5 -0
  49. package/dist/combat/breakMeters.d.ts +10 -0
  50. package/dist/combat/breakMeters.js +10 -0
  51. package/dist/combat/castRunner.d.ts +5 -0
  52. package/dist/combat/castRunner.js +5 -0
  53. package/dist/combat/comboPoints.d.ts +5 -0
  54. package/dist/combat/comboPoints.js +5 -0
  55. package/dist/combat/comboString.d.ts +5 -0
  56. package/dist/combat/comboString.js +5 -0
  57. package/dist/combat/damageInterceptors.d.ts +192 -0
  58. package/dist/combat/damageInterceptors.js +251 -0
  59. package/dist/combat/damageMatchup.d.ts +68 -0
  60. package/dist/combat/damageMatchup.js +42 -0
  61. package/dist/combat/damageResolution.d.ts +63 -0
  62. package/dist/combat/damageResolution.js +50 -0
  63. package/dist/combat/death.d.ts +7 -1
  64. package/dist/combat/death.js +5 -0
  65. package/dist/combat/deathReason.d.ts +14 -0
  66. package/dist/combat/deathReason.js +1 -0
  67. package/dist/combat/defensiveWindow.d.ts +5 -0
  68. package/dist/combat/defensiveWindow.js +5 -0
  69. package/dist/combat/dotField.d.ts +47 -0
  70. package/dist/combat/dotField.js +52 -0
  71. package/dist/combat/downed.d.ts +5 -0
  72. package/dist/combat/downed.js +5 -0
  73. package/dist/combat/effects.d.ts +5 -0
  74. package/dist/combat/effects.js +5 -0
  75. package/dist/combat/encounterSequence.d.ts +258 -0
  76. package/dist/combat/encounterSequence.js +426 -0
  77. package/dist/combat/hitReaction.d.ts +57 -1
  78. package/dist/combat/hitReaction.js +45 -5
  79. package/dist/combat/magazine.d.ts +54 -0
  80. package/dist/combat/magazine.js +96 -0
  81. package/dist/combat/projectiles.d.ts +7 -2
  82. package/dist/combat/projectiles.js +48 -17
  83. package/dist/combat/receivedDamage.d.ts +117 -0
  84. package/dist/combat/receivedDamage.js +92 -0
  85. package/dist/combat/regenShield.d.ts +39 -0
  86. package/dist/combat/regenShield.js +49 -0
  87. package/dist/combat/renderCues.d.ts +51 -0
  88. package/dist/combat/renderCues.js +44 -0
  89. package/dist/combat/resourcePool.d.ts +5 -0
  90. package/dist/combat/resourcePool.js +5 -0
  91. package/dist/combat/rewardAllocation.d.ts +121 -0
  92. package/dist/combat/rewardAllocation.js +251 -0
  93. package/dist/combat/shotOrigin.d.ts +30 -1
  94. package/dist/combat/shotOrigin.js +70 -2
  95. package/dist/combat/statusApplication.d.ts +96 -0
  96. package/dist/combat/statusApplication.js +81 -0
  97. package/dist/combat/telegraph.d.ts +11 -2
  98. package/dist/combat/telegraph.js +11 -2
  99. package/dist/combat/thresholdCrossings.d.ts +85 -0
  100. package/dist/combat/thresholdCrossings.js +116 -0
  101. package/dist/combat.d.ts +34 -0
  102. package/dist/combat.js +34 -0
  103. package/dist/commands/commandRegistry.d.ts +11 -0
  104. package/dist/commands/commandRegistry.js +9 -2
  105. package/dist/crafting/crop.d.ts +18 -0
  106. package/dist/crafting/crop.js +18 -0
  107. package/dist/crafting/production.d.ts +5 -0
  108. package/dist/crafting/production.js +5 -0
  109. package/dist/devtools/rewriteTunables.d.ts +17 -0
  110. package/dist/devtools/rewriteTunables.js +276 -0
  111. package/dist/devtools/saveEndpoint.d.ts +46 -0
  112. package/dist/devtools/saveEndpoint.js +48 -0
  113. package/dist/devtools/transformTunables.d.ts +3 -0
  114. package/dist/devtools/transformTunables.js +3 -0
  115. package/dist/devtools/tunableSchema.d.ts +31 -0
  116. package/dist/devtools/tunableSchema.js +31 -0
  117. package/dist/economy/currency.d.ts +12 -1
  118. package/dist/economy/currency.js +12 -1
  119. package/dist/economy/listingBook.d.ts +91 -0
  120. package/dist/economy/listingBook.js +144 -0
  121. package/dist/economy/resourceLedger.d.ts +222 -0
  122. package/dist/economy/resourceLedger.js +353 -0
  123. package/dist/economy/sharedWallet.d.ts +14 -0
  124. package/dist/economy/sharedWallet.js +14 -0
  125. package/dist/economy/techTree.d.ts +12 -0
  126. package/dist/economy/techTree.js +12 -0
  127. package/dist/economy/wallet.d.ts +26 -2
  128. package/dist/economy/wallet.js +35 -6
  129. package/dist/editor/commands.d.ts +248 -0
  130. package/dist/editor/commands.js +865 -0
  131. package/dist/editor/document.d.ts +186 -0
  132. package/dist/editor/document.js +884 -0
  133. package/dist/editor/grid.d.ts +229 -0
  134. package/dist/editor/grid.js +366 -0
  135. package/dist/editor/gridAdapters.d.ts +80 -0
  136. package/dist/editor/gridAdapters.js +134 -0
  137. package/dist/editor/index.d.ts +97 -0
  138. package/dist/editor/index.js +10 -0
  139. package/dist/editor/liveSync.d.ts +127 -0
  140. package/dist/editor/liveSync.js +249 -0
  141. package/dist/editor/runtimeInspector.d.ts +88 -0
  142. package/dist/editor/runtimeInspector.js +239 -0
  143. package/dist/editor/types.d.ts +175 -0
  144. package/dist/editor/types.js +29 -0
  145. package/dist/faction/reputation.d.ts +5 -0
  146. package/dist/faction/reputation.js +5 -0
  147. package/dist/format/distance.d.ts +17 -0
  148. package/dist/format/distance.js +18 -0
  149. package/dist/format/duration.d.ts +27 -0
  150. package/dist/format/duration.js +45 -0
  151. package/dist/format/speed.d.ts +17 -0
  152. package/dist/format/speed.js +25 -0
  153. package/dist/game/connectedPlayers.d.ts +30 -0
  154. package/dist/game/connectedPlayers.js +21 -0
  155. package/dist/game/cosmetics.d.ts +9 -0
  156. package/dist/game/cosmetics.js +16 -0
  157. package/dist/game/defineGame.d.ts +141 -2
  158. package/dist/game/defineGame.js +39 -1
  159. package/dist/game/defineSystem.d.ts +88 -0
  160. package/dist/game/defineSystem.js +45 -0
  161. package/dist/game/dialogue.d.ts +33 -0
  162. package/dist/game/dialogue.js +21 -0
  163. package/dist/game/events.d.ts +50 -13
  164. package/dist/game/events.js +5 -0
  165. package/dist/game/feed.d.ts +33 -0
  166. package/dist/game/feed.js +35 -2
  167. package/dist/game/gamePhase.d.ts +11 -0
  168. package/dist/game/gamePhase.js +16 -0
  169. package/dist/game/keyValueStore.d.ts +25 -0
  170. package/dist/game/keyValueStore.js +61 -0
  171. package/dist/game/leaderboard.d.ts +5 -0
  172. package/dist/game/leaderboard.js +5 -0
  173. package/dist/game/levelSequence.d.ts +24 -2
  174. package/dist/game/levelSequence.js +51 -2
  175. package/dist/game/loadout.d.ts +5 -0
  176. package/dist/game/loadout.js +5 -0
  177. package/dist/game/lootFilter.d.ts +2 -0
  178. package/dist/game/lootFilter.js +2 -0
  179. package/dist/game/lootPipeline.d.ts +164 -0
  180. package/dist/game/lootPipeline.js +216 -0
  181. package/dist/game/lootTable.d.ts +21 -0
  182. package/dist/game/lootTable.js +15 -4
  183. package/dist/game/modelAnimation.d.ts +8 -0
  184. package/dist/game/modelAnimation.js +18 -0
  185. package/dist/game/objectives.d.ts +43 -0
  186. package/dist/game/objectives.js +36 -0
  187. package/dist/game/paramLayers.d.ts +148 -0
  188. package/dist/game/paramLayers.js +185 -0
  189. package/dist/game/ping.d.ts +5 -0
  190. package/dist/game/ping.js +5 -0
  191. package/dist/game/playableGame.d.ts +160 -12
  192. package/dist/game/quest.d.ts +8 -0
  193. package/dist/game/quest.js +29 -0
  194. package/dist/game/race.d.ts +141 -0
  195. package/dist/game/race.js +169 -0
  196. package/dist/game/recordBook.d.ts +5 -5
  197. package/dist/game/recordBook.js +4 -1
  198. package/dist/game/ruleSelection.d.ts +75 -0
  199. package/dist/game/ruleSelection.js +127 -0
  200. package/dist/game/runDraft.d.ts +5 -0
  201. package/dist/game/runDraft.js +5 -0
  202. package/dist/game/saveStore.d.ts +111 -0
  203. package/dist/game/saveStore.js +312 -0
  204. package/dist/game/snapshotHistory.d.ts +67 -0
  205. package/dist/game/snapshotHistory.js +95 -0
  206. package/dist/game/social.d.ts +38 -1
  207. package/dist/game/social.js +71 -0
  208. package/dist/game/spawnPoints.d.ts +5 -0
  209. package/dist/game/spawnPoints.js +5 -0
  210. package/dist/game/systemRuntime.d.ts +50 -0
  211. package/dist/game/systemRuntime.js +157 -0
  212. package/dist/game/systemSchedule.d.ts +72 -0
  213. package/dist/game/systemSchedule.js +242 -0
  214. package/dist/game/toasts.d.ts +43 -0
  215. package/dist/game/toasts.js +44 -0
  216. package/dist/game/trade.d.ts +10 -0
  217. package/dist/game/trade.js +10 -0
  218. package/dist/game/unlocks.d.ts +8 -0
  219. package/dist/game/unlocks.js +16 -0
  220. package/dist/game/vfxInstance.d.ts +138 -0
  221. package/dist/game/vfxInstance.js +96 -0
  222. package/dist/game/worldItem.d.ts +17 -4
  223. package/dist/game/worldItem.js +17 -4
  224. package/dist/gameplay.d.ts +91 -0
  225. package/dist/gameplay.js +91 -0
  226. package/dist/index.d.ts +5 -7
  227. package/dist/index.js +5 -7
  228. package/dist/input/actionBindings.d.ts +24 -5
  229. package/dist/input/actionBindings.js +23 -5
  230. package/dist/input/axisInput.d.ts +13 -1
  231. package/dist/input/axisInput.js +22 -1
  232. package/dist/input/controlGroups.d.ts +67 -0
  233. package/dist/input/controlGroups.js +41 -0
  234. package/dist/input/touchScheme.d.ts +82 -6
  235. package/dist/input/touchScheme.js +123 -10
  236. package/dist/interaction/contextMenu.d.ts +1 -0
  237. package/dist/interaction/contextMenu.js +1 -0
  238. package/dist/interaction/lockpick.d.ts +61 -0
  239. package/dist/interaction/lockpick.js +168 -0
  240. package/dist/interaction/proximityPrompt.d.ts +5 -1
  241. package/dist/interaction/proximityPrompt.js +5 -3
  242. package/dist/interaction/qte.d.ts +5 -0
  243. package/dist/interaction/qte.js +5 -0
  244. package/dist/interaction/skillCheck.d.ts +5 -0
  245. package/dist/interaction/skillCheck.js +5 -0
  246. package/dist/inventory/inventoryModel.d.ts +12 -0
  247. package/dist/inventory/inventoryModel.js +12 -0
  248. package/dist/inventory/shapedGrid.d.ts +16 -0
  249. package/dist/inventory/shapedGrid.js +16 -0
  250. package/dist/inventory/slotModel.d.ts +10 -0
  251. package/dist/inventory/slotModel.js +10 -0
  252. package/dist/item/durability.d.ts +5 -0
  253. package/dist/item/durability.js +5 -0
  254. package/dist/item/itemIdentity.d.ts +171 -0
  255. package/dist/item/itemIdentity.js +138 -0
  256. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  257. package/dist/item/itemInstanceRegistry.js +34 -0
  258. package/dist/item/itemgen.d.ts +163 -0
  259. package/dist/item/itemgen.js +151 -0
  260. package/dist/item/modularItem.d.ts +5 -0
  261. package/dist/item/modularItem.js +5 -0
  262. package/dist/item/use.d.ts +5 -0
  263. package/dist/item/use.js +5 -0
  264. package/dist/item/useBehavior.d.ts +142 -0
  265. package/dist/item/useBehavior.js +105 -0
  266. package/dist/item/weapon.d.ts +5 -0
  267. package/dist/item/weapon.js +5 -0
  268. package/dist/math/scalar.d.ts +25 -0
  269. package/dist/math/scalar.js +47 -0
  270. package/dist/meta/changelog.d.ts +4 -1
  271. package/dist/meta/changelog.js +36 -1
  272. package/dist/movement/avoidance.d.ts +45 -0
  273. package/dist/movement/avoidance.js +123 -0
  274. package/dist/movement/cameraRig.d.ts +8 -0
  275. package/dist/movement/cameraRig.js +8 -0
  276. package/dist/movement/dash.d.ts +11 -0
  277. package/dist/movement/dash.js +11 -0
  278. package/dist/movement/formation.d.ts +135 -0
  279. package/dist/movement/formation.js +194 -0
  280. package/dist/movement/glideModel.d.ts +5 -0
  281. package/dist/movement/glideModel.js +5 -0
  282. package/dist/movement/grappleSwing.d.ts +5 -0
  283. package/dist/movement/grappleSwing.js +5 -0
  284. package/dist/movement/leaderTrail.d.ts +5 -0
  285. package/dist/movement/leaderTrail.js +5 -0
  286. package/dist/movement/movementModel.d.ts +38 -7
  287. package/dist/movement/movementModel.js +54 -13
  288. package/dist/movement/playerMovement.d.ts +41 -0
  289. package/dist/movement/playerMovement.js +236 -0
  290. package/dist/movement/poseState.d.ts +13 -0
  291. package/dist/movement/poseState.js +16 -0
  292. package/dist/movement/steering.d.ts +8 -0
  293. package/dist/movement/steering.js +18 -0
  294. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  295. package/dist/multiplayer/combatSnapshot.js +3 -0
  296. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  297. package/dist/multiplayer/lagCompensation.js +5 -0
  298. package/dist/multiplayer/presenceModel.d.ts +9 -1
  299. package/dist/multiplayer/presenceModel.js +9 -1
  300. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  301. package/dist/multiplayer/simultaneousCommit.js +3 -0
  302. package/dist/multiplayer.d.ts +11 -0
  303. package/dist/multiplayer.js +11 -0
  304. package/dist/nav/pathFollow.d.ts +57 -0
  305. package/dist/nav/pathFollow.js +109 -0
  306. package/dist/orders/orderKinds.d.ts +156 -0
  307. package/dist/orders/orderKinds.js +197 -0
  308. package/dist/orders/orderQueue.d.ts +208 -0
  309. package/dist/orders/orderQueue.js +211 -0
  310. package/dist/physics/drivableVehicle.d.ts +29 -0
  311. package/dist/physics/drivableVehicle.js +16 -0
  312. package/dist/physics/kinematicVehicle.d.ts +21 -1
  313. package/dist/physics/kinematicVehicle.js +23 -8
  314. package/dist/physics/physicsWorld.d.ts +24 -12
  315. package/dist/physics/physicsWorld.js +11 -5
  316. package/dist/physics/radialImpulse.d.ts +25 -0
  317. package/dist/physics/radialImpulse.js +27 -0
  318. package/dist/procedural.d.ts +3 -0
  319. package/dist/procedural.js +3 -0
  320. package/dist/progression/statGraph.d.ts +116 -0
  321. package/dist/progression/statGraph.js +318 -0
  322. package/dist/puzzle/cellGrid.d.ts +9 -0
  323. package/dist/puzzle/cellGrid.js +9 -0
  324. package/dist/puzzle/fallingPiece.d.ts +9 -0
  325. package/dist/puzzle/fallingPiece.js +9 -0
  326. package/dist/puzzle/nonogram.d.ts +39 -0
  327. package/dist/puzzle/nonogram.js +136 -0
  328. package/dist/random/nameGen.d.ts +5 -0
  329. package/dist/random/nameGen.js +5 -0
  330. package/dist/random/pick.d.ts +8 -0
  331. package/dist/random/pick.js +31 -0
  332. package/dist/random/rng.d.ts +24 -0
  333. package/dist/random/rng.js +30 -8
  334. package/dist/random/seedLink.d.ts +4 -0
  335. package/dist/random/seedLink.js +4 -0
  336. package/dist/relation/keyedValues.d.ts +54 -0
  337. package/dist/relation/keyedValues.js +115 -0
  338. package/dist/relation/thresholds.d.ts +62 -0
  339. package/dist/relation/thresholds.js +62 -0
  340. package/dist/render/color.d.ts +12 -0
  341. package/dist/render/color.js +26 -0
  342. package/dist/render/lookPreset.d.ts +41 -0
  343. package/dist/render/lookPreset.js +29 -0
  344. package/dist/render/postProcessing.d.ts +76 -0
  345. package/dist/render/postProcessing.js +21 -0
  346. package/dist/rules/predicate.d.ts +53 -0
  347. package/dist/rules/predicate.js +64 -0
  348. package/dist/rules/ruleEffects.d.ts +38 -0
  349. package/dist/rules/ruleEffects.js +37 -0
  350. package/dist/rules/triggeredRules.d.ts +160 -0
  351. package/dist/rules/triggeredRules.js +241 -0
  352. package/dist/runtime/adapter.d.ts +58 -0
  353. package/dist/runtime/adapter.js +54 -5
  354. package/dist/runtime/cameraDirector.d.ts +1 -0
  355. package/dist/runtime/cameraDirector.js +1 -0
  356. package/dist/runtime/commandRunner.d.ts +1 -0
  357. package/dist/runtime/commandRunner.js +1 -0
  358. package/dist/runtime/context/combatFx.d.ts +23 -0
  359. package/dist/runtime/context/combatFx.js +161 -0
  360. package/dist/runtime/context/registries.d.ts +13 -0
  361. package/dist/runtime/context/registries.js +84 -0
  362. package/dist/runtime/context/worldItems.d.ts +21 -0
  363. package/dist/runtime/context/worldItems.js +37 -0
  364. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  365. package/dist/runtime/descriptors/baseline.js +134 -0
  366. package/dist/runtime/descriptors/features.d.ts +74 -0
  367. package/dist/runtime/descriptors/features.js +281 -0
  368. package/dist/runtime/gameContext.d.ts +163 -19
  369. package/dist/runtime/gameContext.js +385 -339
  370. package/dist/runtime/gameRuntime.d.ts +1 -0
  371. package/dist/runtime/gameRuntime.js +1 -0
  372. package/dist/runtime/headlessRunner.d.ts +60 -0
  373. package/dist/runtime/headlessRunner.js +44 -0
  374. package/dist/runtime/hostPersistence.d.ts +12 -0
  375. package/dist/runtime/hostPersistence.js +12 -0
  376. package/dist/runtime/hostedGameRunner.d.ts +54 -0
  377. package/dist/runtime/hostedGameRunner.js +85 -0
  378. package/dist/runtime/hostedWorldSession.d.ts +73 -0
  379. package/dist/runtime/hostedWorldSession.js +64 -0
  380. package/dist/runtime/inputSnapshot.d.ts +21 -3
  381. package/dist/runtime/inputSnapshot.js +8 -2
  382. package/dist/runtime/motionIntents.d.ts +12 -1
  383. package/dist/runtime/motionIntents.js +26 -1
  384. package/dist/runtime/perContext.d.ts +15 -0
  385. package/dist/runtime/perContext.js +21 -0
  386. package/dist/runtime/runtimeSave.d.ts +79 -0
  387. package/dist/runtime/runtimeSave.js +105 -0
  388. package/dist/runtime/save.d.ts +4 -0
  389. package/dist/runtime/save.js +4 -0
  390. package/dist/runtime/snapshot.d.ts +7 -0
  391. package/dist/runtime/snapshot.js +7 -0
  392. package/dist/runtime/visibility.d.ts +2 -1
  393. package/dist/runtime/visibility.js +2 -1
  394. package/dist/runtime/worldChannel.d.ts +62 -0
  395. package/dist/runtime/worldChannel.js +114 -0
  396. package/dist/runtime/worldMirror.d.ts +36 -0
  397. package/dist/runtime/worldMirror.js +44 -0
  398. package/dist/runtime/worldProjection.d.ts +47 -0
  399. package/dist/runtime/worldProjection.js +52 -0
  400. package/dist/runtime/worldReplication.d.ts +69 -0
  401. package/dist/runtime/worldReplication.js +217 -0
  402. package/dist/runtime/worldSnapshot.d.ts +44 -0
  403. package/dist/runtime/worldSnapshot.js +30 -0
  404. package/dist/scene/assetCatalog.d.ts +22 -0
  405. package/dist/scene/assetCatalog.js +4 -0
  406. package/dist/scene/assetDiagnostics.d.ts +69 -0
  407. package/dist/scene/assetDiagnostics.js +110 -0
  408. package/dist/scene/assetGenerator.d.ts +65 -0
  409. package/dist/scene/assetGenerator.js +64 -0
  410. package/dist/scene/assetSpace.d.ts +137 -0
  411. package/dist/scene/assetSpace.js +259 -0
  412. package/dist/scene/authoredTriggers.d.ts +169 -0
  413. package/dist/scene/authoredTriggers.js +340 -0
  414. package/dist/scene/behaviorRuntime.d.ts +75 -0
  415. package/dist/scene/behaviorRuntime.js +217 -0
  416. package/dist/scene/behaviors.d.ts +14 -2
  417. package/dist/scene/behaviors.js +7 -2
  418. package/dist/scene/bodyBind.d.ts +60 -0
  419. package/dist/scene/bodyBind.js +51 -0
  420. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  421. package/dist/scene/builtinSceneKinds.js +62 -0
  422. package/dist/scene/colliders.d.ts +18 -0
  423. package/dist/scene/colliders.js +61 -1
  424. package/dist/scene/entityStats.d.ts +13 -0
  425. package/dist/scene/entityStats.js +30 -0
  426. package/dist/scene/entityStore.d.ts +41 -1
  427. package/dist/scene/entityStore.js +75 -0
  428. package/dist/scene/facing.d.ts +18 -0
  429. package/dist/scene/facing.js +26 -0
  430. package/dist/scene/modelSockets.d.ts +33 -0
  431. package/dist/scene/modelSockets.js +29 -0
  432. package/dist/scene/objectQuery.d.ts +2 -0
  433. package/dist/scene/objectQuery.js +2 -0
  434. package/dist/scene/objectStore.d.ts +4 -0
  435. package/dist/scene/objectStore.js +6 -0
  436. package/dist/scene/possession.d.ts +8 -0
  437. package/dist/scene/possession.js +14 -0
  438. package/dist/scene/roster.d.ts +3 -0
  439. package/dist/scene/roster.js +12 -0
  440. package/dist/scene/sceneKinds.d.ts +240 -0
  441. package/dist/scene/sceneKinds.js +214 -0
  442. package/dist/scene/sceneOwnership.d.ts +169 -0
  443. package/dist/scene/sceneOwnership.js +179 -0
  444. package/dist/scene/selectionBookmarks.d.ts +93 -0
  445. package/dist/scene/selectionBookmarks.js +122 -0
  446. package/dist/scene/vehicleSeat.d.ts +68 -0
  447. package/dist/scene/vehicleSeat.js +59 -0
  448. package/dist/sensor/concealment.d.ts +3 -0
  449. package/dist/sensor/concealment.js +3 -0
  450. package/dist/sensor/freezeMonitor.d.ts +1 -0
  451. package/dist/sensor/freezeMonitor.js +1 -0
  452. package/dist/sensor/frustumSensor.d.ts +7 -3
  453. package/dist/sensor/frustumSensor.js +7 -3
  454. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  455. package/dist/sensor/hiddenStateProbe.js +5 -2
  456. package/dist/sensor/recordingBuffer.d.ts +2 -1
  457. package/dist/sensor/recordingBuffer.js +2 -1
  458. package/dist/sensor/replayLoop.d.ts +6 -2
  459. package/dist/sensor/replayLoop.js +6 -2
  460. package/dist/sensor/revealQuery.d.ts +2 -1
  461. package/dist/sensor/revealQuery.js +2 -1
  462. package/dist/sensor/visionCone.d.ts +10 -3
  463. package/dist/sensor/visionCone.js +10 -3
  464. package/dist/session/contestedChannel.d.ts +1 -0
  465. package/dist/session/contestedChannel.js +1 -0
  466. package/dist/session/extraction.d.ts +1 -0
  467. package/dist/session/extraction.js +1 -0
  468. package/dist/session/roles.d.ts +6 -0
  469. package/dist/session/roles.js +6 -0
  470. package/dist/session/roundState.d.ts +8 -0
  471. package/dist/session/roundState.js +2 -0
  472. package/dist/settings/settingsModel.d.ts +1 -0
  473. package/dist/settings/settingsModel.js +1 -0
  474. package/dist/stats/accumulatorMeter.d.ts +6 -0
  475. package/dist/stats/accumulatorMeter.js +6 -0
  476. package/dist/stats/eventMeter.d.ts +5 -0
  477. package/dist/stats/eventMeter.js +5 -0
  478. package/dist/stats/rollCheck.d.ts +5 -0
  479. package/dist/stats/rollCheck.js +5 -0
  480. package/dist/stats/statModifiers.d.ts +5 -0
  481. package/dist/stats/statModifiers.js +5 -0
  482. package/dist/store/defineKeyedStore.d.ts +38 -0
  483. package/dist/store/defineKeyedStore.js +42 -0
  484. package/dist/store/defineStore.d.ts +33 -0
  485. package/dist/store/defineStore.js +35 -0
  486. package/dist/store/observableKeyedStore.d.ts +9 -0
  487. package/dist/store/observableKeyedStore.js +43 -2
  488. package/dist/survival/decayMeter.d.ts +55 -0
  489. package/dist/survival/decayMeter.js +130 -55
  490. package/dist/survival/moodle.d.ts +2 -0
  491. package/dist/survival/regionHealth.d.ts +6 -0
  492. package/dist/survival/regionHealth.js +5 -0
  493. package/dist/tactics/fallingGrid.d.ts +6 -4
  494. package/dist/tactics/fallingGrid.js +6 -4
  495. package/dist/tactics/predictiveQuery.d.ts +3 -0
  496. package/dist/tactics/predictiveQuery.js +3 -0
  497. package/dist/tactics/snapshot.d.ts +2 -0
  498. package/dist/tactics/snapshot.js +2 -0
  499. package/dist/tactics/surface.d.ts +1 -0
  500. package/dist/tactics/surface.js +1 -0
  501. package/dist/tactics/tacticalGrid.d.ts +1 -0
  502. package/dist/tactics/tacticalGrid.js +1 -0
  503. package/dist/time/beatClock.d.ts +14 -4
  504. package/dist/time/beatClock.js +14 -4
  505. package/dist/time/calendarClock.d.ts +3 -0
  506. package/dist/time/calendarClock.js +3 -0
  507. package/dist/time/idleProgress.d.ts +4 -0
  508. package/dist/time/idleProgress.js +4 -0
  509. package/dist/time/simClock.d.ts +2 -0
  510. package/dist/time/simClock.js +20 -5
  511. package/dist/ui/actionModel.d.ts +110 -0
  512. package/dist/ui/actionModel.js +159 -0
  513. package/dist/ui/gameLayout.d.ts +144 -0
  514. package/dist/ui/gameLayout.js +148 -0
  515. package/dist/ui/hudDocument.d.ts +114 -0
  516. package/dist/ui/hudDocument.js +220 -0
  517. package/dist/ui/hudLayout.d.ts +33 -1
  518. package/dist/ui/hudLayout.js +204 -17
  519. package/dist/ui/orientation.d.ts +39 -0
  520. package/dist/ui/orientation.js +49 -0
  521. package/dist/ui/selectionModel.d.ts +92 -0
  522. package/dist/ui/selectionModel.js +88 -0
  523. package/dist/ui/swingTimer.d.ts +42 -0
  524. package/dist/ui/swingTimer.js +38 -0
  525. package/dist/ui/tooltipModel.d.ts +63 -0
  526. package/dist/ui/tooltipModel.js +82 -0
  527. package/dist/ui.d.ts +15 -0
  528. package/dist/ui.js +15 -0
  529. package/dist/visibility/bounds.d.ts +8 -1
  530. package/dist/visibility/bounds.js +8 -1
  531. package/dist/visibility/frustum.d.ts +12 -3
  532. package/dist/visibility/frustum.js +12 -3
  533. package/dist/visibility/spatialIndex.js +34 -20
  534. package/dist/work/jobQueue.d.ts +201 -0
  535. package/dist/work/jobQueue.js +253 -0
  536. package/dist/work/unitTraining.d.ts +58 -0
  537. package/dist/work/unitTraining.js +52 -0
  538. package/dist/world/authoredObjects.d.ts +58 -0
  539. package/dist/world/authoredObjects.js +69 -0
  540. package/dist/world/buildingGenerator.d.ts +18 -0
  541. package/dist/world/buildingGenerator.js +62 -0
  542. package/dist/world/buildings.d.ts +5 -0
  543. package/dist/world/buildings.js +5 -0
  544. package/dist/world/catenary.d.ts +22 -0
  545. package/dist/world/catenary.js +69 -0
  546. package/dist/world/environmentSummary.d.ts +11 -2
  547. package/dist/world/environmentSummary.js +11 -1
  548. package/dist/world/features.d.ts +244 -7
  549. package/dist/world/features.js +92 -4
  550. package/dist/world/footprintGrid.d.ts +59 -0
  551. package/dist/world/footprintGrid.js +141 -0
  552. package/dist/world/geometry.d.ts +64 -0
  553. package/dist/world/geometry.js +94 -0
  554. package/dist/world/grassKind.d.ts +51 -0
  555. package/dist/world/grassKind.js +101 -0
  556. package/dist/world/pathInstances.d.ts +27 -0
  557. package/dist/world/pathInstances.js +27 -0
  558. package/dist/world/pathTerrain.d.ts +80 -0
  559. package/dist/world/pathTerrain.js +142 -0
  560. package/dist/world/placeAsset.d.ts +81 -0
  561. package/dist/world/placeAsset.js +77 -0
  562. package/dist/world/placement.d.ts +4 -0
  563. package/dist/world/placement.js +4 -0
  564. package/dist/world/placementController.d.ts +6 -0
  565. package/dist/world/placementController.js +6 -0
  566. package/dist/world/polyline.d.ts +34 -0
  567. package/dist/world/polyline.js +81 -0
  568. package/dist/world/roads.d.ts +55 -0
  569. package/dist/world/roads.js +184 -0
  570. package/dist/world/scatterRegion.d.ts +164 -0
  571. package/dist/world/scatterRegion.js +409 -0
  572. package/dist/world/sceneShapes.d.ts +43 -0
  573. package/dist/world/sceneShapes.js +1 -0
  574. package/dist/world/segment.d.ts +27 -0
  575. package/dist/world/segment.js +43 -0
  576. package/dist/world/soilKind.d.ts +48 -0
  577. package/dist/world/soilKind.js +92 -0
  578. package/dist/world/spatialSample.d.ts +241 -0
  579. package/dist/world/spatialSample.js +465 -0
  580. package/dist/world/streets.d.ts +80 -0
  581. package/dist/world/streets.js +144 -0
  582. package/dist/world/terraform.d.ts +213 -1
  583. package/dist/world/terraform.js +655 -20
  584. package/dist/world/terrain.d.ts +138 -12
  585. package/dist/world/terrain.js +346 -28
  586. package/dist/world/terrainGuides.d.ts +182 -0
  587. package/dist/world/terrainGuides.js +343 -0
  588. package/dist/world/vec2.d.ts +81 -0
  589. package/dist/world/vec2.js +128 -0
  590. package/dist/world/vec3.d.ts +49 -0
  591. package/dist/world/vec3.js +76 -0
  592. package/dist/world/vegetation.d.ts +71 -0
  593. package/dist/world/vegetation.js +151 -0
  594. package/dist/world/visibilityField.d.ts +154 -0
  595. package/dist/world/visibilityField.js +271 -0
  596. package/dist/world/volumetricClouds.d.ts +52 -0
  597. package/dist/world/volumetricClouds.js +43 -0
  598. package/dist/world/walls.d.ts +9 -0
  599. package/dist/world/walls.js +9 -0
  600. package/dist/world/waterKind.d.ts +55 -0
  601. package/dist/world/waterKind.js +99 -0
  602. package/dist/world.d.ts +132 -0
  603. package/dist/world.js +132 -0
  604. package/package.json +32 -8
  605. package/skills/jgengine/SKILL.md +51 -0
  606. package/skills/jgengine/api.md +434 -0
  607. package/skills/jgengine/capabilities.md +29 -0
  608. package/skills/jgengine/reference-cartridge.md +72 -0
  609. package/skills/jgengine-combat/SKILL.md +34 -0
  610. package/skills/jgengine-combat/api.md +549 -0
  611. package/skills/jgengine-combat/capabilities.md +169 -0
  612. package/skills/jgengine-combat/reference.md +98 -0
  613. package/skills/jgengine-gameplay/SKILL.md +39 -0
  614. package/skills/jgengine-gameplay/api.md +1794 -0
  615. package/skills/jgengine-gameplay/capabilities.md +378 -0
  616. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  617. package/skills/jgengine-world/SKILL.md +38 -0
  618. package/skills/jgengine-world/api.md +2652 -0
  619. package/skills/jgengine-world/capabilities.md +370 -0
  620. package/skills/jgengine-world/reference.md +222 -0
  621. package/dist/cartridge/runtime.d.ts +0 -15
  622. package/dist/cartridge/runtime.js +0 -556
  623. package/dist/cartridge/spec.d.ts +0 -188
  624. package/dist/cartridge/spec.js +0 -19
  625. package/dist/cartridge/validate.d.ts +0 -2
  626. package/dist/cartridge/validate.js +0 -78
  627. package/dist/store/engineStore.d.ts +0 -22
  628. package/dist/store/engineStore.js +0 -50
  629. package/dist/store/features.d.ts +0 -10
  630. package/dist/store/features.js +0 -23
  631. package/llms.txt +0 -4983
@@ -1,4 +1,8 @@
1
1
  import type { BuildingPaletteOverrides, BuildingStyle } from "./buildings.js";
2
+ import type { AvoidZone } from "./geometry.js";
3
+ import type { TerrainPathProfile } from "./pathTerrain.js";
4
+ import type { TerraformSnapshot } from "./terraform.js";
5
+ import type { VolumetricCloudsConfig } from "./volumetricClouds.js";
2
6
  export interface WorldBounds {
3
7
  w: number;
4
8
  d: number;
@@ -15,6 +19,63 @@ export interface TerrainColors {
15
19
  high?: string;
16
20
  waterline?: string;
17
21
  }
22
+ /**
23
+ * Procedural detail-surface layer for terrain: a noise-driven shader that keeps the
24
+ * biome-tinted base ground (from `colors`/`biomeBands`) and blends distinct rock,
25
+ * sand, and snow over it by slope, height, and waterline — turning a flat
26
+ * vertex-colour surface into varied, textured-reading ground with no image assets.
27
+ */
28
+ export interface TerrainDetailConfig {
29
+ /** Steep-slope rock colour. Default "#6f7175". */
30
+ rockColor?: string;
31
+ /** Waterline/beach sand colour. Default "#c2b283". */
32
+ sandColor?: string;
33
+ /** High-altitude snow colour. Default "#eef3f7". */
34
+ snowColor?: string;
35
+ /** Slope (0 flat … 1 vertical) at which rock starts taking over. Default 0.42. */
36
+ rockSlopeStart?: number;
37
+ /** World height above which snow appears. Default 26. */
38
+ snowHeight?: number;
39
+ /** Water level for the sand band; defaults to the terrain's `waterLevel`. */
40
+ waterLevel?: number;
41
+ /** Fine detail noise wavelength in world units. Default 5. */
42
+ detailScale?: number;
43
+ /** Large-scale colour-variation wavelength in world units. Default 45. */
44
+ macroScale?: number;
45
+ /** Surface roughness of the detail material. Default 0.9. */
46
+ roughness?: number;
47
+ /** Overall detail intensity 0..1. Default 1. */
48
+ strength?: number;
49
+ /** Real PBR texture maps blended over the procedural detail — the seam for `@jgengine/assets` `buildMaterialCatalog` output. Omit to keep the procedural-only look. */
50
+ material?: TerrainDetailMaterialConfig;
51
+ }
52
+ /**
53
+ * PBR map URLs for a real ground texture — the same shape
54
+ * `buildMaterialCatalog({ basePath }).resolve(id)!.maps` from `@jgengine/assets` returns. Kept
55
+ * dependency-free here so `core` never imports the assets package; any URLs (pulled maps, a CDN, a
56
+ * data URI) satisfy it.
57
+ */
58
+ export interface TerrainMaterialMaps {
59
+ color: string;
60
+ normal: string;
61
+ roughness: string;
62
+ ao: string;
63
+ displacement: string;
64
+ }
65
+ /**
66
+ * Real PBR texture applied over the ground surface — the seam that lets a game put a
67
+ * `buildMaterialCatalog` material on terrain. Blends with, never replaces, the procedural detail
68
+ * shader: color/roughness/ao tile the maps by world position, `strength` fades them over the
69
+ * existing vertex-colour + noise look.
70
+ */
71
+ export interface TerrainDetailMaterialConfig {
72
+ /** e.g. `buildMaterialCatalog({ basePath: "/materials" }).resolve("material/grass")!.maps`. */
73
+ maps: TerrainMaterialMaps;
74
+ /** World units per texture tile; smaller tiles the texture more densely. Default 4. */
75
+ repeat?: number;
76
+ /** Blend strength of the texture over the procedural/vertex-colour base, 0..1. Default 1. */
77
+ strength?: number;
78
+ }
18
79
  export interface TerrainFlattenMask {
19
80
  center: EnvironmentVec2;
20
81
  radius: number;
@@ -23,16 +84,80 @@ export interface TerrainFlattenMask {
23
84
  /** Extra blend-ring width outside `radius` where the flat height smoothsteps back to the noise value; default `radius * 0.5`. */
24
85
  falloff?: number;
25
86
  }
26
- /** A circular palette zone painted over the base terrain palette — snow caps, ash wastes, sand shores on one heightfield. */
27
- export interface TerrainMaterialRegion {
28
- center: EnvironmentVec2;
29
- radius: number;
87
+ /** Palette and blend fields shared by every `TerrainMaterialRegion` shape. */
88
+ export interface TerrainRegionStyle {
30
89
  /** Named palette preset for this region (see `TERRAIN_MATERIAL_PALETTES` in `world/terrain`); overridden field-by-field by `colors`. */
31
90
  material?: TerrainMaterial;
32
91
  colors?: TerrainColors;
33
- /** Blend-ring width outside `radius` back to the surrounding palette; default `radius * 0.5`. */
92
+ /** Blend-ring width outside the region core back to the surrounding palette; default: half the region's characteristic size. */
34
93
  falloff?: number;
35
94
  }
95
+ /** A circular palette zone painted over the base terrain palette — snow caps, ash wastes, spawn circles. */
96
+ export interface TerrainCircleRegion extends TerrainRegionStyle {
97
+ shape?: "circle";
98
+ center: EnvironmentVec2;
99
+ radius: number;
100
+ }
101
+ /** A ribbon palette zone following a centerline — roads and rivers, instead of chaining overlapping circles. */
102
+ export interface TerrainPolylineRegion extends TerrainRegionStyle {
103
+ shape: "polyline";
104
+ /** Centerline vertices in world XZ; needs at least two points. */
105
+ points: readonly EnvironmentVec2[];
106
+ /** Full ribbon width; the painted core extends `width / 2` either side of the centerline. `falloff` defaults to `width * 0.5`. */
107
+ width: number;
108
+ }
109
+ /** A rectangular palette zone, optionally rotated about the world y axis — plazas, fields, districts. */
110
+ export interface TerrainRectRegion extends TerrainRegionStyle {
111
+ shape: "rect";
112
+ center: EnvironmentVec2;
113
+ /** Half-extents along the region's local x and z before rotation. `falloff` defaults to half the smaller extent. */
114
+ halfExtents: EnvironmentVec2;
115
+ /** Rotation about the world y axis in radians; default 0. */
116
+ rotationY?: number;
117
+ }
118
+ /**
119
+ * A palette zone painted over the base terrain palette. Circle (the default when no `shape` is given),
120
+ * `polyline` ribbons for roads/rivers, and rotatable `rect` districts all paint fully inside their core
121
+ * and blend back across `falloff`; later regions in the list win overlaps.
122
+ */
123
+ export type TerrainMaterialRegion = TerrainCircleRegion | TerrainPolylineRegion | TerrainRectRegion;
124
+ /** Per-band fog override cross-faded along z by `createBiomeFogSampler`; unset fields fall through to the base sky fog. */
125
+ export interface BiomeFog {
126
+ color?: string;
127
+ near?: number;
128
+ far?: number;
129
+ density?: number;
130
+ }
131
+ /** Per-band sky/light override cross-faded along z by `createBiomeSkySampler`; unset fields fall through to the base sky. */
132
+ export interface BiomeSky {
133
+ horizonColor?: string;
134
+ zenithColor?: string;
135
+ sunIntensity?: number;
136
+ ambientIntensity?: number;
137
+ }
138
+ /**
139
+ * A z-ordered ground palette zone — the linear-boundary counterpart to the radial `materialRegions`.
140
+ * Adjacent bands cross-fade into each other across a `fade`-wide window centered on the midpoint z
141
+ * between their centers, so a multi-biome world (vale → marsh → peaks along z) blends its ground
142
+ * color instead of hard-switching. Bands may also carry per-zone `fog`, `sky`, and `weather`. Order
143
+ * the list by ascending `z`.
144
+ */
145
+ export interface BiomeBand {
146
+ /** World-space center z of the zone. */
147
+ z: number;
148
+ /** Cross-fade window width straddling the boundary to the next band. Default 64. */
149
+ fade?: number;
150
+ /** Named palette preset for the zone (see `TERRAIN_MATERIAL_PALETTES`); overridden field-by-field by `colors`. */
151
+ material?: TerrainMaterial;
152
+ /** Explicit low/high/waterline hex colors for the zone. */
153
+ colors?: TerrainColors;
154
+ /** Fog color/near/far/density for the zone, cross-faded per camera z; unset fields keep the base sky fog. */
155
+ fog?: BiomeFog;
156
+ /** Sky horizon/zenith colors and sun/ambient intensity for the zone, cross-faded per camera z; unset fields keep the base sky. */
157
+ sky?: BiomeSky;
158
+ /** Precipitation covering the zone — expands into a full-width weather strip centered at `[0, z]`, `fade`-deep. */
159
+ weather?: "rain" | "snow";
160
+ }
36
161
  export interface TerrainEnvironmentConfig {
37
162
  bounds?: WorldBounds;
38
163
  height?: number;
@@ -49,6 +174,8 @@ export interface TerrainEnvironmentConfig {
49
174
  colors?: TerrainColors;
50
175
  /** Palette zones blended over the base `material`/`colors` for multi-biome readability. */
51
176
  materialRegions?: readonly TerrainMaterialRegion[];
177
+ /** Ordered z-banded ground palettes that cross-fade along the world's z axis (vale → marsh → peaks). Painted under `materialRegions`. */
178
+ biomeBands?: readonly BiomeBand[];
52
179
  segments?: number;
53
180
  seed?: string;
54
181
  frequency?: number;
@@ -58,26 +185,64 @@ export interface TerrainEnvironmentConfig {
58
185
  waterLevel?: number;
59
186
  /** Flat pads carved into the noise field, e.g. for building pads or spawn circles. */
60
187
  flatten?: readonly TerrainFlattenMask[];
188
+ /** Authored path profiles that flatten/grade/carve the heightfield along a centerline (roads, rivers, ramps) with optional retaining walls. Applied after `flatten`. */
189
+ pathProfiles?: readonly TerrainPathProfile[];
190
+ /** Procedural detail surface (noise-driven rock/sand/snow over the biome base). Omit for the flat vertex-colour ground. */
191
+ detail?: TerrainDetailConfig;
61
192
  }
62
193
  export interface RainEnvironmentConfig {
194
+ /**
195
+ * `w`/`d`/`h` size a wrap-volume of raindrops **anchored to and re-centered on the camera every
196
+ * frame** — not a world-space region. `area.position` (and the `position` sugar below) has **no
197
+ * visual effect** on rain/snow: the shell's `RainField`/`SnowField` always run `followCamera` and
198
+ * never apply the mesh's transform, only `camera.position`. Keep `w`/`d`/`h` near camera scale
199
+ * (roughly 50-120 per axis) so drops stay a visible size at normal view distance — sizing the
200
+ * volume to a world region (e.g. matching a district's footprint) spreads the same drop count
201
+ * across that much more space until they're sub-pixel and the storm reads as empty sky, even
202
+ * though `summarizeEnvironment` shows the layer exists. Reach for `density`, `width`, and `opacity`
203
+ * to make a storm read heavier/taller instead of enlarging `area`.
204
+ */
63
205
  area?: EnvironmentArea;
206
+ /** World-space center `[x, z]` of the band, matching `building()`/`ocean()` — sugar for `area.position`. No visual effect on rain/snow (see `area`); kept for API symmetry with other weather-adjacent features. */
207
+ position?: EnvironmentVec2;
64
208
  density?: number;
65
209
  speed?: number;
66
210
  dropLength?: number;
67
211
  wind?: EnvironmentVec2;
68
212
  color?: string;
213
+ /** Streak width of each raindrop quad, in world units. Default 0.018 — raise for a heavier-reading storm without enlarging `area`. */
214
+ width?: number;
215
+ /** Drop opacity, 0-1. Default 0.48 — raise for a denser-reading storm without enlarging `area`. */
216
+ opacity?: number;
69
217
  }
70
218
  export interface SnowEnvironmentConfig {
219
+ /**
220
+ * `w`/`d`/`h` size a wrap-volume of snowflakes **anchored to and re-centered on the camera every
221
+ * frame** — not a world-space region. `area.position` (and the `position` sugar below) has **no
222
+ * visual effect** on rain/snow: the shell's `RainField`/`SnowField` always run `followCamera` and
223
+ * never apply the mesh's transform, only `camera.position`. Keep `w`/`d`/`h` near camera scale
224
+ * (roughly 50-120 per axis) so flakes stay a visible size at normal view distance — sizing the
225
+ * volume to a world region (e.g. matching a district's footprint) spreads the same flake count
226
+ * across that much more space until they're sub-pixel and the storm reads as empty sky, even
227
+ * though `summarizeEnvironment` shows the layer exists. Reach for `density`, `flakeSize`, and
228
+ * `opacity` to make a storm read heavier instead of enlarging `area`.
229
+ */
71
230
  area?: EnvironmentArea;
231
+ /** World-space center `[x, z]` of the band, matching `building()`/`ocean()` — sugar for `area.position`. No visual effect on rain/snow (see `area`); kept for API symmetry with other weather-adjacent features. */
232
+ position?: EnvironmentVec2;
72
233
  density?: number;
73
234
  speed?: number;
74
235
  flakeSize?: number;
75
236
  drift?: number;
76
237
  wind?: EnvironmentVec2;
77
238
  color?: string;
239
+ /** Flake opacity, 0-1. Default 0.86 — raise for a denser-reading storm without enlarging `area`. */
240
+ opacity?: number;
78
241
  }
79
242
  export interface GrassEnvironmentConfig {
80
243
  area?: EnvironmentArea;
244
+ /** World-space center `[x, z]` of the band, matching `building()`/`ocean()` — sugar for `area.position`, letting a biome zone site its own vegetation away from the origin. */
245
+ position?: EnvironmentVec2;
81
246
  density?: number;
82
247
  bladeHeight?: readonly [number, number];
83
248
  bladeWidth?: number;
@@ -111,11 +276,19 @@ export interface SkyEnvironmentConfig {
111
276
  zenithColor?: string;
112
277
  sunIntensity?: number;
113
278
  ambientIntensity?: number;
279
+ /** Sky-dome sphere radius in world units. Enlarge for a playfield sited far from the origin so the viewer never exits the dome. Default 260. */
280
+ radius?: number;
281
+ /** Horizon haze-band strength: 0 removes the dusty band, ~1 makes it heavy. Default 0.5. */
282
+ hazeStrength?: number;
283
+ /** Sun-glow brightness multiplier around the sun disc. Default 1. */
284
+ sunGlowStrength?: number;
114
285
  fog?: {
115
286
  color?: string;
116
287
  near?: number;
117
288
  far?: number;
118
289
  };
290
+ /** Raymarched volumetric cloud layer over the sky dome. Off by default — omit for no clouds. */
291
+ volumetricClouds?: VolumetricCloudsConfig;
119
292
  }
120
293
  export interface BuildingEnvironmentConfig {
121
294
  count?: number;
@@ -158,10 +331,10 @@ export type TerrainIslandDescriptor = Omit<TerrainEnvironmentDescriptor, "kind">
158
331
  };
159
332
  export type RainEnvironmentDescriptor = {
160
333
  kind: "rain";
161
- } & Required<Pick<RainEnvironmentConfig, "area" | "density" | "speed" | "dropLength" | "wind" | "color">>;
334
+ } & Required<Pick<RainEnvironmentConfig, "area" | "density" | "speed" | "dropLength" | "wind" | "color" | "width" | "opacity">>;
162
335
  export type SnowEnvironmentDescriptor = {
163
336
  kind: "snow";
164
- } & Required<Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color">>;
337
+ } & Required<Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color" | "opacity">>;
165
338
  export type GrassEnvironmentDescriptor = {
166
339
  kind: "grass";
167
340
  } & Required<Pick<GrassEnvironmentConfig, "area" | "density" | "bladeHeight" | "bladeWidth" | "windStrength" | "colors">> & Pick<GrassEnvironmentConfig, "seed">;
@@ -177,6 +350,36 @@ export type PadEnvironmentDescriptor = {
177
350
  export type SkyEnvironmentDescriptor = {
178
351
  kind: "sky";
179
352
  } & Required<Pick<SkyEnvironmentConfig, "preset" | "timeOfDay">> & Omit<SkyEnvironmentConfig, "preset" | "timeOfDay">;
353
+ /** Config for {@link road}: a flat asphalt ribbon draped over the terrain along a centerline. */
354
+ export interface RoadEnvironmentConfig {
355
+ /** Centerline vertices in world XZ; at least two points. */
356
+ path: readonly (readonly [number, number])[];
357
+ /** Ribbon width in world units. Default 8. */
358
+ width?: number;
359
+ /** Asphalt color. Default "#3b3e47". */
360
+ color?: string;
361
+ /** Paint a dashed centerline. Default true. */
362
+ markings?: boolean;
363
+ /** Centerline dash color. Default "#e8c74a". */
364
+ markingColor?: string;
365
+ /** Lift above the terrain to avoid z-fighting; stagger overlapping roads. Default 0.08. */
366
+ elevation?: number;
367
+ /** Sidewalk bands on both edges; `false` for none. Default `{ width: 2.6, color: "#a7adb8" }`. */
368
+ sidewalk?: {
369
+ width?: number;
370
+ color?: string;
371
+ } | false;
372
+ }
373
+ /** Resolved road descriptor produced by {@link road} and rendered by the shell environment scene. */
374
+ export type RoadEnvironmentDescriptor = {
375
+ kind: "road";
376
+ } & Required<Pick<RoadEnvironmentConfig, "path" | "width" | "color" | "markings" | "markingColor" | "elevation">> & {
377
+ /** Resolved sidewalk band, or `false` when the road has none. */
378
+ sidewalk: {
379
+ width: number;
380
+ color: string;
381
+ } | false;
382
+ };
180
383
  export type WeatherEnvironmentDescriptor = RainEnvironmentDescriptor | SnowEnvironmentDescriptor;
181
384
  export type VegetationEnvironmentDescriptor = GrassEnvironmentDescriptor;
182
385
  export type WaterEnvironmentDescriptor = OceanEnvironmentDescriptor;
@@ -191,8 +394,22 @@ export interface EnvironmentWorldConfig {
191
394
  vegetation?: EnvironmentDescriptorList<VegetationEnvironmentDescriptor>;
192
395
  water?: EnvironmentDescriptorList<WaterEnvironmentDescriptor>;
193
396
  structures?: EnvironmentDescriptorList<StructureEnvironmentDescriptor>;
397
+ /** Road ribbons draped over the terrain — see `road()`. */
398
+ roads?: EnvironmentDescriptorList<RoadEnvironmentDescriptor>;
194
399
  /** Ground pads, e.g. platforms or paved patches; each implicitly flattens the terrain beneath it. */
195
400
  pads?: readonly PadEnvironmentDescriptor[];
401
+ /**
402
+ * An authored editor {@link TerraformSnapshot} whose offsets layer over the base terrain — the
403
+ * editor-to-runtime ground seam. The same snapshot in a game's `editorLayers.terrain` renders and
404
+ * collides identically at runtime.
405
+ */
406
+ sculpt?: TerraformSnapshot;
407
+ /**
408
+ * Clearance discs flattened into the ground (spawns, plots, paths) — the terrain half of a
409
+ * clearance zone whose foliage half is scatter's `avoid`. Derive them from a document with
410
+ * `clearanceZonesFrom`.
411
+ */
412
+ clearings?: readonly AvoidZone[];
196
413
  }
197
414
  export interface EnvironmentWorldFeature {
198
415
  kind: "environment";
@@ -203,7 +420,12 @@ export interface EnvironmentWorldFeature {
203
420
  vegetation?: readonly VegetationEnvironmentDescriptor[];
204
421
  water?: readonly WaterEnvironmentDescriptor[];
205
422
  structures?: readonly StructureEnvironmentDescriptor[];
423
+ roads?: readonly RoadEnvironmentDescriptor[];
206
424
  pads?: readonly PadEnvironmentDescriptor[];
425
+ /** Authored sculpt snapshot layered over the base terrain — see {@link EnvironmentWorldConfig.sculpt}. */
426
+ sculpt?: TerraformSnapshot;
427
+ /** Clearance discs flattened into the ground — see {@link EnvironmentWorldConfig.clearings}. */
428
+ clearings?: readonly AvoidZone[];
207
429
  }
208
430
  export interface WorldGridCell {
209
431
  x: number;
@@ -242,6 +464,7 @@ export interface PlotsWorldConfig extends WorldGridConfig {
242
464
  export interface TilemapWorldConfig extends WorldGridConfig {
243
465
  map: string;
244
466
  }
467
+ /** A declared world shape — biomes, voxel grid, plots, tilemap, environment, or flat — passed to `defineGame`. */
245
468
  export type WorldFeature = ({
246
469
  kind: "biomes";
247
470
  } & BiomesWorldConfig) | ({
@@ -255,18 +478,32 @@ export type WorldFeature = ({
255
478
  };
256
479
  /** Derives implicit `TerrainFlattenMask`s carving each pad's footprint into the terrain beneath it. Elevated pads (absolute `elevation`) float free and carve nothing. */
257
480
  export declare function padFlattenMasks(pads: readonly PadEnvironmentDescriptor[]): readonly TerrainFlattenMask[];
481
+ /** Composes an `environment()` world feature from terrain, sky, weather, vegetation, water, structures, roads, and pads. */
258
482
  export declare function environment(config?: EnvironmentWorldConfig): EnvironmentWorldFeature;
483
+ /** Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks. */
259
484
  export declare function terrain(config?: TerrainEnvironmentConfig): TerrainEnvironmentDescriptor;
260
485
  export declare function sky(config?: SkyEnvironmentConfig): SkyEnvironmentDescriptor;
486
+ /** Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity. */
261
487
  export declare function rain(config?: RainEnvironmentConfig): RainEnvironmentDescriptor;
488
+ /** Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity. */
262
489
  export declare function snow(config?: SnowEnvironmentConfig): SnowEnvironmentDescriptor;
490
+ /** Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors. */
263
491
  export declare function grass(config?: GrassEnvironmentConfig): GrassEnvironmentDescriptor;
492
+ /** Declares an ocean water body for `environment()` — bounds, level, and wave tuning. */
264
493
  export declare function ocean(config?: OceanEnvironmentConfig): OceanEnvironmentDescriptor;
494
+ /** Declare a road ribbon for an `environment()` world; the shell drapes and renders it over the terrain. */
495
+ export declare function road(config: RoadEnvironmentConfig): RoadEnvironmentDescriptor;
265
496
  export declare function island(config: TerrainIslandConfig): TerrainIslandDescriptor;
497
+ /** Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style. */
266
498
  export declare function building(config?: BuildingEnvironmentConfig): BuildingEnvironmentDescriptor;
267
499
  export declare function pad(config: PadEnvironmentConfig): PadEnvironmentDescriptor;
500
+ /** Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain. */
268
501
  export declare function biomes(config: BiomesWorldConfig): WorldFeature;
502
+ /** Declares a voxel-grid world for block-based games. */
269
503
  export declare function voxel(config: VoxelWorldConfig): WorldFeature;
504
+ /** Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts. */
270
505
  export declare function plots(config?: PlotsWorldConfig): WorldFeature;
506
+ /** Declares a 2D tilemap world from a map string. */
271
507
  export declare function tilemap(config: TilemapWorldConfig): WorldFeature;
508
+ /** Declares an empty flat world — the minimal `WorldFeature` for games with no terrain of their own. */
272
509
  export declare function flat(): WorldFeature;
@@ -27,11 +27,32 @@ function withPadFlatten(terrainDescriptor, pads) {
27
27
  flatten: [...(terrainDescriptor.flatten ?? []), ...padFlattenMasks(pads)],
28
28
  };
29
29
  }
30
+ /** Expands each `biomeBand.weather` into a full-width precipitation strip centered on the band's z, `fade`-deep. */
31
+ function bandWeatherDescriptors(terrainDescriptor) {
32
+ const bands = terrainDescriptor?.biomeBands;
33
+ if (bands === undefined || bands.length === 0)
34
+ return [];
35
+ const width = terrainDescriptor.bounds.w;
36
+ const out = [];
37
+ for (const band of bands) {
38
+ if (band.weather === undefined)
39
+ continue;
40
+ const area = { w: width, d: band.fade ?? 64, h: 80 };
41
+ const position = [0, band.z];
42
+ out.push(band.weather === "rain" ? rain({ area, position }) : snow({ area, position }));
43
+ }
44
+ return out;
45
+ }
46
+ /** Composes an `environment()` world feature from terrain, sky, weather, vegetation, water, structures, roads, and pads. */
30
47
  export function environment(config = {}) {
31
- const weather = list(config.weather);
48
+ const explicitWeather = list(config.weather);
49
+ const bandWeather = bandWeatherDescriptors(config.terrain);
50
+ const weatherAll = [...(explicitWeather ?? []), ...bandWeather];
51
+ const weather = weatherAll.length === 0 ? undefined : weatherAll;
32
52
  const vegetation = list(config.vegetation);
33
53
  const water = list(config.water);
34
54
  const structures = list(config.structures);
55
+ const roads = list(config.roads);
35
56
  const terrainDescriptor = withPadFlatten(config.terrain, config.pads);
36
57
  return {
37
58
  kind: "environment",
@@ -42,9 +63,13 @@ export function environment(config = {}) {
42
63
  ...(vegetation === undefined ? {} : { vegetation }),
43
64
  ...(water === undefined ? {} : { water }),
44
65
  ...(structures === undefined ? {} : { structures }),
66
+ ...(roads === undefined ? {} : { roads }),
45
67
  ...(config.pads === undefined ? {} : { pads: config.pads }),
68
+ ...(config.sculpt === undefined ? {} : { sculpt: config.sculpt }),
69
+ ...(config.clearings === undefined || config.clearings.length === 0 ? {} : { clearings: config.clearings }),
46
70
  };
47
71
  }
72
+ /** Declares a heightfield terrain patch for `environment()` — bounds, noise, materials, and flatten masks. */
48
73
  export function terrain(config = {}) {
49
74
  if (config.baseHeight !== undefined &&
50
75
  config.height === undefined &&
@@ -62,6 +87,7 @@ export function terrain(config = {}) {
62
87
  ...(config.material === undefined ? {} : { material: config.material }),
63
88
  ...(config.colors === undefined ? {} : { colors: config.colors }),
64
89
  ...(config.materialRegions === undefined ? {} : { materialRegions: config.materialRegions }),
90
+ ...(config.biomeBands === undefined ? {} : { biomeBands: config.biomeBands }),
65
91
  ...(config.segments === undefined ? {} : { segments: config.segments }),
66
92
  ...(config.seed === undefined ? {} : { seed: config.seed }),
67
93
  ...(config.frequency === undefined ? {} : { frequency: config.frequency }),
@@ -70,6 +96,8 @@ export function terrain(config = {}) {
70
96
  ...(config.baseHeight === undefined ? {} : { baseHeight: config.baseHeight }),
71
97
  ...(config.waterLevel === undefined ? {} : { waterLevel: config.waterLevel }),
72
98
  ...(config.flatten === undefined ? {} : { flatten: config.flatten }),
99
+ ...(config.pathProfiles === undefined ? {} : { pathProfiles: config.pathProfiles }),
100
+ ...(config.detail === undefined ? {} : { detail: config.detail }),
73
101
  });
74
102
  }
75
103
  export function sky(config = {}) {
@@ -82,36 +110,71 @@ export function sky(config = {}) {
82
110
  ...(config.zenithColor === undefined ? {} : { zenithColor: config.zenithColor }),
83
111
  ...(config.sunIntensity === undefined ? {} : { sunIntensity: config.sunIntensity }),
84
112
  ...(config.ambientIntensity === undefined ? {} : { ambientIntensity: config.ambientIntensity }),
113
+ ...(config.radius === undefined ? {} : { radius: config.radius }),
114
+ ...(config.hazeStrength === undefined ? {} : { hazeStrength: config.hazeStrength }),
115
+ ...(config.sunGlowStrength === undefined ? {} : { sunGlowStrength: config.sunGlowStrength }),
85
116
  ...(config.fog === undefined ? {} : { fog: config.fog }),
117
+ ...(config.volumetricClouds === undefined ? {} : { volumetricClouds: config.volumetricClouds }),
86
118
  });
87
119
  }
120
+ function withAreaPosition(area, position) {
121
+ return position !== undefined && area.position === undefined ? { ...area, position } : area;
122
+ }
123
+ /**
124
+ * Practical ceiling (world units per axis) past which an author-specified rain/snow `area` is almost
125
+ * certainly a world-region size mistakenly handed to the camera-anchored wrap-volume — see the
126
+ * `area` doc on `RainEnvironmentConfig`/`SnowEnvironmentConfig`.
127
+ */
128
+ const WEATHER_AREA_CAMERA_SCALE_HINT = 120;
129
+ function warnIfOversizedWeatherArea(kind, area) {
130
+ if (typeof console === "undefined")
131
+ return;
132
+ if (area.w <= WEATHER_AREA_CAMERA_SCALE_HINT &&
133
+ area.d <= WEATHER_AREA_CAMERA_SCALE_HINT &&
134
+ (area.h ?? 0) <= WEATHER_AREA_CAMERA_SCALE_HINT) {
135
+ return;
136
+ }
137
+ console.warn(`[jgengine:${kind}] area ${area.w}x${area.d}x${area.h ?? "default"} is far larger than the camera-anchored wrap-volume ${kind}() actually renders — area.position is ignored, and an oversized area.w/d/h just spreads drops/flakes thinner until they're sub-pixel at normal view distance, not wider visible coverage. Keep area near camera scale (~50-120 per axis); use density/width/opacity (or flakeSize for snow) to make a storm read heavier instead.`);
138
+ }
139
+ /** Declares a rainfall weather effect for `environment()` — area, density, speed, wind, and drop width/opacity. */
88
140
  export function rain(config = {}) {
141
+ const area = withAreaPosition(config.area ?? { w: 256, d: 256, h: 80 }, config.position);
142
+ if (config.area !== undefined)
143
+ warnIfOversizedWeatherArea("rain", area);
89
144
  return {
90
145
  kind: "rain",
91
- area: config.area ?? { w: 256, d: 256, h: 80 },
146
+ area,
92
147
  density: config.density ?? 0.65,
93
148
  speed: config.speed ?? 18,
94
149
  dropLength: config.dropLength ?? 0.8,
95
150
  wind: config.wind ?? [0, 0],
96
151
  color: config.color ?? "#9ec8ff",
152
+ width: config.width ?? 0.018,
153
+ opacity: config.opacity ?? 0.48,
97
154
  };
98
155
  }
156
+ /** Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity. */
99
157
  export function snow(config = {}) {
158
+ const area = withAreaPosition(config.area ?? { w: 256, d: 256, h: 80 }, config.position);
159
+ if (config.area !== undefined)
160
+ warnIfOversizedWeatherArea("snow", area);
100
161
  return {
101
162
  kind: "snow",
102
- area: config.area ?? { w: 256, d: 256, h: 80 },
163
+ area,
103
164
  density: config.density ?? 0.35,
104
165
  speed: config.speed ?? 2.4,
105
166
  flakeSize: config.flakeSize ?? 0.08,
106
167
  drift: config.drift ?? 0.4,
107
168
  wind: config.wind ?? [0, 0],
108
169
  color: config.color ?? "#ffffff",
170
+ opacity: config.opacity ?? 0.86,
109
171
  };
110
172
  }
173
+ /** Declares a grass vegetation patch for `environment()` — area, blade sizing, density, and colors. */
111
174
  export function grass(config = {}) {
112
175
  return withOptional({
113
176
  kind: "grass",
114
- area: config.area ?? { w: 128, d: 128 },
177
+ area: withAreaPosition(config.area ?? { w: 128, d: 128 }, config.position),
115
178
  density: config.density ?? 4,
116
179
  bladeHeight: config.bladeHeight ?? [0.25, 0.9],
117
180
  bladeWidth: config.bladeWidth ?? 0.035,
@@ -119,6 +182,7 @@ export function grass(config = {}) {
119
182
  colors: config.colors ?? ["#3f7d2d", "#66a83f"],
120
183
  }, config.seed === undefined ? undefined : { seed: config.seed });
121
184
  }
185
+ /** Declares an ocean water body for `environment()` — bounds, level, and wave tuning. */
122
186
  export function ocean(config = {}) {
123
187
  return {
124
188
  kind: "ocean",
@@ -132,11 +196,30 @@ export function ocean(config = {}) {
132
196
  ...(config.levelAt === undefined ? {} : { levelAt: config.levelAt }),
133
197
  };
134
198
  }
199
+ /** Declare a road ribbon for an `environment()` world; the shell drapes and renders it over the terrain. */
200
+ export function road(config) {
201
+ if (config.path.length < 2) {
202
+ throw new Error("road: path needs at least two points");
203
+ }
204
+ return {
205
+ kind: "road",
206
+ path: config.path,
207
+ width: config.width ?? 8,
208
+ color: config.color ?? "#3b3e47",
209
+ markings: config.markings ?? true,
210
+ markingColor: config.markingColor ?? "#e8c74a",
211
+ elevation: config.elevation ?? 0.08,
212
+ sidewalk: config.sidewalk === false
213
+ ? false
214
+ : { width: config.sidewalk?.width ?? 2.6, color: config.sidewalk?.color ?? "#a7adb8" },
215
+ };
216
+ }
135
217
  export function island(config) {
136
218
  const { origin, ...terrainConfig } = config;
137
219
  const { kind: _kind, ...descriptor } = terrain(terrainConfig);
138
220
  return { ...descriptor, kind: "island", origin };
139
221
  }
222
+ /** Declares a cluster of procedurally-massed buildings for `environment()` — count, footprint, stories, style. */
140
223
  export function building(config = {}) {
141
224
  return withOptional({
142
225
  kind: "building",
@@ -164,18 +247,23 @@ export function pad(config) {
164
247
  ...(config.elevation === undefined ? {} : { elevation: config.elevation }),
165
248
  });
166
249
  }
250
+ /** Declares a biome-painted world — the whole-world alternative to a single `environment()` terrain. */
167
251
  export function biomes(config) {
168
252
  return { kind: "biomes", ...config };
169
253
  }
254
+ /** Declares a voxel-grid world for block-based games. */
170
255
  export function voxel(config) {
171
256
  return { kind: "voxel", ...config };
172
257
  }
258
+ /** Declares a subdivided-plots world — farming, base-building, and other parcel-based layouts. */
173
259
  export function plots(config = {}) {
174
260
  return { kind: "plots", ...config };
175
261
  }
262
+ /** Declares a 2D tilemap world from a map string. */
176
263
  export function tilemap(config) {
177
264
  return { kind: "tilemap", ...config };
178
265
  }
266
+ /** Declares an empty flat world — the minimal `WorldFeature` for games with no terrain of their own. */
179
267
  export function flat() {
180
268
  return { kind: "flat" };
181
269
  }
@@ -0,0 +1,59 @@
1
+ import type { Footprint, Vec2 } from "./geometry.js";
2
+ import type { PlacementObstacle } from "./placement.js";
3
+ /** One integer cell address on a {@link FootprintGrid}. */
4
+ export interface GridCell {
5
+ col: number;
6
+ row: number;
7
+ }
8
+ /** Config for {@link createFootprintGrid}. */
9
+ export interface FootprintGridOptions {
10
+ /** World units per cell. Default 1. */
11
+ cellSize?: number;
12
+ }
13
+ /** A live claim on a {@link FootprintGrid}: which cells `id` (a `kind` tag for adjacency checks) holds. */
14
+ export interface FootprintReservation {
15
+ id: string;
16
+ kind: string;
17
+ cells: readonly GridCell[];
18
+ }
19
+ /** Handle returned by {@link createFootprintGrid}. */
20
+ export interface FootprintGrid {
21
+ readonly cellSize: number;
22
+ /** The cells a `footprint` centered on `origin` (world units) covers, honoring `quarterTurns` — feed straight into `reserve`/`isFree`. */
23
+ cellsFor(origin: Vec2, footprint: Footprint, quarterTurns?: number): GridCell[];
24
+ isFree(cells: readonly GridCell[]): boolean;
25
+ /** Claims every cell for `id`/`kind`; fails (no partial reservation) if `id` already holds a reservation or any cell is occupied. */
26
+ reserve(id: string, kind: string, cells: readonly GridCell[]): boolean;
27
+ release(id: string): boolean;
28
+ occupantAt(cell: GridCell): string | null;
29
+ kindAt(cell: GridCell): string | null;
30
+ reservationOf(id: string): FootprintReservation | null;
31
+ list(): readonly FootprintReservation[];
32
+ clear(): void;
33
+ }
34
+ /**
35
+ * Multi-cell footprint occupancy/reservation on a shared build grid — `world/placementController`
36
+ * only owns the ghost preview; this is the persistent claim a committed placement holds so the next
37
+ * hover's `isFree` check (or another player's, in a shared world) sees it. Bridge into
38
+ * `world/placement`'s `PlacementRules.obstacles` with {@link footprintObstacles} instead of
39
+ * hand-rolling an occupancy map per game.
40
+ *
41
+ * @capability footprint-grid multi-cell footprint occupancy/reservation on a shared build grid
42
+ */
43
+ export declare function createFootprintGrid(options?: FootprintGridOptions): FootprintGrid;
44
+ /** One occupied neighbor cell reported by {@link boundaryNeighbors}. */
45
+ export interface AdjacentCell {
46
+ cell: GridCell;
47
+ kind: string;
48
+ }
49
+ /** Every occupied cell orthogonally touching `cells` but outside them — the connective-piece neighbor set. */
50
+ export declare function boundaryNeighbors(grid: FootprintGrid, cells: readonly GridCell[]): AdjacentCell[];
51
+ /**
52
+ * Connective-piece adjacency validity: every occupied neighbor of `cells` must satisfy `accepts`
53
+ * (no incompatible piece touching), and when `requireConnection` is true at least one neighbor must
54
+ * (a road/pipe/belt segment placed with nothing to connect to is invalid). An empty-bordered footprint
55
+ * (no occupied neighbors at all) passes unless `requireConnection` demands one.
56
+ */
57
+ export declare function hasValidAdjacency(grid: FootprintGrid, cells: readonly GridCell[], accepts: (neighborKind: string) => boolean, requireConnection?: boolean): boolean;
58
+ /** Bridges live reservations into `world/placement`'s `PlacementRules.obstacles` so `validatePlacement`/`createPlacementController` see the grid's committed footprints unchanged. */
59
+ export declare function footprintObstacles(grid: FootprintGrid): PlacementObstacle[];