@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,60 @@
1
+ import type { EntityRole, EntityUpdatePatch, SpawnPositionInput } from "./entityStore.js";
2
+ /**
3
+ * One sim body's per-tick pose, as the game's simulation computed it — the shape a game already builds
4
+ * to hand to `setPose`, just declared instead of imperatively pushed. `kind` is the entity catalog name
5
+ * used only the first time `id` is seen (a respawn/despawn never re-reads it).
6
+ */
7
+ export interface BodySnapshot {
8
+ id: string;
9
+ kind: string;
10
+ position: SpawnPositionInput;
11
+ rotationY?: number;
12
+ rotationX?: number;
13
+ rotationZ?: number;
14
+ role?: EntityRole;
15
+ meta?: unknown;
16
+ }
17
+ /** The options a {@link BodyBindDeps.spawn} call receives for an id seen for the first time. */
18
+ export interface BodyBindSpawnInput {
19
+ id: string;
20
+ position: SpawnPositionInput;
21
+ rotationY?: number;
22
+ rotationX?: number;
23
+ rotationZ?: number;
24
+ role?: EntityRole;
25
+ meta?: unknown;
26
+ }
27
+ /** The pose a {@link BodyBindDeps.setPose} call receives for an id already bound. */
28
+ export interface BodyBindPose {
29
+ position: SpawnPositionInput;
30
+ rotationY?: number;
31
+ rotationX?: number;
32
+ rotationZ?: number;
33
+ dt?: number;
34
+ }
35
+ /** Structural entity-store seam a {@link BodyBind} mirrors onto — satisfied by `ctx.scene.entity` itself. */
36
+ export interface BodyBindDeps {
37
+ has(id: string): boolean;
38
+ spawn(kind: string, options: BodyBindSpawnInput): string;
39
+ despawn(id: string): boolean;
40
+ setPose(id: string, pose: BodyBindPose): boolean;
41
+ update(id: string, patch: EntityUpdatePatch): boolean;
42
+ }
43
+ /** The lazily-keyed handle `ctx.scene.entity.bind(key)` returns. */
44
+ export interface BodyBind {
45
+ /**
46
+ * Mirror this tick's `bodies` onto scene entities: spawns an id seen for the first time (catalog
47
+ * `kind` from its snapshot), poses one already bound, despawns one this bind previously spawned that
48
+ * is now absent from `bodies`. `dt` (when given) derives `velocity` the same as a direct `setPose`.
49
+ */
50
+ sync(bodies: Iterable<BodySnapshot>, dt?: number): void;
51
+ /** Ids this bind currently considers itself responsible for (spawned by, and not yet despawned by, `sync`). */
52
+ boundIds(): ReadonlySet<string>;
53
+ }
54
+ /**
55
+ * Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
56
+ * despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
57
+ *
58
+ * @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
59
+ */
60
+ export declare function createBodyBind(deps: BodyBindDeps): BodyBind;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
3
+ * despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
4
+ *
5
+ * @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
6
+ */
7
+ export function createBodyBind(deps) {
8
+ const bound = new Set();
9
+ return {
10
+ sync(bodies, dt) {
11
+ const seen = new Set();
12
+ for (const body of bodies) {
13
+ seen.add(body.id);
14
+ const alreadyBound = bound.has(body.id);
15
+ if (!alreadyBound && !deps.has(body.id)) {
16
+ deps.spawn(body.kind, {
17
+ id: body.id,
18
+ position: body.position,
19
+ rotationY: body.rotationY,
20
+ rotationX: body.rotationX,
21
+ rotationZ: body.rotationZ,
22
+ role: body.role,
23
+ meta: body.meta,
24
+ });
25
+ }
26
+ else {
27
+ deps.setPose(body.id, {
28
+ position: body.position,
29
+ rotationY: body.rotationY,
30
+ rotationX: body.rotationX,
31
+ rotationZ: body.rotationZ,
32
+ ...(dt === undefined ? {} : { dt }),
33
+ });
34
+ if (body.role !== undefined || body.meta !== undefined) {
35
+ deps.update(body.id, { role: body.role, meta: body.meta });
36
+ }
37
+ }
38
+ bound.add(body.id);
39
+ }
40
+ for (const id of bound) {
41
+ if (seen.has(id))
42
+ continue;
43
+ deps.despawn(id);
44
+ bound.delete(id);
45
+ }
46
+ },
47
+ boundIds() {
48
+ return bound;
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,5 @@
1
+ import { type ParamSchema } from "./sceneKinds.js";
2
+ /** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
3
+ export declare const SCATTER_SCHEMA: ParamSchema;
4
+ /** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
5
+ export declare function registerBuiltinSceneKinds(): void;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Registers the engine's built-in *environment* scene kinds against the {@link registerSceneKind}
3
+ * seam: `scatter` (the proof adopter — its inspector, `+ Add` entry, and parse now come from the
4
+ * registry), `water` (a reusable parametric water surface), `grass_field` (GPU vertex-wind grass), and
5
+ * `soil` (crack/moss ground-variation patch). These are genre-agnostic engine primitives, like terrain.
6
+ * Domain studios (poles, bookcases, …) are NOT built in — they register themselves from example/game
7
+ * code via the same public seam, needing zero engine edits (see `examples/studios`). Call
8
+ * {@link registerBuiltinSceneKinds} once at startup (idempotent).
9
+ */
10
+ import { SCATTER_PATH_KIND } from "../world/scatterRegion.js";
11
+ import { registerWaterKind } from "../world/waterKind.js";
12
+ import { registerGrassKind } from "../world/grassKind.js";
13
+ import { registerSoilKind } from "../world/soilKind.js";
14
+ import { registerBuildingGenerator } from "../world/buildingGenerator.js";
15
+ import { registerSceneKind } from "./sceneKinds.js";
16
+ /** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
17
+ export const SCATTER_SCHEMA = {
18
+ fields: [
19
+ { type: "range", key: "density", label: "density", min: 0, max: 2, step: 0.01, default: 0.15, unit: "/m²" },
20
+ { type: "number", key: "minSpacing", label: "spacing", step: 0.25, default: 1.5, min: 0 },
21
+ { type: "number", key: "minScale", label: "min scale", step: 0.05, default: 0.8, min: 0 },
22
+ { type: "number", key: "maxScale", label: "max scale", step: 0.05, default: 1.3, min: 0 },
23
+ { type: "number", key: "maxSlope", label: "max slope", step: 0.05, default: 0, min: 0 },
24
+ { type: "number", key: "edgeFalloff", label: "edge fade", step: 0.5, default: 0, min: 0 },
25
+ { type: "bool", key: "alignToNormal", label: "align to slope", default: false },
26
+ { type: "bool", key: "autoAvoid", label: "auto-avoid gameplay spots", default: true },
27
+ { type: "weightedList", key: "palette", label: "species (weighted)", itemLabel: "grass / tree id", default: [{ item: "grass", weight: 1 }] },
28
+ { type: "seed", key: "seed", label: "seed", default: "" },
29
+ ],
30
+ };
31
+ let registered = false;
32
+ /** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
33
+ export function registerBuiltinSceneKinds() {
34
+ if (registered)
35
+ return;
36
+ registered = true;
37
+ registerSceneKind({
38
+ kind: SCATTER_PATH_KIND,
39
+ target: "path",
40
+ label: "Foliage / scatter",
41
+ pathShape: "area",
42
+ addCategory: "Studios",
43
+ accent: "#34d399",
44
+ schema: SCATTER_SCHEMA,
45
+ note: (object, params) => {
46
+ const points = object.points ?? [];
47
+ if (points.length < 3)
48
+ return "Draw at least 3 points to close the region.";
49
+ let area = 0;
50
+ for (let i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
51
+ area += points[j].x * points[i].z - points[i].x * points[j].z;
52
+ }
53
+ area = Math.abs(area) / 2;
54
+ const density = typeof params["density"] === "number" ? params["density"] : 0;
55
+ return `≈ ${Math.floor(area * density).toLocaleString()} placements over ${Math.round(area).toLocaleString()} m²`;
56
+ },
57
+ });
58
+ registerWaterKind();
59
+ registerGrassKind();
60
+ registerSoilKind();
61
+ registerBuildingGenerator();
62
+ }
@@ -37,13 +37,25 @@ export declare const DEFAULT_OBJECT_HALF_EXTENTS: EntityPosition;
37
37
  export declare const DEFAULT_ENTITY_BODY_HALF_EXTENTS: EntityPosition;
38
38
  /** Entity-local center of the default body hitbox (half its height above the feet). */
39
39
  export declare const DEFAULT_ENTITY_BODY_OFFSET: EntityPosition;
40
+ /** @internal */
40
41
  export declare function defaultEntityColliders(): EntityColliderSet;
42
+ /** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
43
+ * @internal
44
+ */
45
+ export declare function scaledEntityColliders(scale: number): EntityColliderSet;
46
+ /** @internal */
41
47
  export declare function defaultObjectColliders(halfExtents?: EntityPosition): EntityColliderSet;
42
- /** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh). */
48
+ /** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
49
+ * @internal
50
+ */
43
51
  export declare function scaledObjectColliders(scale: readonly [number, number, number]): EntityColliderSet;
52
+ /** @internal */
44
53
  export declare function resolveColliders(set: EntityColliderSet | null | undefined): ResolvedCollider[];
54
+ /** @internal */
45
55
  export declare function worldOffset(local: EntityPosition | undefined, position: EntityPosition, rotationY: number): EntityPosition;
56
+ /** @internal */
46
57
  export declare function colliderWorldCenter(collider: ResolvedCollider, position: EntityPosition, rotationY: number): EntityPosition;
58
+ /** @internal */
47
59
  export declare function colliderBounds(collider: ResolvedCollider, position: EntityPosition, rotationY: number): {
48
60
  min: EntityPosition;
49
61
  max: EntityPosition;
@@ -4,6 +4,7 @@ export const DEFAULT_OBJECT_HALF_EXTENTS = [0.5, 0.5, 0.5];
4
4
  export const DEFAULT_ENTITY_BODY_HALF_EXTENTS = [0.35, 0.9, 0.35];
5
5
  /** Entity-local center of the default body hitbox (half its height above the feet). */
6
6
  export const DEFAULT_ENTITY_BODY_OFFSET = [0, 0.9, 0];
7
+ /** @internal */
7
8
  export function defaultEntityColliders() {
8
9
  return {
9
10
  hitboxes: [
@@ -21,6 +22,35 @@ export function defaultEntityColliders() {
21
22
  ],
22
23
  };
23
24
  }
25
+ /** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
26
+ * @internal
27
+ */
28
+ export function scaledEntityColliders(scale) {
29
+ return {
30
+ hitboxes: [
31
+ {
32
+ name: "body",
33
+ purpose: "damage",
34
+ shape: {
35
+ kind: "aabb",
36
+ halfExtents: [
37
+ DEFAULT_ENTITY_BODY_HALF_EXTENTS[0] * scale,
38
+ DEFAULT_ENTITY_BODY_HALF_EXTENTS[1] * scale,
39
+ DEFAULT_ENTITY_BODY_HALF_EXTENTS[2] * scale,
40
+ ],
41
+ offset: [
42
+ DEFAULT_ENTITY_BODY_OFFSET[0] * scale,
43
+ DEFAULT_ENTITY_BODY_OFFSET[1] * scale,
44
+ DEFAULT_ENTITY_BODY_OFFSET[2] * scale,
45
+ ],
46
+ },
47
+ damageEligible: true,
48
+ blocks: false,
49
+ },
50
+ ],
51
+ };
52
+ }
53
+ /** @internal */
24
54
  export function defaultObjectColliders(halfExtents = DEFAULT_OBJECT_HALF_EXTENTS) {
25
55
  return {
26
56
  body: {
@@ -32,7 +62,9 @@ export function defaultObjectColliders(halfExtents = DEFAULT_OBJECT_HALF_EXTENTS
32
62
  },
33
63
  };
34
64
  }
35
- /** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh). */
65
+ /** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
66
+ * @internal
67
+ */
36
68
  export function scaledObjectColliders(scale) {
37
69
  return {
38
70
  body: {
@@ -48,6 +80,7 @@ export function scaledObjectColliders(scale) {
48
80
  },
49
81
  };
50
82
  }
83
+ /** @internal */
51
84
  export function resolveColliders(set) {
52
85
  if (set === null || set === undefined)
53
86
  return [];
@@ -71,6 +104,7 @@ function resolveOne(def) {
71
104
  blocks,
72
105
  };
73
106
  }
107
+ /** @internal */
74
108
  export function worldOffset(local, position, rotationY) {
75
109
  if (local === undefined)
76
110
  return position;
@@ -81,9 +115,11 @@ export function worldOffset(local, position, rotationY) {
81
115
  const lz = local[2];
82
116
  return [position[0] + lx * cos + lz * sin, position[1] + ly, position[2] - lx * sin + lz * cos];
83
117
  }
118
+ /** @internal */
84
119
  export function colliderWorldCenter(collider, position, rotationY) {
85
120
  return worldOffset(collider.shape.offset, position, rotationY);
86
121
  }
122
+ /** @internal */
87
123
  export function colliderBounds(collider, position, rotationY) {
88
124
  const center = colliderWorldCenter(collider, position, rotationY);
89
125
  if (collider.shape.kind === "sphere") {
@@ -24,13 +24,21 @@ export type PoolDeltaResult = {
24
24
  status: "rejected";
25
25
  reason: string;
26
26
  };
27
+ /** @internal */
27
28
  export declare function getStatValue(map: StatValueMap, statId: string): StatValue | null;
29
+ /** @internal */
28
30
  export declare function setStatValue(map: StatValueMap, statId: string, patch: StatValuePatch): StatValueMap;
31
+ /** @internal */
29
32
  export declare function applyPoolDelta(map: StatValueMap, statId: string, amount: number): PoolDeltaResult;
33
+ /** @internal */
30
34
  export declare function seedStatValues(catalogStats: StatCatalog): StatValueMap;
31
- /** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}. */
35
+ /** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
36
+ * @internal
37
+ */
32
38
  export declare function snapshotEntityStats(store: ReadonlyMap<string, StatValueMap>): Record<string, StatValueMap>;
33
- /** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it. */
39
+ /** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
40
+ * @internal
41
+ */
34
42
  export declare function hydrateEntityStats(store: Map<string, StatValueMap>, data: Record<string, StatValueMap>): void;
35
43
  export interface EntityStatsApi {
36
44
  get(instanceId: string, statId: string): StatValue | null;
@@ -39,4 +47,5 @@ export interface EntityStatsApi {
39
47
  reason: string;
40
48
  };
41
49
  }
50
+ /** @internal */
42
51
  export declare function createEntityStatsApi(resolve: (instanceId: string) => StatValueMap | undefined): EntityStatsApi;
@@ -1,9 +1,11 @@
1
1
  function clamp(value, min, max) {
2
2
  return Math.min(max, Math.max(min, value));
3
3
  }
4
+ /** @internal */
4
5
  export function getStatValue(map, statId) {
5
6
  return map[statId] ?? null;
6
7
  }
8
+ /** @internal */
7
9
  export function setStatValue(map, statId, patch) {
8
10
  const existing = map[statId];
9
11
  const max = patch.max ?? existing?.max ?? 0;
@@ -11,6 +13,7 @@ export function setStatValue(map, statId, patch) {
11
13
  const current = clamp(patch.current ?? existing?.current ?? max, min, max);
12
14
  return { ...map, [statId]: { current, max, min } };
13
15
  }
16
+ /** @internal */
14
17
  export function applyPoolDelta(map, statId, amount) {
15
18
  const existing = map[statId];
16
19
  if (existing === undefined) {
@@ -26,6 +29,7 @@ export function applyPoolDelta(map, statId, amount) {
26
29
  hitMax: current === existing.max,
27
30
  };
28
31
  }
32
+ /** @internal */
29
33
  export function seedStatValues(catalogStats) {
30
34
  const map = {};
31
35
  for (const [statId, declaration] of Object.entries(catalogStats)) {
@@ -35,7 +39,9 @@ export function seedStatValues(catalogStats) {
35
39
  }
36
40
  return map;
37
41
  }
38
- /** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}. */
42
+ /** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
43
+ * @internal
44
+ */
39
45
  export function snapshotEntityStats(store) {
40
46
  const out = {};
41
47
  for (const [instanceId, map] of store) {
@@ -46,7 +52,9 @@ export function snapshotEntityStats(store) {
46
52
  }
47
53
  return out;
48
54
  }
49
- /** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it. */
55
+ /** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
56
+ * @internal
57
+ */
50
58
  export function hydrateEntityStats(store, data) {
51
59
  store.clear();
52
60
  for (const [instanceId, map] of Object.entries(data)) {
@@ -56,6 +64,7 @@ export function hydrateEntityStats(store, data) {
56
64
  store.set(instanceId, copy);
57
65
  }
58
66
  }
67
+ /** @internal */
59
68
  export function createEntityStatsApi(resolve) {
60
69
  return {
61
70
  get(instanceId, statId) {
@@ -22,9 +22,16 @@ export interface SceneEntity<TMeta = unknown> {
22
22
  role: EntityRole;
23
23
  movement: EntityMovement;
24
24
  behaviors: readonly BehaviorDescriptor[];
25
- /** Game-defined per-instance data set at `spawn`/`update` and carried to `renderEntity`/queries — narrow with a cast or type guard on read (#286.1); never encode state in the id/name string. */
25
+ /** Game-defined per-instance data set at `spawn`/`update` and carried to `renderEntity`/queries — narrow with {@link entityMetaOf} (or a type guard) on read (#286.1); never encode state in the id/name string. */
26
26
  meta: TMeta;
27
27
  }
28
+ /**
29
+ * Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null`
30
+ * instead of lying to the type checker.
31
+ *
32
+ * @capability entity-meta cast-free narrow of SceneEntity.meta via a type guard
33
+ */
34
+ export declare function entityMetaOf<T>(entity: SceneEntity<unknown>, isMeta: (value: unknown) => value is T): T | null;
28
35
  /** Ground speed (horizontal magnitude of velocity) in world units per second. Scale to km/h or mph in game code. */
29
36
  export declare function groundSpeed(entity: SceneEntity<unknown>): number;
30
37
  export declare function movedWhileFrozen(entity: SceneEntity<unknown>, threshold?: number): boolean;
@@ -96,8 +103,12 @@ export interface EntityStore<TMeta = unknown> {
96
103
  setPoseConstraint(id: string, constraint: PoseConstraint | null): void;
97
104
  get(id: string): SceneEntity<TMeta> | null;
98
105
  list(): readonly SceneEntity<TMeta>[];
106
+ /** Stable-identity list of live entity ids; identity changes only on spawn/despawn/hydrate, not on pose writes. Pair with {@link subscribeMembership} for membership-only React subscriptions that skip per-frame pose churn (#625). */
107
+ ids(): readonly string[];
99
108
  clear(): void;
100
109
  subscribe(listener: () => void): () => void;
110
+ /** Notified only when the entity set changes (spawn/despawn/hydrate), never on a pose or field update — the render tree re-reconciles on membership, individual markers read live poses imperatively. */
111
+ subscribeMembership(listener: () => void): () => void;
101
112
  snapshot(): readonly SceneEntity<TMeta>[];
102
113
  /**
103
114
  * Apply a `snapshot()` (e.g. from an authoritative host) to this store — the counterpart of `snapshot()`
@@ -1,4 +1,13 @@
1
1
  import { createObservableKeyedStore } from "../store/observableKeyedStore.js";
2
+ /**
3
+ * Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null`
4
+ * instead of lying to the type checker.
5
+ *
6
+ * @capability entity-meta cast-free narrow of SceneEntity.meta via a type guard
7
+ */
8
+ export function entityMetaOf(entity, isMeta) {
9
+ return isMeta(entity.meta) ? entity.meta : null;
10
+ }
2
11
  /** Ground speed (horizontal magnitude of velocity) in world units per second. Scale to km/h or mph in game code. */
3
12
  export function groundSpeed(entity) {
4
13
  return Math.hypot(entity.velocity[0], entity.velocity[2]);
@@ -167,6 +176,9 @@ export function createEntityStore() {
167
176
  list() {
168
177
  return store.arraySnapshot();
169
178
  },
179
+ ids() {
180
+ return store.keysSnapshot();
181
+ },
170
182
  clear() {
171
183
  for (const entity of store.arraySnapshot()) {
172
184
  store.delete(entity.id);
@@ -177,6 +189,9 @@ export function createEntityStore() {
177
189
  subscribe(listener) {
178
190
  return store.subscribe(listener);
179
191
  },
192
+ subscribeMembership(listener) {
193
+ return store.subscribeMembership(listener);
194
+ },
180
195
  snapshot() {
181
196
  return store.arraySnapshot();
182
197
  },
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The forward-axis convention: a generator or scene kind declares which way its "front" faces (a
3
+ * bookcase's open/book face, a building's entrance) once, as data, instead of leaving every placement
4
+ * to hand-tuned `rotationY` trial-and-error. `StudioStage`'s `faceCamera` (`@jgengine/shell/scene/
5
+ * StudioStage`) reads the declared axis to auto-orient a product shot; a placement tool can read the
6
+ * same field to face a freshly dropped asset toward the camera/path by default. `DEFAULT_FORWARD`
7
+ * (+Z) is what a generator/scene-kind gets when it omits `forward` — build your front toward it.
8
+ * @capability forward-axis declared front convention for parametric assets — auto-orient product shots
9
+ */
10
+ export declare const DEFAULT_FORWARD: readonly [number, number, number];
11
+ /**
12
+ * The yaw (radians, around Y) that rotates `forward` so it points from `origin` toward `target`, both
13
+ * XZ points. Pure — no three.js — so `StudioStage.faceCamera` and any future placement tool share one
14
+ * tested formula instead of re-deriving atan2 math per call site. Only `forward`'s X/Z components
15
+ * matter (yaw is a rotation about Y); returns 0 when `origin` and `target` coincide.
16
+ * @internal — consumed through `StudioStage`'s `faceCamera` prop, not called directly by game code.
17
+ */
18
+ export declare function yawToFace(forward: readonly [number, number, number], origin: readonly [number, number], target: readonly [number, number]): number;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The forward-axis convention: a generator or scene kind declares which way its "front" faces (a
3
+ * bookcase's open/book face, a building's entrance) once, as data, instead of leaving every placement
4
+ * to hand-tuned `rotationY` trial-and-error. `StudioStage`'s `faceCamera` (`@jgengine/shell/scene/
5
+ * StudioStage`) reads the declared axis to auto-orient a product shot; a placement tool can read the
6
+ * same field to face a freshly dropped asset toward the camera/path by default. `DEFAULT_FORWARD`
7
+ * (+Z) is what a generator/scene-kind gets when it omits `forward` — build your front toward it.
8
+ * @capability forward-axis declared front convention for parametric assets — auto-orient product shots
9
+ */
10
+ export const DEFAULT_FORWARD = [0, 0, 1];
11
+ /**
12
+ * The yaw (radians, around Y) that rotates `forward` so it points from `origin` toward `target`, both
13
+ * XZ points. Pure — no three.js — so `StudioStage.faceCamera` and any future placement tool share one
14
+ * tested formula instead of re-deriving atan2 math per call site. Only `forward`'s X/Z components
15
+ * matter (yaw is a rotation about Y); returns 0 when `origin` and `target` coincide.
16
+ * @internal — consumed through `StudioStage`'s `faceCamera` prop, not called directly by game code.
17
+ */
18
+ export function yawToFace(forward, origin, target) {
19
+ const dx = target[0] - origin[0];
20
+ const dz = target[1] - origin[1];
21
+ if (dx === 0 && dz === 0)
22
+ return 0;
23
+ const angleToTarget = Math.atan2(dx, dz);
24
+ const angleForward = Math.atan2(forward[0], forward[2]);
25
+ return angleToTarget - angleForward;
26
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Generic named-socket reader for loaded 3D models. Walks a node tree (any object with `.name`,
3
+ * `.position`, and `.children` — structurally satisfied by `THREE.Object3D`) and collects the local
4
+ * offsets of nodes whose name marks an attachment point. Genre-agnostic: wire anchors on a pylon,
5
+ * muzzle/hand mounts on a character, hardpoints on a ship, seat/decal slots on furniture — anything
6
+ * an artist tags with an empty in the GLB. Pure data (no three.js import), so it lives in core.
7
+ *
8
+ * @capability model-sockets named attachment points read from a model
9
+ */
10
+ /** Minimal shape of a model node this reader walks — structurally satisfied by `THREE.Object3D`. */
11
+ export interface ModelNode {
12
+ name: string;
13
+ position: {
14
+ x: number;
15
+ y: number;
16
+ z: number;
17
+ };
18
+ children?: readonly ModelNode[];
19
+ }
20
+ /** One resolved socket: its node name and local-space offset from the model origin. */
21
+ export interface ModelSocket {
22
+ name: string;
23
+ offset: readonly [number, number, number];
24
+ }
25
+ /** Default socket-name matcher: "socket", "wire", "attach", "anchor", "mount", "hardpoint" (any case). */
26
+ export declare const SOCKET_PATTERN: RegExp;
27
+ /**
28
+ * Depth-first collect every socket-named node's local offset, sorted by descending Y then ascending X
29
+ * so socket indices are stable across loads (top first, left-to-right). Empty when the model tags
30
+ * none — callers then fall back to computed offsets. Pass a custom `pattern` for a bespoke naming
31
+ * convention.
32
+ */
33
+ export declare function readNamedSockets(root: ModelNode, pattern?: RegExp): ModelSocket[];
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Generic named-socket reader for loaded 3D models. Walks a node tree (any object with `.name`,
3
+ * `.position`, and `.children` — structurally satisfied by `THREE.Object3D`) and collects the local
4
+ * offsets of nodes whose name marks an attachment point. Genre-agnostic: wire anchors on a pylon,
5
+ * muzzle/hand mounts on a character, hardpoints on a ship, seat/decal slots on furniture — anything
6
+ * an artist tags with an empty in the GLB. Pure data (no three.js import), so it lives in core.
7
+ *
8
+ * @capability model-sockets named attachment points read from a model
9
+ */
10
+ /** Default socket-name matcher: "socket", "wire", "attach", "anchor", "mount", "hardpoint" (any case). */
11
+ export const SOCKET_PATTERN = /socket|wire|attach|anchor|mount|hardpoint/i;
12
+ /**
13
+ * Depth-first collect every socket-named node's local offset, sorted by descending Y then ascending X
14
+ * so socket indices are stable across loads (top first, left-to-right). Empty when the model tags
15
+ * none — callers then fall back to computed offsets. Pass a custom `pattern` for a bespoke naming
16
+ * convention.
17
+ */
18
+ export function readNamedSockets(root, pattern = SOCKET_PATTERN) {
19
+ const found = [];
20
+ const walk = (node) => {
21
+ if (pattern.test(node.name))
22
+ found.push({ name: node.name, offset: [node.position.x, node.position.y, node.position.z] });
23
+ for (const child of node.children ?? [])
24
+ walk(child);
25
+ };
26
+ walk(root);
27
+ found.sort((a, b) => b.offset[1] - a.offset[1] || a.offset[0] - b.offset[0]);
28
+ return found;
29
+ }
@@ -24,6 +24,8 @@ declare function intersectAabb(origin: EntityPosition, direction: EntityPosition
24
24
  distance: number;
25
25
  normal: EntityPosition;
26
26
  } | null;
27
+ /** @internal */
27
28
  export declare function raycastObjects(source: ObjectRaycastSource, input: ObjectRaycastInput): ObjectRaycastHit | null;
29
+ /** @internal */
28
30
  export declare function raycastObjectsAll(source: ObjectRaycastSource, input: ObjectRaycastInput): ObjectRaycastHit[];
29
31
  export { intersectAabb, normalize as normalizeDirection };
@@ -102,6 +102,7 @@ function resolveCandidates(source, origin, direction, maxDistance, halfExtents)
102
102
  const bounds = raySegmentBounds(origin, direction, maxDistance, halfExtents);
103
103
  return source.inBox(bounds.min, bounds.max);
104
104
  }
105
+ /** @internal */
105
106
  export function raycastObjects(source, input) {
106
107
  const direction = normalize(input.direction);
107
108
  if (direction[0] === 0 && direction[1] === 0 && direction[2] === 0)
@@ -120,6 +121,7 @@ export function raycastObjects(source, input) {
120
121
  }
121
122
  return nearest;
122
123
  }
124
+ /** @internal */
123
125
  export function raycastObjectsAll(source, input) {
124
126
  const direction = normalize(input.direction);
125
127
  if (direction[0] === 0 && direction[1] === 0 && direction[2] === 0)
@@ -31,10 +31,14 @@ export interface ObjectStore {
31
31
  setVisual(instanceId: string, visual: ObjectVisual | undefined): boolean;
32
32
  get(instanceId: string): SceneObject | null;
33
33
  list(filter?: ObjectListFilter): readonly SceneObject[];
34
+ /** Stable-identity list of all placed object ids; identity changes only on place/remove, not on move/rotate/setVisual. Pair with {@link subscribeMembership} for membership-only React subscriptions (#625). */
35
+ ids(): readonly string[];
34
36
  at(x: number, y: number, z: number, tolerance?: number): SceneObject[];
35
37
  inBox(min: EntityPosition, max: EntityPosition): readonly SceneObject[];
36
38
  clear(): void;
37
39
  subscribe(listener: () => void): () => void;
40
+ /** Notified only when the object set changes (place/remove), never on move/rotate/setVisual — markers read live poses imperatively. */
41
+ subscribeMembership(listener: () => void): () => void;
38
42
  snapshot(): readonly SceneObject[];
39
43
  }
40
44
  export declare function createObjectStore(): ObjectStore;
@@ -112,6 +112,9 @@ export function createObjectStore() {
112
112
  return all;
113
113
  return all.filter((object) => object.parentSpace === filter.parentSpace);
114
114
  },
115
+ ids() {
116
+ return store.keysSnapshot();
117
+ },
115
118
  at(x, y, z, tolerance = 0) {
116
119
  const minCx = cellIndexOf(x - tolerance);
117
120
  const maxCx = cellIndexOf(x + tolerance);
@@ -180,6 +183,9 @@ export function createObjectStore() {
180
183
  subscribe(listener) {
181
184
  return store.subscribe(listener);
182
185
  },
186
+ subscribeMembership(listener) {
187
+ return store.subscribeMembership(listener);
188
+ },
183
189
  snapshot() {
184
190
  return store.arraySnapshot();
185
191
  },
@@ -17,6 +17,10 @@ export interface PossessionDeps {
17
17
  entities: PossessionEntities;
18
18
  events?: PossessionEvents;
19
19
  }
20
+ export interface PossessionSnapshot {
21
+ owned: Record<string, readonly string[]>;
22
+ active: Record<string, string>;
23
+ }
20
24
  export interface Possession {
21
25
  own(userId: string, entityId: string): void;
22
26
  disown(userId: string, entityId: string): void;
@@ -26,5 +30,9 @@ export interface Possession {
26
30
  possess(userId: string, entityId: string): {
27
31
  reason: string;
28
32
  } | null;
33
+ /** Snapshot every user's owned entities and active pawn for a whole-world save. */
34
+ snapshotAll(): PossessionSnapshot;
35
+ /** Restore every user's owned entities and active pawn from a {@link snapshotAll} payload. Entity roles are restored by the entity snapshot, not re-applied here. */
36
+ hydrateAll(state: PossessionSnapshot): void;
29
37
  }
30
38
  export declare function createPossession(deps: PossessionDeps): Possession;