@jgengine/core 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/spawnDirector.d.ts +7 -2
  21. package/dist/ai/spawnDirector.js +18 -15
  22. package/dist/ai/spawnPoint.d.ts +3 -1
  23. package/dist/ai/spawnPoint.js +3 -1
  24. package/dist/ai/targetAcquisition.d.ts +84 -0
  25. package/dist/ai/targetAcquisition.js +92 -0
  26. package/dist/anim/easing.d.ts +19 -0
  27. package/dist/anim/easing.js +19 -0
  28. package/dist/anim/oscillator.d.ts +12 -0
  29. package/dist/anim/oscillator.js +25 -0
  30. package/dist/area/areaEffectField.d.ts +127 -0
  31. package/dist/area/areaEffectField.js +175 -0
  32. package/dist/area/stackPolicy.d.ts +47 -0
  33. package/dist/area/stackPolicy.js +99 -0
  34. package/dist/authoring.d.ts +1 -0
  35. package/dist/authoring.js +1 -0
  36. package/dist/board/laneBoard.d.ts +13 -0
  37. package/dist/board/laneBoard.js +13 -0
  38. package/dist/board/timelineBoard.d.ts +10 -0
  39. package/dist/board/timelineBoard.js +10 -0
  40. package/dist/combat/abilityKit.d.ts +18 -0
  41. package/dist/combat/abilityKit.js +24 -9
  42. package/dist/combat/animationState.d.ts +5 -0
  43. package/dist/combat/animationState.js +5 -0
  44. package/dist/combat/breakMeters.d.ts +10 -0
  45. package/dist/combat/breakMeters.js +10 -0
  46. package/dist/combat/castRunner.d.ts +5 -0
  47. package/dist/combat/castRunner.js +5 -0
  48. package/dist/combat/comboPoints.d.ts +5 -0
  49. package/dist/combat/comboPoints.js +5 -0
  50. package/dist/combat/comboString.d.ts +5 -0
  51. package/dist/combat/comboString.js +5 -0
  52. package/dist/combat/damageInterceptors.d.ts +192 -0
  53. package/dist/combat/damageInterceptors.js +251 -0
  54. package/dist/combat/damageMatchup.d.ts +68 -0
  55. package/dist/combat/damageMatchup.js +42 -0
  56. package/dist/combat/damageResolution.d.ts +63 -0
  57. package/dist/combat/damageResolution.js +50 -0
  58. package/dist/combat/death.d.ts +7 -1
  59. package/dist/combat/death.js +5 -0
  60. package/dist/combat/deathReason.d.ts +14 -0
  61. package/dist/combat/deathReason.js +1 -0
  62. package/dist/combat/defensiveWindow.d.ts +5 -0
  63. package/dist/combat/defensiveWindow.js +5 -0
  64. package/dist/combat/dotField.d.ts +5 -1
  65. package/dist/combat/dotField.js +5 -1
  66. package/dist/combat/downed.d.ts +5 -0
  67. package/dist/combat/downed.js +5 -0
  68. package/dist/combat/effects.d.ts +5 -0
  69. package/dist/combat/effects.js +5 -0
  70. package/dist/combat/encounterSequence.d.ts +258 -0
  71. package/dist/combat/encounterSequence.js +426 -0
  72. package/dist/combat/hitReaction.d.ts +57 -1
  73. package/dist/combat/hitReaction.js +45 -5
  74. package/dist/combat/magazine.d.ts +54 -0
  75. package/dist/combat/magazine.js +96 -0
  76. package/dist/combat/projectiles.d.ts +5 -0
  77. package/dist/combat/projectiles.js +32 -14
  78. package/dist/combat/receivedDamage.d.ts +117 -0
  79. package/dist/combat/receivedDamage.js +92 -0
  80. package/dist/combat/regenShield.d.ts +5 -1
  81. package/dist/combat/regenShield.js +5 -1
  82. package/dist/combat/renderCues.d.ts +51 -0
  83. package/dist/combat/renderCues.js +44 -0
  84. package/dist/combat/resourcePool.d.ts +5 -0
  85. package/dist/combat/resourcePool.js +5 -0
  86. package/dist/combat/rewardAllocation.d.ts +121 -0
  87. package/dist/combat/rewardAllocation.js +251 -0
  88. package/dist/combat/shotOrigin.d.ts +18 -1
  89. package/dist/combat/shotOrigin.js +39 -0
  90. package/dist/combat/statusApplication.d.ts +96 -0
  91. package/dist/combat/statusApplication.js +81 -0
  92. package/dist/combat/telegraph.d.ts +11 -2
  93. package/dist/combat/telegraph.js +11 -2
  94. package/dist/combat/thresholdCrossings.d.ts +85 -0
  95. package/dist/combat/thresholdCrossings.js +116 -0
  96. package/dist/combat.d.ts +34 -0
  97. package/dist/combat.js +34 -0
  98. package/dist/commands/commandRegistry.d.ts +11 -0
  99. package/dist/commands/commandRegistry.js +9 -2
  100. package/dist/crafting/crop.d.ts +18 -0
  101. package/dist/crafting/crop.js +18 -0
  102. package/dist/crafting/production.d.ts +5 -0
  103. package/dist/crafting/production.js +5 -0
  104. package/dist/devtools/rewriteTunables.d.ts +17 -0
  105. package/dist/devtools/rewriteTunables.js +276 -0
  106. package/dist/devtools/saveEndpoint.d.ts +46 -0
  107. package/dist/devtools/saveEndpoint.js +48 -0
  108. package/dist/devtools/transformTunables.d.ts +3 -0
  109. package/dist/devtools/transformTunables.js +3 -0
  110. package/dist/devtools/tunableSchema.d.ts +31 -0
  111. package/dist/devtools/tunableSchema.js +31 -0
  112. package/dist/economy/currency.d.ts +12 -1
  113. package/dist/economy/currency.js +12 -1
  114. package/dist/economy/listingBook.d.ts +91 -0
  115. package/dist/economy/listingBook.js +144 -0
  116. package/dist/economy/resourceLedger.d.ts +222 -0
  117. package/dist/economy/resourceLedger.js +353 -0
  118. package/dist/economy/sharedWallet.d.ts +14 -0
  119. package/dist/economy/sharedWallet.js +14 -0
  120. package/dist/economy/techTree.d.ts +12 -0
  121. package/dist/economy/techTree.js +12 -0
  122. package/dist/economy/wallet.d.ts +26 -2
  123. package/dist/economy/wallet.js +35 -6
  124. package/dist/editor/commands.d.ts +190 -7
  125. package/dist/editor/commands.js +727 -55
  126. package/dist/editor/document.d.ts +159 -13
  127. package/dist/editor/document.js +750 -19
  128. package/dist/editor/grid.d.ts +229 -0
  129. package/dist/editor/grid.js +366 -0
  130. package/dist/editor/gridAdapters.d.ts +80 -0
  131. package/dist/editor/gridAdapters.js +134 -0
  132. package/dist/editor/index.d.ts +73 -6
  133. package/dist/editor/index.js +6 -2
  134. package/dist/editor/liveSync.d.ts +127 -0
  135. package/dist/editor/liveSync.js +249 -0
  136. package/dist/editor/runtimeInspector.d.ts +88 -0
  137. package/dist/editor/runtimeInspector.js +239 -0
  138. package/dist/editor/types.d.ts +107 -1
  139. package/dist/faction/reputation.d.ts +5 -0
  140. package/dist/faction/reputation.js +5 -0
  141. package/dist/format/distance.d.ts +17 -0
  142. package/dist/format/distance.js +18 -0
  143. package/dist/format/duration.d.ts +27 -0
  144. package/dist/format/duration.js +45 -0
  145. package/dist/format/speed.d.ts +17 -0
  146. package/dist/format/speed.js +25 -0
  147. package/dist/game/connectedPlayers.d.ts +6 -4
  148. package/dist/game/connectedPlayers.js +2 -2
  149. package/dist/game/cosmetics.d.ts +9 -0
  150. package/dist/game/cosmetics.js +16 -0
  151. package/dist/game/defineGame.d.ts +100 -2
  152. package/dist/game/defineGame.js +39 -2
  153. package/dist/game/defineSystem.d.ts +88 -0
  154. package/dist/game/defineSystem.js +45 -0
  155. package/dist/game/dialogue.d.ts +33 -0
  156. package/dist/game/dialogue.js +21 -0
  157. package/dist/game/events.d.ts +35 -13
  158. package/dist/game/events.js +5 -0
  159. package/dist/game/feed.d.ts +33 -0
  160. package/dist/game/feed.js +35 -2
  161. package/dist/game/gamePhase.d.ts +11 -0
  162. package/dist/game/gamePhase.js +16 -0
  163. package/dist/game/leaderboard.d.ts +5 -0
  164. package/dist/game/leaderboard.js +5 -0
  165. package/dist/game/loadout.d.ts +5 -0
  166. package/dist/game/loadout.js +5 -0
  167. package/dist/game/lootFilter.d.ts +2 -0
  168. package/dist/game/lootFilter.js +2 -0
  169. package/dist/game/lootPipeline.d.ts +164 -0
  170. package/dist/game/lootPipeline.js +216 -0
  171. package/dist/game/lootTable.d.ts +19 -2
  172. package/dist/game/lootTable.js +15 -5
  173. package/dist/game/objectives.d.ts +43 -0
  174. package/dist/game/objectives.js +36 -0
  175. package/dist/game/paramLayers.d.ts +148 -0
  176. package/dist/game/paramLayers.js +185 -0
  177. package/dist/game/ping.d.ts +5 -0
  178. package/dist/game/ping.js +5 -0
  179. package/dist/game/playableGame.d.ts +92 -7
  180. package/dist/game/quest.d.ts +8 -0
  181. package/dist/game/quest.js +29 -0
  182. package/dist/game/race.d.ts +141 -0
  183. package/dist/game/race.js +169 -0
  184. package/dist/game/recordBook.d.ts +3 -1
  185. package/dist/game/recordBook.js +4 -1
  186. package/dist/game/ruleSelection.d.ts +75 -0
  187. package/dist/game/ruleSelection.js +127 -0
  188. package/dist/game/runDraft.d.ts +5 -0
  189. package/dist/game/runDraft.js +5 -0
  190. package/dist/game/saveStore.d.ts +111 -0
  191. package/dist/game/saveStore.js +312 -0
  192. package/dist/game/snapshotHistory.d.ts +67 -0
  193. package/dist/game/snapshotHistory.js +95 -0
  194. package/dist/game/social.d.ts +38 -1
  195. package/dist/game/social.js +71 -0
  196. package/dist/game/spawnPoints.d.ts +5 -0
  197. package/dist/game/spawnPoints.js +5 -0
  198. package/dist/game/systemRuntime.d.ts +50 -0
  199. package/dist/game/systemRuntime.js +157 -0
  200. package/dist/game/systemSchedule.d.ts +72 -0
  201. package/dist/game/systemSchedule.js +242 -0
  202. package/dist/game/toasts.d.ts +43 -0
  203. package/dist/game/toasts.js +44 -0
  204. package/dist/game/trade.d.ts +10 -0
  205. package/dist/game/trade.js +10 -0
  206. package/dist/game/unlocks.d.ts +8 -0
  207. package/dist/game/unlocks.js +16 -0
  208. package/dist/game/vfxInstance.d.ts +138 -0
  209. package/dist/game/vfxInstance.js +96 -0
  210. package/dist/game/worldItem.d.ts +17 -4
  211. package/dist/game/worldItem.js +17 -4
  212. package/dist/gameplay.d.ts +91 -0
  213. package/dist/gameplay.js +91 -0
  214. package/dist/index.d.ts +5 -14
  215. package/dist/index.js +5 -14
  216. package/dist/input/actionBindings.d.ts +23 -6
  217. package/dist/input/actionBindings.js +23 -6
  218. package/dist/input/axisInput.d.ts +7 -2
  219. package/dist/input/axisInput.js +7 -2
  220. package/dist/input/controlGroups.d.ts +67 -0
  221. package/dist/input/controlGroups.js +41 -0
  222. package/dist/input/touchScheme.d.ts +82 -6
  223. package/dist/input/touchScheme.js +123 -10
  224. package/dist/interaction/lockpick.d.ts +61 -0
  225. package/dist/interaction/lockpick.js +168 -0
  226. package/dist/interaction/proximityPrompt.d.ts +2 -0
  227. package/dist/interaction/proximityPrompt.js +2 -0
  228. package/dist/interaction/qte.d.ts +5 -0
  229. package/dist/interaction/qte.js +5 -0
  230. package/dist/interaction/skillCheck.d.ts +5 -0
  231. package/dist/interaction/skillCheck.js +5 -0
  232. package/dist/inventory/inventoryModel.d.ts +12 -0
  233. package/dist/inventory/inventoryModel.js +12 -0
  234. package/dist/inventory/shapedGrid.d.ts +16 -0
  235. package/dist/inventory/shapedGrid.js +16 -0
  236. package/dist/inventory/slotModel.d.ts +10 -0
  237. package/dist/inventory/slotModel.js +10 -0
  238. package/dist/item/durability.d.ts +5 -0
  239. package/dist/item/durability.js +5 -0
  240. package/dist/item/itemIdentity.d.ts +171 -0
  241. package/dist/item/itemIdentity.js +138 -0
  242. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  243. package/dist/item/itemInstanceRegistry.js +34 -0
  244. package/dist/item/itemgen.d.ts +163 -0
  245. package/dist/item/itemgen.js +151 -0
  246. package/dist/item/modularItem.d.ts +5 -0
  247. package/dist/item/modularItem.js +5 -0
  248. package/dist/item/use.d.ts +5 -0
  249. package/dist/item/use.js +5 -0
  250. package/dist/item/useBehavior.d.ts +142 -0
  251. package/dist/item/useBehavior.js +105 -0
  252. package/dist/item/weapon.d.ts +5 -0
  253. package/dist/item/weapon.js +5 -0
  254. package/dist/math/scalar.d.ts +25 -0
  255. package/dist/math/scalar.js +47 -0
  256. package/dist/meta/changelog.d.ts +4 -1
  257. package/dist/meta/changelog.js +16 -2
  258. package/dist/movement/avoidance.d.ts +45 -0
  259. package/dist/movement/avoidance.js +123 -0
  260. package/dist/movement/cameraRig.d.ts +8 -0
  261. package/dist/movement/cameraRig.js +8 -0
  262. package/dist/movement/dash.d.ts +11 -0
  263. package/dist/movement/dash.js +11 -0
  264. package/dist/movement/formation.d.ts +135 -0
  265. package/dist/movement/formation.js +194 -0
  266. package/dist/movement/glideModel.d.ts +5 -0
  267. package/dist/movement/glideModel.js +5 -0
  268. package/dist/movement/grappleSwing.d.ts +5 -0
  269. package/dist/movement/grappleSwing.js +5 -0
  270. package/dist/movement/leaderTrail.d.ts +5 -0
  271. package/dist/movement/leaderTrail.js +5 -0
  272. package/dist/movement/movementModel.d.ts +35 -8
  273. package/dist/movement/movementModel.js +42 -14
  274. package/dist/movement/playerMovement.js +65 -10
  275. package/dist/movement/poseState.d.ts +13 -0
  276. package/dist/movement/poseState.js +16 -0
  277. package/dist/movement/steering.d.ts +8 -0
  278. package/dist/movement/steering.js +18 -0
  279. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  280. package/dist/multiplayer/combatSnapshot.js +3 -0
  281. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  282. package/dist/multiplayer/lagCompensation.js +5 -0
  283. package/dist/multiplayer/presenceModel.d.ts +9 -1
  284. package/dist/multiplayer/presenceModel.js +9 -1
  285. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  286. package/dist/multiplayer/simultaneousCommit.js +3 -0
  287. package/dist/multiplayer.d.ts +11 -0
  288. package/dist/multiplayer.js +11 -0
  289. package/dist/nav/pathFollow.d.ts +57 -0
  290. package/dist/nav/pathFollow.js +109 -0
  291. package/dist/orders/orderKinds.d.ts +156 -0
  292. package/dist/orders/orderKinds.js +197 -0
  293. package/dist/orders/orderQueue.d.ts +208 -0
  294. package/dist/orders/orderQueue.js +211 -0
  295. package/dist/physics/drivableVehicle.d.ts +29 -0
  296. package/dist/physics/drivableVehicle.js +16 -0
  297. package/dist/physics/kinematicVehicle.d.ts +21 -1
  298. package/dist/physics/kinematicVehicle.js +23 -8
  299. package/dist/physics/physicsWorld.d.ts +24 -12
  300. package/dist/physics/physicsWorld.js +11 -5
  301. package/dist/physics/radialImpulse.d.ts +25 -0
  302. package/dist/physics/radialImpulse.js +27 -0
  303. package/dist/procedural.d.ts +3 -0
  304. package/dist/procedural.js +3 -0
  305. package/dist/progression/statGraph.d.ts +116 -0
  306. package/dist/progression/statGraph.js +318 -0
  307. package/dist/puzzle/cellGrid.d.ts +9 -0
  308. package/dist/puzzle/cellGrid.js +9 -0
  309. package/dist/puzzle/fallingPiece.d.ts +9 -0
  310. package/dist/puzzle/fallingPiece.js +9 -0
  311. package/dist/puzzle/nonogram.d.ts +39 -0
  312. package/dist/puzzle/nonogram.js +136 -0
  313. package/dist/random/nameGen.d.ts +5 -0
  314. package/dist/random/nameGen.js +5 -0
  315. package/dist/random/pick.d.ts +8 -0
  316. package/dist/random/pick.js +31 -0
  317. package/dist/random/rng.d.ts +22 -0
  318. package/dist/random/rng.js +28 -8
  319. package/dist/random/seedLink.d.ts +4 -0
  320. package/dist/random/seedLink.js +4 -0
  321. package/dist/relation/keyedValues.d.ts +54 -0
  322. package/dist/relation/keyedValues.js +115 -0
  323. package/dist/relation/thresholds.d.ts +62 -0
  324. package/dist/relation/thresholds.js +62 -0
  325. package/dist/render/color.d.ts +12 -0
  326. package/dist/render/color.js +26 -0
  327. package/dist/render/lookPreset.d.ts +41 -0
  328. package/dist/render/lookPreset.js +29 -0
  329. package/dist/render/postProcessing.d.ts +20 -0
  330. package/dist/render/postProcessing.js +21 -1
  331. package/dist/rules/predicate.d.ts +53 -0
  332. package/dist/rules/predicate.js +64 -0
  333. package/dist/rules/ruleEffects.d.ts +38 -0
  334. package/dist/rules/ruleEffects.js +37 -0
  335. package/dist/rules/triggeredRules.d.ts +160 -0
  336. package/dist/rules/triggeredRules.js +241 -0
  337. package/dist/runtime/adapter.d.ts +42 -3
  338. package/dist/runtime/adapter.js +44 -1
  339. package/dist/runtime/cameraDirector.d.ts +1 -0
  340. package/dist/runtime/cameraDirector.js +1 -0
  341. package/dist/runtime/commandRunner.d.ts +1 -0
  342. package/dist/runtime/commandRunner.js +1 -0
  343. package/dist/runtime/context/combatFx.d.ts +23 -0
  344. package/dist/runtime/context/combatFx.js +161 -0
  345. package/dist/runtime/context/registries.d.ts +13 -0
  346. package/dist/runtime/context/registries.js +84 -0
  347. package/dist/runtime/context/worldItems.d.ts +21 -0
  348. package/dist/runtime/context/worldItems.js +37 -0
  349. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  350. package/dist/runtime/descriptors/baseline.js +134 -0
  351. package/dist/runtime/descriptors/features.d.ts +74 -0
  352. package/dist/runtime/descriptors/features.js +281 -0
  353. package/dist/runtime/gameContext.d.ts +114 -13
  354. package/dist/runtime/gameContext.js +303 -395
  355. package/dist/runtime/gameRuntime.d.ts +1 -0
  356. package/dist/runtime/gameRuntime.js +1 -0
  357. package/dist/runtime/headlessRunner.d.ts +60 -0
  358. package/dist/runtime/headlessRunner.js +44 -0
  359. package/dist/runtime/hostPersistence.d.ts +12 -0
  360. package/dist/runtime/hostPersistence.js +12 -0
  361. package/dist/runtime/hostedGameRunner.d.ts +8 -3
  362. package/dist/runtime/hostedGameRunner.js +26 -3
  363. package/dist/runtime/hostedWorldSession.d.ts +12 -4
  364. package/dist/runtime/hostedWorldSession.js +11 -4
  365. package/dist/runtime/inputSnapshot.d.ts +8 -3
  366. package/dist/runtime/inputSnapshot.js +6 -2
  367. package/dist/runtime/motionIntents.d.ts +11 -2
  368. package/dist/runtime/motionIntents.js +16 -2
  369. package/dist/runtime/perContext.d.ts +15 -0
  370. package/dist/runtime/perContext.js +21 -0
  371. package/dist/runtime/runtimeSave.d.ts +79 -0
  372. package/dist/runtime/runtimeSave.js +105 -0
  373. package/dist/runtime/save.d.ts +4 -0
  374. package/dist/runtime/save.js +4 -0
  375. package/dist/runtime/snapshot.d.ts +7 -0
  376. package/dist/runtime/snapshot.js +7 -0
  377. package/dist/runtime/visibility.d.ts +2 -1
  378. package/dist/runtime/visibility.js +2 -1
  379. package/dist/runtime/worldChannel.d.ts +7 -3
  380. package/dist/runtime/worldChannel.js +51 -6
  381. package/dist/runtime/worldMirror.d.ts +14 -2
  382. package/dist/runtime/worldMirror.js +15 -2
  383. package/dist/runtime/worldProjection.d.ts +47 -0
  384. package/dist/runtime/worldProjection.js +52 -0
  385. package/dist/runtime/worldReplication.d.ts +30 -7
  386. package/dist/runtime/worldReplication.js +41 -9
  387. package/dist/runtime/worldSnapshot.d.ts +30 -3
  388. package/dist/runtime/worldSnapshot.js +20 -5
  389. package/dist/scene/assetCatalog.d.ts +21 -0
  390. package/dist/scene/assetCatalog.js +4 -0
  391. package/dist/scene/assetDiagnostics.d.ts +69 -0
  392. package/dist/scene/assetDiagnostics.js +110 -0
  393. package/dist/scene/assetGenerator.d.ts +65 -0
  394. package/dist/scene/assetGenerator.js +64 -0
  395. package/dist/scene/assetSpace.d.ts +137 -0
  396. package/dist/scene/assetSpace.js +259 -0
  397. package/dist/scene/authoredTriggers.d.ts +169 -0
  398. package/dist/scene/authoredTriggers.js +340 -0
  399. package/dist/scene/behaviorRuntime.d.ts +75 -0
  400. package/dist/scene/behaviorRuntime.js +217 -0
  401. package/dist/scene/behaviors.d.ts +14 -2
  402. package/dist/scene/behaviors.js +7 -2
  403. package/dist/scene/bodyBind.d.ts +60 -0
  404. package/dist/scene/bodyBind.js +51 -0
  405. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  406. package/dist/scene/builtinSceneKinds.js +62 -0
  407. package/dist/scene/colliders.d.ts +13 -1
  408. package/dist/scene/colliders.js +37 -1
  409. package/dist/scene/entityStats.d.ts +11 -2
  410. package/dist/scene/entityStats.js +11 -2
  411. package/dist/scene/entityStore.d.ts +12 -1
  412. package/dist/scene/entityStore.js +15 -0
  413. package/dist/scene/facing.d.ts +18 -0
  414. package/dist/scene/facing.js +26 -0
  415. package/dist/scene/modelSockets.d.ts +33 -0
  416. package/dist/scene/modelSockets.js +29 -0
  417. package/dist/scene/objectQuery.d.ts +2 -0
  418. package/dist/scene/objectQuery.js +2 -0
  419. package/dist/scene/objectStore.d.ts +4 -0
  420. package/dist/scene/objectStore.js +6 -0
  421. package/dist/scene/possession.d.ts +8 -0
  422. package/dist/scene/possession.js +14 -0
  423. package/dist/scene/roster.d.ts +3 -0
  424. package/dist/scene/roster.js +12 -0
  425. package/dist/scene/sceneKinds.d.ts +240 -0
  426. package/dist/scene/sceneKinds.js +214 -0
  427. package/dist/scene/sceneOwnership.d.ts +169 -0
  428. package/dist/scene/sceneOwnership.js +179 -0
  429. package/dist/scene/selectionBookmarks.d.ts +93 -0
  430. package/dist/scene/selectionBookmarks.js +122 -0
  431. package/dist/scene/vehicleSeat.d.ts +68 -0
  432. package/dist/scene/vehicleSeat.js +59 -0
  433. package/dist/sensor/concealment.d.ts +3 -0
  434. package/dist/sensor/concealment.js +3 -0
  435. package/dist/sensor/freezeMonitor.d.ts +1 -0
  436. package/dist/sensor/freezeMonitor.js +1 -0
  437. package/dist/sensor/frustumSensor.d.ts +7 -3
  438. package/dist/sensor/frustumSensor.js +7 -3
  439. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  440. package/dist/sensor/hiddenStateProbe.js +5 -2
  441. package/dist/sensor/recordingBuffer.d.ts +2 -1
  442. package/dist/sensor/recordingBuffer.js +2 -1
  443. package/dist/sensor/replayLoop.d.ts +6 -2
  444. package/dist/sensor/replayLoop.js +6 -2
  445. package/dist/sensor/revealQuery.d.ts +2 -1
  446. package/dist/sensor/revealQuery.js +2 -1
  447. package/dist/sensor/visionCone.d.ts +10 -3
  448. package/dist/sensor/visionCone.js +10 -3
  449. package/dist/session/contestedChannel.d.ts +1 -0
  450. package/dist/session/contestedChannel.js +1 -0
  451. package/dist/session/extraction.d.ts +1 -0
  452. package/dist/session/extraction.js +1 -0
  453. package/dist/session/roles.d.ts +6 -0
  454. package/dist/session/roles.js +6 -0
  455. package/dist/session/roundState.d.ts +8 -0
  456. package/dist/session/roundState.js +2 -0
  457. package/dist/settings/settingsModel.d.ts +1 -0
  458. package/dist/settings/settingsModel.js +1 -0
  459. package/dist/stats/accumulatorMeter.d.ts +6 -0
  460. package/dist/stats/accumulatorMeter.js +6 -0
  461. package/dist/stats/eventMeter.d.ts +5 -0
  462. package/dist/stats/eventMeter.js +5 -0
  463. package/dist/stats/rollCheck.d.ts +5 -0
  464. package/dist/stats/rollCheck.js +5 -0
  465. package/dist/stats/statModifiers.d.ts +5 -0
  466. package/dist/stats/statModifiers.js +5 -0
  467. package/dist/store/defineKeyedStore.d.ts +38 -0
  468. package/dist/store/defineKeyedStore.js +42 -0
  469. package/dist/store/defineStore.d.ts +33 -0
  470. package/dist/store/defineStore.js +35 -0
  471. package/dist/store/observableKeyedStore.d.ts +5 -0
  472. package/dist/store/observableKeyedStore.js +34 -2
  473. package/dist/survival/decayMeter.d.ts +55 -0
  474. package/dist/survival/decayMeter.js +130 -55
  475. package/dist/survival/moodle.d.ts +2 -0
  476. package/dist/survival/regionHealth.d.ts +6 -0
  477. package/dist/survival/regionHealth.js +5 -0
  478. package/dist/tactics/fallingGrid.d.ts +4 -2
  479. package/dist/tactics/fallingGrid.js +4 -2
  480. package/dist/tactics/predictiveQuery.d.ts +3 -0
  481. package/dist/tactics/predictiveQuery.js +3 -0
  482. package/dist/tactics/snapshot.d.ts +2 -0
  483. package/dist/tactics/snapshot.js +2 -0
  484. package/dist/tactics/surface.d.ts +1 -0
  485. package/dist/tactics/surface.js +1 -0
  486. package/dist/tactics/tacticalGrid.d.ts +1 -0
  487. package/dist/tactics/tacticalGrid.js +1 -0
  488. package/dist/time/beatClock.d.ts +14 -4
  489. package/dist/time/beatClock.js +14 -4
  490. package/dist/time/calendarClock.d.ts +3 -0
  491. package/dist/time/calendarClock.js +3 -0
  492. package/dist/time/idleProgress.d.ts +4 -0
  493. package/dist/time/idleProgress.js +4 -0
  494. package/dist/time/simClock.d.ts +2 -0
  495. package/dist/time/simClock.js +20 -5
  496. package/dist/ui/actionModel.d.ts +110 -0
  497. package/dist/ui/actionModel.js +159 -0
  498. package/dist/ui/gameLayout.d.ts +30 -11
  499. package/dist/ui/gameLayout.js +30 -11
  500. package/dist/ui/hudDocument.d.ts +114 -0
  501. package/dist/ui/hudDocument.js +220 -0
  502. package/dist/ui/hudLayout.d.ts +33 -1
  503. package/dist/ui/hudLayout.js +204 -17
  504. package/dist/ui/selectionModel.d.ts +92 -0
  505. package/dist/ui/selectionModel.js +88 -0
  506. package/dist/ui/tooltipModel.d.ts +63 -0
  507. package/dist/ui/tooltipModel.js +82 -0
  508. package/dist/ui.d.ts +15 -0
  509. package/dist/ui.js +15 -0
  510. package/dist/visibility/bounds.d.ts +8 -1
  511. package/dist/visibility/bounds.js +8 -1
  512. package/dist/visibility/frustum.d.ts +12 -3
  513. package/dist/visibility/frustum.js +12 -3
  514. package/dist/work/jobQueue.d.ts +201 -0
  515. package/dist/work/jobQueue.js +253 -0
  516. package/dist/work/unitTraining.d.ts +58 -0
  517. package/dist/work/unitTraining.js +52 -0
  518. package/dist/world/authoredObjects.d.ts +58 -0
  519. package/dist/world/authoredObjects.js +69 -0
  520. package/dist/world/buildingGenerator.d.ts +18 -0
  521. package/dist/world/buildingGenerator.js +62 -0
  522. package/dist/world/buildings.d.ts +5 -0
  523. package/dist/world/buildings.js +5 -0
  524. package/dist/world/catenary.d.ts +22 -0
  525. package/dist/world/catenary.js +69 -0
  526. package/dist/world/features.d.ts +115 -7
  527. package/dist/world/features.js +56 -5
  528. package/dist/world/footprintGrid.d.ts +59 -0
  529. package/dist/world/footprintGrid.js +141 -0
  530. package/dist/world/geometry.d.ts +64 -0
  531. package/dist/world/geometry.js +94 -0
  532. package/dist/world/grassKind.d.ts +51 -0
  533. package/dist/world/grassKind.js +101 -0
  534. package/dist/world/pathInstances.d.ts +27 -0
  535. package/dist/world/pathInstances.js +27 -0
  536. package/dist/world/pathTerrain.d.ts +80 -0
  537. package/dist/world/pathTerrain.js +142 -0
  538. package/dist/world/placeAsset.d.ts +81 -0
  539. package/dist/world/placeAsset.js +77 -0
  540. package/dist/world/placement.d.ts +4 -0
  541. package/dist/world/placement.js +4 -0
  542. package/dist/world/placementController.d.ts +6 -0
  543. package/dist/world/placementController.js +6 -0
  544. package/dist/world/polyline.d.ts +34 -0
  545. package/dist/world/polyline.js +81 -0
  546. package/dist/world/roads.d.ts +8 -0
  547. package/dist/world/roads.js +38 -0
  548. package/dist/world/scatterRegion.d.ts +164 -0
  549. package/dist/world/scatterRegion.js +409 -0
  550. package/dist/world/sceneShapes.d.ts +43 -0
  551. package/dist/world/sceneShapes.js +1 -0
  552. package/dist/world/segment.d.ts +27 -0
  553. package/dist/world/segment.js +43 -0
  554. package/dist/world/soilKind.d.ts +48 -0
  555. package/dist/world/soilKind.js +92 -0
  556. package/dist/world/spatialSample.d.ts +241 -0
  557. package/dist/world/spatialSample.js +465 -0
  558. package/dist/world/terraform.d.ts +213 -1
  559. package/dist/world/terraform.js +655 -20
  560. package/dist/world/terrain.d.ts +119 -20
  561. package/dist/world/terrain.js +247 -41
  562. package/dist/world/terrainGuides.d.ts +182 -0
  563. package/dist/world/terrainGuides.js +343 -0
  564. package/dist/world/vec2.d.ts +81 -0
  565. package/dist/world/vec2.js +128 -0
  566. package/dist/world/vec3.d.ts +49 -0
  567. package/dist/world/vec3.js +76 -0
  568. package/dist/world/vegetation.d.ts +71 -0
  569. package/dist/world/vegetation.js +151 -0
  570. package/dist/world/visibilityField.d.ts +154 -0
  571. package/dist/world/visibilityField.js +271 -0
  572. package/dist/world/volumetricClouds.d.ts +52 -0
  573. package/dist/world/volumetricClouds.js +43 -0
  574. package/dist/world/walls.d.ts +9 -0
  575. package/dist/world/walls.js +9 -0
  576. package/dist/world/waterKind.d.ts +55 -0
  577. package/dist/world/waterKind.js +99 -0
  578. package/dist/world.d.ts +132 -0
  579. package/dist/world.js +132 -0
  580. package/package.json +32 -8
  581. package/skills/jgengine/SKILL.md +51 -0
  582. package/skills/jgengine/api.md +434 -0
  583. package/skills/jgengine/capabilities.md +29 -0
  584. package/skills/jgengine/reference-cartridge.md +72 -0
  585. package/skills/jgengine-combat/SKILL.md +34 -0
  586. package/skills/jgengine-combat/api.md +549 -0
  587. package/skills/jgengine-combat/capabilities.md +169 -0
  588. package/skills/jgengine-combat/reference.md +98 -0
  589. package/skills/jgengine-gameplay/SKILL.md +39 -0
  590. package/skills/jgengine-gameplay/api.md +1794 -0
  591. package/skills/jgengine-gameplay/capabilities.md +378 -0
  592. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  593. package/skills/jgengine-world/SKILL.md +38 -0
  594. package/skills/jgengine-world/api.md +2652 -0
  595. package/skills/jgengine-world/capabilities.md +370 -0
  596. package/skills/jgengine-world/reference.md +222 -0
  597. package/dist/cartridge/runtime.d.ts +0 -15
  598. package/dist/cartridge/runtime.js +0 -556
  599. package/dist/cartridge/spec.d.ts +0 -188
  600. package/dist/cartridge/spec.js +0 -19
  601. package/dist/cartridge/validate.d.ts +0 -2
  602. package/dist/cartridge/validate.js +0 -78
  603. package/dist/store/engineStore.d.ts +0 -22
  604. package/dist/store/engineStore.js +0 -50
  605. package/dist/store/features.d.ts +0 -10
  606. package/dist/store/features.js +0 -23
  607. package/llms.txt +0 -5389
