@jgengine/core 0.18.1 → 0.21.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 (404) hide show
  1. package/CHANGELOG.md +504 -7
  2. package/dist/ai/decisionGraph.d.ts +50 -4
  3. package/dist/ai/decisionGraph.js +159 -23
  4. package/dist/ai/flock.d.ts +1 -1
  5. package/dist/ai/flock.js +7 -4
  6. package/dist/ai/groupAssist.d.ts +10 -0
  7. package/dist/ai/groupAssist.js +11 -0
  8. package/dist/ai/pursuit.d.ts +1 -1
  9. package/dist/ai/pursuit.js +1 -1
  10. package/dist/ai/threat.d.ts +8 -0
  11. package/dist/ai/threat.js +10 -0
  12. package/dist/anim/animGraph.d.ts +43 -1
  13. package/dist/anim/animGraph.js +326 -10
  14. package/dist/anim/boneTexture.d.ts +55 -0
  15. package/dist/anim/boneTexture.js +43 -0
  16. package/dist/anim/footPlacement.d.ts +57 -0
  17. package/dist/anim/footPlacement.js +67 -0
  18. package/dist/anim/locomotionGraph.d.ts +18 -1
  19. package/dist/anim/locomotionGraph.js +42 -3
  20. package/dist/audio/audioFalloff.d.ts +6 -0
  21. package/dist/audio/doppler.d.ts +21 -0
  22. package/dist/audio/doppler.js +32 -0
  23. package/dist/audio/engineLayers.d.ts +83 -0
  24. package/dist/audio/engineLayers.js +115 -0
  25. package/dist/audio/voiceAllocator.d.ts +46 -0
  26. package/dist/audio/voiceAllocator.js +76 -0
  27. package/dist/combat/abilityKit.d.ts +20 -0
  28. package/dist/combat/abilityKit.js +41 -4
  29. package/dist/combat/death.d.ts +11 -3
  30. package/dist/combat/death.js +3 -3
  31. package/dist/combat/magazine.d.ts +9 -0
  32. package/dist/combat/magazine.js +24 -2
  33. package/dist/combat/projectiles.d.ts +94 -2
  34. package/dist/combat/projectiles.js +282 -61
  35. package/dist/combat/regenShield.d.ts +14 -0
  36. package/dist/combat/regenShield.js +23 -7
  37. package/dist/combat/shotOrigin.d.ts +6 -0
  38. package/dist/combat/shotOrigin.js +6 -0
  39. package/dist/combat/weaponFeedback.d.ts +36 -0
  40. package/dist/combat/weaponFeedback.js +42 -0
  41. package/dist/combat/weaponHandling.d.ts +161 -0
  42. package/dist/combat/weaponHandling.js +202 -0
  43. package/dist/combat/weaponPresentation.d.ts +115 -0
  44. package/dist/combat/weaponPresentation.js +96 -0
  45. package/dist/crafting/recipeCatalog.d.ts +16 -0
  46. package/dist/crafting/recipeCatalog.js +55 -0
  47. package/dist/devtools/warnOnce.d.ts +8 -0
  48. package/dist/devtools/warnOnce.js +18 -0
  49. package/dist/economy/auctionBook.d.ts +1 -1
  50. package/dist/economy/auctionBook.js +11 -1
  51. package/dist/economy/listingBook.d.ts +1 -1
  52. package/dist/economy/listingBook.js +11 -1
  53. package/dist/economy/resourceLedger.js +3 -3
  54. package/dist/economy/shopStock.js +7 -6
  55. package/dist/economy/techTree.js +7 -6
  56. package/dist/economy/unlockPoints.js +3 -6
  57. package/dist/editor/commandApply.js +89 -16
  58. package/dist/editor/commands.d.ts +38 -1
  59. package/dist/editor/commands.js +320 -3
  60. package/dist/editor/creatorStorage.d.ts +59 -0
  61. package/dist/editor/creatorStorage.js +164 -0
  62. package/dist/editor/document.d.ts +4 -0
  63. package/dist/editor/document.js +119 -18
  64. package/dist/editor/environment.js +8 -0
  65. package/dist/editor/index.d.ts +2 -0
  66. package/dist/editor/liveSync.d.ts +4 -1
  67. package/dist/editor/liveSync.js +26 -10
  68. package/dist/editor/materialAuthoring.d.ts +14 -0
  69. package/dist/editor/materialAuthoring.js +38 -0
  70. package/dist/editor/modelNodeVisibility.d.ts +11 -0
  71. package/dist/editor/modelNodeVisibility.js +29 -0
  72. package/dist/editor/movementCatalog.d.ts +90 -0
  73. package/dist/editor/movementCatalog.js +144 -0
  74. package/dist/editor/simulation.d.ts +60 -0
  75. package/dist/editor/simulation.js +202 -0
  76. package/dist/editor/staticPrefab.d.ts +17 -0
  77. package/dist/editor/staticPrefab.js +51 -0
  78. package/dist/editor/types.d.ts +15 -0
  79. package/dist/faction/reputation.d.ts +6 -0
  80. package/dist/faction/reputation.js +11 -0
  81. package/dist/game/cameraConfig.d.ts +54 -2
  82. package/dist/game/clipRoles.d.ts +2 -1
  83. package/dist/game/clipRoles.js +7 -3
  84. package/dist/game/contentValidation.d.ts +69 -0
  85. package/dist/game/contentValidation.js +118 -0
  86. package/dist/game/controlGate.d.ts +8 -0
  87. package/dist/game/controlGate.js +43 -6
  88. package/dist/game/defineGame.d.ts +32 -3
  89. package/dist/game/dialogueGraph.d.ts +20 -0
  90. package/dist/game/dialogueGraph.js +107 -0
  91. package/dist/game/events.d.ts +11 -0
  92. package/dist/game/keyValueStore.d.ts +17 -4
  93. package/dist/game/keyValueStore.js +35 -23
  94. package/dist/game/lootModifiers.d.ts +17 -0
  95. package/dist/game/lootModifiers.js +26 -0
  96. package/dist/game/lootTable.d.ts +4 -0
  97. package/dist/game/lootTable.js +16 -0
  98. package/dist/game/narrativeAuthoring.d.ts +67 -0
  99. package/dist/game/narrativeAuthoring.js +122 -0
  100. package/dist/game/playableGame.d.ts +134 -35
  101. package/dist/game/quest.d.ts +15 -0
  102. package/dist/game/quest.js +209 -63
  103. package/dist/game/questCatalog.d.ts +50 -0
  104. package/dist/game/questCatalog.js +205 -0
  105. package/dist/game/saveStore.d.ts +6 -5
  106. package/dist/game/saveStore.js +57 -57
  107. package/dist/game/systemRuntime.d.ts +2 -2
  108. package/dist/game/systemRuntime.js +84 -33
  109. package/dist/game/toasts.d.ts +8 -0
  110. package/dist/game/toasts.js +7 -0
  111. package/dist/game/vfxInstance.d.ts +9 -0
  112. package/dist/game/vfxInstance.js +12 -1
  113. package/dist/game/viewports.d.ts +43 -0
  114. package/dist/game/viewports.js +46 -0
  115. package/dist/game/worldItem.d.ts +5 -1
  116. package/dist/game/worldItem.js +0 -1
  117. package/dist/gameplay.d.ts +3 -0
  118. package/dist/gameplay.js +3 -0
  119. package/dist/input/actionBindings.d.ts +15 -1
  120. package/dist/input/actionBindings.js +14 -3
  121. package/dist/input/actionContexts.d.ts +25 -1
  122. package/dist/input/actionContexts.js +82 -25
  123. package/dist/input/axisInput.d.ts +4 -0
  124. package/dist/input/axisInput.js +4 -0
  125. package/dist/input/axisShaper.d.ts +73 -0
  126. package/dist/input/axisShaper.js +105 -0
  127. package/dist/input/gamepadModel.d.ts +36 -2
  128. package/dist/input/gamepadModel.js +69 -30
  129. package/dist/input/haptics.d.ts +50 -0
  130. package/dist/input/haptics.js +74 -0
  131. package/dist/input/inputBuffer.d.ts +40 -0
  132. package/dist/input/inputBuffer.js +59 -0
  133. package/dist/input/lookChannel.d.ts +10 -0
  134. package/dist/input/lookChannel.js +6 -0
  135. package/dist/input/pointer.d.ts +2 -0
  136. package/dist/input/pointer.js +4 -0
  137. package/dist/interaction/promptRegistry.d.ts +5 -4
  138. package/dist/interaction/promptRegistry.js +8 -2
  139. package/dist/inventory/inventoryModel.js +9 -6
  140. package/dist/inventory/shapedGrid.d.ts +48 -9
  141. package/dist/inventory/shapedGrid.js +69 -10
  142. package/dist/item/affix.d.ts +6 -0
  143. package/dist/item/affix.js +6 -0
  144. package/dist/item/durability.js +4 -0
  145. package/dist/item/itemInstanceRegistry.d.ts +32 -1
  146. package/dist/item/itemInstanceRegistry.js +111 -7
  147. package/dist/item/itemgen.d.ts +1 -1
  148. package/dist/item/itemgen.js +1 -1
  149. package/dist/item/modularItem.js +7 -1
  150. package/dist/material/appearanceSignals.d.ts +53 -0
  151. package/dist/material/appearanceSignals.js +47 -0
  152. package/dist/material/hairCards.d.ts +47 -0
  153. package/dist/material/hairCards.js +136 -0
  154. package/dist/material/materialAsset.d.ts +162 -0
  155. package/dist/material/materialAsset.js +382 -0
  156. package/dist/meta/changelog.d.ts +1 -1
  157. package/dist/meta/changelog.js +444 -1
  158. package/dist/movement/characterController.d.ts +5 -2
  159. package/dist/movement/characterController.js +50 -23
  160. package/dist/movement/freeFlight.d.ts +2 -2
  161. package/dist/movement/freeFlight.js +3 -3
  162. package/dist/movement/glideModel.d.ts +3 -0
  163. package/dist/movement/glideModel.js +6 -0
  164. package/dist/movement/grappleSwing.d.ts +2 -0
  165. package/dist/movement/grappleSwing.js +5 -1
  166. package/dist/movement/movementModel.d.ts +63 -1
  167. package/dist/movement/movementModel.js +136 -26
  168. package/dist/movement/movementProbe.d.ts +51 -0
  169. package/dist/movement/movementProbe.js +119 -0
  170. package/dist/movement/playerMovement.d.ts +48 -2
  171. package/dist/movement/playerMovement.js +493 -87
  172. package/dist/movement/poseState.d.ts +2 -0
  173. package/dist/movement/poseState.js +29 -1
  174. package/dist/movement/solidObstacles.d.ts +11 -1
  175. package/dist/movement/solidObstacles.js +48 -3
  176. package/dist/movement/terrainGrade.d.ts +13 -0
  177. package/dist/movement/terrainGrade.js +33 -0
  178. package/dist/movement/voxelController.d.ts +2 -2
  179. package/dist/movement/voxelController.js +10 -10
  180. package/dist/nav/navFromEnvironment.d.ts +9 -3
  181. package/dist/nav/navFromEnvironment.js +18 -12
  182. package/dist/nav/navGrid.d.ts +19 -1
  183. package/dist/nav/navGrid.js +26 -10
  184. package/dist/nav/navMesh.d.ts +43 -2
  185. package/dist/nav/navMesh.js +534 -128
  186. package/dist/nav/solidRoute.d.ts +50 -0
  187. package/dist/nav/solidRoute.js +144 -0
  188. package/dist/physics/aircraftDynamics.d.ts +390 -0
  189. package/dist/physics/aircraftDynamics.js +704 -0
  190. package/dist/physics/ballisticSweep.d.ts +10 -3
  191. package/dist/physics/ballisticSweep.js +53 -29
  192. package/dist/physics/boatDynamics.d.ts +116 -0
  193. package/dist/physics/boatDynamics.js +160 -0
  194. package/dist/physics/drivableVehicle.d.ts +22 -8
  195. package/dist/physics/drivableVehicle.js +4 -2
  196. package/dist/physics/flightDynamics.d.ts +21 -4
  197. package/dist/physics/flightDynamics.js +28 -5
  198. package/dist/physics/forceVolume.d.ts +41 -0
  199. package/dist/physics/forceVolume.js +88 -0
  200. package/dist/physics/handlingProbe.d.ts +249 -0
  201. package/dist/physics/handlingProbe.js +606 -0
  202. package/dist/physics/kinematicVehicle.d.ts +40 -5
  203. package/dist/physics/kinematicVehicle.js +17 -2
  204. package/dist/physics/physicsBackend.d.ts +12 -0
  205. package/dist/physics/physicsBackendConformance.js +34 -0
  206. package/dist/physics/physicsWorldBackend.d.ts +1 -0
  207. package/dist/physics/physicsWorldBackend.js +52 -3
  208. package/dist/physics/spatialGrid.d.ts +1 -1
  209. package/dist/physics/spatialGrid.js +8 -9
  210. package/dist/physics/vehicleBackendLink.d.ts +49 -0
  211. package/dist/physics/vehicleBackendLink.js +102 -0
  212. package/dist/physics/vehicleDynamics.d.ts +375 -0
  213. package/dist/physics/vehicleDynamics.js +737 -0
  214. package/dist/physics/vehicleObstacles.d.ts +3 -2
  215. package/dist/physics/vehicleObstacles.js +29 -5
  216. package/dist/physics/worldColliders.d.ts +1 -1
  217. package/dist/physics/worldColliders.js +35 -3
  218. package/dist/puzzle/cellGrid.d.ts +15 -9
  219. package/dist/puzzle/cellGrid.js +13 -9
  220. package/dist/render/lookPreset.d.ts +9 -2
  221. package/dist/render/lookPreset.js +29 -2
  222. package/dist/render/postProcessing.d.ts +30 -0
  223. package/dist/render/postProcessing.js +1 -1
  224. package/dist/runtime/cameraDirector.d.ts +54 -3
  225. package/dist/runtime/cameraDirector.js +187 -0
  226. package/dist/runtime/commandDispatch.d.ts +14 -0
  227. package/dist/runtime/commandDispatch.js +19 -0
  228. package/dist/runtime/commandInput.d.ts +37 -0
  229. package/dist/runtime/commandInput.js +58 -0
  230. package/dist/runtime/commandRunner.d.ts +27 -0
  231. package/dist/runtime/commandRunner.js +31 -3
  232. package/dist/runtime/context/combat.d.ts +12 -4
  233. package/dist/runtime/context/combat.js +179 -11
  234. package/dist/runtime/context/deathLoot.d.ts +11 -8
  235. package/dist/runtime/context/deathLoot.js +17 -16
  236. package/dist/runtime/context/scene.d.ts +2 -0
  237. package/dist/runtime/context/scene.js +13 -21
  238. package/dist/runtime/descriptors/baseline.js +34 -3
  239. package/dist/runtime/descriptors/features.d.ts +2 -1
  240. package/dist/runtime/descriptors/features.js +18 -0
  241. package/dist/runtime/gameContext.js +86 -13
  242. package/dist/runtime/gameContextTypes.d.ts +33 -3
  243. package/dist/runtime/gameRuntime.d.ts +3 -1
  244. package/dist/runtime/gameRuntime.js +4 -0
  245. package/dist/runtime/headlessRunner.d.ts +3 -1
  246. package/dist/runtime/headlessRunner.js +11 -11
  247. package/dist/runtime/hostedGameRunner.d.ts +24 -1
  248. package/dist/runtime/hostedGameRunner.js +156 -10
  249. package/dist/runtime/hostedWorldSession.d.ts +17 -5
  250. package/dist/runtime/hostedWorldSession.js +154 -16
  251. package/dist/runtime/hostedWorldStore.d.ts +2 -2
  252. package/dist/runtime/inputRecorder.d.ts +1 -1
  253. package/dist/runtime/inputRecorder.js +21 -1
  254. package/dist/runtime/inputSnapshot.d.ts +22 -4
  255. package/dist/runtime/inputSnapshot.js +41 -3
  256. package/dist/runtime/localPlayers.d.ts +73 -0
  257. package/dist/runtime/localPlayers.js +119 -0
  258. package/dist/runtime/runtimeSave.d.ts +10 -6
  259. package/dist/runtime/runtimeSave.js +11 -5
  260. package/dist/runtime/simContext.d.ts +8 -3
  261. package/dist/runtime/simContext.js +7 -3
  262. package/dist/runtime/simSnapshot.js +2 -0
  263. package/dist/runtime/transport.d.ts +9 -0
  264. package/dist/runtime/transport.js +7 -1
  265. package/dist/runtime/worldReplication.d.ts +2 -0
  266. package/dist/runtime/worldReplication.js +1 -1
  267. package/dist/scene/assetCatalog.d.ts +2 -0
  268. package/dist/scene/behaviorRuntime.d.ts +38 -7
  269. package/dist/scene/behaviorRuntime.js +293 -30
  270. package/dist/scene/behaviors.d.ts +35 -2
  271. package/dist/scene/behaviors.js +29 -0
  272. package/dist/scene/entityStore.d.ts +14 -3
  273. package/dist/scene/entityStore.js +45 -9
  274. package/dist/scene/mount.d.ts +9 -0
  275. package/dist/scene/mount.js +35 -0
  276. package/dist/scene/possession.d.ts +2 -0
  277. package/dist/scene/possession.js +21 -1
  278. package/dist/scene/sceneKinds.d.ts +9 -0
  279. package/dist/scene/sceneRaycast.d.ts +7 -0
  280. package/dist/scene/sceneRaycast.js +55 -0
  281. package/dist/scene/spatial.d.ts +20 -1
  282. package/dist/scene/spatial.js +94 -2
  283. package/dist/scene/vehicleSeat.d.ts +41 -3
  284. package/dist/scene/vehicleSeat.js +94 -3
  285. package/dist/sensor/concealment.d.ts +6 -0
  286. package/dist/sensor/concealment.js +8 -0
  287. package/dist/sensor/freezeMonitor.d.ts +6 -0
  288. package/dist/sensor/freezeMonitor.js +8 -0
  289. package/dist/sensor/perception.d.ts +11 -1
  290. package/dist/sensor/perception.js +57 -10
  291. package/dist/sensor/recordingBuffer.d.ts +3 -0
  292. package/dist/sensor/recordingBuffer.js +8 -0
  293. package/dist/session/roundState.d.ts +4 -0
  294. package/dist/session/roundState.js +11 -0
  295. package/dist/settings/frameRateLimit.d.ts +16 -0
  296. package/dist/settings/frameRateLimit.js +37 -0
  297. package/dist/settings/graphicsProfile.d.ts +2 -0
  298. package/dist/settings/graphicsProfile.js +12 -0
  299. package/dist/settings/graphicsSettings.d.ts +40 -0
  300. package/dist/settings/graphicsSettings.js +81 -0
  301. package/dist/settings/settingsModel.d.ts +9 -1
  302. package/dist/settings/settingsModel.js +10 -0
  303. package/dist/stats/accumulatorMeter.d.ts +10 -0
  304. package/dist/stats/accumulatorMeter.js +6 -0
  305. package/dist/stats/eventMeter.d.ts +10 -3
  306. package/dist/stats/eventMeter.js +6 -3
  307. package/dist/store/defineStore.d.ts +3 -1
  308. package/dist/store/defineStore.js +3 -1
  309. package/dist/store/observableKeyedStore.d.ts +1 -1
  310. package/dist/store/observableKeyedStore.js +8 -6
  311. package/dist/time/simClock.d.ts +6 -2
  312. package/dist/time/simClock.js +5 -0
  313. package/dist/vfx/feedbackMixer.d.ts +61 -0
  314. package/dist/vfx/feedbackMixer.js +106 -0
  315. package/dist/vfx/particleDirector.d.ts +58 -6
  316. package/dist/vfx/particleDirector.js +113 -22
  317. package/dist/vfx/particles.d.ts +68 -5
  318. package/dist/vfx/particles.js +284 -32
  319. package/dist/visibility/assetStreaming.d.ts +21 -3
  320. package/dist/visibility/assetStreaming.js +108 -24
  321. package/dist/visibility/settings.d.ts +8 -2
  322. package/dist/visibility/settings.js +3 -0
  323. package/dist/visibility/simulationCulling.d.ts +8 -1
  324. package/dist/visibility/simulationCulling.js +7 -0
  325. package/dist/visibility/spatialIndex.d.ts +21 -0
  326. package/dist/visibility/spatialIndex.js +16 -0
  327. package/dist/visibility/visibilitySystem.js +1 -0
  328. package/dist/work/expedition.d.ts +110 -0
  329. package/dist/work/expedition.js +195 -0
  330. package/dist/work/staffedStation.d.ts +29 -0
  331. package/dist/work/staffedStation.js +27 -0
  332. package/dist/world/authoredAnimation.d.ts +38 -0
  333. package/dist/world/authoredAnimation.js +99 -0
  334. package/dist/world/authoredObjects.d.ts +24 -4
  335. package/dist/world/authoredObjects.js +43 -16
  336. package/dist/world/authoredSimulation.d.ts +74 -0
  337. package/dist/world/authoredSimulation.js +302 -0
  338. package/dist/world/authoredSolids.d.ts +46 -0
  339. package/dist/world/authoredSolids.js +75 -0
  340. package/dist/world/authoredWeather.d.ts +120 -0
  341. package/dist/world/authoredWeather.js +314 -0
  342. package/dist/world/buildingGenerator.js +2 -2
  343. package/dist/world/buildingKit.d.ts +11 -4
  344. package/dist/world/buildingKit.js +21 -8
  345. package/dist/world/buildings.d.ts +34 -2
  346. package/dist/world/buildings.js +11 -1
  347. package/dist/world/cityKind.d.ts +7 -0
  348. package/dist/world/cityKind.js +52 -1
  349. package/dist/world/environmentForces.d.ts +21 -0
  350. package/dist/world/environmentForces.js +42 -0
  351. package/dist/world/features.d.ts +32 -5
  352. package/dist/world/features.js +6 -0
  353. package/dist/world/footprintGrid.d.ts +62 -0
  354. package/dist/world/footprintGrid.js +217 -0
  355. package/dist/world/interiors.d.ts +1 -0
  356. package/dist/world/interiors.js +5 -3
  357. package/dist/world/lod.d.ts +6 -0
  358. package/dist/world/lod.js +8 -0
  359. package/dist/world/pathTerrain.d.ts +1 -1
  360. package/dist/world/terraform.d.ts +9 -1
  361. package/dist/world/terraform.js +53 -18
  362. package/dist/world/walls.d.ts +7 -0
  363. package/dist/world/walls.js +7 -0
  364. package/dist/world/weather.d.ts +17 -0
  365. package/dist/world/weather.js +116 -20
  366. package/dist/world/worldSolids.d.ts +95 -0
  367. package/dist/world/worldSolids.js +351 -0
  368. package/dist/world.d.ts +6 -6
  369. package/dist/world.js +5 -5
  370. package/package.json +1 -1
  371. package/skills/ce-handoff/SKILL.md +2 -2
  372. package/skills/game-design/SKILL.md +2 -2
  373. package/skills/jgengine/SKILL.md +28 -6
  374. package/skills/jgengine/api.md +139 -99
  375. package/skills/jgengine/capabilities.md +28 -0
  376. package/skills/jgengine/recipes/minimal-game.md +10 -2
  377. package/skills/jgengine-combat/SKILL.md +13 -2
  378. package/skills/jgengine-combat/api.md +150 -103
  379. package/skills/jgengine-combat/capabilities.md +29 -1
  380. package/skills/jgengine-combat/recipes/portable-runtime-state.md +60 -6
  381. package/skills/jgengine-combat/recipes/portable-weapon-plumbing.md +37 -3
  382. package/skills/jgengine-combat/recipes/weapon-feel.md +50 -0
  383. package/skills/jgengine-combat/reference.md +24 -2
  384. package/skills/jgengine-gameplay/SKILL.md +63 -0
  385. package/skills/jgengine-gameplay/api.md +583 -463
  386. package/skills/jgengine-gameplay/capabilities.md +92 -0
  387. package/skills/jgengine-gameplay/recipes/device-save-status.md +46 -0
  388. package/skills/jgengine-gameplay/recipes/expeditions.md +108 -0
  389. package/skills/jgengine-gameplay/recipes/narrative-authoring.md +76 -0
  390. package/skills/jgengine-gameplay/recipes/paged-item-storage.md +101 -0
  391. package/skills/jgengine-gameplay/recipes/quest-authoring.md +63 -0
  392. package/skills/jgengine-gameplay/recipes/shaped-inventory.md +50 -0
  393. package/skills/jgengine-gameplay/reference-content-validation.md +74 -0
  394. package/skills/jgengine-gameplay/reference-systems.md +123 -0
  395. package/skills/jgengine-world/SKILL.md +25 -4
  396. package/skills/jgengine-world/api.md +1045 -655
  397. package/skills/jgengine-world/capabilities.md +246 -9
  398. package/skills/jgengine-world/recipes/character-animation.md +62 -0
  399. package/skills/jgengine-world/recipes/controls.md +48 -0
  400. package/skills/jgengine-world/recipes/flight-feel.md +76 -0
  401. package/skills/jgengine-world/recipes/npc-senses.md +55 -0
  402. package/skills/jgengine-world/recipes/vehicle-feel.md +87 -0
  403. package/skills/jgengine-world/reference.md +180 -4
  404. package/skills/jgengine-world/visibility.md +139 -0
