@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,80 @@
1
+ /**
2
+ * Path-driven terrain modifiers: one authored centerline reshapes a heightfield across a corridor —
3
+ * flatten a roadbed, grade a constant-slope ramp, carve a river/trench, and hold retaining walls where
4
+ * the corridor cuts or fills into the surrounding ground. Genre-agnostic: roads, rails, rivers,
5
+ * trenches, runways, and accessibility ramps are all the same profile with different numbers, so no game
6
+ * hand-rolls its own flatten-mask generator. Pure XZ math over a polyline — deterministic, bounded
7
+ * (O(points) per sample), and serializable; it composes onto any height sampler and pairs with
8
+ * `resolveTerrainField` so the same authored path drives both the rendered mesh and player collision.
9
+ * @capability path-terrain flatten / grade / carve a heightfield from an authored path with retaining profiles
10
+ * @consumer packages/core/src/world/terrain.ts (resolveTerrainField), Games/the-robots roads
11
+ */
12
+ import type { Vec2 } from "./geometry.js";
13
+ /**
14
+ * Where a path corridor drives its centerline height:
15
+ * - `sample` — follow the base terrain under the centerline, so the corridor drapes level across its
16
+ * width while still tracking the hills the path crosses (the natural policy for a road or trail).
17
+ * - `fixed` — hold one constant height for the whole corridor (a level causeway, runway, or dam crest).
18
+ * - `grade` — interpolate linearly from `start` to `end` height along the path's arc length, a
19
+ * constant-slope ramp between two anchors (a switchback, a graded rail bed, an accessibility ramp).
20
+ */
21
+ export type PathHeightPolicy = {
22
+ readonly kind: "sample";
23
+ } | {
24
+ readonly kind: "fixed";
25
+ readonly height: number;
26
+ } | {
27
+ readonly kind: "grade";
28
+ readonly start: number;
29
+ readonly end: number;
30
+ };
31
+ /**
32
+ * Retaining behavior for a path corridor's shoulders. A wall rises only where the corridor already cuts or
33
+ * fills into the surrounding ground by at least `threshold` — gentle stretches stay open — so a road
34
+ * through a canyon gets held banks while the same profile on flat ground does not. The wall fades in
35
+ * smoothly across `taper` above the threshold so it never steps on or off between adjacent samples.
36
+ */
37
+ export interface PathRetaining {
38
+ /** Crest height raised above the corridor edge on both shoulders (canyon walls, road berms, levee banks). */
39
+ readonly wallHeight: number;
40
+ /** Minimum cut/fill (world units) between corridor and surrounding ground before a wall rises. Default 0 (wall the whole path). */
41
+ readonly threshold?: number;
42
+ /** Cut/fill band above `threshold` over which the wall fades from none to full height. Default equal to `threshold`. */
43
+ readonly taper?: number;
44
+ }
45
+ /**
46
+ * A serializable path-driven terrain modifier. The `points` centerline reshapes the heightfield across a
47
+ * corridor of `width`, feathering back to the surrounding ground across `shoulder`. `height` sets the
48
+ * centerline target (sample / fixed / grade); `depth` carves a channel below it (deepest at the
49
+ * centerline, easing to zero at the core edge — rivers and trenches); `retaining` raises walls where the
50
+ * cut/fill exceeds a threshold; `maxCut`/`maxFill` cap how far the ground may move from its base height.
51
+ * All fields are plain data (numbers, string enums, point arrays) so a profile round-trips through the
52
+ * scene document and evaluates identically at author time and runtime.
53
+ */
54
+ export interface TerrainPathProfile {
55
+ /** Centerline vertices in world XZ; needs at least two points. Repeat the first point as the last for a closed loop. */
56
+ readonly points: readonly Vec2[];
57
+ /** Full corridor width; the reshaped core extends `width / 2` either side of the centerline. */
58
+ readonly width: number;
59
+ /** Blend-ring width outside the core where the corridor height smoothsteps back to the surrounding ground. Default `width * 0.5`. */
60
+ readonly shoulder?: number;
61
+ /** Centerline target-height policy. Default `{ kind: "sample" }` (drape level across the base terrain). */
62
+ readonly height?: PathHeightPolicy;
63
+ /** Carve depth below the target height, deepest at the centerline and easing to zero at the core edge (0 = flat corridor). Default 0. */
64
+ readonly depth?: number;
65
+ /** Never cut the ground more than this far below its base height. Omit for unlimited cut. */
66
+ readonly maxCut?: number;
67
+ /** Never fill the ground more than this far above its base height. Omit for unlimited fill. */
68
+ readonly maxFill?: number;
69
+ /** Raise retaining walls along the shoulders where the corridor cuts/fills into the surrounding ground. */
70
+ readonly retaining?: PathRetaining;
71
+ }
72
+ /**
73
+ * Wraps a height sampler so each authored `TerrainPathProfile` reshapes it. Profiles apply in list order
74
+ * (later profiles compose over earlier ones, so an intersection's last profile wins its core); each reads
75
+ * the running height as its surrounding ground and the original `base` for `sample` centerline heights.
76
+ * The returned sampler is pure and deterministic. Degenerate profiles (fewer than two points, non-positive
77
+ * width or length) are skipped; with no usable profile the original `base` is returned unchanged.
78
+ * @capability path-terrain compose flatten/grade/carve/retaining path profiles onto a height sampler
79
+ */
80
+ export declare function withPathProfiles(base: (x: number, z: number) => number, profiles: readonly TerrainPathProfile[]): (x: number, z: number) => number;
@@ -0,0 +1,142 @@
1
+ function clamp01(value) {
2
+ return value < 0 ? 0 : value > 1 ? 1 : value;
3
+ }
4
+ function lerp(a, b, t) {
5
+ return a + (b - a) * t;
6
+ }
7
+ function smoothstep01(t) {
8
+ const clamped = clamp01(t);
9
+ return clamped * clamped * (3 - 2 * clamped);
10
+ }
11
+ function buildCorridor(points) {
12
+ const cumulative = [0];
13
+ for (let i = 1; i < points.length; i += 1) {
14
+ const a = points[i - 1];
15
+ const b = points[i];
16
+ cumulative.push(cumulative[i - 1] + Math.hypot(b[0] - a[0], b[1] - a[1]));
17
+ }
18
+ return { points, cumulative, total: cumulative[cumulative.length - 1] ?? 0 };
19
+ }
20
+ /**
21
+ * Closest point on the corridor to `(x, z)`: unsigned lateral distance and arc-length position. Self-
22
+ * contained (each segment projects independently and the minimum lateral wins) so a vertex always reports
23
+ * a near-zero lateral, regardless of which side of the line the neighbours fall.
24
+ */
25
+ function nearestOnCorridor(corridor, x, z) {
26
+ let bestLateral = Number.POSITIVE_INFINITY;
27
+ let bestAlong = 0;
28
+ let bestPoint = corridor.points[0] ?? [x, z];
29
+ for (let i = 1; i < corridor.points.length; i += 1) {
30
+ const a = corridor.points[i - 1];
31
+ const b = corridor.points[i];
32
+ const abx = b[0] - a[0];
33
+ const abz = b[1] - a[1];
34
+ const segLenSq = abx * abx + abz * abz;
35
+ const t = segLenSq <= 0 ? 0 : Math.max(0, Math.min(1, ((x - a[0]) * abx + (z - a[1]) * abz) / segLenSq));
36
+ const px = a[0] + abx * t;
37
+ const pz = a[1] + abz * t;
38
+ const lateral = Math.hypot(x - px, z - pz);
39
+ if (lateral < bestLateral) {
40
+ bestLateral = lateral;
41
+ bestAlong = corridor.cumulative[i - 1] + t * Math.sqrt(segLenSq);
42
+ bestPoint = [px, pz];
43
+ }
44
+ }
45
+ return { lateral: bestLateral, along: bestAlong, point: bestPoint };
46
+ }
47
+ function resolveProfile(profile) {
48
+ if (profile.points.length < 2 || profile.width <= 0)
49
+ return null;
50
+ const corridor = buildCorridor(profile.points.map((point) => [point[0], point[1]]));
51
+ if (corridor.total <= 0)
52
+ return null;
53
+ const shoulder = Math.max(0, profile.shoulder ?? profile.width * 0.5);
54
+ return {
55
+ corridor,
56
+ half: profile.width / 2,
57
+ shoulder,
58
+ reach: profile.width / 2 + shoulder,
59
+ height: profile.height ?? { kind: "sample" },
60
+ depth: Math.max(0, profile.depth ?? 0),
61
+ ...(profile.maxCut === undefined ? {} : { maxCut: Math.max(0, profile.maxCut) }),
62
+ ...(profile.maxFill === undefined ? {} : { maxFill: Math.max(0, profile.maxFill) }),
63
+ wallHeight: Math.max(0, profile.retaining?.wallHeight ?? 0),
64
+ threshold: Math.max(0, profile.retaining?.threshold ?? 0),
65
+ taper: Math.max(0, profile.retaining?.taper ?? profile.retaining?.threshold ?? 0),
66
+ };
67
+ }
68
+ /** Wall strength 0..1: full above `threshold + taper`, none below `threshold`, smooth between. */
69
+ function wallStrength(profile, cutFill) {
70
+ if (profile.wallHeight <= 0)
71
+ return 0;
72
+ if (cutFill < profile.threshold)
73
+ return 0;
74
+ if (profile.taper <= 0)
75
+ return 1;
76
+ return smoothstep01((cutFill - profile.threshold) / profile.taper);
77
+ }
78
+ function clampCutFill(height, base, maxCut, maxFill) {
79
+ let out = height;
80
+ if (maxFill !== undefined && out > base + maxFill)
81
+ out = base + maxFill;
82
+ if (maxCut !== undefined && out < base - maxCut)
83
+ out = base - maxCut;
84
+ return out;
85
+ }
86
+ function centerlineTarget(profile, along, point, base) {
87
+ const policy = profile.height;
88
+ if (policy.kind === "fixed")
89
+ return policy.height;
90
+ if (policy.kind === "grade") {
91
+ const fraction = profile.corridor.total <= 0 ? 0 : clamp01(along / profile.corridor.total);
92
+ return policy.start + (policy.end - policy.start) * fraction;
93
+ }
94
+ return base(point[0], point[1]);
95
+ }
96
+ function applyProfileAt(profile, x, z, surrounding, base) {
97
+ const hit = nearestOnCorridor(profile.corridor, x, z);
98
+ const lateral = hit.lateral;
99
+ if (lateral > profile.reach)
100
+ return surrounding;
101
+ const target = clampCutFill(centerlineTarget(profile, hit.along, hit.point, base), surrounding, profile.maxCut, profile.maxFill);
102
+ // Inside the core: carve a channel below the target, deepest at the centerline, level at the edge.
103
+ if (lateral <= profile.half) {
104
+ const edgeT = profile.half <= 0 ? 0 : lateral / profile.half;
105
+ const carved = target - profile.depth * (1 - edgeT * edgeT);
106
+ return clampCutFill(carved, surrounding, profile.maxCut, profile.maxFill);
107
+ }
108
+ // Shoulder: feather the corridor edge (target) back to the surrounding ground, or hold a retaining wall.
109
+ const shoulderT = clamp01((lateral - profile.half) / profile.shoulder);
110
+ const feathered = lerp(target, surrounding, smoothstep01(shoulderT));
111
+ const strength = wallStrength(profile, Math.abs(target - surrounding));
112
+ if (strength <= 0)
113
+ return feathered;
114
+ const crest = target + profile.wallHeight;
115
+ const walled = shoulderT <= 0.5 ? lerp(target, crest, smoothstep01(shoulderT / 0.5)) : lerp(crest, surrounding, smoothstep01((shoulderT - 0.5) / 0.5));
116
+ return lerp(feathered, walled, strength);
117
+ }
118
+ /**
119
+ * Wraps a height sampler so each authored `TerrainPathProfile` reshapes it. Profiles apply in list order
120
+ * (later profiles compose over earlier ones, so an intersection's last profile wins its core); each reads
121
+ * the running height as its surrounding ground and the original `base` for `sample` centerline heights.
122
+ * The returned sampler is pure and deterministic. Degenerate profiles (fewer than two points, non-positive
123
+ * width or length) are skipped; with no usable profile the original `base` is returned unchanged.
124
+ * @capability path-terrain compose flatten/grade/carve/retaining path profiles onto a height sampler
125
+ */
126
+ export function withPathProfiles(base, profiles) {
127
+ const resolved = [];
128
+ for (const profile of profiles) {
129
+ const prepared = resolveProfile(profile);
130
+ if (prepared !== null)
131
+ resolved.push(prepared);
132
+ }
133
+ if (resolved.length === 0)
134
+ return base;
135
+ return (x, z) => {
136
+ let height = base(x, z);
137
+ for (const profile of resolved) {
138
+ height = applyProfileAt(profile, x, z, height, base);
139
+ }
140
+ return height;
141
+ };
142
+ }
@@ -0,0 +1,81 @@
1
+ import { type AssetSpace } from "../scene/assetSpace.js";
2
+ import type { PlacementCommit } from "./placementController.js";
3
+ import type { AddStructureInput, StructureVec3 } from "./placedStructureStore.js";
4
+ /** World-space point shared by structure stores and editor markers. */
5
+ export type PlaceAssetVec3 = {
6
+ x: number;
7
+ y: number;
8
+ z: number;
9
+ };
10
+ /**
11
+ * Shared place-asset verb: one resolved payload for editor `place_asset` and in-game
12
+ * build-mode commits. Convert with {@link toStructureInput} / {@link toEditorMarker}.
13
+ * @capability place-asset resolve a placement commit into a shared asset placement payload
14
+ */
15
+ export interface PlaceAssetResult {
16
+ id: string;
17
+ assetId: string;
18
+ kind: string;
19
+ label: string;
20
+ position: PlaceAssetVec3;
21
+ rotationY: number;
22
+ color: string;
23
+ meta: Readonly<Record<string, unknown>>;
24
+ }
25
+ /** Inputs to {@link resolvePlaceAsset}: asset id, pose, and optional catalog/known fields. */
26
+ export interface ResolvePlaceAssetInput {
27
+ assetId: string;
28
+ position: PlaceAssetVec3 | StructureVec3;
29
+ kind?: string;
30
+ label?: string;
31
+ rotationY?: number;
32
+ /**
33
+ * Placement heading in degrees (engine north = `0`, clockwise). When set it takes precedence over
34
+ * `rotationY`: the resolved `rotationY` runs through `space.rotation` (the asset's rotation policy)
35
+ * and `space.forwardDegrees` (canonical facing), so the catalog owns the correction instead of games.
36
+ */
37
+ headingDegrees?: number;
38
+ /** Asset-space metadata driving the heading resolution when `headingDegrees` is set. */
39
+ space?: AssetSpace;
40
+ id?: string;
41
+ color?: string;
42
+ meta?: Readonly<Record<string, unknown>>;
43
+ url?: string;
44
+ knownKind?: string;
45
+ knownLabel?: string;
46
+ knownUrl?: string;
47
+ }
48
+ /** Optional catalog/label overrides for {@link placeAssetFromCommit}. */
49
+ export interface PlaceAssetFromCommitOptions {
50
+ kind?: string;
51
+ label?: string;
52
+ id?: string;
53
+ color?: string;
54
+ meta?: Readonly<Record<string, unknown>>;
55
+ url?: string;
56
+ knownKind?: string;
57
+ knownLabel?: string;
58
+ knownUrl?: string;
59
+ }
60
+ /**
61
+ * Resolve a place-asset intent into a shared payload (editor + games, one verb).
62
+ * @capability place-asset resolve a placement commit into a shared asset placement payload
63
+ */
64
+ export declare function resolvePlaceAsset(input: ResolvePlaceAssetInput): PlaceAssetResult;
65
+ /**
66
+ * Bridge a {@link PlacementCommit} into the shared place-asset verb.
67
+ * @capability place-asset resolve a placement commit into a shared asset placement payload
68
+ */
69
+ export declare function placeAssetFromCommit(commit: PlacementCommit, assetId: string, options?: PlaceAssetFromCommitOptions): PlaceAssetResult;
70
+ /** Game-state form: feed {@link createPlacedStructureStore}.add. */
71
+ export declare function toStructureInput(result: PlaceAssetResult): AddStructureInput;
72
+ /** Scene-document form: feed editor `addMarker` / `place_asset` path. */
73
+ export declare function toEditorMarker(result: PlaceAssetResult): {
74
+ id: string;
75
+ kind: string;
76
+ position: PlaceAssetVec3;
77
+ rotationY: number;
78
+ label: string;
79
+ color: string;
80
+ meta: Record<string, unknown>;
81
+ };
@@ -0,0 +1,77 @@
1
+ import { applyRotationPolicy, resolveFacingRotationY } from "../scene/assetSpace.js";
2
+ function normalizePosition(position) {
3
+ if (typeof position.x === "number") {
4
+ const p = position;
5
+ return { x: p.x, y: p.y, z: p.z };
6
+ }
7
+ const t = position;
8
+ return { x: t[0], y: t[1], z: t[2] };
9
+ }
10
+ function placementId(assetId, explicit) {
11
+ if (explicit !== undefined && explicit.length > 0)
12
+ return explicit;
13
+ return `placed_${assetId}_${Date.now().toString(36)}`;
14
+ }
15
+ /**
16
+ * Resolve a place-asset intent into a shared payload (editor + games, one verb).
17
+ * @capability place-asset resolve a placement commit into a shared asset placement payload
18
+ */
19
+ export function resolvePlaceAsset(input) {
20
+ const position = normalizePosition(input.position);
21
+ const assetId = input.assetId;
22
+ const kind = input.kind ?? input.knownKind ?? "prop";
23
+ const label = input.label ?? input.knownLabel ?? assetId;
24
+ const url = input.url ?? input.knownUrl;
25
+ const meta = {
26
+ assetId,
27
+ ...(url === undefined ? {} : { url }),
28
+ ...(input.meta ?? {}),
29
+ };
30
+ const rotationY = input.headingDegrees === undefined
31
+ ? (input.rotationY ?? 0)
32
+ : resolveFacingRotationY(applyRotationPolicy(input.headingDegrees, input.space?.rotation), input.space);
33
+ return {
34
+ id: placementId(assetId, input.id),
35
+ assetId,
36
+ kind,
37
+ label,
38
+ position,
39
+ rotationY,
40
+ color: input.color ?? "#e2e8f0",
41
+ meta,
42
+ };
43
+ }
44
+ /**
45
+ * Bridge a {@link PlacementCommit} into the shared place-asset verb.
46
+ * @capability place-asset resolve a placement commit into a shared asset placement payload
47
+ */
48
+ export function placeAssetFromCommit(commit, assetId, options = {}) {
49
+ return resolvePlaceAsset({
50
+ assetId,
51
+ position: [commit.center[0], commit.y, commit.center[1]],
52
+ rotationY: commit.rotationY,
53
+ ...options,
54
+ });
55
+ }
56
+ /** Game-state form: feed {@link createPlacedStructureStore}.add. */
57
+ export function toStructureInput(result) {
58
+ return {
59
+ id: result.id,
60
+ catalogId: result.assetId,
61
+ position: [result.position.x, result.position.y, result.position.z],
62
+ rotationY: result.rotationY,
63
+ data: { ...result.meta, kind: result.kind, label: result.label, color: result.color },
64
+ };
65
+ }
66
+ /** Scene-document form: feed editor `addMarker` / `place_asset` path. */
67
+ export function toEditorMarker(result) {
68
+ return {
69
+ id: result.id,
70
+ kind: result.kind,
71
+ position: result.position,
72
+ rotationY: result.rotationY,
73
+ label: result.label,
74
+ color: result.color,
75
+ meta: { ...result.meta },
76
+ };
77
+ }
@@ -26,5 +26,9 @@ export type PlacementResult = {
26
26
  obstacle: PlacementObstacle;
27
27
  index: number;
28
28
  };