@@ -0,0 +1,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[];
@@ -0,0 +1,141 @@
1
+ function cellKey(cell) {
2
+ return `${cell.col}:${cell.row}`;
3
+ }
4
+ /**
5
+ * Multi-cell footprint occupancy/reservation on a shared build grid — `world/placementController`
6
+ * only owns the ghost preview; this is the persistent claim a committed placement holds so the next
7
+ * hover's `isFree` check (or another player's, in a shared world) sees it. Bridge into
8
+ * `world/placement`'s `PlacementRules.obstacles` with {@link footprintObstacles} instead of
9
+ * hand-rolling an occupancy map per game.
10
+ *
11
+ * @capability footprint-grid multi-cell footprint occupancy/reservation on a shared build grid
12
+ */
13
+ export function createFootprintGrid(options = {}) {
14
+ const cellSize = options.cellSize ?? 1;
15
+ const occupied = new Map();
16
+ const reservations = new Map();
17
+ return {
18
+ cellSize,
19
+ cellsFor(origin, footprint, quarterTurns = 0) {
20
+ const turned = ((quarterTurns % 2) + 2) % 2 === 1;
21
+ const cols = Math.max(1, Math.round((turned ? footprint.d : footprint.w) / cellSize));
22
+ const rows = Math.max(1, Math.round((turned ? footprint.w : footprint.d) / cellSize));
23
+ const originCol = Math.round(origin[0] / cellSize - cols / 2);
24
+ const originRow = Math.round(origin[1] / cellSize - rows / 2);
25
+ const cells = [];
26
+ for (let row = 0; row < rows; row += 1) {
27
+ for (let col = 0; col < cols; col += 1)
28
+ cells.push({ col: originCol + col, row: originRow + row });
29
+ }
30
+ return cells;
31
+ },
32
+ isFree(cells) {
33
+ return cells.every((cell) => !occupied.has(cellKey(cell)));
34
+ },
35
+ reserve(id, kind, cells) {
36
+ if (reservations.has(id))
37
+ return false;
38
+ if (!cells.every((cell) => !occupied.has(cellKey(cell))))
39
+ return false;
40
+ for (const cell of cells)
41
+ occupied.set(cellKey(cell), id);
42
+ reservations.set(id, { id, kind, cells: cells.slice() });
43
+ return true;
44
+ },
45
+ release(id) {
46
+ const reservation = reservations.get(id);
47
+ if (reservation === undefined)
48
+ return false;
49
+ for (const cell of reservation.cells)
50
+ occupied.delete(cellKey(cell));
51
+ reservations.delete(id);
52
+ return true;
53
+ },
54
+ occupantAt(cell) {
55
+ return occupied.get(cellKey(cell)) ?? null;
56
+ },
57
+ kindAt(cell) {
58
+ const id = occupied.get(cellKey(cell));
59
+ if (id === undefined)
60
+ return null;
61
+ return reservations.get(id)?.kind ?? null;
62
+ },
63
+ reservationOf(id) {
64
+ return reservations.get(id) ?? null;
65
+ },
66
+ list() {
67
+ return Array.from(reservations.values());
68
+ },
69
+ clear() {
70
+ occupied.clear();
71
+ reservations.clear();
72
+ },
73
+ };
74
+ }
75
+ const CARDINAL_OFFSETS = [
76
+ { col: 0, row: -1 },
77
+ { col: 1, row: 0 },
78
+ { col: 0, row: 1 },
79
+ { col: -1, row: 0 },
80
+ ];
81
+ /** Every occupied cell orthogonally touching `cells` but outside them — the connective-piece neighbor set. */
82
+ export function boundaryNeighbors(grid, cells) {
83
+ const own = new Set(cells.map(cellKey));
84
+ const seen = new Set();
85
+ const out = [];
86
+ for (const cell of cells) {
87
+ for (const offset of CARDINAL_OFFSETS) {
88
+ const neighbor = { col: cell.col + offset.col, row: cell.row + offset.row };
89
+ const key = cellKey(neighbor);
90
+ if (own.has(key) || seen.has(key))
91
+ continue;
92
+ seen.add(key);
93
+ const kind = grid.kindAt(neighbor);
94
+ if (kind !== null)
95
+ out.push({ cell: neighbor, kind });
96
+ }
97
+ }
98
+ return out;
99
+ }
100
+ /**
101
+ * Connective-piece adjacency validity: every occupied neighbor of `cells` must satisfy `accepts`
102
+ * (no incompatible piece touching), and when `requireConnection` is true at least one neighbor must
103
+ * (a road/pipe/belt segment placed with nothing to connect to is invalid). An empty-bordered footprint
104
+ * (no occupied neighbors at all) passes unless `requireConnection` demands one.
105
+ */
106
+ export function hasValidAdjacency(grid, cells, accepts, requireConnection = false) {
107
+ const neighbors = boundaryNeighbors(grid, cells);
108
+ if (requireConnection && neighbors.length === 0)
109
+ return false;
110
+ if (!neighbors.every((neighbor) => accepts(neighbor.kind)))
111
+ return false;
112
+ return !requireConnection || neighbors.some((neighbor) => accepts(neighbor.kind));
113
+ }
114
+ /** Bridges live reservations into `world/placement`'s `PlacementRules.obstacles` so `validatePlacement`/`createPlacementController` see the grid's committed footprints unchanged. */
115
+ export function footprintObstacles(grid) {
116
+ return grid.list().map((reservation) => {
117
+ let minCol = Infinity;
118
+ let minRow = Infinity;
119
+ let maxCol = -Infinity;
120
+ let maxRow = -Infinity;
121
+ for (const cell of reservation.cells) {
122
+ if (cell.col < minCol)
123
+ minCol = cell.col;
124
+ if (cell.col > maxCol)
125
+ maxCol = cell.col;
126
+ if (cell.row < minRow)
127
+ minRow = cell.row;
128
+ if (cell.row > maxRow)
129
+ maxRow = cell.row;
130
+ }
131
+ return {
132
+ id: reservation.id,
133
+ aabb: {
134
+ minX: minCol * grid.cellSize,
135
+ maxX: (maxCol + 1) * grid.cellSize,
136
+ minZ: minRow * grid.cellSize,
137
+ maxZ: (maxRow + 1) * grid.cellSize,
138
+ },
139
+ };
140
+ });
141
+ }
@@ -1,4 +1,6 @@
1
1
  export type Vec2 = readonly [number, number];