@@ -1,11 +1,14 @@
1
1
  import type { AnimGraph } from "../anim/animGraph.js";
2
2
  import type { AudioBusDef, SoundDef } from "../audio/audioFalloff.js";
3
3
  import type { MusicTheme } from "../audio/music.js";
4
+ import type { MaterialAsset, MaterialAssignment, MaterialSurfaceParameters, MaterialTextureRole } from "../material/materialAsset.js";
4
5
  import type { EditorCatalogDefinition, EditorDocument } from "../editor/types.js";
5
6
  import type { PostProcessingConfig } from "../render/postProcessing.js";
6
7
  import type { EnvironmentSource } from "../render/environment.js";
7
8
  import type { SpriteAtlas } from "../assets/spriteAtlas.js";
8
9
  import type { LookPreset } from "../render/lookPreset.js";
10
+ import type { GamepadFeelConfig } from "../input/gamepadModel.js";
11
+ import type { LocalPlayersConfig } from "../runtime/localPlayers.js";
9
12
  import type { TouchControlsConfig } from "../input/touchScheme.js";
10
13
  import type { GameSettingsConfig } from "../settings/settingsModel.js";
11
14
  import type { GraphicsProfile } from "../settings/graphicsProfile.js";
@@ -15,6 +18,7 @@ import type { PositionedPrompt } from "../interaction/proximityPrompt.js";
15
18
  import type { ChaseCameraTuning } from "../runtime/cameraDirector.js";