29
+ /**
30
+ * Footprint validity: bounds + obstacle overlap after optional grid snap.
31
+ * @capability placement-math grid/surface footprint validity for build mode
32
+ */
29
33
  export declare function validatePlacement(request: PlacementRequest, rules?: PlacementRules): PlacementResult;
30
34
  export declare function footprintObstacle(request: PlacementRequest, id?: string): PlacementObstacle;
@@ -1,4 +1,8 @@
1
1
  import { aabbContains, aabbOverlap, footprintAabb, snapToGrid, } from "./geometry.js";
2
+ /**
3
+ * Footprint validity: bounds + obstacle overlap after optional grid snap.
4
+ * @capability placement-math grid/surface footprint validity for build mode
5
+ */
2
6
  export function validatePlacement(request, rules = {}) {
3
7
  const center = rules.snap === undefined ? request.center : snapToGrid(request.center, rules.snap);
4
8
  const aabb = footprintAabb(center, request.footprint, request.quarterTurns ?? 0);
@@ -65,5 +65,11 @@ export interface PlacementController {
65
65
  commit(): PlacementCommit | null;
66
66
  reset(): void;
67
67
  }
68
+ /** Maps 0–3 quarter turns onto radians for ghost/commit rotation. */
68
69
  export declare function quarterTurnsToRotationY(quarterTurns: number): number;
70
+ /**
71
+ * Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit.
72
+ * Pair with `@jgengine/shell/structures` `PlacementGhost` and {@link placeAssetFromCommit}.
73
+ * @capability placement-controller interactive build-mode ghost preview and commit
74
+ */
69
75
  export declare function createPlacementController(config: PlacementControllerConfig): PlacementController;
@@ -5,10 +5,16 @@ const DEFAULT_SLOT_RADIUS = 1.5;
5
5
  function distanceVec3(a, b) {
6
6
  return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
7
7
  }
8
+ /** Maps 0–3 quarter turns onto radians for ghost/commit rotation. */
8
9
  export function quarterTurnsToRotationY(quarterTurns) {
9
10
  const turns = ((quarterTurns % 4) + 4) % 4;
10
11
  return turns === 0 ? 0 : -turns * (Math.PI / 2);
11
12
  }
13
+ /**
14
+ * Headless placement ghost: hover → valid/invalid preview, rotate, grid/free/surface snap, commit.
15
+ * Pair with `@jgengine/shell/structures` `PlacementGhost` and {@link placeAssetFromCommit}.
16
+ * @capability placement-controller interactive build-mode ghost preview and commit
17
+ */
12
18
  export function createPlacementController(config) {
13
19
  let footprint = config.footprint;
14
20
  let rules = config.rules ?? {};
@@ -0,0 +1,34 @@
1
+ import type { Vec2 } from "./geometry.js";
2
+ /** A polyline prepared for repeated distance/fraction sampling, with cumulative arc-length precomputed. */
3
+ export interface Polyline {
4
+ readonly points: readonly Vec2[];
5
+ readonly cumulative: readonly number[];
6
+ readonly length: number;
7
+ }
8
+ /** The closest point on a polyline to a query point, with where it lands along the line. */
9
+ export interface PolylineHit {
10
+ readonly point: Vec2;
11
+ readonly distanceAlong: number;
12
+ readonly segment: number;
13
+ readonly lateral: number;
14
+ }
15
+ /** Prepare a polyline from ordered points, computing cumulative arc-length once for O(log n) sampling.
16
+ * @internal
17
+ */
18
+ export declare function polyline(points: readonly Vec2[]): Polyline;
19
+ /** Point at an absolute arc-length distance along the line, clamped to the endpoints.
20
+ * @internal
21
+ */
22
+ export declare function pointAtDistance(line: Polyline, dist: number): Vec2;
23
+ /** Point at a `[0, 1]` fraction of the line's total length.
24
+ * @internal
25
+ */
26
+ export declare function pointAtFraction(line: Polyline, fraction: number): Vec2;
27
+ /** Unit tangent (direction of travel) at an absolute distance along the line.
28
+ * @internal
29
+ */
30
+ export declare function tangentAtDistance(line: Polyline, dist: number): Vec2;
31
+ /** Closest point on the line to `query`, reporting arc-length position, segment index, and signed lateral offset.
32
+ * @internal
33
+ */
34
+ export declare function closestPoint(line: Polyline, query: Vec2): PolylineHit;
@@ -0,0 +1,81 @@
1
+ import { distance, lerp, normalize, perp, sub } from "./vec2.js";
2
+ /** Prepare a polyline from ordered points, computing cumulative arc-length once for O(log n) sampling.
3
+ * @internal
4
+ */
5
+ export function polyline(points) {
6
+ const cumulative = [0];
7
+ for (let i = 1; i < points.length; i += 1) {
8
+ cumulative.push(cumulative[i - 1] + distance(points[i - 1], points[i]));
9
+ }
10
+ return { points, cumulative, length: cumulative[cumulative.length - 1] ?? 0 };
11
+ }
12
+ function segmentAt(line, dist) {
13
+ const { cumulative } = line;
14
+ const clamped = dist < 0 ? 0 : dist > line.length ? line.length : dist;
15
+ let lo = 1;
16
+ let hi = cumulative.length - 1;
17
+ while (lo < hi) {
18
+ const mid = (lo + hi) >> 1;
19
+ if (cumulative[mid] < clamped)
20
+ lo = mid + 1;
21
+ else
22
+ hi = mid;
23
+ }
24
+ const start = cumulative[lo - 1];
25
+ const span = cumulative[lo] - start;
26
+ return { index: lo, t: span <= 0 ? 0 : (clamped - start) / span };
27
+ }
28
+ /** Point at an absolute arc-length distance along the line, clamped to the endpoints.
29
+ * @internal
30
+ */
31
+ export function pointAtDistance(line, dist) {
32
+ if (line.points.length === 0)
33
+ return [0, 0];
34
+ if (line.points.length === 1)
35
+ return line.points[0];
36
+ const { index, t } = segmentAt(line, dist);
37
+ return lerp(line.points[index - 1], line.points[index], t);
38
+ }
39
+ /** Point at a `[0, 1]` fraction of the line's total length.
40
+ * @internal
41
+ */
42
+ export function pointAtFraction(line, fraction) {
43
+ return pointAtDistance(line, fraction * line.length);
44
+ }
45
+ /** Unit tangent (direction of travel) at an absolute distance along the line.
46
+ * @internal
47
+ */
48
+ export function tangentAtDistance(line, dist) {
49
+ if (line.points.length < 2)
50
+ return [0, 1];
51
+ const { index } = segmentAt(line, dist);
52
+ return normalize(sub(line.points[index], line.points[index - 1]));
53
+ }
54
+ /** Closest point on the line to `query`, reporting arc-length position, segment index, and signed lateral offset.
55
+ * @internal
56
+ */
57
+ export function closestPoint(line, query) {
58
+ const { points, cumulative } = line;
59
+ if (points.length === 0)
60
+ return { point: [0, 0], distanceAlong: 0, segment: 0, lateral: 0 };
61
+ if (points.length === 1) {
62
+ return { point: points[0], distanceAlong: 0, segment: 0, lateral: distance(points[0], query) };
63
+ }
64
+ let best = { point: points[0], distanceAlong: 0, segment: 0, lateral: Infinity };
65
+ for (let i = 1; i < points.length; i += 1) {
66
+ const a = points[i - 1];
67
+ const b = points[i];
68
+ const abx = b[0] - a[0];
69
+ const aby = b[1] - a[1];
70
+ const segLenSq = abx * abx + aby * aby;
71
+ const t = segLenSq <= 0 ? 0 : Math.max(0, Math.min(1, ((query[0] - a[0]) * abx + (query[1] - a[1]) * aby) / segLenSq));
72
+ const point = [a[0] + abx * t, a[1] + aby * t];
73
+ const lateral = distance(point, query);
74
+ if (lateral < best.lateral) {
75
+ const along = cumulative[i - 1] + t * Math.sqrt(segLenSq);
76
+ const side = Math.sign(perp(normalize([abx, aby]))[0] * (query[0] - point[0]) + perp(normalize([abx, aby]))[1] * (query[1] - point[1]));
77
+ best = { point, distanceAlong: along, segment: i - 1, lateral: lateral * (side === 0 ? 1 : side) };
78
+ }
79
+ }
80
+ return best;
81
+ }
@@ -7,6 +7,14 @@ export interface RoadRibbon {
7
7
  /** Triangle indices into `positions`. */
8
8
  indices: Uint32Array;
9
9
  }
10
+ /**
11
+ * Fillets sharp corners of a centerline into short arcs so a ribbon built from it reads as a smooth
12
+ * road instead of overlapping/notching rectangles at each bend. Each interior vertex is replaced by a
13
+ * quadratic-bezier arc of `radius` (clamped to half the shorter adjacent segment) sampled at
14
+ * `cornerSegments` steps; endpoints and near-straight vertices pass through unchanged.
15
+ * @internal — the corner-smoothing behind `<AuthoredPaths>`; games get it for free through the render.
16
+ */
17
+ export declare function roundPathCorners(points: readonly RoadPoint[], radius: number, cornerSegments?: number): RoadPoint[];
10
18
  /** Options for {@link buildRoadRibbon}. */
11
19
  export interface RoadRibbonOptions {
12
20
  /** Lift above the sampled ground so the ribbon never z-fights the terrain. Default 0.08. */
@@ -1,3 +1,41 @@
1
+ /**
2
+ * Fillets sharp corners of a centerline into short arcs so a ribbon built from it reads as a smooth
3
+ * road instead of overlapping/notching rectangles at each bend. Each interior vertex is replaced by a
4
+ * quadratic-bezier arc of `radius` (clamped to half the shorter adjacent segment) sampled at
5
+ * `cornerSegments` steps; endpoints and near-straight vertices pass through unchanged.
6
+ * @internal — the corner-smoothing behind `<AuthoredPaths>`; games get it for free through the render.
7
+ */
8
+ export function roundPathCorners(points, radius, cornerSegments = 5) {
9
+ if (points.length < 3 || radius <= 0)
10
+ return points.map((point) => [point[0], point[1]]);
11
+ const out = [[points[0][0], points[0][1]]];
12
+ for (let i = 1; i < points.length - 1; i += 1) {
13
+ const a = points[i - 1];
14
+ const v = points[i];
15
+ const b = points[i + 1];
16
+ const ax = a[0] - v[0];
17
+ const az = a[1] - v[1];
18
+ const bx = b[0] - v[0];
19
+ const bz = b[1] - v[1];
20
+ const la = Math.hypot(ax, az) || 1;
21
+ const lb = Math.hypot(bx, bz) || 1;
22
+ const r = Math.min(radius, la / 2, lb / 2);
23
+ const p0 = [v[0] + (ax / la) * r, v[1] + (az / la) * r];
24
+ const p1 = [v[0] + (bx / lb) * r, v[1] + (bz / lb) * r];
25
+ out.push(p0);
26
+ for (let s = 1; s < cornerSegments; s += 1) {
27
+ const t = s / cornerSegments;
28
+ const u = 1 - t;
29
+ out.push([
30
+ u * u * p0[0] + 2 * u * t * v[0] + t * t * p1[0],
31
+ u * u * p0[1] + 2 * u * t * v[1] + t * t * p1[1],
32
+ ]);
33
+ }
34
+ out.push(p1);
35
+ }
36
+ out.push([points[points.length - 1][0], points[points.length - 1][1]]);
37
+ return out;
38
+ }
1
39
  function subdividePath(path, maxLength) {
2
40
  const out = [];
3
41
  for (let i = 0; i < path.length - 1; i += 1) {