2
+ /** A 3D point/vector as an `[x, y, z]` tuple — the engine's zero-allocation spatial primitive. */
3
+ export type Vec3 = readonly [number, number, number];
2
4
  export interface Footprint {
3
5
  w: number;
4
6
  d: number;
@@ -13,11 +15,73 @@ export interface MoveOptions {
13
15
  bounds?: Aabb;
14
16
  radius?: number;
15
17
  }
18
+ /**
19
+ * A circular clearance around a gameplay spot (spawn, plot, path point, POI): scatter is repelled
20
+ * from it and terrain is flattened toward its center. `feather` (meters) is the soft outer band —
21
+ * full effect within `radius - feather`, ramping to zero at `radius`.
22
+ */
23
+ export interface AvoidZone {
24
+ x: number;
25
+ z: number;
26
+ radius: number;
27
+ feather?: number;
28
+ }
29
+ /**
30
+ * A clearance *corridor* along a polyline (a path/road): scatter is repelled within `halfWidth` of
31
+ * the centerline, feathered over the outer band. Clean straight edges — unlike approximating a
32
+ * corridor with a scalloped chain of discs.
33
+ */
34
+ export interface AvoidCorridor {
35
+ points: readonly Vec2[];
36
+ halfWidth: number;
37
+ feather?: number;
38
+ }
39
+ /** A clearance region: point discs (spawns/plots) plus centerline corridors (paths). */
40
+ export interface AvoidMasks {
41
+ discs: readonly AvoidZone[];
42
+ corridors: readonly AvoidCorridor[];
43
+ }
44
+ /**
45
+ * How strongly a point falls inside a clearance zone: 1 at/inside the solid core, ramping to 0 at
46
+ * the zone's outer `radius` across its `feather` band, 0 outside. The max over all zones.
47
+ * @internal — the falloff math behind scatter avoid and terrain flatten.
48
+ */
49
+ export declare function zoneInfluence(x: number, z: number, zones: readonly AvoidZone[]): number;
50
+ /** Clearance influence of a corridor: nearest-segment distance vs `halfWidth`, feathered. @internal */
51
+ export declare function corridorInfluence(x: number, z: number, corridor: AvoidCorridor): number;
52
+ /** Combined clearance influence of discs + corridors — the max over every mask. @internal */
53
+ export declare function masksInfluence(x: number, z: number, masks: AvoidMasks): number;
54
+ /** @internal */
16
55
  export declare function snapToGrid(point: Vec2, size: number): Vec2;
56
+ /** @internal */
17
57
  export declare function footprintAabb(center: Vec2, footprint: Footprint, quarterTurns?: number): Aabb;
58
+ /** @internal */
18
59
  export declare function expandAabb(aabb: Aabb, margin: number): Aabb;
60
+ /** @internal */
19
61
  export declare function aabbOverlap(a: Aabb, b: Aabb): boolean;
62
+ /** @internal */
20
63
  export declare function aabbContains(outer: Aabb, inner: Aabb): boolean;
64
+ /** @internal */
21
65
  export declare function pointInAabb(point: Vec2, aabb: Aabb): boolean;
66
+ /** @internal */
22
67
  export declare function clampToAabb(point: Vec2, aabb: Aabb): Vec2;
68
+ /** @internal */
23
69
  export declare function resolveMove(from: Vec2, delta: Vec2, blockers: readonly Aabb[], options?: MoveOptions): Vec2;
70
+ /** An axis-aligned ellipse: `center` with semi-axes `radiusX` and `radiusY`. */
71
+ export interface Ellipse {
72
+ center: Vec2;
73
+ radiusX: number;
74
+ radiusY: number;
75
+ }
76
+ /** True when `point` sits inside (or on) the ellipse — the oval-arena containment test.
77
+ * @internal
78
+ */
79
+ export declare function pointInEllipse(point: Vec2, ellipse: Ellipse): boolean;
80
+ /** Clamp `point` to the ellipse boundary when it strays outside, else return it unchanged.
81
+ * @internal
82
+ */
83
+ export declare function clampToEllipse(point: Vec2, ellipse: Ellipse): Vec2;
84
+ /** Outward unit normal of the ellipse at the point nearest `point` — the boundary bounce direction.
85
+ * @internal
86
+ */
87
+ export declare function ellipseNormal(point: Vec2, ellipse: Ellipse): Vec2;
@@ -1,8 +1,61 @@
1
+ function bandInfluence(dist, radius, feather) {
2
+ if (dist >= radius)
3
+ return 0;
4
+ const inner = radius - Math.max(0, feather);
5
+ return dist <= inner || feather <= 0 ? 1 : (radius - dist) / feather;
6
+ }
7
+ /** Perpendicular distance from a point to a polyline segment [a,b] on the XZ plane. */
8
+ function distanceToSegment(px, pz, a, b) {
9
+ const dx = b[0] - a[0];
10
+ const dz = b[1] - a[1];
11
+ const lenSq = dx * dx + dz * dz || 1;
12
+ let t = ((px - a[0]) * dx + (pz - a[1]) * dz) / lenSq;
13
+ t = t < 0 ? 0 : t > 1 ? 1 : t;
14
+ return Math.hypot(px - (a[0] + dx * t), pz - (a[1] + dz * t));
15
+ }
16
+ /**
17
+ * How strongly a point falls inside a clearance zone: 1 at/inside the solid core, ramping to 0 at
18
+ * the zone's outer `radius` across its `feather` band, 0 outside. The max over all zones.
19
+ * @internal — the falloff math behind scatter avoid and terrain flatten.
20
+ */
21
+ export function zoneInfluence(x, z, zones) {
22
+ let best = 0;
23
+ for (const zone of zones) {
24
+ const t = bandInfluence(Math.hypot(x - zone.x, z - zone.z), zone.radius, zone.feather ?? 0);
25
+ if (t > best)
26
+ best = t;
27
+ }
28
+ return best;
29
+ }
30
+ /** Clearance influence of a corridor: nearest-segment distance vs `halfWidth`, feathered. @internal */
31
+ export function corridorInfluence(x, z, corridor) {
32
+ const { points, halfWidth } = corridor;
33
+ const feather = corridor.feather ?? 0;
34
+ let best = 0;
35
+ for (let i = 1; i < points.length; i += 1) {
36
+ const t = bandInfluence(distanceToSegment(x, z, points[i - 1], points[i]), halfWidth, feather);
37
+ if (t > best)
38
+ best = t;
39
+ }
40
+ return best;
41
+ }
42
+ /** Combined clearance influence of discs + corridors — the max over every mask. @internal */
43
+ export function masksInfluence(x, z, masks) {
44
+ let best = zoneInfluence(x, z, masks.discs);
45
+ for (const corridor of masks.corridors) {
46
+ const t = corridorInfluence(x, z, corridor);
47
+ if (t > best)
48
+ best = t;
49
+ }
50
+ return best;
51
+ }
52
+ /** @internal */
1
53
  export function snapToGrid(point, size) {
2
54
  if (!(size > 0))
3
55
  return point;
4
56
  return [Math.round(point[0] / size) * size, Math.round(point[1] / size) * size];
5
57
  }
58
+ /** @internal */
6
59
  export function footprintAabb(center, footprint, quarterTurns = 0) {
7
60
  const turned = ((quarterTurns % 2) + 2) % 2 === 1;
8
61
  const halfW = (turned ? footprint.d : footprint.w) / 2;
@@ -14,6 +67,7 @@ export function footprintAabb(center, footprint, quarterTurns = 0) {
14
67
  maxZ: center[1] + halfD,
15
68
  };
16
69
  }
70
+ /** @internal */
17
71
  export function expandAabb(aabb, margin) {
18
72
  return {
19
73
  minX: aabb.minX - margin,
@@ -22,18 +76,22 @@ export function expandAabb(aabb, margin) {
22
76
  maxZ: aabb.maxZ + margin,
23
77
  };
24
78
  }
79
+ /** @internal */
25
80
  export function aabbOverlap(a, b) {
26
81
  return a.minX < b.maxX && a.maxX > b.minX && a.minZ < b.maxZ && a.maxZ > b.minZ;
27
82
  }
83
+ /** @internal */
28
84
  export function aabbContains(outer, inner) {
29
85
  return (inner.minX >= outer.minX &&
30
86
  inner.maxX <= outer.maxX &&
31
87
  inner.minZ >= outer.minZ &&
32
88
  inner.maxZ <= outer.maxZ);
33
89
  }
90
+ /** @internal */
34
91
  export function pointInAabb(point, aabb) {
35
92
  return point[0] >= aabb.minX && point[0] <= aabb.maxX && point[1] >= aabb.minZ && point[1] <= aabb.maxZ;
36
93
  }
94
+ /** @internal */
37
95
  export function clampToAabb(point, aabb) {
38
96
  return [
39
97
  Math.min(Math.max(point[0], aabb.minX), aabb.maxX),
@@ -62,6 +120,7 @@ function resolveAxis(main, cross, delta, blockers, axisX) {
62
120
  }
63
121
  return next;
64
122
  }
123
+ /** @internal */
65
124
  export function resolveMove(from, delta, blockers, options = {}) {
66
125
  const radius = options.radius ?? 0;
67
126
  const expanded = radius === 0 ? blockers : blockers.map((blocker) => expandAabb(blocker, radius));
@@ -73,3 +132,38 @@ export function resolveMove(from, delta, blockers, options = {}) {
73
132
  z = Math.min(Math.max(z, options.bounds.minZ + radius), options.bounds.maxZ - radius);
74
133
  return [x, z];
75
134
  }
135
+ function normalizedRadius2(point, ellipse) {
136
+ const nx = ellipse.radiusX > 0 ? (point[0] - ellipse.center[0]) / ellipse.radiusX : 0;
137
+ const ny = ellipse.radiusY > 0 ? (point[1] - ellipse.center[1]) / ellipse.radiusY : 0;
138
+ return nx * nx + ny * ny;
139
+ }
140
+ /** True when `point` sits inside (or on) the ellipse — the oval-arena containment test.
141
+ * @internal
142
+ */
143
+ export function pointInEllipse(point, ellipse) {
144
+ return normalizedRadius2(point, ellipse) <= 1;
145
+ }
146
+ /** Clamp `point` to the ellipse boundary when it strays outside, else return it unchanged.
147
+ * @internal
148
+ */
149
+ export function clampToEllipse(point, ellipse) {
150
+ const r2 = normalizedRadius2(point, ellipse);
151
+ if (r2 <= 1)
152
+ return point;
153
+ const scale = 1 / Math.sqrt(r2);
154
+ return [
155
+ ellipse.center[0] + (point[0] - ellipse.center[0]) * scale,
156
+ ellipse.center[1] + (point[1] - ellipse.center[1]) * scale,
157
+ ];
158
+ }
159
+ /** Outward unit normal of the ellipse at the point nearest `point` — the boundary bounce direction.
160
+ * @internal
161
+ */
162
+ export function ellipseNormal(point, ellipse) {
163
+ const nx = ellipse.radiusX > 0 ? (point[0] - ellipse.center[0]) / (ellipse.radiusX * ellipse.radiusX) : 0;
164
+ const ny = ellipse.radiusY > 0 ? (point[1] - ellipse.center[1]) / (ellipse.radiusY * ellipse.radiusY) : 0;
165
+ const len = Math.hypot(nx, ny);
166
+ if (len < 1e-6)
167
+ return [1, 0];
168
+ return [nx / len, ny / len];
169
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `grass_field` studio: a GPU grass patch authored as a box volume — its XZ footprint is the grass
3
+ * area, its top the ground height. Pure config here (blade/wind/color params + a footprint resolver);
4
+ * the instanced vertex-wind grass mesh lives in the `shell` renderer, which drives the existing
5
+ * `GrassField`. An engine environment kind (like water/scatter) so grass wind and colours are
6
+ * slider-authorable in the editor and persisted in `editor.scene.json` — the #813 grass studio.
7
+ *
8
+ * @capability grass-field editor-authorable GPU grass patch
9
+ */
10
+ import { type ParamSchema, type SceneKindObject } from "../scene/sceneKinds.js";
11
+ /** The editor volume kind marking a box as a GPU grass patch. */
12
+ export declare const GRASS_FIELD_KIND = "grass_field";
13
+ /** Fully-defaulted grass params parsed from a volume's `meta`. */
14
+ export interface GrassRules {
15
+ /** Blades per square meter (the shell caps by an instance budget). */
16
+ density: number;
17
+ /** Blade height in meters. */
18
+ bladeHeight: number;
19
+ /** Base (root) color, hex. */
20
+ colorBase: string;
21
+ /** Tip color, hex. */
22
+ colorTip: string;
23
+ /** Per-blade color jitter, 0..1. */
24
+ colorVariation: number;
25
+ /** Vertex-wind sway strength, 0..1. */
26
+ windStrength: number;
27
+ /** Wind animation speed. */
28
+ windSpeed: number;
29
+ /** Gust patch scale (spatial frequency of gusts). */
30
+ windGust: number;
31
+ /** Blade material roughness, 0..1. */
32
+ roughness: number;
33
+ /** Seed string; same seed reproduces the same blade layout. */
34
+ seed: string;
35
+ }
36
+ /** Grass defaults: a lush, lightly-swaying meadow. */
37
+ export declare const GRASS_DEFAULTS: GrassRules;
38
+ /** The grass parameter schema — drives the inspector and `meta` parse via the studio seam. */
39
+ export declare const GRASS_SCHEMA: ParamSchema;
40
+ /** Parse a volume's `meta` into fully-defaulted grass rules. @internal */
41
+ export declare function readGrassRules(meta: Record<string, unknown> | undefined): GrassRules;
42
+ /** A resolved grass patch: world-space area center at ground height, footprint size (XZ), and rules. */
43
+ export interface ResolvedGrass {
44
+ center: readonly [number, number, number];
45
+ size: readonly [number, number];
46
+ rules: GrassRules;
47
+ }
48
+ /** Resolve a grass volume into an area footprint (from box half-extents / radius) at the box base. @internal */
49
+ export declare function resolveGrassObject(object: SceneKindObject): ResolvedGrass | null;
50
+ /** Registers the `grass_field` scene kind (schema + resolver). Called by {@link registerBuiltinSceneKinds}. @internal */
51
+ export declare function registerGrassKind(): void;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * `grass_field` studio: a GPU grass patch authored as a box volume — its XZ footprint is the grass
3
+ * area, its top the ground height. Pure config here (blade/wind/color params + a footprint resolver);
4
+ * the instanced vertex-wind grass mesh lives in the `shell` renderer, which drives the existing
5
+ * `GrassField`. An engine environment kind (like water/scatter) so grass wind and colours are
6
+ * slider-authorable in the editor and persisted in `editor.scene.json` — the #813 grass studio.
7
+ *
8
+ * @capability grass-field editor-authorable GPU grass patch
9
+ */
10
+ import { registerSceneKind } from "../scene/sceneKinds.js";
11
+ /** The editor volume kind marking a box as a GPU grass patch. */
12
+ export const GRASS_FIELD_KIND = "grass_field";
13
+ /** Grass defaults: a lush, lightly-swaying meadow. */
14
+ export const GRASS_DEFAULTS = {
15
+ density: 4,
16
+ bladeHeight: 0.6,
17
+ colorBase: "#3f6f37",
18
+ colorTip: "#9ac25a",
19
+ colorVariation: 0.35,
20
+ windStrength: 0.22,
21
+ windSpeed: 1.6,
22
+ windGust: 0.16,
23
+ roughness: 0.85,
24
+ seed: "",
25
+ };
26
+ /** The grass parameter schema — drives the inspector and `meta` parse via the studio seam. */
27
+ export const GRASS_SCHEMA = {
28
+ fields: [
29
+ { type: "range", key: "density", label: "density", min: 0.5, max: 16, step: 0.5, default: GRASS_DEFAULTS.density, unit: "/m²" },
30
+ { type: "range", key: "bladeHeight", label: "blade height", min: 0.1, max: 2, step: 0.05, default: GRASS_DEFAULTS.bladeHeight, unit: "m" },
31
+ { type: "color", key: "colorBase", label: "base color", default: GRASS_DEFAULTS.colorBase },
32
+ { type: "color", key: "colorTip", label: "tip color", default: GRASS_DEFAULTS.colorTip },
33
+ { type: "range", key: "colorVariation", label: "color variation", min: 0, max: 1, step: 0.02, default: GRASS_DEFAULTS.colorVariation },
34
+ { type: "range", key: "windStrength", label: "wind strength", min: 0, max: 1, step: 0.01, default: GRASS_DEFAULTS.windStrength },
35
+ { type: "range", key: "windSpeed", label: "wind speed", min: 0, max: 4, step: 0.05, default: GRASS_DEFAULTS.windSpeed },
36
+ { type: "range", key: "windGust", label: "gust scale", min: 0, max: 1, step: 0.02, default: GRASS_DEFAULTS.windGust },
37
+ { type: "range", key: "roughness", label: "roughness", min: 0, max: 1, step: 0.02, default: GRASS_DEFAULTS.roughness },
38
+ { type: "seed", key: "seed", label: "seed", default: "" },
39
+ ],
40
+ };
41
+ function metaNumber(meta, key, fallback) {
42
+ const value = meta?.[key];
43
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
44
+ }
45
+ function metaString(meta, key, fallback) {
46
+ const value = meta?.[key];
47
+ return typeof value === "string" ? value : fallback;
48
+ }
49
+ /** Parse a volume's `meta` into fully-defaulted grass rules. @internal */
50
+ export function readGrassRules(meta) {
51
+ return {
52
+ density: Math.max(0, metaNumber(meta, "density", GRASS_DEFAULTS.density)),
53
+ bladeHeight: Math.max(0.05, metaNumber(meta, "bladeHeight", GRASS_DEFAULTS.bladeHeight)),
54
+ colorBase: metaString(meta, "colorBase", GRASS_DEFAULTS.colorBase),
55
+ colorTip: metaString(meta, "colorTip", GRASS_DEFAULTS.colorTip),
56
+ colorVariation: metaNumber(meta, "colorVariation", GRASS_DEFAULTS.colorVariation),
57
+ windStrength: metaNumber(meta, "windStrength", GRASS_DEFAULTS.windStrength),
58
+ windSpeed: metaNumber(meta, "windSpeed", GRASS_DEFAULTS.windSpeed),
59
+ windGust: metaNumber(meta, "windGust", GRASS_DEFAULTS.windGust),
60
+ roughness: metaNumber(meta, "roughness", GRASS_DEFAULTS.roughness),
61
+ seed: metaString(meta, "seed", GRASS_DEFAULTS.seed),
62
+ };
63
+ }
64
+ function axis(value) {
65
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
66
+ }
67
+ /** Resolve a grass volume into an area footprint (from box half-extents / radius) at the box base. @internal */
68
+ export function resolveGrassObject(object) {
69
+ const center = object.center ?? object.position;
70
+ if (center === undefined)
71
+ return null;
72
+ const he = object.halfExtents;
73
+ const radius = object.radius;
74
+ const halfX = axis(he?.x) ?? radius ?? 10;
75
+ const halfZ = axis(he?.z) ?? radius ?? 10;
76
+ const halfY = axis(he?.y) ?? 0;
77
+ return {
78
+ center: [center.x, center.y - halfY, center.z],
79
+ size: [Math.max(0.5, halfX * 2), Math.max(0.5, halfZ * 2)],
80
+ rules: readGrassRules(object.meta),
81
+ };
82
+ }
83
+ /** Registers the `grass_field` scene kind (schema + resolver). Called by {@link registerBuiltinSceneKinds}. @internal */
84
+ export function registerGrassKind() {
85
+ registerSceneKind({
86
+ kind: GRASS_FIELD_KIND,
87
+ target: "volume",
88
+ label: "Grass field",
89
+ addCategory: "Studios",
90
+ accent: "#7fbf4d",
91
+ schema: GRASS_SCHEMA,
92
+ resolve: (object) => resolveGrassObject(object),
93
+ note: (object) => {
94
+ const resolved = resolveGrassObject(object);
95
+ if (resolved === null)
96
+ return "Give the volume a box footprint.";
97
+ const area = resolved.size[0] * resolved.size[1];
98
+ return `${Math.round(resolved.size[0])}×${Math.round(resolved.size[1])} m · ≈${Math.round(area * resolved.rules.density).toLocaleString()} blades`;
99
+ },
100
+ });
101
+ }
@@ -0,0 +1,27 @@
1
+ /** One placed transform along a path: grounded position, facing yaw, and its ordinal + arc distance. */
2
+ export interface PathInstance {
3
+ index: number;
4
+ /** Arc-length distance from the path start, meters. */
5
+ distance: number;
6
+ position: readonly [number, number, number];
7
+ /** Yaw (radians) facing along the direction of travel. */
8
+ yaw: number;
9
+ }
10
+ /** Options for {@link placeAlongPath}. */
11
+ export interface PlaceAlongPathOptions {
12
+ /** Target meters between instances. The run is divided into equal spans nearest this spacing. */
13
+ spacing: number;
14
+ /** Ground each instance to this height sampler (else y = 0). */
15
+ sampleHeight?: (x: number, z: number) => number;
16
+ /** Force at least this many instances regardless of length. Default 1 (endpoints only when short). */
17
+ minCount?: number;
18
+ }
19
+ /**
20
+ * Evenly place transforms along `points` (XZ polyline). The run length is divided into the whole
21
+ * number of equal spans closest to `spacing`, so instances always land on both endpoints and stay
22
+ * evenly distributed. Returns `spans + 1` instances. Empty for fewer than 2 points.
23
+ */
24
+ export declare function placeAlongPath(points: readonly {
25
+ x: number;
26
+ z: number;
27
+ }[], options: PlaceAlongPathOptions): PathInstance[];
@@ -0,0 +1,27 @@
1
+ import { pointAtDistance, polyline, tangentAtDistance } from "./polyline.js";
2
+ /**
3
+ * Evenly place transforms along `points` (XZ polyline). The run length is divided into the whole
4
+ * number of equal spans closest to `spacing`, so instances always land on both endpoints and stay
5
+ * evenly distributed. Returns `spans + 1` instances. Empty for fewer than 2 points.
6
+ */
7
+ export function placeAlongPath(points, options) {
8
+ if (points.length < 2)
9
+ return [];
10
+ const line = polyline(points.map((point) => [point.x, point.z]));
11
+ const total = line.length;
12
+ if (total <= 0)
13
+ return [];
14
+ const spacing = Math.max(0.01, options.spacing);
15
+ const minSpans = Math.max(1, (options.minCount ?? 1) - 1);
16
+ const spans = Math.max(minSpans, Math.round(total / spacing), 1);
17
+ const step = total / spans;
18
+ const out = [];
19
+ for (let i = 0; i <= spans; i += 1) {
20
+ const distance = i * step;
21
+ const [x, z] = pointAtDistance(line, distance);
22
+ const [tx, tz] = tangentAtDistance(line, Math.min(distance, total - 1e-4));
23
+ const y = options.sampleHeight?.(x, z) ?? 0;
24
+ out.push({ index: i, distance, position: [x, y, z], yaw: Math.atan2(tx, tz) });
25
+ }
26
+ return out;
27
+ }