@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,3 +1,4 @@
1
+ import { withPathProfiles } from "./pathTerrain.js";
1
2
  import { nearestOnPath } from "./roads.js";
2
3
  function clamp01(value) {
3
4
  return value < 0 ? 0 : value > 1 ? 1 : value;
@@ -14,7 +15,9 @@ function hash2(ix, iz, seed) {
14
15
  h ^= h >>> 12;
15
16
  return (h >>> 0) / 4294967295;
16
17
  }
17
- /** Smoothly interpolated 2D value noise in `[-1, 1]` for the given seed. */
18
+ /** Smoothly interpolated 2D value noise in `[-1, 1]` for the given seed.
19
+ * @internal
20
+ */
18
21
  export function valueNoise(x, z, seed) {
19
22
  const x0 = Math.floor(x);
20
23
  const z0 = Math.floor(z);
@@ -30,7 +33,9 @@ export function valueNoise(x, z, seed) {
30
33
  const bottom = lerp(v01, v11, sx);
31
34
  return lerp(top, bottom, sz) * 2 - 1;
32
35
  }
33
- /** Layers `valueNoise` octaves per `config` into a single normalized noise sample. */
36
+ /** Layers `valueNoise` octaves per `config` into a single normalized noise sample.
37
+ * @internal
38
+ */
34
39
  export function fractalNoise(x, z, config) {
35
40
  let amplitude = 1;
36
41
  let frequency = config.frequency;
@@ -47,6 +52,7 @@ export function fractalNoise(x, z, config) {
47
52
  }
48
53
  return norm === 0 ? 0 : sum / norm;
49
54
  }
55
+ /** @internal */
50
56
  export function seedFrom(value, fallback) {
51
57
  if (typeof value === "number")
52
58
  return value | 0;
@@ -60,7 +66,9 @@ export function seedFrom(value, fallback) {
60
66
  }
61
67
  return fallback;
62
68
  }
63
- /** Derives a `TerrainField.sampleNormal` from a height sampler via finite-difference gradients. */
69
+ /** Derives a `TerrainField.sampleNormal` from a height sampler via finite-difference gradients.
70
+ * @internal
71
+ */
64
72
  export function withNormal(sampleHeight) {
65
73
  const epsilon = 0.75;
66
74
  return (x, z) => {
@@ -85,11 +93,15 @@ export const FLAT_FIELD = {
85
93
  sampleHeight: () => 0,
86
94
  sampleNormal: () => [0, 1, 0],
87
95
  };
88
- /** A flat, zero-height `TerrainField` for arenas with no elevation. */
96
+ /** A flat, zero-height `TerrainField` for arenas with no elevation.
97
+ * @internal
98
+ */
89
99
  export function flatField() {
90
100
  return FLAT_FIELD;
91
101
  }
92
- /** Builds a `TerrainField` whose height is fractal noise shaped by `config`. */
102
+ /** Builds a `TerrainField` whose height is fractal noise shaped by `config`.
103
+ * @internal
104
+ */
93
105
  export function noiseField(config = {}) {
94
106
  const fractal = {
95
107
  seed: seedFrom(config.seed, 1337),
@@ -106,6 +118,7 @@ export function noiseField(config = {}) {
106
118
  waterLevel: config.waterLevel,
107
119
  });
108
120
  }
121
+ /** @internal */
109
122
  export function rollingField(config = {}) {
110
123
  return noiseField({
111
124
  seed: config.seed ?? "rolling",
@@ -126,7 +139,9 @@ function smoothstep(edge0, edge1, value) {
126
139
  const t = clamp01((value - edge0) / (edge1 - edge0));
127
140
  return t * t * (3 - 2 * t);
128
141
  }
129
- /** Builds a `TerrainField` with a flat spawn plateau, rolling hills, and a basin, for combat arenas. */
142
+ /** Builds a `TerrainField` with a flat spawn plateau, rolling hills, and a basin, for combat arenas.
143
+ * @internal
144
+ */
130
145
  export function arenaField(config = {}) {
131
146
  const seed = seedFrom(config.seed ?? "arena", 7);
132
147
  const rolling = {
@@ -155,12 +170,19 @@ export function arenaField(config = {}) {
155
170
  };
156
171
  return fieldFromHeight(sampleHeight, { bounds: config.bounds, waterLevel: ARENA_WATER_LEVEL });
157
172
  }
173
+ /** @internal */
158
174
  export function groundFieldFor(world) {
159
175
  if (world !== undefined && world.kind === "environment")
160
176
  return resolveEnvironmentField(world);
177
+ // Place worlds (`world()` from world/place) stand on a flat baseline field: flat/board grounds are
178
+ // exactly y=0, while round/voxel grounds keep their sampled shape in the game's own generation
179
+ // systems (the substrate declaration never bakes a heightfield). Editor-authored sculpt still
180
+ // layers through the environment path above.
161
181
  return flatField();
162
182
  }
163
- /** Whether a world declares real terrain (base heightfield or islands) rather than a flat plane — gates terrain-floor sampling in the movement controllers. */
183
+ /** Whether a world declares real terrain (base heightfield or islands) rather than a flat plane — gates terrain-floor sampling in the movement controllers.
184
+ * @internal
185
+ */
164
186
  export function hasEnvironmentTerrain(world) {
165
187
  return world?.kind === "environment" && (world.terrain !== undefined || (world.islands?.length ?? 0) > 0);
166
188
  }
@@ -174,7 +196,8 @@ function islandContains(descriptor, x, z) {
174
196
  * Composes a base terrain and any number of bounded islands into one world field: inside an island's
175
197
  * rect the island's own field (sampled in island-local coordinates) wins, elsewhere the base terrain
176
198
  * answers, and with no base the gap is `ISLAND_VOID_HEIGHT` void. Later islands win overlaps.
177
- */
199
+ * @internal
200
+ */
178
201
  export function composeIslandFields(base, islands, voidHeight = ISLAND_VOID_HEIGHT) {
179
202
  if (islands.length === 0)
180
203
  return base ?? flatField();
@@ -209,14 +232,95 @@ export function composeIslandFields(base, islands, voidHeight = ISLAND_VOID_HEIG
209
232
  ...(base?.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
210
233
  };
211
234
  }
212
- /** The full ground field for an environment world: base `terrain` composed with any `islands`. */
235
+ /** Bilinear offset sampled from an editor {@link TerraformSnapshot}'s vertex grid at a world point. */
236
+ function sampleSnapshotOffset(snapshot, x, z) {
237
+ const { bounds, cols, rows, offsets } = snapshot;
238
+ const vertsX = cols + 1;
239
+ const spanX = Math.max(bounds.maxX - bounds.minX, snapshot.cellSize);
240
+ const spanZ = Math.max(bounds.maxZ - bounds.minZ, snapshot.cellSize);
241
+ const fx = clamp01((x - bounds.minX) / spanX) * cols;
242
+ const fz = clamp01((z - bounds.minZ) / spanZ) * rows;
243
+ const x0 = Math.min(cols, Math.floor(fx));
244
+ const z0 = Math.min(rows, Math.floor(fz));
245
+ const x1 = Math.min(cols, x0 + 1);
246
+ const z1 = Math.min(rows, z0 + 1);
247
+ const tx = fx - x0;
248
+ const tz = fz - z0;
249
+ const v00 = offsets[z0 * vertsX + x0] ?? 0;
250
+ const v10 = offsets[z0 * vertsX + x1] ?? 0;
251
+ const v01 = offsets[z1 * vertsX + x0] ?? 0;
252
+ const v11 = offsets[z1 * vertsX + x1] ?? 0;
253
+ const top = v00 + (v10 - v00) * tx;
254
+ const bottom = v01 + (v11 - v01) * tx;
255
+ return top + (bottom - top) * tz;
256
+ }
257
+ /**
258
+ * Layers an authored sculpt snapshot's offsets over a base field — the editor-to-runtime ground seam.
259
+ * @internal — reached through `environment({ sculpt })`; not called directly by games.
260
+ */
261
+ export function sculptedField(base, snapshot) {
262
+ const sampleHeight = (x, z) => base.sampleHeight(x, z) + sampleSnapshotOffset(snapshot, x, z);
263
+ return {
264
+ sampleHeight,
265
+ sampleNormal: withNormal(sampleHeight),
266
+ ...(base.bounds === undefined ? {} : { bounds: base.bounds }),
267
+ ...(base.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
268
+ };
269
+ }
270
+ /**
271
+ * Levels a base field toward each clearance zone's center height within its radius (feathered) — so
272
+ * spawns, plots, and paths sit on flat ground even when a mound is nearby. The strongest overlapping
273
+ * zone wins. Pairs with scatter's avoid: one clearance zone both flattens ground and repels foliage.
274
+ * @internal — reached through `environment({ clearings })`; not called directly by games.
275
+ */
276
+ export function flattenFieldAround(base, zones) {
277
+ if (zones.length === 0)
278
+ return base;
279
+ const sampleHeight = (x, z) => {
280
+ let best = 0;
281
+ let target = 0;
282
+ for (const zone of zones) {
283
+ const dist = Math.hypot(x - zone.x, z - zone.z);
284
+ if (dist >= zone.radius)
285
+ continue;
286
+ const feather = Math.max(0, zone.feather ?? 0);
287
+ const inner = zone.radius - feather;
288
+ const t = dist <= inner || feather <= 0 ? 1 : (zone.radius - dist) / feather;
289
+ if (t > best) {
290
+ best = t;
291
+ target = base.sampleHeight(zone.x, zone.z);
292
+ }
293
+ }
294
+ const height = base.sampleHeight(x, z);
295
+ return best > 0 ? height + (target - height) * best : height;
296
+ };
297
+ return {
298
+ sampleHeight,
299
+ sampleNormal: withNormal(sampleHeight),
300
+ ...(base.bounds === undefined ? {} : { bounds: base.bounds }),
301
+ ...(base.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
302
+ };
303
+ }
304
+ /**
305
+ * The full ground field for an environment world: base `terrain` composed with any `islands`, then
306
+ * any authored `sculpt` snapshot, then any `clearings` flattened on top — so an editor-sculpted
307
+ * heightfield drives both the rendered mesh and player collision, and gameplay spots stay level,
308
+ * through the one seam every consumer already reads.
309
+ * @internal
310
+ */
213
311
  export function resolveEnvironmentField(feature) {
214
312
  const base = feature.terrain === undefined ? null : resolveTerrainField(feature.terrain);
215
- if (feature.islands === undefined || feature.islands.length === 0)
216
- return base ?? flatField();
217
- return composeIslandFields(base, feature.islands);
218
- }
219
- /** Local slope from the field's normal — the input for gravity-roll, ski acceleration, and slide checks (#284.6). */
313
+ const composed = feature.islands === undefined || feature.islands.length === 0
314
+ ? base ?? flatField()
315
+ : composeIslandFields(base, feature.islands);
316
+ const sculpted = feature.sculpt === undefined ? composed : sculptedField(composed, feature.sculpt);
317
+ return feature.clearings === undefined || feature.clearings.length === 0
318
+ ? sculpted
319
+ : flattenFieldAround(sculpted, feature.clearings);
320
+ }
321
+ /** Local slope from the field's normal — the input for gravity-roll, ski acceleration, and slide checks (#284.6).
322
+ * @internal
323
+ */
220
324
  export function sampleSlope(field, x, z) {
221
325
  const [nx, ny, nz] = field.sampleNormal(x, z);
222
326
  const horizontal = Math.hypot(nx, nz);
@@ -230,13 +334,88 @@ export function sampleSlope(field, x, z) {
230
334
  /**
231
335
  * Downhill force/acceleration from the local slope: direction × sin(slope angle) × `scale`.
232
336
  * Add it to any integrator's XZ velocity each tick (`scale` ≈ gravity for a free-rolling body).
233
- */
337
+ * @internal
338
+ */
234
339
  export function slopeForce(field, x, z, scale = 9.8) {
235
340
  const [nx, , nz] = field.sampleNormal(x, z);
236
341
  if (Math.hypot(nx, nz) < 1e-9)
237
342
  return [0, 0];
238
343
  return [nx * scale, nz * scale];
239
344
  }
345
+ /**
346
+ * Intersects a ray with a `sampleHeight` field by fixed-step raymarching plus bisection — the
347
+ * O(steps) editor/gameplay picking seam that replaces brute-force triangle raycasts against a
348
+ * tessellated ground mesh (tens of thousands of triangle tests per pick on a sculpt-sized grid).
349
+ * The ray is clipped to `bounds` on XZ first, marched at `step`, and the first above→below
350
+ * crossing is bisected. An origin already under the surface hits immediately at entry. Returns
351
+ * null when the clipped ray never crosses the surface.
352
+ * @capability terrain-raycast pick a point on a heightfield along a camera/pointer ray
353
+ */
354
+ export function raycastHeightField(sampleHeight, origin, direction, options) {
355
+ const length = Math.hypot(direction[0], direction[1], direction[2]);
356
+ if (length < 1e-12)
357
+ return null;
358
+ const dx = direction[0] / length;
359
+ const dy = direction[1] / length;
360
+ const dz = direction[2] / length;
361
+ const { bounds } = options;
362
+ // Clip [t0, t1] to the XZ slab of bounds.
363
+ let t0 = 0;
364
+ let t1 = options.maxDistance ?? Infinity;
365
+ for (const [o, d, min, max] of [
366
+ [origin[0], dx, bounds.minX, bounds.maxX],
367
+ [origin[2], dz, bounds.minZ, bounds.maxZ],
368
+ ]) {
369
+ if (Math.abs(d) < 1e-12) {
370
+ if (o < min || o > max)
371
+ return null;
372
+ continue;
373
+ }
374
+ const ta = (min - o) / d;
375
+ const tb = (max - o) / d;
376
+ const near = Math.min(ta, tb);
377
+ const far = Math.max(ta, tb);
378
+ if (near > t0)
379
+ t0 = near;
380
+ if (far < t1)
381
+ t1 = far;
382
+ }
383
+ if (t1 <= t0)
384
+ return null;
385
+ const spanX = bounds.maxX - bounds.minX;
386
+ const spanZ = bounds.maxZ - bounds.minZ;
387
+ const step = options.step ?? Math.min(4, Math.max(0.25, Math.max(spanX, spanZ) / 256));
388
+ const refine = options.refine ?? 8;
389
+ const maxSteps = options.maxSteps ?? 4096;
390
+ const above = (t) => origin[1] + dy * t - sampleHeight(origin[0] + dx * t, origin[2] + dz * t);
391
+ let prevT = t0;
392
+ if (above(t0) <= 0) {
393
+ return { x: origin[0] + dx * t0, y: origin[1] + dy * t0, z: origin[2] + dz * t0, distance: t0 };
394
+ }
395
+ let steps = 0;
396
+ while (prevT < t1 && steps < maxSteps) {
397
+ steps += 1;
398
+ const t = Math.min(prevT + step, t1);
399
+ if (above(t) <= 0) {
400
+ let lo = prevT;
401
+ let hi = t;
402
+ for (let i = 0; i < refine; i += 1) {
403
+ const mid = (lo + hi) / 2;
404
+ if (above(mid) <= 0)
405
+ hi = mid;
406
+ else
407
+ lo = mid;
408
+ }
409
+ const x = origin[0] + dx * hi;
410
+ const z = origin[2] + dz * hi;
411
+ return { x, y: sampleHeight(x, z), z, distance: hi };
412
+ }
413
+ if (t >= t1)
414
+ break;
415
+ prevT = t;
416
+ }
417
+ return null;
418
+ }
240
419
  export const DEFAULT_TERRAIN_MATERIAL = "grass";
241
420
  export const TERRAIN_MATERIAL_PALETTES = {
242
421
  grass: { low: "#30402c", high: "#7f8b50", waterline: "#1d4c6e" },
@@ -258,7 +437,11 @@ const DEFAULT_TERRAIN_DETAIL = {
258
437
  roughness: 0.9,
259
438
  strength: 1,
260
439
  };
261
- /** Fill a `TerrainDetailConfig` with defaults; `waterLevel` falls back to the terrain's own water level. */
440
+ const DEFAULT_TERRAIN_MATERIAL_REPEAT = 4;
441
+ const DEFAULT_TERRAIN_MATERIAL_STRENGTH = 1;
442
+ /** Fill a `TerrainDetailConfig` with defaults; `waterLevel` falls back to the terrain's own water level.
443
+ * @internal
444
+ */
262
445
  export function resolveTerrainDetail(config, terrainWaterLevel = 0) {
263
446
  return {
264
447
  rockColor: config.rockColor ?? DEFAULT_TERRAIN_DETAIL.rockColor,
@@ -269,10 +452,20 @@ export function resolveTerrainDetail(config, terrainWaterLevel = 0) {
269
452
  detailScale: config.detailScale ?? DEFAULT_TERRAIN_DETAIL.detailScale,
270
453
  macroScale: config.macroScale ?? DEFAULT_TERRAIN_DETAIL.macroScale,
271
454
  roughness: config.roughness ?? DEFAULT_TERRAIN_DETAIL.roughness,
272
- strength: config.strength ?? DEFAULT_TERRAIN_DETAIL.strength,
455
+ strength: clamp01(config.strength ?? DEFAULT_TERRAIN_DETAIL.strength),
273
456
  waterLevel: config.waterLevel ?? terrainWaterLevel,
457
+ ...(config.material === undefined
458
+ ? {}
459
+ : {
460
+ material: {
461
+ maps: config.material.maps,
462
+ repeat: config.material.repeat ?? DEFAULT_TERRAIN_MATERIAL_REPEAT,
463
+ strength: clamp01(config.material.strength ?? DEFAULT_TERRAIN_MATERIAL_STRENGTH),
464
+ },
465
+ }),
274
466
  };
275
467
  }
468
+ /** @internal */
276
469
  export function resolveTerrainPalette(descriptor = {}) {
277
470
  const material = descriptor.material ?? DEFAULT_TERRAIN_MATERIAL;
278
471
  const preset = TERRAIN_MATERIAL_PALETTES[material];
@@ -314,25 +507,19 @@ function mixPalette(from, to, t) {
314
507
  waterline: mixHex(from.waterline, to.waterline, t),
315
508
  };
316
509
  }
317
- /**
318
- * Per-z palette sampler over a descriptor's `biomeBands` — ordered zones that cross-fade their
319
- * ground palette across a `fade`-wide window centered on the midpoint z between adjacent centers.
320
- * Below the first / above the last band clamps to that band's palette. Returns `fallback` when no
321
- * bands are declared. Pure math, unit-testable independent of rendering.
322
- */
323
- export function createBiomeBandSampler(bands, fallback) {
510
+ function createBandValueSampler(bands, fallback, resolve, mix) {
324
511
  if (bands.length === 0)
325
512
  return () => fallback;
326
513
  const resolved = bands
327
- .map((band) => ({ z: band.z, fade: band.fade ?? 64, palette: resolveTerrainPalette(band) }))
514
+ .map((band) => ({ z: band.z, fade: band.fade ?? 64, value: resolve(band) }))
328
515
  .sort((a, b) => a.z - b.z);
329
516
  const first = resolved[0];
330
517
  const last = resolved[resolved.length - 1];
331
518
  return (z) => {
332
519
  if (z <= first.z)
333
- return first.palette;
520
+ return first.value;
334
521
  if (z >= last.z)
335
- return last.palette;
522
+ return last.value;
336
523
  for (let i = 0; i < resolved.length - 1; i += 1) {
337
524
  const lower = resolved[i];
338
525
  const upper = resolved[i + 1];
@@ -341,19 +528,86 @@ export function createBiomeBandSampler(bands, fallback) {
341
528
  const boundary = (lower.z + upper.z) / 2;
342
529
  const half = Math.min(lower.fade, upper.fade) / 2;
343
530
  if (z <= boundary - half)
344
- return lower.palette;
531
+ return lower.value;
345
532
  if (z >= boundary + half)
346
- return upper.palette;
347
- return mixPalette(lower.palette, upper.palette, smoothstep(boundary - half, boundary + half, z));
533
+ return upper.value;
534
+ return mix(lower.value, upper.value, smoothstep(boundary - half, boundary + half, z));
348
535
  }
349
536
  return fallback;
350
537
  };
351
538
  }
539
+ /**
540
+ * Per-z palette sampler over a descriptor's `biomeBands` — ordered zones that cross-fade their
541
+ * ground palette across a `fade`-wide window centered on the midpoint z between adjacent centers.
542
+ * Below the first / above the last band clamps to that band's palette. Returns `fallback` when no
543
+ * bands are declared. Pure math, unit-testable independent of rendering.
544
+ * @internal
545
+ */
546
+ export function createBiomeBandSampler(bands, fallback) {
547
+ return createBandValueSampler(bands, fallback, resolveTerrainPalette, mixPalette);
548
+ }
549
+ function mixBiomeFog(from, to, t) {
550
+ if (t <= 0)
551
+ return from;
552
+ if (t >= 1)
553
+ return to;
554
+ return {
555
+ color: mixHex(from.color, to.color, t),
556
+ near: lerp(from.near, to.near, t),
557
+ far: lerp(from.far, to.far, t),
558
+ density: lerp(from.density, to.density, t),
559
+ };
560
+ }
561
+ /**
562
+ * Per-z fog sampler over a descriptor's `biomeBands` — cross-fades each band's `fog` (unset fields
563
+ * falling through to `fallback`) across the same `fade` window as the ground sampler, so fog color and
564
+ * range track the camera's z. Bands with no `fog` resolve to `fallback`. Pure math, unit-testable.
565
+ * @internal
566
+ */
567
+ export function createBiomeFogSampler(bands, fallback) {
568
+ return createBandValueSampler(bands, fallback, (band) => band.fog === undefined
569
+ ? fallback
570
+ : {
571
+ color: band.fog.color ?? fallback.color,
572
+ near: band.fog.near ?? fallback.near,
573
+ far: band.fog.far ?? fallback.far,
574
+ density: band.fog.density ?? fallback.density,
575
+ }, mixBiomeFog);
576
+ }
577
+ function mixBiomeSky(from, to, t) {
578
+ if (t <= 0)
579
+ return from;
580
+ if (t >= 1)
581
+ return to;
582
+ return {
583
+ horizonColor: mixHex(from.horizonColor, to.horizonColor, t),
584
+ zenithColor: mixHex(from.zenithColor, to.zenithColor, t),
585
+ sunIntensity: lerp(from.sunIntensity, to.sunIntensity, t),
586
+ ambientIntensity: lerp(from.ambientIntensity, to.ambientIntensity, t),
587
+ };
588
+ }
589
+ /**
590
+ * Per-z sky sampler over a descriptor's `biomeBands` — cross-fades each band's `sky` (unset fields
591
+ * falling through to `fallback`) across the same `fade` window as the ground sampler, so horizon/zenith
592
+ * colors and sun/ambient intensity track the camera's z. Bands with no `sky` resolve to `fallback`.
593
+ * @internal
594
+ */
595
+ export function createBiomeSkySampler(bands, fallback) {
596
+ return createBandValueSampler(bands, fallback, (band) => band.sky === undefined
597
+ ? fallback
598
+ : {
599
+ horizonColor: band.sky.horizonColor ?? fallback.horizonColor,
600
+ zenithColor: band.sky.zenithColor ?? fallback.zenithColor,
601
+ sunIntensity: band.sky.sunIntensity ?? fallback.sunIntensity,
602
+ ambientIntensity: band.sky.ambientIntensity ?? fallback.ambientIntensity,
603
+ }, mixBiomeSky);
604
+ }
352
605
  /**
353
606
  * Per-position palette sampler over the descriptor's base `material`/`colors` plus its z-ordered
354
607
  * `biomeBands` (painted first) and radial `materialRegions` (painted over) — the multi-biome coloring
355
608
  * seam. Regions paint fully inside `radius` and blend back across `falloff`; later regions win overlaps.
356
- */
609
+ * @internal
610
+ */
357
611
  export function createTerrainPaletteSampler(descriptor) {
358
612
  const base = resolveTerrainPalette(descriptor);
359
613
  const bandSampler = descriptor.biomeBands === undefined || descriptor.biomeBands.length === 0
@@ -440,6 +694,7 @@ function withFlattenMasks(sampleHeight, masks) {
440
694
  return height;
441
695
  };
442
696
  }
697
+ /** @internal */
443
698
  export function heightMapField(config) {
444
699
  const { columns, rows, samples } = config;
445
700
  if (columns <= 0 || rows <= 0)
@@ -476,7 +731,9 @@ export function heightMapField(config) {
476
731
  ...(config.waterLevel === undefined ? {} : { waterLevel: config.waterLevel }),
477
732
  });
478
733
  }
479
- /** Resolves a `TerrainEnvironmentDescriptor` into a concrete `TerrainField`, applying flatten masks. */
734
+ /** Resolves a `TerrainEnvironmentDescriptor` into a concrete `TerrainField`, applying flatten masks.
735
+ * @internal
736
+ */
480
737
  export function resolveTerrainField(descriptor) {
481
738
  if (descriptor === undefined)
482
739
  return flatField();
@@ -498,19 +755,44 @@ export function resolveTerrainField(descriptor) {
498
755
  waterLevel: descriptor.waterLevel,
499
756
  bounds: descriptor.bounds,
500
757
  });
501
- if (descriptor.flatten === undefined || descriptor.flatten.length === 0)
502
- return base;
503
- return fieldFromHeight(withFlattenMasks(base.sampleHeight, descriptor.flatten), {
504
- bounds: base.bounds,
505
- waterLevel: base.waterLevel,
506
- });
758
+ const flattened = descriptor.flatten === undefined || descriptor.flatten.length === 0
759
+ ? base
760
+ : fieldFromHeight(withFlattenMasks(base.sampleHeight, descriptor.flatten), {
761
+ bounds: base.bounds,
762
+ waterLevel: base.waterLevel,
763
+ });
764
+ if (descriptor.pathProfiles === undefined || descriptor.pathProfiles.length === 0)
765
+ return flattened;
766
+ return applyPathProfiles(flattened, descriptor.pathProfiles);
507
767
  }
508
- /** Returns `position` with `y` replaced by the field's ground height (plus `offset`) at its `x`/`z`. */
768
+ /**
769
+ * Composes authored path profiles onto a field — the shared seam that turns a scene road/river/ramp path
770
+ * into flattened, graded, carved, or retained ground. Applies after `flatten` masks in `resolveTerrainField`
771
+ * so a corridor grades over already-leveled pads; call it directly to layer profiles onto any field a game
772
+ * builds by hand. Returns the field unchanged when no profile is given.
773
+ * @capability path-terrain apply flatten/grade/carve/retaining path profiles to a terrain field
774
+ */
775
+ export function applyPathProfiles(field, profiles) {
776
+ if (profiles.length === 0)
777
+ return field;
778
+ const sampleHeight = withPathProfiles((x, z) => field.sampleHeight(x, z), profiles);
779
+ return {
780
+ sampleHeight,
781
+ sampleNormal: withNormal(sampleHeight),
782
+ ...(field.bounds === undefined ? {} : { bounds: field.bounds }),
783
+ ...(field.waterLevel === undefined ? {} : { waterLevel: field.waterLevel }),
784
+ };
785
+ }
786
+ /** Returns `position` with `y` replaced by the field's ground height (plus `offset`) at its `x`/`z`.
787
+ * @internal
788
+ */
509
789
  export function snapToGround(field, position, offset = 0) {
510
790
  const [x, , z] = position;
511
791
  return [x, field.sampleHeight(x, z) + offset, z];
512
792
  }
513
- /** Ground-snaps an already-spawned entity in place; returns false when `id` is unknown. */
793
+ /** Ground-snaps an already-spawned entity in place; returns false when `id` is unknown.
794
+ * @internal
795
+ */
514
796
  export function snapEntityToGround(entities, id, field, offset = 0) {
515
797
  const entity = entities.get(id);
516
798
  if (entity === null)
@@ -518,7 +800,9 @@ export function snapEntityToGround(entities, id, field, offset = 0) {
518
800
  return entities.setPose(id, { position: snapToGround(field, entity.position, offset) });
519
801
  }
520
802
  export const DEFAULT_MAX_WALK_SLOPE = 0.6;
521
- /** Zeroes out a movement step's x or z component where it would climb steeper than `maxSlope`. */
803
+ /** Zeroes out a movement step's x or z component where it would climb steeper than `maxSlope`.
804
+ * @internal
805
+ */
522
806
  export function resolveGroundStep(field, x, z, stepX, stepZ, maxSlope = DEFAULT_MAX_WALK_SLOPE) {
523
807
  const baseHeight = field.sampleHeight(x, z);
524
808
  const tooSteep = (dx, dz) => {