16
19
  import type { CatalogEntityRole, GameContext, GameContextContent } from "../runtime/gameContext.js";
17
20
  import type { FreeFlightBindings } from "../movement/freeFlight.js";
21
+ import type { SceneEntity } from "../scene/entityStore.js";
18
22
  import type { ModelDims } from "../scene/assetCatalog.js";
19
23
  import type { PartMotionParams, PartRole } from "./partAnimation.js";
20
24
  import type { CollisionMeshData } from "../scene/collisionMesh.js";
@@ -22,14 +26,21 @@ import type { SkyEnvironmentConfig } from "../world/features.js";
22
26
  import type { VisibilityConfig } from "../visibility/config.js";
23
27
  import type { GameDefinition, GameLoop } from "./defineGame.js";
24
28
  import type { GameCameraConfig } from "./cameraConfig.js";
29
+ import type { ViewportsConfig } from "./viewports.js";
25
30
  import type { LootFilterRule } from "./lootFilter.js";
26
31
  import type { RarityStyle } from "./worldItem.js";
27
- export type { CameraFollowState, CameraKeyframe, CameraProjection, CameraRigKind, CameraShakeConfig, ChaseCameraConfig, ChaseView, CinematicCameraConfig, FirstPersonCameraConfig, GameCameraConfig, InspectionCameraConfig, InspectionZoomAnchor, LockOnCameraConfig, ObserverCameraConfig, PlayerFovConfig, RtsCameraConfig, ShoulderCameraConfig, SideScrollCameraConfig, TopDownCameraConfig, TurntableCameraConfig, } from "./cameraConfig.js";
32
+ export type { CameraFollowState, CameraKeyframe, CameraProjection, CameraRigKind, CameraWeaponView, CameraShakeConfig, ChaseCameraConfig, ChaseView, CinematicCameraConfig, FirstPersonCameraConfig, GameCameraConfig, InspectionCameraConfig, InspectionZoomAnchor, LockOnCameraConfig, ObserverCameraConfig, PlayerFovConfig, RtsCameraConfig, ShoulderCameraConfig, SideScrollCameraConfig, TopDownCameraConfig, TurntableCameraConfig, } from "./cameraConfig.js";
28
33
  export { CAMERA_FRUSTUM_DEFAULTS } from "./cameraConfig.js";
