@jgengine/core 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The generator-asset seam: register a parametric asset generator (`generate(params, seed) → parts`)
3
+ * so a slider-driven prop (a bookcase with width/shelves/book-density, a building with floors/bays)
4
+ * lives in the catalog alongside static GLBs. A placed instance stores only `{ assetId, params, seed }`
5
+ * — the geometry is re-resolved at runtime, never baked. Schema drives the inspector via #809. The
6
+ * generic seam is engine; concrete generators (building, bookcase) are adopters registered from
7
+ * game/example code — the building generator is the one engine adopter, as a proof it composes.
8
+ *
9
+ * @capability asset-generator seeded parametric geometry registered as a placeable asset
10
+ */
11
+ import { parseParams } from "./sceneKinds.js";
12
+ const generators = new Map();
13
+ /** Register a parametric asset generator. Idempotent per id (last wins); call at module load. */
14
+ export function registerAssetGenerator(definition) {
15
+ generators.set(definition.id, definition);
16
+ }
17
+ /** The registered generator for an id, or undefined. @internal */
18
+ export function getAssetGenerator(id) {
19
+ return generators.get(id);
20
+ }
21
+ /** Every registered generator, in registration order. @internal */
22
+ export function listAssetGenerators() {
23
+ return [...generators.values()];
24
+ }
25
+ /**
26
+ * Compute bounds from parts (each part is an axis-aligned box at its center) — a helper generators
27
+ * return so callers can frame/ground the asset without re-deriving it.
28
+ */
29
+ export function partsBounds(parts) {
30
+ if (parts.length === 0)
31
+ return { min: [0, 0, 0], max: [0, 0, 0] };
32
+ let minX = Infinity;
33
+ let minY = Infinity;
34
+ let minZ = Infinity;
35
+ let maxX = -Infinity;
36
+ let maxY = -Infinity;
37
+ let maxZ = -Infinity;
38
+ for (const part of parts) {
39
+ minX = Math.min(minX, part.position[0] - part.size[0] / 2);
40
+ minY = Math.min(minY, part.position[1] - part.size[1] / 2);
41
+ minZ = Math.min(minZ, part.position[2] - part.size[2] / 2);
42
+ maxX = Math.max(maxX, part.position[0] + part.size[0] / 2);
43
+ maxY = Math.max(maxY, part.position[1] + part.size[1] / 2);
44
+ maxZ = Math.max(maxZ, part.position[2] + part.size[2] / 2);
45
+ }
46
+ return { min: [minX, minY, minZ], max: [maxX, maxY, maxZ] };
47
+ }
48
+ /**
49
+ * Re-resolve a placed generator instance from its stored `meta` (`{ assetId, seed, ...params }`): look
50
+ * up the generator, parse its params off `meta` against the schema, and generate. Returns null when
51
+ * `assetId` names no registered generator. This is what a runtime renderer calls per placed instance.
52
+ * @internal
53
+ */
54
+ export function resolveGeneratorAsset(meta) {
55
+ const assetId = typeof meta?.["assetId"] === "string" ? meta["assetId"] : undefined;
56
+ if (assetId === undefined)
57
+ return null;
58
+ const generator = generators.get(assetId);
59
+ if (generator === undefined)
60
+ return null;
61
+ const seed = typeof meta?.["seed"] === "string" ? meta["seed"] : assetId;
62
+ const params = parseParams(generator.schema, meta);
63
+ return generator.generate(params, seed);
64
+ }
@@ -0,0 +1,137 @@
1
+ import type { Aabb, Footprint, Vec2 } from "../world/geometry.js";
2
+ /**
3
+ * Wrap `degrees` into `[0, 360)` — the canonical heading range every policy and conversion here works
4
+ * in. Non-finite input collapses to `0` so bad metadata never leaks a `NaN` heading downstream.
5
+ * @capability asset-heading normalize a placement heading into the engine's degree convention
6
+ */
7
+ export declare function normalizeDegrees(degrees: number): number;
8
+ /**
9
+ * Convert a compass heading (degrees, `0` = engine north, increasing clockwise) into the Three.js
10
+ * Y-rotation (radians, wrapped to `(-PI, PI]`) a renderer applies. Sign matches
11
+ * `world/placementController.quarterTurnsToRotationY`, so heading `90` equals one clockwise quarter
12
+ * turn. This is the one place degrees cross into the private radian space Three.js requires.
13
+ * @capability asset-heading turn a north-relative degree heading into a Three.js Y-rotation
14
+ */
15
+ export declare function headingToRotationY(headingDegrees: number): number;
16
+ /**
17
+ * Inverse of {@link headingToRotationY}: recover the `[0, 360)` compass heading from a Three.js
18
+ * Y-rotation. Lets a gizmo or inspector present radians as the degrees authors edit.
19
+ * @capability asset-heading read a Three.js Y-rotation back as a north-relative degree heading
20
+ */
21
+ export declare function rotationYToHeading(rotationY: number): number;
22
+ /** Bridge the legacy 0–3 quarter-turn placement model onto degrees (each turn is 90 degrees clockwise). @internal */
23
+ export declare function quarterTurnsToHeading(quarterTurns: number): number;
24
+ /**
25
+ * A per-asset/per-tool rotation constraint, authored as data instead of hardcoded in build code:
26
+ * `locked` pins every placement to one heading, `snap` quantizes to an increment (15, 45, …), and
27
+ * `free` allows any heading. Serializable — this is the shape stored on a catalog entry or a tool.
28
+ */
29
+ export type PlacementRotationPolicy = {
30
+ readonly mode: "locked";
31
+ readonly degrees?: number;
32
+ } | {
33
+ readonly mode: "snap";
34
+ readonly snapDegrees: number;
35
+ } | {
36
+ readonly mode: "free";
37
+ };
38
+ /**
39
+ * Quantize `degrees` to the nearest multiple of `increment` (both in the `[0, 360)` convention). A
40
+ * non-positive increment is treated as free rotation and only normalizes. The math behind a
41
+ * `snap`-mode {@link PlacementRotationPolicy}.
42
+ * @capability placement-rotation snap a heading to a fixed degree increment
43
+ */
44
+ export declare function snapHeading(degrees: number, increment: number): number;
45
+ /**
46
+ * Resolve a raw drag/scroll heading through a {@link PlacementRotationPolicy} into the heading a
47
+ * placement should actually commit: `locked` ignores the input for its fixed heading, `snap` quantizes,
48
+ * `free` (or an absent policy) normalizes. Deterministic — the single interpreter preview, editor
49
+ * placement, and runtime spawning share instead of each re-implementing the modes.
50
+ * @capability placement-rotation apply a rotation policy to a candidate placement heading
51
+ */
52
+ export declare function applyRotationPolicy(degrees: number, policy: PlacementRotationPolicy | undefined): number;
53
+ /**
54
+ * Where a model's pivot sits within its footprint: `center` (origin at the footprint center),
55
+ * `corner` (origin at the min-X/min-Z corner), or a normalized `{ x, z }` fraction in `[-0.5, 0.5]`.
56
+ */
57
+ export type AssetAnchor = "center" | "corner" | {
58
+ readonly x: number;
59
+ readonly z: number;
60
+ };
61
+ /**
62
+ * Catalog-level asset-space metadata: how a model is authored relative to the engine, owned by the
63
+ * catalog entry rather than re-derived per game. Every field is optional so an unmeasured asset stays
64
+ * valid; {@link resolveFacingRotationY}/{@link assetUnitScale}/{@link resolveAnchorOffset} supply the
65
+ * documented defaults.
66
+ */
67
+ export interface AssetSpace {
68
+ /** Compass heading (degrees, `0` = north) the model's front visually points at `rotationY = 0`. Default `0`. */
69
+ forwardDegrees?: number;
70
+ /** Multiply source-space lengths by this to reach engine meters (a kit's native tile size correction). Default `1`. */
71
+ unitScale?: number;
72
+ /** Authored footprint in engine meters — the grid/placement extent, independent of the raw mesh bounds. */
73
+ footprint?: Footprint;
74
+ /** Authored grid cell size in engine meters this asset snaps to. */
75
+ gridSize?: number;
76
+ /** Where the model origin sits within {@link footprint}. Default `center`. */
77
+ anchor?: AssetAnchor;
78
+ /** Optional asset-local placement bounds (XZ) a tool clamps a drop position into. */
79
+ bounds?: Aabb;
80
+ /** Default rotation constraint when this asset is placed. Absent means free rotation. */
81
+ rotation?: PlacementRotationPolicy;
82
+ }
83
+ /**
84
+ * The Three.js Y-rotation that makes a model whose front is authored at `forwardDegrees` visually point
85
+ * `headingDegrees` (engine north = `0`). This is the catalog-owned replacement for per-game corrective
86
+ * yaw: a model authored facing south (`forwardDegrees: 180`) placed toward north resolves to `Math.PI`.
87
+ * @capability asset-facing resolve a placement heading into a Three.js Y-rotation using canonical forward
88
+ */
89
+ export declare function resolveFacingRotationY(headingDegrees: number, space?: Pick<AssetSpace, "forwardDegrees">): number;
90
+ /** The effective, guarded unit scale for an asset — a finite positive `unitScale`, else `1`. @internal */
91
+ export declare function assetUnitScale(space?: Pick<AssetSpace, "unitScale">): number;
92
+ /**
93
+ * Convert a source-space length to engine meters through the asset's {@link AssetSpace.unitScale} — the
94
+ * data-owned replacement for per-game scale constants (a native ~4-unit kit tile down to a 1-unit grid).
95
+ * @capability asset-units convert a source-space length to engine meters via catalog unit scale
96
+ */
97
+ export declare function toEngineUnits(sourceValue: number, space?: Pick<AssetSpace, "unitScale">): number;
98
+ /**
99
+ * The pivot's offset from the footprint center, in engine meters, implied by {@link AssetSpace.anchor}
100
+ * and {@link AssetSpace.footprint}. `center` yields `[0, 0]`; `corner` yields the min corner; a
101
+ * normalized `{ x, z }` scales by the footprint. Subtract it to seat a footprint centered on a point.
102
+ * @capability asset-anchor resolve a model's pivot offset from its footprint center
103
+ */
104
+ export declare function resolveAnchorOffset(space?: Pick<AssetSpace, "anchor" | "footprint">): Vec2;
105
+ /**
106
+ * The axis-aligned footprint extent after rotating a rectangular {@link Footprint} by `headingDegrees`
107
+ * — footprint-aware placement: a 90-degree turn swaps width/depth, and arbitrary headings grow the
108
+ * bounding box so overlap and snap checks see the space the rotated asset truly occupies.
109
+ * @capability asset-footprint rotate a rectangular footprint into its axis-aligned extent
110
+ */
111
+ export declare function rotatedFootprint(footprint: Footprint, headingDegrees: number): Footprint;
112
+ /** One problem found by {@link validateAssetSpace}: which metadata field and why it is invalid. */
113
+ export interface AssetSpaceIssue {
114
+ field: string;
115
+ message: string;
116
+ }
117
+ /**
118
+ * Report contradictory or malformed asset-space metadata so catalog generation can reject it before it
119
+ * reaches a tool: non-finite headings, non-positive scales/sizes, inverted bounds, unknown anchors, and
120
+ * ill-formed rotation policies (a `snap` with a non-positive increment, an unknown `mode`). An empty
121
+ * array means valid. Validation lives here so tools consume resolved metadata instead of reinterpreting.
122
+ * @capability asset-space validate catalog asset-space metadata during index generation
123
+ */
124
+ export declare function validateAssetSpace(raw: unknown): AssetSpaceIssue[];
125
+ /**
126
+ * Parse an untrusted rotation policy (from a scene document or catalog JSON) into a valid
127
+ * {@link PlacementRotationPolicy}, defaulting to `free` when absent or malformed. The lenient companion
128
+ * to {@link validateAssetSpace} for the read path.
129
+ * @capability placement-rotation parse a serialized rotation policy, defaulting to free
130
+ */
131
+ export declare function parseRotationPolicy(raw: unknown): PlacementRotationPolicy;
132
+ /**
133
+ * Parse untrusted JSON into an {@link AssetSpace}, dropping malformed fields, or `undefined` when
134
+ * nothing valid remains — the round-trippable read path for serialized catalog/scene metadata.
135
+ * @capability asset-space parse serialized asset-space metadata into a validated shape
136
+ */
137
+ export declare function parseAssetSpace(raw: unknown): AssetSpace | undefined;
@@ -0,0 +1,257 @@
1
+ import { clamp } from "../math/scalar.js";
2
+ /**
3
+ * Asset-space metadata + placement rotation policy: the catalog-owned description of how a model sits
4
+ * in its source space and how a placement tool may rotate it. Games author scenes against engine north
5
+ * (heading `0` degrees, increasing clockwise) instead of transplanting per-game yaw offsets and magic
6
+ * scales; the catalog entry ({@link "scene/assetCatalog".ModelAssetRef}) is the upstream owner of the
7
+ * correction. Public APIs speak degrees; the only radians here are the private Three.js Y-rotation this
8
+ * module converts to, matching `world/placementController`'s `quarterTurnsToRotationY` sign so a
9
+ * quarter turn still equals 90 degrees clockwise. Pure and serializable — no three.js, no allocation of
10
+ * shared state — so preview, placement, and runtime spawning share one interpretation.
11
+ */
12
+ const DEG2RAD = Math.PI / 180;
13
+ const RAD2DEG = 180 / Math.PI;
14
+ const FULL_TURN = 360;
15
+ /**
16
+ * Wrap `degrees` into `[0, 360)` — the canonical heading range every policy and conversion here works
17
+ * in. Non-finite input collapses to `0` so bad metadata never leaks a `NaN` heading downstream.
18
+ * @capability asset-heading normalize a placement heading into the engine's degree convention
19
+ */
20
+ export function normalizeDegrees(degrees) {
21
+ if (!Number.isFinite(degrees))
22
+ return 0;
23
+ const wrapped = degrees % FULL_TURN;
24
+ return wrapped < 0 ? wrapped + FULL_TURN : wrapped;
25
+ }
26
+ function wrapRadians(radians) {
27
+ let r = radians % (2 * Math.PI);
28
+ if (r <= -Math.PI)
29
+ r += 2 * Math.PI;
30
+ if (r > Math.PI)
31
+ r -= 2 * Math.PI;
32
+ return r + 0; // normalize -0 to 0
33
+ }
34
+ /**
35
+ * Convert a compass heading (degrees, `0` = engine north, increasing clockwise) into the Three.js
36
+ * Y-rotation (radians, wrapped to `(-PI, PI]`) a renderer applies. Sign matches
37
+ * `world/placementController.quarterTurnsToRotationY`, so heading `90` equals one clockwise quarter
38
+ * turn. This is the one place degrees cross into the private radian space Three.js requires.
39
+ * @capability asset-heading turn a north-relative degree heading into a Three.js Y-rotation
40
+ */
41
+ export function headingToRotationY(headingDegrees) {
42
+ return wrapRadians(-normalizeDegrees(headingDegrees) * DEG2RAD);
43
+ }
44
+ /**
45
+ * Inverse of {@link headingToRotationY}: recover the `[0, 360)` compass heading from a Three.js
46
+ * Y-rotation. Lets a gizmo or inspector present radians as the degrees authors edit.
47
+ * @capability asset-heading read a Three.js Y-rotation back as a north-relative degree heading
48
+ */
49
+ export function rotationYToHeading(rotationY) {
50
+ return normalizeDegrees(-rotationY * RAD2DEG);
51
+ }
52
+ /** Bridge the legacy 0–3 quarter-turn placement model onto degrees (each turn is 90 degrees clockwise). @internal */
53
+ export function quarterTurnsToHeading(quarterTurns) {
54
+ return normalizeDegrees(Math.round(quarterTurns) * 90);
55
+ }
56
+ /**
57
+ * Quantize `degrees` to the nearest multiple of `increment` (both in the `[0, 360)` convention). A
58
+ * non-positive increment is treated as free rotation and only normalizes. The math behind a
59
+ * `snap`-mode {@link PlacementRotationPolicy}.
60
+ * @capability placement-rotation snap a heading to a fixed degree increment
61
+ */
62
+ export function snapHeading(degrees, increment) {
63
+ if (!(increment > 0))
64
+ return normalizeDegrees(degrees);
65
+ return normalizeDegrees(Math.round(normalizeDegrees(degrees) / increment) * increment);
66
+ }
67
+ /**
68
+ * Resolve a raw drag/scroll heading through a {@link PlacementRotationPolicy} into the heading a
69
+ * placement should actually commit: `locked` ignores the input for its fixed heading, `snap` quantizes,
70
+ * `free` (or an absent policy) normalizes. Deterministic — the single interpreter preview, editor
71
+ * placement, and runtime spawning share instead of each re-implementing the modes.
72
+ * @capability placement-rotation apply a rotation policy to a candidate placement heading
73
+ */
74
+ export function applyRotationPolicy(degrees, policy) {
75
+ if (policy === undefined || policy.mode === "free")
76
+ return normalizeDegrees(degrees);
77
+ if (policy.mode === "locked")
78
+ return normalizeDegrees(policy.degrees ?? 0);
79
+ return snapHeading(degrees, policy.snapDegrees);
80
+ }
81
+ /**
82
+ * The Three.js Y-rotation that makes a model whose front is authored at `forwardDegrees` visually point
83
+ * `headingDegrees` (engine north = `0`). This is the catalog-owned replacement for per-game corrective
84
+ * yaw: a model authored facing south (`forwardDegrees: 180`) placed toward north resolves to `Math.PI`.
85
+ * @capability asset-facing resolve a placement heading into a Three.js Y-rotation using canonical forward
86
+ */
87
+ export function resolveFacingRotationY(headingDegrees, space) {
88
+ return headingToRotationY(headingDegrees - (space?.forwardDegrees ?? 0));
89
+ }
90
+ /** The effective, guarded unit scale for an asset — a finite positive `unitScale`, else `1`. @internal */
91
+ export function assetUnitScale(space) {
92
+ const s = space?.unitScale;
93
+ return typeof s === "number" && Number.isFinite(s) && s > 0 ? s : 1;
94
+ }
95
+ /**
96
+ * Convert a source-space length to engine meters through the asset's {@link AssetSpace.unitScale} — the
97
+ * data-owned replacement for per-game scale constants (a native ~4-unit kit tile down to a 1-unit grid).
98
+ * @capability asset-units convert a source-space length to engine meters via catalog unit scale
99
+ */
100
+ export function toEngineUnits(sourceValue, space) {
101
+ return sourceValue * assetUnitScale(space);
102
+ }
103
+ /**
104
+ * The pivot's offset from the footprint center, in engine meters, implied by {@link AssetSpace.anchor}
105
+ * and {@link AssetSpace.footprint}. `center` yields `[0, 0]`; `corner` yields the min corner; a
106
+ * normalized `{ x, z }` scales by the footprint. Subtract it to seat a footprint centered on a point.
107
+ * @capability asset-anchor resolve a model's pivot offset from its footprint center
108
+ */
109
+ export function resolveAnchorOffset(space) {
110
+ const w = space?.footprint?.w ?? 0;
111
+ const d = space?.footprint?.d ?? 0;
112
+ const anchor = space?.anchor ?? "center";
113
+ let fx = 0;
114
+ let fz = 0;
115
+ if (anchor === "corner") {
116
+ fx = -0.5;
117
+ fz = -0.5;
118
+ }
119
+ else if (typeof anchor === "object") {
120
+ fx = clamp(anchor.x, -0.5, 0.5);
121
+ fz = clamp(anchor.z, -0.5, 0.5);
122
+ }
123
+ return [fx * w, fz * d];
124
+ }
125
+ /**
126
+ * The axis-aligned footprint extent after rotating a rectangular {@link Footprint} by `headingDegrees`
127
+ * — footprint-aware placement: a 90-degree turn swaps width/depth, and arbitrary headings grow the
128
+ * bounding box so overlap and snap checks see the space the rotated asset truly occupies.
129
+ * @capability asset-footprint rotate a rectangular footprint into its axis-aligned extent
130
+ */
131
+ export function rotatedFootprint(footprint, headingDegrees) {
132
+ const rad = normalizeDegrees(headingDegrees) * DEG2RAD;
133
+ const cos = Math.abs(Math.cos(rad));
134
+ const sin = Math.abs(Math.sin(rad));
135
+ return {
136
+ w: footprint.w * cos + footprint.d * sin,
137
+ d: footprint.w * sin + footprint.d * cos,
138
+ };
139
+ }
140
+ function isRecord(value) {
141
+ return typeof value === "object" && value !== null;
142
+ }
143
+ function finitePositive(value) {
144
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
145
+ }
146
+ function validateRotationPolicy(raw) {
147
+ if (!isRecord(raw))
148
+ return [{ field: "mode", message: "expected an object" }];
149
+ if (raw.mode === "free")
150
+ return [];
151
+ if (raw.mode === "locked") {
152
+ return raw.degrees !== undefined && (typeof raw.degrees !== "number" || !Number.isFinite(raw.degrees))
153
+ ? [{ field: "degrees", message: "expected a finite number" }]
154
+ : [];
155
+ }
156
+ if (raw.mode === "snap") {
157
+ return finitePositive(raw.snapDegrees) ? [] : [{ field: "snapDegrees", message: "expected a positive number" }];
158
+ }
159
+ return [{ field: "mode", message: "expected 'locked', 'snap', or 'free'" }];
160
+ }
161
+ /**
162
+ * Report contradictory or malformed asset-space metadata so catalog generation can reject it before it
163
+ * reaches a tool: non-finite headings, non-positive scales/sizes, inverted bounds, unknown anchors, and
164
+ * ill-formed rotation policies (a `snap` with a non-positive increment, an unknown `mode`). An empty
165
+ * array means valid. Validation lives here so tools consume resolved metadata instead of reinterpreting.
166
+ * @capability asset-space validate catalog asset-space metadata during index generation
167
+ */
168
+ export function validateAssetSpace(raw) {
169
+ const issues = [];
170
+ if (!isRecord(raw)) {
171
+ issues.push({ field: "", message: "expected an object" });
172
+ return issues;
173
+ }
174
+ if (raw.forwardDegrees !== undefined && (typeof raw.forwardDegrees !== "number" || !Number.isFinite(raw.forwardDegrees))) {
175
+ issues.push({ field: "forwardDegrees", message: "expected a finite number" });
176
+ }
177
+ if (raw.unitScale !== undefined && !finitePositive(raw.unitScale)) {
178
+ issues.push({ field: "unitScale", message: "expected a positive number" });
179
+ }
180
+ if (raw.gridSize !== undefined && !finitePositive(raw.gridSize)) {
181
+ issues.push({ field: "gridSize", message: "expected a positive number" });
182
+ }
183
+ if (raw.footprint !== undefined) {
184
+ const fp = raw.footprint;
185
+ if (!isRecord(fp) || !finitePositive(fp.w) || !finitePositive(fp.d)) {
186
+ issues.push({ field: "footprint", message: "expected { w > 0, d > 0 }" });
187
+ }
188
+ }
189
+ if (raw.anchor !== undefined) {
190
+ const a = raw.anchor;
191
+ const named = a === "center" || a === "corner";
192
+ const explicit = isRecord(a) && typeof a.x === "number" && typeof a.z === "number";
193
+ if (!named && !explicit)
194
+ issues.push({ field: "anchor", message: "expected 'center', 'corner', or { x, z }" });
195
+ }
196
+ if (raw.bounds !== undefined) {
197
+ const b = raw.bounds;
198
+ if (!isRecord(b) || typeof b.minX !== "number" || typeof b.maxX !== "number" || typeof b.minZ !== "number" || typeof b.maxZ !== "number") {
199
+ issues.push({ field: "bounds", message: "expected an Aabb" });
200
+ }
201
+ else if (b.maxX < b.minX || b.maxZ < b.minZ) {
202
+ issues.push({ field: "bounds", message: "max must be >= min" });
203
+ }
204
+ }
205
+ if (raw.rotation !== undefined) {
206
+ issues.push(...validateRotationPolicy(raw.rotation).map((m) => ({ field: `rotation.${m.field}`, message: m.message })));
207
+ }
208
+ return issues;
209
+ }
210
+ /**
211
+ * Parse an untrusted rotation policy (from a scene document or catalog JSON) into a valid
212
+ * {@link PlacementRotationPolicy}, defaulting to `free` when absent or malformed. The lenient companion
213
+ * to {@link validateAssetSpace} for the read path.
214
+ * @capability placement-rotation parse a serialized rotation policy, defaulting to free
215
+ */
216
+ export function parseRotationPolicy(raw) {
217
+ if (isRecord(raw)) {
218
+ if (raw.mode === "locked") {
219
+ return typeof raw.degrees === "number" && Number.isFinite(raw.degrees)
220
+ ? { mode: "locked", degrees: normalizeDegrees(raw.degrees) }
221
+ : { mode: "locked" };
222
+ }
223
+ if (raw.mode === "snap" && finitePositive(raw.snapDegrees))
224
+ return { mode: "snap", snapDegrees: raw.snapDegrees };
225
+ }
226
+ return { mode: "free" };
227
+ }
228
+ /**
229
+ * Parse untrusted JSON into an {@link AssetSpace}, dropping malformed fields, or `undefined` when
230
+ * nothing valid remains — the round-trippable read path for serialized catalog/scene metadata.
231
+ * @capability asset-space parse serialized asset-space metadata into a validated shape
232
+ */
233
+ export function parseAssetSpace(raw) {
234
+ if (!isRecord(raw))
235
+ return undefined;
236
+ const out = {};
237
+ if (typeof raw.forwardDegrees === "number" && Number.isFinite(raw.forwardDegrees))
238
+ out.forwardDegrees = normalizeDegrees(raw.forwardDegrees);
239
+ if (finitePositive(raw.unitScale))
240
+ out.unitScale = raw.unitScale;
241
+ if (finitePositive(raw.gridSize))
242
+ out.gridSize = raw.gridSize;
243
+ if (isRecord(raw.footprint) && finitePositive(raw.footprint.w) && finitePositive(raw.footprint.d)) {
244
+ out.footprint = { w: raw.footprint.w, d: raw.footprint.d };
245
+ }
246
+ if (raw.anchor === "center" || raw.anchor === "corner")
247
+ out.anchor = raw.anchor;
248
+ else if (isRecord(raw.anchor) && typeof raw.anchor.x === "number" && typeof raw.anchor.z === "number") {
249
+ out.anchor = { x: raw.anchor.x, z: raw.anchor.z };
250
+ }
251
+ if (isRecord(raw.bounds) && typeof raw.bounds.minX === "number" && typeof raw.bounds.maxX === "number" && typeof raw.bounds.minZ === "number" && typeof raw.bounds.maxZ === "number") {
252
+ out.bounds = { minX: raw.bounds.minX, maxX: raw.bounds.maxX, minZ: raw.bounds.minZ, maxZ: raw.bounds.maxZ };
253
+ }
254
+ if (isRecord(raw.rotation))
255
+ out.rotation = parseRotationPolicy(raw.rotation);
256
+ return Object.keys(out).length === 0 ? undefined : out;
257
+ }