@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,71 @@
1
+ import type { Aabb } from "./geometry.js";
2
+ import type { GrassEnvironmentConfig } from "./features.js";
3
+ import type { SceneDocumentLike, SceneVolumeLike } from "./sceneShapes.js";
4
+ /** The editor volume kind that marks an area as vegetation fill. */
5
+ export declare const VEGETATION_VOLUME_KIND = "vegetation";
6
+ /**
7
+ * How a vegetation volume fills its area, read from the volume's `meta`.
8
+ * `density` is items per square meter — the one slider number: grass blades,
9
+ * trees, bushes, rocks all scale with it. Every field has a default, so a
10
+ * freshly placed `kind: "vegetation"` volume already grows grass.
11
+ */
12
+ export interface VegetationSettings {
13
+ /** `"grass"` for shell-rendered blades, otherwise an asset/catalog item id the game maps to a model. */
14
+ item: string;
15
+ /** Items per square meter (grass blades: ~4; trees: ~0.02; bushes: ~0.08). */
16
+ density: number;
17
+ /** Random uniform scale range applied per placement. */
18
+ minScale: number;
19
+ maxScale: number;
20
+ /** Minimum spacing between placements in meters; 0 allows clumping. */
21
+ minDistance: number;
22
+ /** Extra seed folded into the volume id so re-rolls are one string away. */
23
+ seed: string;
24
+ }
25
+ /** Defaults a bare `kind: "vegetation"` volume grows with: grass at 4 blades/m². */
26
+ export declare const VEGETATION_DEFAULTS: VegetationSettings;
27
+ /** True when an editor volume is a vegetation fill area.
28
+ * @internal
29
+ */
30
+ export declare function isVegetationVolume(volume: SceneVolumeLike): boolean;
31
+ /** The volume's vegetation settings with defaults filled in; null for non-vegetation volumes.
32
+ * @internal
33
+ */
34
+ export declare function readVegetationSettings(volume: SceneVolumeLike): VegetationSettings | null;
35
+ /** The ground-plane footprint of a volume: box half-extents or sphere/cylinder radius.
36
+ * @internal
37
+ */
38
+ export declare function vegetationFootprint(volume: SceneVolumeLike): Aabb;
39
+ /** One placed vegetation instance — position on the ground plane plus per-instance variation. */
40
+ export interface VegetationPlacement {
41
+ id: string;
42
+ volumeId: string;
43
+ item: string;
44
+ x: number;
45
+ z: number;
46
+ scale: number;
47
+ rotation: number;
48
+ }
49
+ /**
50
+ * Deterministic placements for one vegetation volume: scatter its footprint at
51
+ * `density` items/m² (respecting `minDistance`), clip round shapes to their
52
+ * radius, and derive per-instance scale/rotation from the volume id + seed, so
53
+ * the same saved scene always grows the same field.
54
+ * @internal
55
+ */
56
+ export declare function resolveVegetationVolume(volume: SceneVolumeLike): VegetationPlacement[];
57
+ /**
58
+ * All model-item placements in a document (every vegetation volume except
59
+ * `item: "grass"`, which the shell renders as blades — see
60
+ * `grassPatchesFromVegetation`). A game maps each placement's `item` to a
61
+ * mesh/entity via its render catalog and places it grounded.
62
+ * @internal
63
+ */
64
+ export declare function resolveVegetation(doc: SceneDocumentLike): VegetationPlacement[];
65
+ /**
66
+ * Grass-blade patches for every `item: "grass"` vegetation volume, ready to
67
+ * spread into `environment()`'s `grass` list — the volume's density number is
68
+ * the blades-per-m² the shell renders, so the editor slider drives it directly.
69
+ * @internal
70
+ */
71
+ export declare function grassPatchesFromVegetation(doc: SceneDocumentLike): GrassEnvironmentConfig[];
@@ -0,0 +1,151 @@
1
+ import { scatter } from "./scatter.js";
2
+ /** The editor volume kind that marks an area as vegetation fill. */
3
+ export const VEGETATION_VOLUME_KIND = "vegetation";
4
+ /** Defaults a bare `kind: "vegetation"` volume grows with: grass at 4 blades/m². */
5
+ export const VEGETATION_DEFAULTS = {
6
+ item: "grass",
7
+ density: 4,
8
+ minScale: 0.8,
9
+ maxScale: 1.2,
10
+ minDistance: 0,
11
+ seed: "",
12
+ };
13
+ function metaNumber(meta, key, fallback) {
14
+ const value = meta?.[key];
15
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
16
+ }
17
+ function metaString(meta, key, fallback) {
18
+ const value = meta?.[key];
19
+ return typeof value === "string" && value.length > 0 ? value : fallback;
20
+ }
21
+ /** True when an editor volume is a vegetation fill area.
22
+ * @internal
23
+ */
24
+ export function isVegetationVolume(volume) {
25
+ return volume.kind === VEGETATION_VOLUME_KIND;
26
+ }
27
+ /** The volume's vegetation settings with defaults filled in; null for non-vegetation volumes.
28
+ * @internal
29
+ */
30
+ export function readVegetationSettings(volume) {
31
+ if (!isVegetationVolume(volume))
32
+ return null;
33
+ return {
34
+ item: metaString(volume.meta, "item", VEGETATION_DEFAULTS.item),
35
+ density: Math.max(0, metaNumber(volume.meta, "density", VEGETATION_DEFAULTS.density)),
36
+ minScale: metaNumber(volume.meta, "minScale", VEGETATION_DEFAULTS.minScale),
37
+ maxScale: metaNumber(volume.meta, "maxScale", VEGETATION_DEFAULTS.maxScale),
38
+ minDistance: Math.max(0, metaNumber(volume.meta, "minDistance", VEGETATION_DEFAULTS.minDistance)),
39
+ seed: metaString(volume.meta, "seed", VEGETATION_DEFAULTS.seed),
40
+ };
41
+ }
42
+ /** The ground-plane footprint of a volume: box half-extents or sphere/cylinder radius.
43
+ * @internal
44
+ */
45
+ export function vegetationFootprint(volume) {
46
+ const halfW = volume.shape === "box" ? (volume.halfExtents?.x ?? 5) : (volume.radius ?? 5);
47
+ const halfD = volume.shape === "box" ? (volume.halfExtents?.z ?? 5) : (volume.radius ?? 5);
48
+ return {
49
+ minX: volume.center.x - halfW,
50
+ minZ: volume.center.z - halfD,
51
+ maxX: volume.center.x + halfW,
52
+ maxZ: volume.center.z + halfD,
53
+ };
54
+ }
55
+ function placementHash(volumeId, seed, index, salt) {
56
+ const text = `${volumeId}:${seed}:${index}:${salt}`;
57
+ let h = 2166136261 >>> 0;
58
+ for (let i = 0; i < text.length; i++) {
59
+ h ^= text.charCodeAt(i);
60
+ h = Math.imul(h, 16777619);
61
+ }
62
+ return (h >>> 0) / 4294967296;
63
+ }
64
+ /**
65
+ * Deterministic placements for one vegetation volume: scatter its footprint at
66
+ * `density` items/m² (respecting `minDistance`), clip round shapes to their
67
+ * radius, and derive per-instance scale/rotation from the volume id + seed, so
68
+ * the same saved scene always grows the same field.
69
+ * @internal
70
+ */
71
+ export function resolveVegetationVolume(volume) {
72
+ const settings = readVegetationSettings(volume);
73
+ if (settings === null || settings.density <= 0)
74
+ return [];
75
+ const area = vegetationFootprint(volume);
76
+ const points = scatter({
77
+ area,
78
+ density: settings.density,
79
+ minDistance: settings.minDistance,
80
+ seed: `${volume.id}:${settings.seed}`,
81
+ });
82
+ const round = volume.shape !== "box";
83
+ const radius = volume.radius ?? 5;
84
+ const radiusSq = radius * radius;
85
+ const placements = [];
86
+ for (const point of points) {
87
+ if (round) {
88
+ const dx = point.x - volume.center.x;
89
+ const dz = point.z - volume.center.z;
90
+ if (dx * dx + dz * dz > radiusSq)
91
+ continue;
92
+ }
93
+ const t = placementHash(volume.id, settings.seed, point.index, 0x51);
94
+ placements.push({
95
+ id: `${volume.id}/${point.index}`,
96
+ volumeId: volume.id,
97
+ item: settings.item,
98
+ x: point.x,
99
+ z: point.z,
100
+ scale: settings.minScale + (settings.maxScale - settings.minScale) * t,
101
+ rotation: placementHash(volume.id, settings.seed, point.index, 0x9e) * Math.PI * 2,
102
+ });
103
+ }
104
+ return placements;
105
+ }
106
+ /**
107
+ * All model-item placements in a document (every vegetation volume except
108
+ * `item: "grass"`, which the shell renders as blades — see
109
+ * `grassPatchesFromVegetation`). A game maps each placement's `item` to a
110
+ * mesh/entity via its render catalog and places it grounded.
111
+ * @internal
112
+ */
113
+ export function resolveVegetation(doc) {
114
+ const out = [];
115
+ for (const volume of doc.volumes) {
116
+ if (!isVegetationVolume(volume))
117
+ continue;
118
+ const settings = readVegetationSettings(volume);
119
+ if (settings === null || settings.item === "grass")
120
+ continue;
121
+ out.push(...resolveVegetationVolume(volume));
122
+ }
123
+ return out;
124
+ }
125
+ /**
126
+ * Grass-blade patches for every `item: "grass"` vegetation volume, ready to
127
+ * spread into `environment()`'s `grass` list — the volume's density number is
128
+ * the blades-per-m² the shell renders, so the editor slider drives it directly.
129
+ * @internal
130
+ */
131
+ export function grassPatchesFromVegetation(doc) {
132
+ const patches = [];
133
+ for (const volume of doc.volumes) {
134
+ if (!isVegetationVolume(volume))
135
+ continue;
136
+ const settings = readVegetationSettings(volume);
137
+ if (settings === null || settings.item !== "grass" || settings.density <= 0)
138
+ continue;
139
+ const area = vegetationFootprint(volume);
140
+ patches.push({
141
+ area: {
142
+ w: area.maxX - area.minX,
143
+ d: area.maxZ - area.minZ,
144
+ position: [volume.center.x, volume.center.z],
145
+ },
146
+ density: settings.density,
147
+ seed: `${volume.id}:${settings.seed}`,
148
+ });
149
+ }
150
+ return patches;
151
+ }
@@ -0,0 +1,154 @@
1
+ import type { FogBounds } from "./fog.js";
2
+ /** Numeric code for a cell no group member has seen, or has fully forgotten. */
3
+ export declare const VISIBILITY_HIDDEN = 0;
4
+ /** Numeric code for a cell seen before but not currently in view (last-known). */
5
+ export declare const VISIBILITY_REMEMBERED = 1;
6
+ /** Numeric code for a cell a group currently observes. */
7
+ export declare const VISIBILITY_OBSERVED = 2;
8
+ /** One viewer group's knowledge of a cell: never/forgotten, last-known, or live. */
9
+ export type VisibilityState = "hidden" | "remembered" | "observed";
10
+ /**
11
+ * How a cell decays after a group stops observing it — the terrain-memory policy.
12
+ * `permanent` keeps last-known terrain forever (RTS explored map); `none` drops
13
+ * it straight back to hidden the moment it leaves view (pure line-of-sight
14
+ * stealth); `decay` remembers it for `updates` observe cycles, then hides it.
15
+ * Day/night, height, sensor, and stealth rules are NOT encoded here — the caller
16
+ * bakes those into which cells it reports as observed each update.
17
+ */
18
+ export type VisibilityMemory = {
19
+ readonly kind: "permanent";
20
+ } | {
21
+ readonly kind: "none";
22
+ } | {
23
+ readonly kind: "decay";
24
+ readonly updates: number;
25
+ };
26
+ /** Construction options for {@link createVisibilityField}. */
27
+ export interface VisibilityFieldConfig {
28
+ /** World-space rectangle the grid covers (reused from `world/fog`). */
29
+ readonly bounds: FogBounds;
30
+ /** World units per grid cell. Must be positive. */
31
+ readonly cellSize: number;
32
+ /** Default memory policy applied to every group. Default `{ kind: "permanent" }`. */
33
+ readonly memory?: VisibilityMemory;
34
+ /** Rehydrate from a previously serialized field (see {@link VisibilityField.toState}). */
35
+ readonly restore?: VisibilityFieldState;
36
+ }
37
+ /**
38
+ * The cells that changed state for one group in a single {@link VisibilityField.observe}
39
+ * call — a pure incremental readout for rendering, minimaps, AI, UI, and
40
+ * authoritative replication. Never lists unchanged cells, so it stays bounded by
41
+ * how much the group's view actually moved.
42
+ */
43
+ export interface VisibilityDelta {
44
+ readonly group: string;
45
+ /** Cells that entered observation this update. */
46
+ readonly observed: readonly number[];
47
+ /** Cells that left observation into remembered (last-known) state. */
48
+ readonly remembered: readonly number[];
49
+ /** Cells that fell out of memory entirely (decay expiry or `none` policy). */
50
+ readonly hidden: readonly number[];
51
+ }
52
+ /** Sparse serialized knowledge for one group — only non-hidden cells are stored. */
53
+ export interface VisibilityGroupState {
54
+ /** Currently observed cell indices. */
55
+ readonly observed: readonly number[];
56
+ /** Remembered cells as `[cellIndex, lastObservedTick]` pairs. */
57
+ readonly remembered: readonly (readonly [number, number])[];
58
+ /** Monotonic update counter, used to age remembered cells under a decay policy. */
59
+ readonly tick: number;
60
+ /** Per-group memory override, when it differs from the field default. */
61
+ readonly memory?: VisibilityMemory;
62
+ }
63
+ /** Serializable snapshot of a whole field — JSON round-trips losslessly. */
64
+ export interface VisibilityFieldState {
65
+ readonly cols: number;
66
+ readonly rows: number;
67
+ readonly minX: number;
68
+ readonly minZ: number;
69
+ readonly cellSize: number;
70
+ readonly memory: VisibilityMemory;
71
+ readonly groups: Readonly<Record<string, VisibilityGroupState>>;
72
+ }
73
+ /** Dense per-cell readout for one group, shaped for minimap/overlay drawing. */
74
+ export interface VisibilityCells {
75
+ readonly cols: number;
76
+ readonly rows: number;
77
+ readonly minX: number;
78
+ readonly minZ: number;
79
+ readonly cellSize: number;
80
+ /** Row-major `VISIBILITY_*` codes; index = row * cols + col. */
81
+ readonly codes: Uint8Array;
82
+ }
83
+ /**
84
+ * A gameplay (fog-of-war) knowledge field: per viewer group, every grid cell is
85
+ * hidden, remembered, or observed. Distinct from render culling in
86
+ * `core/visibility` — this models what a team KNOWS, not what a camera can draw.
87
+ * It generalizes `world/fog`'s single-group reveal-once model to many groups
88
+ * with configurable terrain memory, and keeps each group's knowledge isolated so
89
+ * one group's hidden state can never be derived from another's.
90
+ */
91
+ export interface VisibilityField {
92
+ readonly cols: number;
93
+ readonly rows: number;
94
+ cellCount(): number;
95
+ colOf(x: number): number;
96
+ rowOf(z: number): number;
97
+ /** Row-major cell index for a world point, clamped into the grid. */
98
+ cellIndex(x: number, z: number): number;
99
+ /** Register a viewer group, optionally with its own memory policy. Idempotent. */
100
+ ensureGroup(group: string, memory?: VisibilityMemory): void;
101
+ hasGroup(group: string): boolean;
102
+ groups(): string[];
103
+ /** Forget everything for a group and drop it. */
104
+ removeGroup(group: string): void;
105
+ /**
106
+ * Cell indices whose centers fall within `radius` of a world point (bounded
107
+ * disc), appended into `out` when supplied. Feed these into {@link observe};
108
+ * union several sources' discs before observing to model overlapping observers.
109
+ */
110
+ cellsInRadius(x: number, z: number, radius: number, out?: number[]): number[];
111
+ /**
112
+ * Replace a group's observed set for this update. Cells newly covered become
113
+ * observed; cells that dropped out become remembered (or hidden under `none`);
114
+ * decayed memory expires. Work is bounded by the observed + remembered working
115
+ * sets — it never scans the whole grid. Returns the resulting {@link VisibilityDelta}.
116
+ */
117
+ observe(group: string, cells: Iterable<number>): VisibilityDelta;
118
+ /** Convenience {@link observe} over a single disc around a source. */
119
+ observeCircle(group: string, x: number, z: number, radius: number): VisibilityDelta;
120
+ stateAtCell(group: string, cell: number): VisibilityState;
121
+ stateAt(group: string, x: number, z: number): VisibilityState;
122
+ isObserved(group: string, x: number, z: number): boolean;
123
+ isRemembered(group: string, x: number, z: number): boolean;
124
+ /** Terrain disclosure: observed OR remembered (anything the group has ever mapped). */
125
+ isKnown(group: string, x: number, z: number): boolean;
126
+ observedCount(group: string): number;
127
+ knownCount(group: string): number;
128
+ /**
129
+ * Authoritative entity-disclosure filter: keep only entities standing in a cell
130
+ * the group currently OBSERVES. Remembered and hidden cells never disclose live
131
+ * entities, so a unit that moved away or was destroyed re-hides. Reads only this
132
+ * group's state, so it is the seam that stops one group's hidden entities from
133
+ * leaking into another group's replicated view.
134
+ */
135
+ visibleTo<T>(group: string, entities: readonly T[], positionOf: (entity: T) => {
136
+ readonly x: number;
137
+ readonly z: number;
138
+ }): T[];
139
+ /** Dense per-cell codes for a group, for minimap/overlay rendering. */
140
+ cells(group: string): VisibilityCells;
141
+ /** Sparse serializable snapshot; round-trips through {@link createVisibilityField}'s `restore`. */
142
+ toState(): VisibilityFieldState;
143
+ /** Forget one group's knowledge, or every group when `group` is omitted. */
144
+ reset(group?: string): void;
145
+ }
146
+ /**
147
+ * Build a per-group gameplay visibility field. First adopters: an RTS/stealth
148
+ * team whose scout observes terrain (which stays remembered after it leaves)
149
+ * while enemy units re-hide once no scout observes their cell, and any
150
+ * authoritative host that must filter hidden entities out of a client's replica.
151
+ *
152
+ * @capability visibility-field per-viewer-group observed/remembered/hidden fog-of-war knowledge with terrain memory and authoritative entity disclosure
153
+ */
154
+ export declare function createVisibilityField(config: VisibilityFieldConfig): VisibilityField;
@@ -0,0 +1,271 @@
1
+ /** Numeric code for a cell no group member has seen, or has fully forgotten. */
2
+ export const VISIBILITY_HIDDEN = 0;
3
+ /** Numeric code for a cell seen before but not currently in view (last-known). */
4
+ export const VISIBILITY_REMEMBERED = 1;
5
+ /** Numeric code for a cell a group currently observes. */
6
+ export const VISIBILITY_OBSERVED = 2;
7
+ function clampInt(value, min, max) {
8
+ const rounded = Math.floor(value);
9
+ return rounded < min ? min : rounded > max ? max : rounded;
10
+ }
11
+ function stateOf(code) {
12
+ return code === VISIBILITY_OBSERVED
13
+ ? "observed"
14
+ : code === VISIBILITY_REMEMBERED
15
+ ? "remembered"
16
+ : "hidden";
17
+ }
18
+ /**
19
+ * Build a per-group gameplay visibility field. First adopters: an RTS/stealth
20
+ * team whose scout observes terrain (which stays remembered after it leaves)
21
+ * while enemy units re-hide once no scout observes their cell, and any
22
+ * authoritative host that must filter hidden entities out of a client's replica.
23
+ *
24
+ * @capability visibility-field per-viewer-group observed/remembered/hidden fog-of-war knowledge with terrain memory and authoritative entity disclosure
25
+ */
26
+ export function createVisibilityField(config) {
27
+ const cellSize = config.cellSize;
28
+ if (cellSize <= 0)
29
+ throw new Error("createVisibilityField: cellSize must be positive");
30
+ const restore = config.restore;
31
+ const minX = restore?.minX ?? config.bounds.minX;
32
+ const minZ = restore?.minZ ?? config.bounds.minZ;
33
+ const cols = restore?.cols ?? Math.max(1, Math.ceil((config.bounds.maxX - config.bounds.minX) / cellSize));
34
+ const rows = restore?.rows ?? Math.max(1, Math.ceil((config.bounds.maxZ - config.bounds.minZ) / cellSize));
35
+ const total = cols * rows;
36
+ const defaultMemory = restore?.memory ?? config.memory ?? { kind: "permanent" };
37
+ const groups = new Map();
38
+ function makeGroup(memory) {
39
+ return {
40
+ codes: new Uint8Array(total),
41
+ observed: new Set(),
42
+ remembered: new Map(),
43
+ tick: 0,
44
+ memory,
45
+ };
46
+ }
47
+ function getGroup(group) {
48
+ let data = groups.get(group);
49
+ if (data === undefined) {
50
+ data = makeGroup(defaultMemory);
51
+ groups.set(group, data);
52
+ }
53
+ return data;
54
+ }
55
+ if (restore !== undefined) {
56
+ for (const [name, state] of Object.entries(restore.groups)) {
57
+ const data = makeGroup(state.memory ?? defaultMemory);
58
+ data.tick = state.tick;
59
+ for (const cell of state.observed) {
60
+ if (cell >= 0 && cell < total) {
61
+ data.codes[cell] = VISIBILITY_OBSERVED;
62
+ data.observed.add(cell);
63
+ }
64
+ }
65
+ for (const [cell, tick] of state.remembered) {
66
+ if (cell >= 0 && cell < total && data.codes[cell] === VISIBILITY_HIDDEN) {
67
+ data.codes[cell] = VISIBILITY_REMEMBERED;
68
+ data.remembered.set(cell, tick);
69
+ }
70
+ }
71
+ groups.set(name, data);
72
+ }
73
+ }
74
+ function colOf(x) {
75
+ return clampInt((x - minX) / cellSize, 0, cols - 1);
76
+ }
77
+ function rowOf(z) {
78
+ return clampInt((z - minZ) / cellSize, 0, rows - 1);
79
+ }
80
+ function cellIndex(x, z) {
81
+ return rowOf(z) * cols + colOf(x);
82
+ }
83
+ function cellsInRadius(x, z, radius, out = []) {
84
+ const centerCol = colOf(x);
85
+ const centerRow = rowOf(z);
86
+ if (radius <= 0) {
87
+ out.push(centerRow * cols + centerCol);
88
+ return out;
89
+ }
90
+ const span = Math.ceil(radius / cellSize);
91
+ const radiusSq = radius * radius;
92
+ for (let dr = -span; dr <= span; dr += 1) {
93
+ const row = centerRow + dr;
94
+ if (row < 0 || row >= rows)
95
+ continue;
96
+ for (let dc = -span; dc <= span; dc += 1) {
97
+ const col = centerCol + dc;
98
+ if (col < 0 || col >= cols)
99
+ continue;
100
+ const cellX = minX + (col + 0.5) * cellSize;
101
+ const cellZ = minZ + (row + 0.5) * cellSize;
102
+ const dx = cellX - x;
103
+ const dz = cellZ - z;
104
+ if (dx * dx + dz * dz > radiusSq)
105
+ continue;
106
+ out.push(row * cols + col);
107
+ }
108
+ }
109
+ return out;
110
+ }
111
+ function observe(group, cells) {
112
+ const data = getGroup(group);
113
+ data.tick += 1;
114
+ const now = data.tick;
115
+ const remembering = data.memory.kind !== "none";
116
+ const next = new Set();
117
+ const observedDelta = [];
118
+ for (const cell of cells) {
119
+ if (cell < 0 || cell >= total || next.has(cell))
120
+ continue;
121
+ next.add(cell);
122
+ if (data.codes[cell] !== VISIBILITY_OBSERVED) {
123
+ data.codes[cell] = VISIBILITY_OBSERVED;
124
+ data.remembered.delete(cell);
125
+ observedDelta.push(cell);
126
+ }
127
+ }
128
+ const rememberedDelta = [];
129
+ const hiddenDelta = [];
130
+ for (const cell of data.observed) {
131
+ if (next.has(cell))
132
+ continue;
133
+ if (remembering) {
134
+ data.codes[cell] = VISIBILITY_REMEMBERED;
135
+ data.remembered.set(cell, now);
136
+ rememberedDelta.push(cell);
137
+ }
138
+ else {
139
+ data.codes[cell] = VISIBILITY_HIDDEN;
140
+ hiddenDelta.push(cell);
141
+ }
142
+ }
143
+ data.observed = next;
144
+ if (data.memory.kind === "decay") {
145
+ const maxAge = data.memory.updates;
146
+ for (const [cell, seen] of data.remembered) {
147
+ if (now - seen >= maxAge) {
148
+ data.codes[cell] = VISIBILITY_HIDDEN;
149
+ data.remembered.delete(cell);
150
+ hiddenDelta.push(cell);
151
+ }
152
+ }
153
+ }
154
+ return { group, observed: observedDelta, remembered: rememberedDelta, hidden: hiddenDelta };
155
+ }
156
+ return {
157
+ cols,
158
+ rows,
159
+ cellCount() {
160
+ return total;
161
+ },
162
+ colOf,
163
+ rowOf,
164
+ cellIndex,
165
+ ensureGroup(group, memory) {
166
+ const existing = groups.get(group);
167
+ if (existing === undefined) {
168
+ groups.set(group, makeGroup(memory ?? defaultMemory));
169
+ }
170
+ else if (memory !== undefined) {
171
+ existing.memory = memory;
172
+ }
173
+ },
174
+ hasGroup(group) {
175
+ return groups.has(group);
176
+ },
177
+ groups() {
178
+ return Array.from(groups.keys());
179
+ },
180
+ removeGroup(group) {
181
+ groups.delete(group);
182
+ },
183
+ cellsInRadius,
184
+ observe,
185
+ observeCircle(group, x, z, radius) {
186
+ return observe(group, cellsInRadius(x, z, radius));
187
+ },
188
+ stateAtCell(group, cell) {
189
+ const data = groups.get(group);
190
+ if (data === undefined || cell < 0 || cell >= total)
191
+ return "hidden";
192
+ return stateOf(data.codes[cell]);
193
+ },
194
+ stateAt(group, x, z) {
195
+ const data = groups.get(group);
196
+ if (data === undefined)
197
+ return "hidden";
198
+ return stateOf(data.codes[cellIndex(x, z)]);
199
+ },
200
+ isObserved(group, x, z) {
201
+ const data = groups.get(group);
202
+ return data !== undefined && data.codes[cellIndex(x, z)] === VISIBILITY_OBSERVED;
203
+ },
204
+ isRemembered(group, x, z) {
205
+ const data = groups.get(group);
206
+ return data !== undefined && data.codes[cellIndex(x, z)] === VISIBILITY_REMEMBERED;
207
+ },
208
+ isKnown(group, x, z) {
209
+ const data = groups.get(group);
210
+ return data !== undefined && data.codes[cellIndex(x, z)] !== VISIBILITY_HIDDEN;
211
+ },
212
+ observedCount(group) {
213
+ return groups.get(group)?.observed.size ?? 0;
214
+ },
215
+ knownCount(group) {
216
+ const data = groups.get(group);
217
+ if (data === undefined)
218
+ return 0;
219
+ return data.observed.size + data.remembered.size;
220
+ },
221
+ visibleTo(group, entities, positionOf) {
222
+ const data = groups.get(group);
223
+ if (data === undefined)
224
+ return [];
225
+ const result = [];
226
+ for (const entity of entities) {
227
+ const position = positionOf(entity);
228
+ if (data.codes[cellIndex(position.x, position.z)] === VISIBILITY_OBSERVED) {
229
+ result.push(entity);
230
+ }
231
+ }
232
+ return result;
233
+ },
234
+ cells(group) {
235
+ const data = groups.get(group);
236
+ const codes = data === undefined ? new Uint8Array(total) : data.codes.slice();
237
+ return { cols, rows, minX, minZ, cellSize, codes };
238
+ },
239
+ toState() {
240
+ const out = {};
241
+ for (const [name, data] of groups) {
242
+ const remembered = Array.from(data.remembered.entries()).sort((a, b) => a[0] - b[0]);
243
+ out[name] = {
244
+ observed: Array.from(data.observed).sort((a, b) => a - b),
245
+ remembered,
246
+ tick: data.tick,
247
+ memory: data.memory,
248
+ };
249
+ }
250
+ return { cols, rows, minX, minZ, cellSize, memory: defaultMemory, groups: out };
251
+ },
252
+ reset(group) {
253
+ if (group === undefined) {
254
+ for (const data of groups.values()) {
255
+ data.codes.fill(VISIBILITY_HIDDEN);
256
+ data.observed.clear();
257
+ data.remembered.clear();
258
+ data.tick = 0;
259
+ }
260
+ return;
261
+ }
262
+ const data = groups.get(group);
263
+ if (data === undefined)
264
+ return;
265
+ data.codes.fill(VISIBILITY_HIDDEN);
266
+ data.observed.clear();
267
+ data.remembered.clear();
268
+ data.tick = 0;
269
+ },
270
+ };
271
+ }