34
+ /**
35
+ * Mouse/touch pointer bindings for `defineGame({ pointer })`.
36
+ *
37
+ * @capability pointer-commands click an entity or the ground to run a command (click-to-target, click-to-move, grab loot, marquee select)
38
+ */
29
39
  export interface PointerConfig {
30
40
  /**
31
- * Left-click on open ground runs this command with `{ point, entity, object }`
32
- * (click-to-move / ground-target). Suppresses the default left-click hotbar fire.
41
+ * Left-click runs this command with `{ point, entity, object }`; `entity` is the clicked entity id or
42
+ * null, so the same command covers click-to-move, ground-target and click-to-target
43
+ * (`ctx.scene.entity.setTarget`). Suppresses the default left-click hotbar fire.
33
44
  */
34
45
  moveCommand?: string;
35
46
  /** Enable left-drag marquee + single-click box-select of entities (RTS unit command). */
@@ -111,6 +122,10 @@ export interface ModelAnimationStates {
111
122
  }
112
123
  /** Rig playback for a `ModelConfig`'s GLTF animation clips — looping idles, one-shots, and held poses. */
113
124
  export interface ModelAnimationConfig {
125
+ /** Infer defaults from the loaded rig's actual clip roles, then replace fields with explicit overrides. Requires an identifiable idle clip. */
126
+ auto?: true;
127
+ /** Playback clock: real seconds (default), or entity-bound locally accepted clock progress after speed/timescale and before calendar scale. Requires an advancing accepted-progress clock; unbound previews use real seconds. */
128
+ clock?: "real" | "game";
114
129
  /** Clip name to play; defaults to the GLB's first clip. */
115
130
  clip?: string;
116
131
  /** Loop the clip. Default true. */
@@ -142,24 +157,13 @@ export interface ModelAnimationConfig {
142
157
  /**
143
158
  * Real PBR map URLs (e.g. `buildMaterialCatalog(...).resolve(id)!.maps` from `@jgengine/assets`)
144
159
  * layered onto a model's material — the seam for texturing an otherwise-flat/untextured GLB. Any
145
- * role may be omitted to keep the model's own map.
160
+ * supported MaterialTextureRole may be omitted to keep the model's own map. Physical roles use the
161
+ * renderer's physical material; map URLs and response parameters remain caller-owned.
146
162
  */
147
- export interface ModelMaterialMaps {
148
- color?: string;
149
- normal?: string;
150
- roughness?: string;
151
- ao?: string;
152
- metalness?: string;
153
- emissive?: string;
154
- height?: string;
163
+ export interface ModelMaterialMaps extends Partial<Record<MaterialTextureRole, string>> {
155
164
  }
156
165
  /** Per-entity PBR material override (#151.3) applied to every standard or physical material in the model's cloned scene graph. */
157
- export interface ModelMaterialOverride {
158
- color?: string;
159
- metalness?: number;
160
- roughness?: number;
161
- emissive?: string;
162
- emissiveIntensity?: number;
166
+ export interface ModelMaterialOverride extends MaterialSurfaceParameters {
163
167
  /** Real PBR texture maps applied over the model's material — see {@link ModelMaterialMaps}. */
164
168
  maps?: ModelMaterialMaps;
165
169
  /**
@@ -225,6 +229,12 @@ export interface ModelConfig {
225
229
  collisionMesh?: CollisionMeshData;
226
230
  /** Per-entity PBR tint/finish override (#151.3); cloned onto each `MeshStandardMaterial` in the model so shared GLTF caches stay untouched. */
227
231
  material?: ModelMaterialOverride;
232
+ /** Reusable authored surfaces available to this model's named slot assignments. */
233
+ materialAssets?: readonly MaterialAsset[];
234
+ /** Sparse per-slot assignments; unselected imported materials keep their original appearance. */
235
+ materialAssignments?: readonly MaterialAssignment[];
236
+ /** Hide named visual subtrees on this instance before placement measurement. Exact runtime names or unique original imported names resolve without removing bones or changing the cached model; missing or ambiguous names warn and leave existing visibility unchanged. Malformed lists reject before model or texture allocation. Omit or pass [] to retain imported visibility. */
237
+ hiddenNodes?: readonly string[];
228
238
  /** Shadow participation of every mesh in the model. Default `"both"` (casts and receives); `"none"` for foliage cards, decals, or viewmodels that must never shadow the world. */
229
239
  shadows?: "cast" | "receive" | "both" | "none";
230
240
  /**
@@ -236,17 +246,14 @@ export interface ModelConfig {
236
246
  * rig's bind pose.
237
247
  */
238
248
  animation?: ModelAnimationConfig | "auto" | "none";
239
- /** Optional runtime inverse-kinematics targets for a rigged model. Bone names are resolved on the loaded scene. */
240
- ik?: {
241
- feet: readonly {
242
- root: string;
243
- mid: string;
244
- tip: string;
245
- }[];
246
- lookAt?: {
247
- bone: string;
248
- };
249
- };
249
+ /**
250
+ * Runtime inverse kinematics for a rigged model, applied after the animation mixer each frame.
251
+ * Feet follow slopes and steps while keeping each clip's swing lift, soles never sink below the
252
+ * ground, the pelvis drops so the lower leg can reach, and the correction fades out while airborne.
253
+ * `"auto"` finds the legs by bone name (`UpLeg`, `UpperLeg`, `Thigh`); bone names resolve on the
254
+ * loaded scene.
255
+ */
256
+ ik?: "auto" | ModelIkConfig;
250
257
  /** Props/weapons parented to named bones on this model's rig; each follows its bone through animation. */
251
258
  attachments?: readonly ModelAttachment[];
252
259
  /** Static kit-of-parts pieces stacked at fixed local offsets — no bone/rig involved. Use this for a compound entity assembled from several modular meshes (a castle keep from base + mid + roof pieces); use `attachments` for props parented to an animated rig's bones. Tag parts with a `role` to procedurally animate a rig-less character composition. */
@@ -254,6 +261,25 @@ export interface ModelConfig {
254
261
  /** Tuning for the procedural part-motion driver when any part carries a `role`; omit for defaults. */
255
262
  partMotion?: PartMotionParams;
256
263
  }
264
+ /** Bone names and limits for {@link ModelConfig.ik}. */
265
+ export interface ModelIkConfig {
266
+ /** Thigh → shin → foot chains; omit to find them by bone name. `[]` turns foot IK off. */
267
+ feet?: readonly {
268
+ root: string;
269
+ mid: string;
270
+ tip: string;
271
+ }[];
272
+ /** Bone shifted down when a foot has to reach lower ground; defaults to the first thigh's parent. */
273
+ pelvis?: string;
274
+ /** Largest foot or pelvis correction, as a fraction of leg length. Default `0.4`. */
275
+ maxAdjust?: number;
276
+ /** Tilt planted feet to the ground normal, `0..1`. Default `1`. */
277
+ alignToGround?: number;
278
+ /** Turns this bone toward the camera. */
279
+ lookAt?: {
280
+ bone: string;
281
+ };
282
+ }
257
283
  export interface ObjectStyle {
258
284
  color?: string;
259
285
  opacity?: number;
@@ -328,7 +354,7 @@ export interface BackdropConfig {
328
354
  sky?: SkyEnvironmentConfig;
329
355
  fog?: BackdropFogConfig;
330
356
  }
331
- /** Free-flight families moved into the walk controller so one seam covers ground + air — creative/spectator/noclip/hover are weightless, aircraft/rotorcraft stay on `flightDynamics`. */
357
+ /** Free-flight families moved into the walk controller so one seam covers ground + air — creative/spectator/noclip/hover are weightless, aircraft, rotorcraft and rockets use `physics/aircraftDynamics`. */
332
358
  export interface FlightConfig {
333
359
  /** Which free-flight family to use when flight is active. Default "creative". */
334
360
  mode?: "creative" | "spectator" | "noclip" | "hover";
@@ -355,6 +381,35 @@ export interface FlightConfig {
355
381
  /** Gate flight behind live game state — creative toggle, stamina check, etc. `false` stays walking. Default true when `flight` is present. */
356
382
  canFly?: (ctx: GameContext) => boolean;
357
383
  }
384
+ /** Feel knobs for the built-in walk controller; see {@link PlayerMovementConfig.feel}. */
385
+ export interface MovementFeelConfig {
386
+ /** Ground velocity response, 1/s (default 26). Lower drifts into and out of motion; higher is snappy. */
387
+ groundAcceleration?: number;
388
+ /** Air velocity response, 1/s (default 12). `0` commits to the jump arc; high values steer freely in the air. */
389
+ airAcceleration?: number;
390
+ /** Stopping response on the ground with no input, 1/s (default 18). Lower slides like ice. */
391
+ groundFriction?: number;
392
+ /** Sprint speed as a multiple of walk speed (default 2.25). */
393
+ runMultiplier?: number;
394
+ /** Crouch speed as a multiple of walk speed (default 0.45). */
395
+ crouchMultiplier?: number;
396
+ /** A jump pressed up to this many ms before landing fires on landing (default 0). */
397
+ jumpBufferMs?: number;
398
+ /** A jump pressed up to this many ms after walking off a ledge still fires (default 0). */
399
+ coyoteMs?: number;
400
+ /** Rising speed kept when jump is released early, 0..1 (default 1: no cut). Lower makes a tap a hop. */
401
+ jumpCutFactor?: number;
402
+ /** Gravity multiplier near the peak, while vertical speed is under `apexSpeed` (default 1). Below 1 hangs. */
403
+ apexGravityScale?: number;
404
+ /** Vertical speed under which `apexGravityScale` applies, m/s (default 1.5). */
405
+ apexSpeed?: number;
406
+ /** Gravity multiplier while falling (default 1). Above 1 drops faster than it rose. */
407
+ fallGravityScale?: number;
408
+ /** After landing, jumps wait and walk speed ramps back from `landingSpeedScale` over this many ms (default 0). */
409
+ landingRecoveryMs?: number;
410
+ /** Walk speed share right after landing when `landingRecoveryMs` is set (default 0.5). */
411
+ landingSpeedScale?: number;
412
+ }
358
413
  /** Movement-control levers for the shell-driven local player walk controller. */
359
414
  export interface PlayerMovementConfig {
360
415
  /** "free" (default) moves camera-relative across the plane; "axis" locks travel to one world axis; "grid" snaps each committed position to cell centers. */
@@ -371,6 +426,8 @@ export interface PlayerMovementConfig {
371
426
  * colliders instead of relying on this switch.
372
427
  */
373
428
  collideObjects?: boolean;
429
+ /** Heightfield collision span from feet, finite and positive; default 1.8 meters. Live growth waits for clear headroom. Capsule and voxel paths retain their own dimensions; model proportions and camera placement remain game-owned. */
430
+ collisionHeight?: number;
374
431
  /** Tallest object ledge stepped up while walking (and largest drop still snapped down instead of falling). Default 0.4. */
375
432
  stepHeight?: number;
376
433
  /** Intercepts each frame's resolved position before the pose commits (and before onTick): return a replacement [x,y,z] to constrain or redirect the step, or nothing to accept it. */
@@ -379,6 +436,13 @@ export interface PlayerMovementConfig {
379
436
  canSprint?: (ctx: GameContext) => boolean;
380
437
  /** Fraction of walk speed while backpedalling (holding `moveBack`). Overrides the engine default (0.65). */
381
438
  backpedalMult?: number;
439
+ /**
440
+ * Walk-controller feel. Acceleration and friction are exponential response rates (1/s): higher reaches
441
+ * the target velocity or stops sooner. Omitted fields keep the engine defaults, so nothing changes until a
442
+ * game sets one. The heightfield and physics-backed capsule paths share jump feel; a `collision.voxel`
443
+ * body retains press-frame jumping with plain gravity. Tune against `measureMovement` (`@jgengine/core/movement/movementProbe`).
444
+ */
445
+ feel?: MovementFeelConfig;
382
446
  /** Radians/second the rendered body rotates toward its movement heading (shortest arc), so strafing/backpedalling read as a turn rather than an instant flip; also the rate the internally-integrated `turnLeft`/`turnRight` heading turns when the shell doesn't own yaw. Unset = body facing snaps instantly (no change to existing feel). */
383
447
  turnSpeed?: number;
384
448
  /** On-foot swimming when the terrain declares a `waterLevel` and the player is submerged: caps speed and floats them at the surface. `true` uses defaults; default off. */
@@ -389,12 +453,25 @@ export interface PlayerMovementConfig {
389
453
  slopeSlide?: {
390
454
  maxClimbSlope?: number;
391
455
  } | boolean;
456
+ /**
457
+ * Maximum sampled uphill rise/run for heightfield walking, including jumps. A rejected step
458
+ * slides along a traversable X or Z axis and feet use the accepted ground. Finite, nonnegative;
459
+ * omitted means unrestricted. Capsule, voxel and flight paths retain their own collision rules.
460
+ */
461
+ maxClimbGrade?: number;
462
+ /**
463
+ * Optional terrain-policy sampler for `maxClimbGrade`; defaults to the resolved ground sampler.
464
+ * Use when grade rules follow a different terrain field (for example before road cuts). This
465
+ * does not change foot grounding. Called at most four times per constrained walking step;
466
+ * must return finite heights or the step throws with the invalid sampling coordinate.
467
+ */
468
+ climbGradeHeight?: (x: number, z: number) => number;
392
469
  /**
393
470
  * Free-flight — creative/spectator/noclip/hover — folded into the same walk controller so a game
394
471
  * doesn't hand-roll a second movement loop to get Minecraft-like flight. `true` uses creative defaults;
395
472
  * an object tunes speed/vertical/sprint/collide/canFly. Horizontal is always yaw-relative strafe
396
- * (A = left, D = right — never roll/bank), vertical is Space/Ctrl, and aircraft/rotorcraft remain
397
- * on `physics/flightDynamics`. The shell drives this automatically when present; `canFly` toggles
473
+ * (A = left, D = right — never roll/bank), vertical is Space/Ctrl, and aircraft, rotorcraft and rockets
474
+ * use `physics/aircraftDynamics`. The shell drives this automatically when present; `canFly` toggles
398
475
  * between walking and flying per tick without rebuilding the config.
399
476
  */
400
477
  flight?: FlightConfig | boolean;
@@ -537,25 +614,35 @@ export interface PlayableGame<TUi = unknown, TWorldOverlay = unknown, TRenderEnt
537
614
  pointer?: PointerConfig;
538
615
  /** Touch controls on coarse-pointer devices. Unset derives a scheme from `input` (virtual joystick for movement actions, on-screen buttons for the rest); a config refines it with gestures and curated buttons; `false` opts out. */
539
616
  touch?: TouchControlsConfig | false;
617
+ /** Gamepad stick deadzone, response curve and trigger deadzone the shell's pad poll applies before publishing analog values. Unset keeps the shell defaults (axial `0.12`/`0.95`, linear). */
618
+ gamepad?: GamepadFeelConfig;
619
+ /** Local seats on this screen for couch co-op. With `maxSlots > 1` each extra pad hot-joins its own seat on its first button press, the shell calls `loop.onNewPlayer(ctx, { userId, isNew: true })` for it, and its input lands on `localPlayers(ctx).local(slotId).input` instead of `ctx.input`. Unset keeps one seat: every device drives `ctx.player`. */
620
+ localPlayers?: LocalPlayersConfig;
621
+ /** Split-screen for local seats (`localPlayers`): one viewport per joined seat, each following its own entity. The primary seat keeps the main camera rig; post-processing is skipped while more than one viewport is drawn. */
622
+ viewports?: ViewportsConfig;
540
623
  /** Phone orientation contract. Legacy `"landscape"`/`"portrait"` stays advisory (a dismissible rotate hint). The object form `{ mobile: "landscape-required" }` is strict — the shell shows an engine-owned rotate screen and blocks gameplay until the device is turned. See `GameOrientation`. */
541
624
  orientation?: GameOrientation;
542
625
  /** Where the game is meant to be played. Default `["web", "mobile"]` — design-resolution HUD fit is on for every game: `HudCanvas` auto-scales from `hudFit.designSize` down to the live viewport, so the desktop layout shrinks to fit a phone instead of overflowing it. Declare `["web"]` to opt a desktop-only game out (compact displays fall back to the legacy fixed 0.85 zoom). */
543
626
  platforms?: readonly HudPlatform[];
544
627
  /** HUD design resolution + scale clamps (default 1600×900, scale 0.4–1). `mobile` overrides tune the phone fit separately — the same resolution system drives desktop UI-scale and phone shrink. */
545
628
  hudFit?: HudViewportConfig;
546
- /** Opt in to world-space health bars floating over non-local entities that carry the stat. `roles` restricts bars to entities whose catalog entry declares one of the given roles; `maxDistance` hides bars beyond this many world units from the player (default 60). */
629
+ /** Opt in to world-space health bars floating over non-local entities that carry the stat. `roles` restricts bars to entities whose catalog entry declares one of the given roles; `maxDistance` hides bars beyond this many world units from the render camera (default 60). */
547
630
  worldHealthBars?: boolean | {
548
631
  statId?: string;
549
632
  roles?: readonly CatalogEntityRole[];
550
633
  maxDistance?: number;
551
- /** Hide a bar when world geometry stands between the player and the entity. These bars are a screen-space overlay outside the depth buffer, so by default they draw through walls. Default false. */
634
+ /** Maximum overlays and visibility rays per refresh. Default 64, capped at 256. */
635
+ maxSamples?: number;
636
+ /** Minimum refresh interval in ms. Default 80 for bars, 120 for plates. */
637
+ tickMs?: number;
638
+ /** Hide bars behind blocking geometry from the render camera. Default true; false explicitly reveals through walls. */
552
639
  occlude?: boolean;
553
640
  };
554
641
  /**
555
642
  * Opt in to billboarded nameplates (name + optional HP bar) floating over non-local entities — the
556
643
  * MMO "who's this and how hurt are they" readout. `roles` restricts to entities whose catalog entry
557
644
  * declares one of the given roles (default: all); `maxDistance` hides nameplates beyond this many
558
- * world units from the player (default 40). Headless: skin every part via `className`/`data-*` hooks
645
+ * world units from the render camera (default 40). Headless: skin every part via `className`/`data-*` hooks
559
646
  * on `WorldNameplates` (`@jgengine/shell/world/WorldHud`) — this flag only turns the readout on and
560
647
  * scopes which entities it covers. Set `showHealth: false` for a name-only plate when a game already
561
648
  * draws the HP bar itself (its own HUD, or `worldHealthBars`) — otherwise the nameplate's built-in bar
@@ -565,7 +652,15 @@ export interface PlayableGame<TUi = unknown, TWorldOverlay = unknown, TRenderEnt
565
652
  statId?: string;
566
653
  roles?: readonly CatalogEntityRole[];
567
654
  maxDistance?: number;
655
+ /** Maximum overlays and visibility rays per refresh. Default 64, capped at 256. */
656
+ maxSamples?: number;
657
+ /** Minimum refresh interval in ms. Default 80 for bars, 120 for plates. */
658
+ tickMs?: number;
568
659
  showHealth?: boolean;
660
+ /** Hide plates behind blocking geometry from the render camera. Default true; false explicitly reveals through walls. */
661
+ occlude?: boolean;
662
+ /** Authored display name. Return null to omit a plate; default suppresses machine identifiers. */
663
+ resolveName?: (entity: SceneEntity) => string | null;
569
664
  };
570
665
  /**
571
666
  * Combat presentation stack mounted inside the 3D canvas (telegraphs, spell VFX, retained VFX,
@@ -577,6 +672,10 @@ export interface PlayableGame<TUi = unknown, TWorldOverlay = unknown, TRenderEnt
577
672
  /** Sound catalog + mix buses (music/sfx/ambient/…) the shell's Web Audio glue plays from. Catalog-first — no per-game audio wiring. `sounds` may be sample (`url`) or procedural (`synth`); `music` holds procedural themes crossfaded via `ctx.game.audio.music(id)`. */
578
673
  audio?: {
579
674
  sounds: Record<string, SoundDef>;
675
+ /** SFX playback/patch budget, including pending samples; individual synth oscillators share one slot. Default 64; zero disables SFX. */
676
+ maxVoices?: number;
677
+ /** Overflow rejects new cues or steals the lowest-priority oldest cue. Default "steal-lowest". */
678
+ voiceOverflow?: "steal-lowest" | "reject";
580
679
  buses?: Record<string, AudioBusDef>;
581
680
  music?: Record<string, MusicTheme>;
582
681
  musicBus?: string;
@@ -59,12 +59,17 @@ export interface QuestJournalDeps {
59
59
  grantItem(userId: string, inventoryId: string, itemId: string, count: number): {
60
60
  reason: string;
61
61
  } | null;
62
+ /** Grant the whole item batch, or reject without granting any items. Required for multiple item rewards. */
63
+ grantItems?(userId: string, items: Readonly<NonNullable<QuestRewards["items"]>>): {
64
+ reason: string;
65
+ } | null;
62
66
  grantUnlock(userId: string, unlockId: string): void;
63
67
  };
64
68
  hasUnlock?(userId: string, id: string): boolean;
65
69
  partyMembersNear?(userId: string, radius: number): string[];
66
70
  }
67
71
  export interface QuestJournal {
72
+ /** Add or replace definitions and refresh active credit indexes; re-register after editing objectives. */
68
73
  register(catalog: readonly QuestDef[] | Record<string, QuestDef>): void;
69
74
  has(questId: string): boolean;
70
75
  canAccept(userId: string, questId: string): {
@@ -86,6 +91,7 @@ export interface QuestJournal {
86
91
  }): void;
87
92
  revoke(userId: string, questId: string): void;
88
93
  list(userId: string): QuestInstance[];
94
+ /** Credit objectives active at event start in catalog order; quests activated during credit join the next event. */
89
95
  bind(action: "entity.died" | "inventory.added"): () => void;
90
96
  snapshot(userId: string): QuestSnapshotEntry[];
91
97
  hydrate(userId: string, data: QuestSnapshotEntry[]): void;
@@ -157,12 +163,21 @@ export interface QuestEvaluator {
157
163
  creditCollect(state: readonly QuestSnapshotEntry[], itemId: string, count: number): QuestSnapshotEntry[];
158
164
  list(state: readonly QuestSnapshotEntry[]): QuestInstance[];
159
165
  }
166
+ /**
167
+ * Apply items before XP, currency, and unlocks. Multiple items require an all-or-reject `grantItems`
168
+ * callback; legacy single-item appliers remain supported. Rejected callbacks must make no writes.
169
+ * Arbitrary callback side effects or thrown exceptions cannot be rolled back by this helper.
170
+ */
160
171
  export declare function applyQuestRewards(rewards: QuestRewards, appliers: {
161
172
  grantXp?(amount: number): void;
162
173
  grantEconomy?(currencyId: string, amount: number): void;
163
174
  grantItem?(inventoryId: string, itemId: string, count: number): {
164
175
  reason: string;
165
176
  } | null | void;
177
+ /** Grant every item, or reject without writes. Takes precedence over `grantItem`. */
178
+ grantItems?(items: Readonly<NonNullable<QuestRewards["items"]>>): {
179
+ reason: string;
180
+ } | null | void;
166
181
  grantUnlock?(unlockId: string): void;
167
182
  }): {
168
183
  reason: string;