@jgengine/core 0.9.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 (631) hide show
  1. package/CHANGELOG.md +34 -3
  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 +19 -1
  21. package/dist/ai/spawnDirector.js +53 -26
  22. package/dist/ai/spawnPoint.d.ts +7 -0
  23. package/dist/ai/spawnPoint.js +7 -0
  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/audio/audioFalloff.d.ts +5 -2
  35. package/dist/audio/music.d.ts +53 -0
  36. package/dist/audio/music.js +34 -0
  37. package/dist/audio/synth.d.ts +60 -0
  38. package/dist/audio/synth.js +8 -0
  39. package/dist/authoring.d.ts +15 -0
  40. package/dist/authoring.js +15 -0
  41. package/dist/board/laneBoard.d.ts +13 -0
  42. package/dist/board/laneBoard.js +13 -0
  43. package/dist/board/timelineBoard.d.ts +10 -0
  44. package/dist/board/timelineBoard.js +10 -0
  45. package/dist/combat/abilityKit.d.ts +18 -0
  46. package/dist/combat/abilityKit.js +24 -9
  47. package/dist/combat/animationState.d.ts +5 -0
  48. package/dist/combat/animationState.js +5 -0
  49. package/dist/combat/breakMeters.d.ts +10 -0
  50. package/dist/combat/breakMeters.js +10 -0
  51. package/dist/combat/castRunner.d.ts +5 -0
  52. package/dist/combat/castRunner.js +5 -0
  53. package/dist/combat/comboPoints.d.ts +5 -0
  54. package/dist/combat/comboPoints.js +5 -0
  55. package/dist/combat/comboString.d.ts +5 -0
  56. package/dist/combat/comboString.js +5 -0
  57. package/dist/combat/damageInterceptors.d.ts +192 -0
  58. package/dist/combat/damageInterceptors.js +251 -0
  59. package/dist/combat/damageMatchup.d.ts +68 -0
  60. package/dist/combat/damageMatchup.js +42 -0
  61. package/dist/combat/damageResolution.d.ts +63 -0
  62. package/dist/combat/damageResolution.js +50 -0
  63. package/dist/combat/death.d.ts +7 -1
  64. package/dist/combat/death.js +5 -0
  65. package/dist/combat/deathReason.d.ts +14 -0
  66. package/dist/combat/deathReason.js +1 -0
  67. package/dist/combat/defensiveWindow.d.ts +5 -0
  68. package/dist/combat/defensiveWindow.js +5 -0
  69. package/dist/combat/dotField.d.ts +47 -0
  70. package/dist/combat/dotField.js +52 -0
  71. package/dist/combat/downed.d.ts +5 -0
  72. package/dist/combat/downed.js +5 -0
  73. package/dist/combat/effects.d.ts +5 -0
  74. package/dist/combat/effects.js +5 -0
  75. package/dist/combat/encounterSequence.d.ts +258 -0
  76. package/dist/combat/encounterSequence.js +426 -0
  77. package/dist/combat/hitReaction.d.ts +57 -1
  78. package/dist/combat/hitReaction.js +45 -5
  79. package/dist/combat/magazine.d.ts +54 -0
  80. package/dist/combat/magazine.js +96 -0
  81. package/dist/combat/projectiles.d.ts +7 -2
  82. package/dist/combat/projectiles.js +48 -17
  83. package/dist/combat/receivedDamage.d.ts +117 -0
  84. package/dist/combat/receivedDamage.js +92 -0
  85. package/dist/combat/regenShield.d.ts +39 -0
  86. package/dist/combat/regenShield.js +49 -0
  87. package/dist/combat/renderCues.d.ts +51 -0
  88. package/dist/combat/renderCues.js +44 -0
  89. package/dist/combat/resourcePool.d.ts +5 -0
  90. package/dist/combat/resourcePool.js +5 -0
  91. package/dist/combat/rewardAllocation.d.ts +121 -0
  92. package/dist/combat/rewardAllocation.js +251 -0
  93. package/dist/combat/shotOrigin.d.ts +30 -1
  94. package/dist/combat/shotOrigin.js +70 -2
  95. package/dist/combat/statusApplication.d.ts +96 -0
  96. package/dist/combat/statusApplication.js +81 -0
  97. package/dist/combat/telegraph.d.ts +11 -2
  98. package/dist/combat/telegraph.js +11 -2
  99. package/dist/combat/thresholdCrossings.d.ts +85 -0
  100. package/dist/combat/thresholdCrossings.js +116 -0
  101. package/dist/combat.d.ts +34 -0
  102. package/dist/combat.js +34 -0
  103. package/dist/commands/commandRegistry.d.ts +11 -0
  104. package/dist/commands/commandRegistry.js +9 -2
  105. package/dist/crafting/crop.d.ts +18 -0
  106. package/dist/crafting/crop.js +18 -0
  107. package/dist/crafting/production.d.ts +5 -0
  108. package/dist/crafting/production.js +5 -0
  109. package/dist/devtools/rewriteTunables.d.ts +17 -0
  110. package/dist/devtools/rewriteTunables.js +276 -0
  111. package/dist/devtools/saveEndpoint.d.ts +46 -0
  112. package/dist/devtools/saveEndpoint.js +48 -0
  113. package/dist/devtools/transformTunables.d.ts +3 -0
  114. package/dist/devtools/transformTunables.js +3 -0
  115. package/dist/devtools/tunableSchema.d.ts +31 -0
  116. package/dist/devtools/tunableSchema.js +31 -0
  117. package/dist/economy/currency.d.ts +12 -1
  118. package/dist/economy/currency.js +12 -1
  119. package/dist/economy/listingBook.d.ts +91 -0
  120. package/dist/economy/listingBook.js +144 -0
  121. package/dist/economy/resourceLedger.d.ts +222 -0
  122. package/dist/economy/resourceLedger.js +353 -0
  123. package/dist/economy/sharedWallet.d.ts +14 -0
  124. package/dist/economy/sharedWallet.js +14 -0
  125. package/dist/economy/techTree.d.ts +12 -0
  126. package/dist/economy/techTree.js +12 -0
  127. package/dist/economy/wallet.d.ts +26 -2
  128. package/dist/economy/wallet.js +35 -6
  129. package/dist/editor/commands.d.ts +248 -0
  130. package/dist/editor/commands.js +865 -0
  131. package/dist/editor/document.d.ts +186 -0
  132. package/dist/editor/document.js +884 -0
  133. package/dist/editor/grid.d.ts +229 -0
  134. package/dist/editor/grid.js +366 -0
  135. package/dist/editor/gridAdapters.d.ts +80 -0
  136. package/dist/editor/gridAdapters.js +134 -0
  137. package/dist/editor/index.d.ts +97 -0
  138. package/dist/editor/index.js +10 -0
  139. package/dist/editor/liveSync.d.ts +127 -0
  140. package/dist/editor/liveSync.js +249 -0
  141. package/dist/editor/runtimeInspector.d.ts +88 -0
  142. package/dist/editor/runtimeInspector.js +239 -0
  143. package/dist/editor/types.d.ts +175 -0
  144. package/dist/editor/types.js +29 -0
  145. package/dist/faction/reputation.d.ts +5 -0
  146. package/dist/faction/reputation.js +5 -0
  147. package/dist/format/distance.d.ts +17 -0
  148. package/dist/format/distance.js +18 -0
  149. package/dist/format/duration.d.ts +27 -0
  150. package/dist/format/duration.js +45 -0
  151. package/dist/format/speed.d.ts +17 -0
  152. package/dist/format/speed.js +25 -0
  153. package/dist/game/connectedPlayers.d.ts +30 -0
  154. package/dist/game/connectedPlayers.js +21 -0
  155. package/dist/game/cosmetics.d.ts +9 -0
  156. package/dist/game/cosmetics.js +16 -0
  157. package/dist/game/defineGame.d.ts +141 -2
  158. package/dist/game/defineGame.js +39 -1
  159. package/dist/game/defineSystem.d.ts +88 -0
  160. package/dist/game/defineSystem.js +45 -0
  161. package/dist/game/dialogue.d.ts +33 -0
  162. package/dist/game/dialogue.js +21 -0
  163. package/dist/game/events.d.ts +50 -13
  164. package/dist/game/events.js +5 -0
  165. package/dist/game/feed.d.ts +33 -0
  166. package/dist/game/feed.js +35 -2
  167. package/dist/game/gamePhase.d.ts +11 -0
  168. package/dist/game/gamePhase.js +16 -0
  169. package/dist/game/keyValueStore.d.ts +25 -0
  170. package/dist/game/keyValueStore.js +61 -0
  171. package/dist/game/leaderboard.d.ts +5 -0
  172. package/dist/game/leaderboard.js +5 -0
  173. package/dist/game/levelSequence.d.ts +24 -2
  174. package/dist/game/levelSequence.js +51 -2
  175. package/dist/game/loadout.d.ts +5 -0
  176. package/dist/game/loadout.js +5 -0
  177. package/dist/game/lootFilter.d.ts +2 -0
  178. package/dist/game/lootFilter.js +2 -0
  179. package/dist/game/lootPipeline.d.ts +164 -0
  180. package/dist/game/lootPipeline.js +216 -0
  181. package/dist/game/lootTable.d.ts +21 -0
  182. package/dist/game/lootTable.js +15 -4
  183. package/dist/game/modelAnimation.d.ts +8 -0
  184. package/dist/game/modelAnimation.js +18 -0
  185. package/dist/game/objectives.d.ts +43 -0
  186. package/dist/game/objectives.js +36 -0
  187. package/dist/game/paramLayers.d.ts +148 -0
  188. package/dist/game/paramLayers.js +185 -0
  189. package/dist/game/ping.d.ts +5 -0
  190. package/dist/game/ping.js +5 -0
  191. package/dist/game/playableGame.d.ts +160 -12
  192. package/dist/game/quest.d.ts +8 -0
  193. package/dist/game/quest.js +29 -0
  194. package/dist/game/race.d.ts +141 -0
  195. package/dist/game/race.js +169 -0
  196. package/dist/game/recordBook.d.ts +5 -5
  197. package/dist/game/recordBook.js +4 -1
  198. package/dist/game/ruleSelection.d.ts +75 -0
  199. package/dist/game/ruleSelection.js +127 -0
  200. package/dist/game/runDraft.d.ts +5 -0
  201. package/dist/game/runDraft.js +5 -0
  202. package/dist/game/saveStore.d.ts +111 -0
  203. package/dist/game/saveStore.js +312 -0
  204. package/dist/game/snapshotHistory.d.ts +67 -0
  205. package/dist/game/snapshotHistory.js +95 -0
  206. package/dist/game/social.d.ts +38 -1
  207. package/dist/game/social.js +71 -0
  208. package/dist/game/spawnPoints.d.ts +5 -0
  209. package/dist/game/spawnPoints.js +5 -0
  210. package/dist/game/systemRuntime.d.ts +50 -0
  211. package/dist/game/systemRuntime.js +157 -0
  212. package/dist/game/systemSchedule.d.ts +72 -0
  213. package/dist/game/systemSchedule.js +242 -0
  214. package/dist/game/toasts.d.ts +43 -0
  215. package/dist/game/toasts.js +44 -0
  216. package/dist/game/trade.d.ts +10 -0
  217. package/dist/game/trade.js +10 -0
  218. package/dist/game/unlocks.d.ts +8 -0
  219. package/dist/game/unlocks.js +16 -0
  220. package/dist/game/vfxInstance.d.ts +138 -0
  221. package/dist/game/vfxInstance.js +96 -0
  222. package/dist/game/worldItem.d.ts +17 -4
  223. package/dist/game/worldItem.js +17 -4
  224. package/dist/gameplay.d.ts +91 -0
  225. package/dist/gameplay.js +91 -0
  226. package/dist/index.d.ts +5 -7
  227. package/dist/index.js +5 -7
  228. package/dist/input/actionBindings.d.ts +24 -5
  229. package/dist/input/actionBindings.js +23 -5
  230. package/dist/input/axisInput.d.ts +13 -1
  231. package/dist/input/axisInput.js +22 -1
  232. package/dist/input/controlGroups.d.ts +67 -0
  233. package/dist/input/controlGroups.js +41 -0
  234. package/dist/input/touchScheme.d.ts +82 -6
  235. package/dist/input/touchScheme.js +123 -10
  236. package/dist/interaction/contextMenu.d.ts +1 -0
  237. package/dist/interaction/contextMenu.js +1 -0
  238. package/dist/interaction/lockpick.d.ts +61 -0
  239. package/dist/interaction/lockpick.js +168 -0
  240. package/dist/interaction/proximityPrompt.d.ts +5 -1
  241. package/dist/interaction/proximityPrompt.js +5 -3
  242. package/dist/interaction/qte.d.ts +5 -0
  243. package/dist/interaction/qte.js +5 -0
  244. package/dist/interaction/skillCheck.d.ts +5 -0
  245. package/dist/interaction/skillCheck.js +5 -0
  246. package/dist/inventory/inventoryModel.d.ts +12 -0
  247. package/dist/inventory/inventoryModel.js +12 -0
  248. package/dist/inventory/shapedGrid.d.ts +16 -0
  249. package/dist/inventory/shapedGrid.js +16 -0
  250. package/dist/inventory/slotModel.d.ts +10 -0
  251. package/dist/inventory/slotModel.js +10 -0
  252. package/dist/item/durability.d.ts +5 -0
  253. package/dist/item/durability.js +5 -0
  254. package/dist/item/itemIdentity.d.ts +171 -0
  255. package/dist/item/itemIdentity.js +138 -0
  256. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  257. package/dist/item/itemInstanceRegistry.js +34 -0
  258. package/dist/item/itemgen.d.ts +163 -0
  259. package/dist/item/itemgen.js +151 -0
  260. package/dist/item/modularItem.d.ts +5 -0
  261. package/dist/item/modularItem.js +5 -0
  262. package/dist/item/use.d.ts +5 -0
  263. package/dist/item/use.js +5 -0
  264. package/dist/item/useBehavior.d.ts +142 -0
  265. package/dist/item/useBehavior.js +105 -0
  266. package/dist/item/weapon.d.ts +5 -0
  267. package/dist/item/weapon.js +5 -0
  268. package/dist/math/scalar.d.ts +25 -0
  269. package/dist/math/scalar.js +47 -0
  270. package/dist/meta/changelog.d.ts +4 -1
  271. package/dist/meta/changelog.js +36 -1
  272. package/dist/movement/avoidance.d.ts +45 -0
  273. package/dist/movement/avoidance.js +123 -0
  274. package/dist/movement/cameraRig.d.ts +8 -0
  275. package/dist/movement/cameraRig.js +8 -0
  276. package/dist/movement/dash.d.ts +11 -0
  277. package/dist/movement/dash.js +11 -0
  278. package/dist/movement/formation.d.ts +135 -0
  279. package/dist/movement/formation.js +194 -0
  280. package/dist/movement/glideModel.d.ts +5 -0
  281. package/dist/movement/glideModel.js +5 -0
  282. package/dist/movement/grappleSwing.d.ts +5 -0
  283. package/dist/movement/grappleSwing.js +5 -0
  284. package/dist/movement/leaderTrail.d.ts +5 -0
  285. package/dist/movement/leaderTrail.js +5 -0
  286. package/dist/movement/movementModel.d.ts +38 -7
  287. package/dist/movement/movementModel.js +54 -13
  288. package/dist/movement/playerMovement.d.ts +41 -0
  289. package/dist/movement/playerMovement.js +236 -0
  290. package/dist/movement/poseState.d.ts +13 -0
  291. package/dist/movement/poseState.js +16 -0
  292. package/dist/movement/steering.d.ts +8 -0
  293. package/dist/movement/steering.js +18 -0
  294. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  295. package/dist/multiplayer/combatSnapshot.js +3 -0
  296. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  297. package/dist/multiplayer/lagCompensation.js +5 -0
  298. package/dist/multiplayer/presenceModel.d.ts +9 -1
  299. package/dist/multiplayer/presenceModel.js +9 -1
  300. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  301. package/dist/multiplayer/simultaneousCommit.js +3 -0
  302. package/dist/multiplayer.d.ts +11 -0
  303. package/dist/multiplayer.js +11 -0
  304. package/dist/nav/pathFollow.d.ts +57 -0
  305. package/dist/nav/pathFollow.js +109 -0
  306. package/dist/orders/orderKinds.d.ts +156 -0
  307. package/dist/orders/orderKinds.js +197 -0
  308. package/dist/orders/orderQueue.d.ts +208 -0
  309. package/dist/orders/orderQueue.js +211 -0
  310. package/dist/physics/drivableVehicle.d.ts +29 -0
  311. package/dist/physics/drivableVehicle.js +16 -0
  312. package/dist/physics/kinematicVehicle.d.ts +21 -1
  313. package/dist/physics/kinematicVehicle.js +23 -8
  314. package/dist/physics/physicsWorld.d.ts +24 -12
  315. package/dist/physics/physicsWorld.js +11 -5
  316. package/dist/physics/radialImpulse.d.ts +25 -0
  317. package/dist/physics/radialImpulse.js +27 -0
  318. package/dist/procedural.d.ts +3 -0
  319. package/dist/procedural.js +3 -0
  320. package/dist/progression/statGraph.d.ts +116 -0
  321. package/dist/progression/statGraph.js +318 -0
  322. package/dist/puzzle/cellGrid.d.ts +9 -0
  323. package/dist/puzzle/cellGrid.js +9 -0
  324. package/dist/puzzle/fallingPiece.d.ts +9 -0
  325. package/dist/puzzle/fallingPiece.js +9 -0
  326. package/dist/puzzle/nonogram.d.ts +39 -0
  327. package/dist/puzzle/nonogram.js +136 -0
  328. package/dist/random/nameGen.d.ts +5 -0
  329. package/dist/random/nameGen.js +5 -0
  330. package/dist/random/pick.d.ts +8 -0
  331. package/dist/random/pick.js +31 -0
  332. package/dist/random/rng.d.ts +24 -0
  333. package/dist/random/rng.js +30 -8
  334. package/dist/random/seedLink.d.ts +4 -0
  335. package/dist/random/seedLink.js +4 -0
  336. package/dist/relation/keyedValues.d.ts +54 -0
  337. package/dist/relation/keyedValues.js +115 -0
  338. package/dist/relation/thresholds.d.ts +62 -0
  339. package/dist/relation/thresholds.js +62 -0
  340. package/dist/render/color.d.ts +12 -0
  341. package/dist/render/color.js +26 -0
  342. package/dist/render/lookPreset.d.ts +41 -0
  343. package/dist/render/lookPreset.js +29 -0
  344. package/dist/render/postProcessing.d.ts +76 -0
  345. package/dist/render/postProcessing.js +21 -0
  346. package/dist/rules/predicate.d.ts +53 -0
  347. package/dist/rules/predicate.js +64 -0
  348. package/dist/rules/ruleEffects.d.ts +38 -0
  349. package/dist/rules/ruleEffects.js +37 -0
  350. package/dist/rules/triggeredRules.d.ts +160 -0
  351. package/dist/rules/triggeredRules.js +241 -0
  352. package/dist/runtime/adapter.d.ts +58 -0
  353. package/dist/runtime/adapter.js +54 -5
  354. package/dist/runtime/cameraDirector.d.ts +1 -0
  355. package/dist/runtime/cameraDirector.js +1 -0
  356. package/dist/runtime/commandRunner.d.ts +1 -0
  357. package/dist/runtime/commandRunner.js +1 -0
  358. package/dist/runtime/context/combatFx.d.ts +23 -0
  359. package/dist/runtime/context/combatFx.js +161 -0
  360. package/dist/runtime/context/registries.d.ts +13 -0
  361. package/dist/runtime/context/registries.js +84 -0
  362. package/dist/runtime/context/worldItems.d.ts +21 -0
  363. package/dist/runtime/context/worldItems.js +37 -0
  364. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  365. package/dist/runtime/descriptors/baseline.js +134 -0
  366. package/dist/runtime/descriptors/features.d.ts +74 -0
  367. package/dist/runtime/descriptors/features.js +281 -0
  368. package/dist/runtime/gameContext.d.ts +163 -19
  369. package/dist/runtime/gameContext.js +385 -339
  370. package/dist/runtime/gameRuntime.d.ts +1 -0
  371. package/dist/runtime/gameRuntime.js +1 -0
  372. package/dist/runtime/headlessRunner.d.ts +60 -0
  373. package/dist/runtime/headlessRunner.js +44 -0
  374. package/dist/runtime/hostPersistence.d.ts +12 -0
  375. package/dist/runtime/hostPersistence.js +12 -0
  376. package/dist/runtime/hostedGameRunner.d.ts +54 -0
  377. package/dist/runtime/hostedGameRunner.js +85 -0
  378. package/dist/runtime/hostedWorldSession.d.ts +73 -0
  379. package/dist/runtime/hostedWorldSession.js +64 -0
  380. package/dist/runtime/inputSnapshot.d.ts +21 -3
  381. package/dist/runtime/inputSnapshot.js +8 -2
  382. package/dist/runtime/motionIntents.d.ts +12 -1
  383. package/dist/runtime/motionIntents.js +26 -1
  384. package/dist/runtime/perContext.d.ts +15 -0
  385. package/dist/runtime/perContext.js +21 -0
  386. package/dist/runtime/runtimeSave.d.ts +79 -0
  387. package/dist/runtime/runtimeSave.js +105 -0
  388. package/dist/runtime/save.d.ts +4 -0
  389. package/dist/runtime/save.js +4 -0
  390. package/dist/runtime/snapshot.d.ts +7 -0
  391. package/dist/runtime/snapshot.js +7 -0
  392. package/dist/runtime/visibility.d.ts +2 -1
  393. package/dist/runtime/visibility.js +2 -1
  394. package/dist/runtime/worldChannel.d.ts +62 -0
  395. package/dist/runtime/worldChannel.js +114 -0
  396. package/dist/runtime/worldMirror.d.ts +36 -0
  397. package/dist/runtime/worldMirror.js +44 -0
  398. package/dist/runtime/worldProjection.d.ts +47 -0
  399. package/dist/runtime/worldProjection.js +52 -0
  400. package/dist/runtime/worldReplication.d.ts +69 -0
  401. package/dist/runtime/worldReplication.js +217 -0
  402. package/dist/runtime/worldSnapshot.d.ts +44 -0
  403. package/dist/runtime/worldSnapshot.js +30 -0
  404. package/dist/scene/assetCatalog.d.ts +22 -0
  405. package/dist/scene/assetCatalog.js +4 -0
  406. package/dist/scene/assetDiagnostics.d.ts +69 -0
  407. package/dist/scene/assetDiagnostics.js +110 -0
  408. package/dist/scene/assetGenerator.d.ts +65 -0
  409. package/dist/scene/assetGenerator.js +64 -0
  410. package/dist/scene/assetSpace.d.ts +137 -0
  411. package/dist/scene/assetSpace.js +259 -0
  412. package/dist/scene/authoredTriggers.d.ts +169 -0
  413. package/dist/scene/authoredTriggers.js +340 -0
  414. package/dist/scene/behaviorRuntime.d.ts +75 -0
  415. package/dist/scene/behaviorRuntime.js +217 -0
  416. package/dist/scene/behaviors.d.ts +14 -2
  417. package/dist/scene/behaviors.js +7 -2
  418. package/dist/scene/bodyBind.d.ts +60 -0
  419. package/dist/scene/bodyBind.js +51 -0
  420. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  421. package/dist/scene/builtinSceneKinds.js +62 -0
  422. package/dist/scene/colliders.d.ts +18 -0
  423. package/dist/scene/colliders.js +61 -1
  424. package/dist/scene/entityStats.d.ts +13 -0
  425. package/dist/scene/entityStats.js +30 -0
  426. package/dist/scene/entityStore.d.ts +41 -1
  427. package/dist/scene/entityStore.js +75 -0
  428. package/dist/scene/facing.d.ts +18 -0
  429. package/dist/scene/facing.js +26 -0
  430. package/dist/scene/modelSockets.d.ts +33 -0
  431. package/dist/scene/modelSockets.js +29 -0
  432. package/dist/scene/objectQuery.d.ts +2 -0
  433. package/dist/scene/objectQuery.js +2 -0
  434. package/dist/scene/objectStore.d.ts +4 -0
  435. package/dist/scene/objectStore.js +6 -0
  436. package/dist/scene/possession.d.ts +8 -0
  437. package/dist/scene/possession.js +14 -0
  438. package/dist/scene/roster.d.ts +3 -0
  439. package/dist/scene/roster.js +12 -0
  440. package/dist/scene/sceneKinds.d.ts +240 -0
  441. package/dist/scene/sceneKinds.js +214 -0
  442. package/dist/scene/sceneOwnership.d.ts +169 -0
  443. package/dist/scene/sceneOwnership.js +179 -0
  444. package/dist/scene/selectionBookmarks.d.ts +93 -0
  445. package/dist/scene/selectionBookmarks.js +122 -0
  446. package/dist/scene/vehicleSeat.d.ts +68 -0
  447. package/dist/scene/vehicleSeat.js +59 -0
  448. package/dist/sensor/concealment.d.ts +3 -0
  449. package/dist/sensor/concealment.js +3 -0
  450. package/dist/sensor/freezeMonitor.d.ts +1 -0
  451. package/dist/sensor/freezeMonitor.js +1 -0
  452. package/dist/sensor/frustumSensor.d.ts +7 -3
  453. package/dist/sensor/frustumSensor.js +7 -3
  454. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  455. package/dist/sensor/hiddenStateProbe.js +5 -2
  456. package/dist/sensor/recordingBuffer.d.ts +2 -1
  457. package/dist/sensor/recordingBuffer.js +2 -1
  458. package/dist/sensor/replayLoop.d.ts +6 -2
  459. package/dist/sensor/replayLoop.js +6 -2
  460. package/dist/sensor/revealQuery.d.ts +2 -1
  461. package/dist/sensor/revealQuery.js +2 -1
  462. package/dist/sensor/visionCone.d.ts +10 -3
  463. package/dist/sensor/visionCone.js +10 -3
  464. package/dist/session/contestedChannel.d.ts +1 -0
  465. package/dist/session/contestedChannel.js +1 -0
  466. package/dist/session/extraction.d.ts +1 -0
  467. package/dist/session/extraction.js +1 -0
  468. package/dist/session/roles.d.ts +6 -0
  469. package/dist/session/roles.js +6 -0
  470. package/dist/session/roundState.d.ts +8 -0
  471. package/dist/session/roundState.js +2 -0
  472. package/dist/settings/settingsModel.d.ts +1 -0
  473. package/dist/settings/settingsModel.js +1 -0
  474. package/dist/stats/accumulatorMeter.d.ts +6 -0
  475. package/dist/stats/accumulatorMeter.js +6 -0
  476. package/dist/stats/eventMeter.d.ts +5 -0
  477. package/dist/stats/eventMeter.js +5 -0
  478. package/dist/stats/rollCheck.d.ts +5 -0
  479. package/dist/stats/rollCheck.js +5 -0
  480. package/dist/stats/statModifiers.d.ts +5 -0
  481. package/dist/stats/statModifiers.js +5 -0
  482. package/dist/store/defineKeyedStore.d.ts +38 -0
  483. package/dist/store/defineKeyedStore.js +42 -0
  484. package/dist/store/defineStore.d.ts +33 -0
  485. package/dist/store/defineStore.js +35 -0
  486. package/dist/store/observableKeyedStore.d.ts +9 -0
  487. package/dist/store/observableKeyedStore.js +43 -2
  488. package/dist/survival/decayMeter.d.ts +55 -0
  489. package/dist/survival/decayMeter.js +130 -55
  490. package/dist/survival/moodle.d.ts +2 -0
  491. package/dist/survival/regionHealth.d.ts +6 -0
  492. package/dist/survival/regionHealth.js +5 -0
  493. package/dist/tactics/fallingGrid.d.ts +6 -4
  494. package/dist/tactics/fallingGrid.js +6 -4
  495. package/dist/tactics/predictiveQuery.d.ts +3 -0
  496. package/dist/tactics/predictiveQuery.js +3 -0
  497. package/dist/tactics/snapshot.d.ts +2 -0
  498. package/dist/tactics/snapshot.js +2 -0
  499. package/dist/tactics/surface.d.ts +1 -0
  500. package/dist/tactics/surface.js +1 -0
  501. package/dist/tactics/tacticalGrid.d.ts +1 -0
  502. package/dist/tactics/tacticalGrid.js +1 -0
  503. package/dist/time/beatClock.d.ts +14 -4
  504. package/dist/time/beatClock.js +14 -4
  505. package/dist/time/calendarClock.d.ts +3 -0
  506. package/dist/time/calendarClock.js +3 -0
  507. package/dist/time/idleProgress.d.ts +4 -0
  508. package/dist/time/idleProgress.js +4 -0
  509. package/dist/time/simClock.d.ts +2 -0
  510. package/dist/time/simClock.js +20 -5
  511. package/dist/ui/actionModel.d.ts +110 -0
  512. package/dist/ui/actionModel.js +159 -0
  513. package/dist/ui/gameLayout.d.ts +144 -0
  514. package/dist/ui/gameLayout.js +148 -0
  515. package/dist/ui/hudDocument.d.ts +114 -0
  516. package/dist/ui/hudDocument.js +220 -0
  517. package/dist/ui/hudLayout.d.ts +33 -1
  518. package/dist/ui/hudLayout.js +204 -17
  519. package/dist/ui/orientation.d.ts +39 -0
  520. package/dist/ui/orientation.js +49 -0
  521. package/dist/ui/selectionModel.d.ts +92 -0
  522. package/dist/ui/selectionModel.js +88 -0
  523. package/dist/ui/swingTimer.d.ts +42 -0
  524. package/dist/ui/swingTimer.js +38 -0
  525. package/dist/ui/tooltipModel.d.ts +63 -0
  526. package/dist/ui/tooltipModel.js +82 -0
  527. package/dist/ui.d.ts +15 -0
  528. package/dist/ui.js +15 -0
  529. package/dist/visibility/bounds.d.ts +8 -1
  530. package/dist/visibility/bounds.js +8 -1
  531. package/dist/visibility/frustum.d.ts +12 -3
  532. package/dist/visibility/frustum.js +12 -3
  533. package/dist/visibility/spatialIndex.js +34 -20
  534. package/dist/work/jobQueue.d.ts +201 -0
  535. package/dist/work/jobQueue.js +253 -0
  536. package/dist/work/unitTraining.d.ts +58 -0
  537. package/dist/work/unitTraining.js +52 -0
  538. package/dist/world/authoredObjects.d.ts +58 -0
  539. package/dist/world/authoredObjects.js +69 -0
  540. package/dist/world/buildingGenerator.d.ts +18 -0
  541. package/dist/world/buildingGenerator.js +62 -0
  542. package/dist/world/buildings.d.ts +5 -0
  543. package/dist/world/buildings.js +5 -0
  544. package/dist/world/catenary.d.ts +22 -0
  545. package/dist/world/catenary.js +69 -0
  546. package/dist/world/environmentSummary.d.ts +11 -2
  547. package/dist/world/environmentSummary.js +11 -1
  548. package/dist/world/features.d.ts +244 -7
  549. package/dist/world/features.js +92 -4
  550. package/dist/world/footprintGrid.d.ts +59 -0
  551. package/dist/world/footprintGrid.js +141 -0
  552. package/dist/world/geometry.d.ts +64 -0
  553. package/dist/world/geometry.js +94 -0
  554. package/dist/world/grassKind.d.ts +51 -0
  555. package/dist/world/grassKind.js +101 -0
  556. package/dist/world/pathInstances.d.ts +27 -0
  557. package/dist/world/pathInstances.js +27 -0
  558. package/dist/world/pathTerrain.d.ts +80 -0
  559. package/dist/world/pathTerrain.js +142 -0
  560. package/dist/world/placeAsset.d.ts +81 -0
  561. package/dist/world/placeAsset.js +77 -0
  562. package/dist/world/placement.d.ts +4 -0
  563. package/dist/world/placement.js +4 -0
  564. package/dist/world/placementController.d.ts +6 -0
  565. package/dist/world/placementController.js +6 -0
  566. package/dist/world/polyline.d.ts +34 -0
  567. package/dist/world/polyline.js +81 -0
  568. package/dist/world/roads.d.ts +55 -0
  569. package/dist/world/roads.js +184 -0
  570. package/dist/world/scatterRegion.d.ts +164 -0
  571. package/dist/world/scatterRegion.js +409 -0
  572. package/dist/world/sceneShapes.d.ts +43 -0
  573. package/dist/world/sceneShapes.js +1 -0
  574. package/dist/world/segment.d.ts +27 -0
  575. package/dist/world/segment.js +43 -0
  576. package/dist/world/soilKind.d.ts +48 -0
  577. package/dist/world/soilKind.js +92 -0
  578. package/dist/world/spatialSample.d.ts +241 -0
  579. package/dist/world/spatialSample.js +465 -0
  580. package/dist/world/streets.d.ts +80 -0
  581. package/dist/world/streets.js +144 -0
  582. package/dist/world/terraform.d.ts +213 -1
  583. package/dist/world/terraform.js +655 -20
  584. package/dist/world/terrain.d.ts +138 -12
  585. package/dist/world/terrain.js +346 -28
  586. package/dist/world/terrainGuides.d.ts +182 -0
  587. package/dist/world/terrainGuides.js +343 -0
  588. package/dist/world/vec2.d.ts +81 -0
  589. package/dist/world/vec2.js +128 -0
  590. package/dist/world/vec3.d.ts +49 -0
  591. package/dist/world/vec3.js +76 -0
  592. package/dist/world/vegetation.d.ts +71 -0
  593. package/dist/world/vegetation.js +151 -0
  594. package/dist/world/visibilityField.d.ts +154 -0
  595. package/dist/world/visibilityField.js +271 -0
  596. package/dist/world/volumetricClouds.d.ts +52 -0
  597. package/dist/world/volumetricClouds.js +43 -0
  598. package/dist/world/walls.d.ts +9 -0
  599. package/dist/world/walls.js +9 -0
  600. package/dist/world/waterKind.d.ts +55 -0
  601. package/dist/world/waterKind.js +99 -0
  602. package/dist/world.d.ts +132 -0
  603. package/dist/world.js +132 -0
  604. package/package.json +32 -8
  605. package/skills/jgengine/SKILL.md +51 -0
  606. package/skills/jgengine/api.md +434 -0
  607. package/skills/jgengine/capabilities.md +29 -0
  608. package/skills/jgengine/reference-cartridge.md +72 -0
  609. package/skills/jgengine-combat/SKILL.md +34 -0
  610. package/skills/jgengine-combat/api.md +549 -0
  611. package/skills/jgengine-combat/capabilities.md +169 -0
  612. package/skills/jgengine-combat/reference.md +98 -0
  613. package/skills/jgengine-gameplay/SKILL.md +39 -0
  614. package/skills/jgengine-gameplay/api.md +1794 -0
  615. package/skills/jgengine-gameplay/capabilities.md +378 -0
  616. package/skills/jgengine-gameplay/reference-systems.md +60 -0
  617. package/skills/jgengine-world/SKILL.md +38 -0
  618. package/skills/jgengine-world/api.md +2652 -0
  619. package/skills/jgengine-world/capabilities.md +370 -0
  620. package/skills/jgengine-world/reference.md +222 -0
  621. package/dist/cartridge/runtime.d.ts +0 -15
  622. package/dist/cartridge/runtime.js +0 -556
  623. package/dist/cartridge/spec.d.ts +0 -188
  624. package/dist/cartridge/spec.js +0 -19
  625. package/dist/cartridge/validate.d.ts +0 -2
  626. package/dist/cartridge/validate.js +0 -78
  627. package/dist/store/engineStore.d.ts +0 -22
  628. package/dist/store/engineStore.js +0 -50
  629. package/dist/store/features.d.ts +0 -10
  630. package/dist/store/features.js +0 -23
  631. package/llms.txt +0 -4983
@@ -1,556 +0,0 @@
1
- import { advanceSpawnDirector, createSpawnDirectorState } from "../ai/spawnDirector.js";
2
- import { createAbilityKit } from "../combat/abilityKit.js";
3
- import { setGamePhase } from "../game/gamePhase.js";
4
- import { leveling } from "../game/progression.js";
5
- import { createRunDraft } from "../game/runDraft.js";
6
- import { aimToPoint } from "../input/pointer.js";
7
- import { seededRng } from "../item/affix.js";
8
- import { selectAutoTarget } from "../scene/autoTarget.js";
9
- import { HIT_EFFECT, XP_GEM_BASE_TYPE, leveled, } from "./spec.js";
10
- function gemRarity(spec, value) {
11
- for (const [threshold, rarity] of spec.xpGems.rarityThresholds) {
12
- if (value >= threshold)
13
- return rarity;
14
- }
15
- return spec.xpGems.defaultRarity;
16
- }
17
- function facing(fromX, fromZ, toX, toZ) {
18
- return Math.atan2(toX - fromX, toZ - fromZ);
19
- }
20
- function buildKit(spec, levels) {
21
- return createAbilityKit(Object.entries(spec.weapons).map(([id, weapon]) => ({
22
- id,
23
- cooldownMs: leveled(weapon.cooldownMs, levels[id] ?? 1),
24
- })));
25
- }
26
- function compileEntities(spec) {
27
- const out = {
28
- [spec.player.kind]: {
29
- role: "player",
30
- movement: { walkSpeed: spec.player.walkSpeed },
31
- stats: {
32
- health: { max: spec.player.health, min: 0 },
33
- xp: { max: 1, min: 0, current: 0 },
34
- level: { max: spec.progression.maxLevel, min: 1, current: 1 },
35
- },
36
- receive: { hit: { order: ["health"] } },
37
- },
38
- };
39
- for (const [id, enemy] of Object.entries(spec.enemies)) {
40
- out[id] = {
41
- role: "enemy",
42
- movement: { walkSpeed: enemy.walkSpeed },
43
- stats: { health: { max: enemy.health, min: 0 } },
44
- receive: { hit: { order: ["health"] } },
45
- };
46
- }
47
- return out;
48
- }
49
- export function createCartridge(spec) {
50
- const track = leveling({ xpForLevel: spec.progression.xp, maxLevel: spec.progression.maxLevel });
51
- const entities = compileEntities(spec);
52
- const runs = new WeakMap();
53
- function initialPhase() {
54
- if (spec.flow?.start === "gate")
55
- return "start";
56
- if ((spec.flow?.countdownSeconds ?? 0) > 0)
57
- return "countdown";
58
- return "playing";
59
- }
60
- function seededState() {
61
- const seed = spec.seed ?? "cartridge";
62
- const weaponLevels = {};
63
- for (const id of Object.keys(spec.weapons))
64
- weaponLevels[id] = 1;
65
- const offers = spec.progression.draft.upgrades.map((upgrade) => ({
66
- id: upgrade.id,
67
- label: upgrade.label,
68
- weight: upgrade.weight,
69
- maxStacks: upgrade.maxStacks,
70
- }));
71
- return {
72
- rng: seededRng(seed),
73
- spawn: createSpawnDirectorState(spec.spawning.director),
74
- weaponLevels,
75
- kit: buildKit(spec, weaponLevels),
76
- fields: { ...spec.fields },
77
- enemyNextHitAt: new Map(),
78
- phase: initialPhase(),
79
- playingSeconds: 0,
80
- countdownRemaining: spec.flow?.countdownSeconds ?? 0,
81
- kills: 0,
82
- levelUpQueue: 0,
83
- draft: createRunDraft({ offers, rng: seededRng(`${seed}-draft`) }),
84
- pendingOffers: null,
85
- bolts: [],
86
- pulses: [],
87
- fxCounter: 0,
88
- };
89
- }
90
- function createRun() {
91
- const run = {
92
- ...seededState(),
93
- listeners: new Set(),
94
- view: {
95
- get phase() {
96
- return run.phase;
97
- },
98
- get playingSeconds() {
99
- return run.playingSeconds;
100
- },
101
- get countdownRemaining() {
102
- return run.countdownRemaining;
103
- },
104
- get kills() {
105
- return run.kills;
106
- },
107
- weaponLevel: (weaponId) => run.weaponLevels[weaponId] ?? 1,
108
- field: (name) => run.fields[name] ?? 0,
109
- get pendingOffers() {
110
- if (run.pendingOffers === null)
111
- return null;
112
- return run.pendingOffers.map((offer) => ({ id: offer.id, label: offer.label ?? offer.id }));
113
- },
114
- get bolts() {
115
- return run.bolts;
116
- },
117
- get pulses() {
118
- return run.pulses;
119
- },
120
- subscribe(listener) {
121
- run.listeners.add(listener);
122
- return () => run.listeners.delete(listener);
123
- },
124
- },
125
- };
126
- return run;
127
- }
128
- function getRun(ctx) {
129
- let existing = runs.get(ctx);
130
- if (existing === undefined) {
131
- existing = createRun();
132
- runs.set(ctx, existing);
133
- }
134
- return existing;
135
- }
136
- function notify(run) {
137
- for (const listener of run.listeners)
138
- listener();
139
- }
140
- function syncPhase(ctx, run) {
141
- setGamePhase(ctx, run.phase === "playing" ? "playing" : run.phase === "won" || run.phase === "lost" ? "ended" : "menu");
142
- }
143
- function damageMultiplier(run) {
144
- return run.fields["damageMultiplier"] ?? 1;
145
- }
146
- function spawnPoint(ctx, run) {
147
- const placement = spec.spawning.placement;
148
- if (placement.kind === "custom")
149
- return placement.position(ctx, run.view);
150
- const angle = run.rng() * Math.PI * 2;
151
- const x = Math.cos(angle) * placement.radius;
152
- const z = Math.sin(angle) * placement.radius;
153
- return [x, ctx.world.groundHeightAt(x, z), z];
154
- }
155
- function advanceSpawning(ctx, run, dt) {
156
- const alive = ctx.scene.entity.list().filter((entity) => spec.enemies[entity.name] !== undefined).length;
157
- const step = advanceSpawnDirector(spec.spawning.director, run.spawn, dt, { alive, players: 1 });
158
- run.spawn = step.state;
159
- for (const request of step.spawns) {
160
- if (spec.enemies[request.entryId] === undefined)
161
- continue;
162
- ctx.scene.entity.spawn(request.entryId, { position: spawnPoint(ctx, run) });
163
- }
164
- }
165
- function advanceEnemies(ctx, run, dt) {
166
- const playerId = ctx.player.userId;
167
- const player = ctx.scene.entity.get(playerId);
168
- if (player === null)
169
- return;
170
- const now = ctx.time.now();
171
- for (const enemy of ctx.scene.entity.list()) {
172
- const def = spec.enemies[enemy.name];
173
- if (def === undefined)
174
- continue;
175
- const next = def.behavior === "none" ? null : ctx.scene.entity.moveToward(enemy.id, playerId, { speed: def.walkSpeed, dt });
176
- if (next !== null) {
177
- const grounded = [
178
- next[0],
179
- ctx.world.groundHeightAt(next[0], next[2]),
180
- next[2],
181
- ];
182
- ctx.scene.entity.setPose(enemy.id, {
183
- position: grounded,
184
- rotationY: facing(enemy.position[0], enemy.position[2], player.position[0], player.position[2]),
185
- });
186
- }
187
- const distance = ctx.scene.entity.distance(enemy.id, playerId);
188
- if (distance === null || distance > spec.combat.contactRadius)
189
- continue;
190
- const readyAt = run.enemyNextHitAt.get(enemy.id) ?? 0;
191
- if (now < readyAt)
192
- continue;
193
- run.enemyNextHitAt.set(enemy.id, now + def.contact.intervalSeconds);
194
- ctx.scene.entity.effect({ from: enemy.id, to: playerId, effect: HIT_EFFECT, via: { amount: def.contact.damage } });
195
- }
196
- }
197
- function enemyIds(ctx) {
198
- return ctx.scene.entity
199
- .list()
200
- .filter((entity) => spec.enemies[entity.name] !== undefined)
201
- .map((entity) => entity.id);
202
- }
203
- function fireProjectile(ctx, run, weaponId, weapon, playerId, playerPos, enemies) {
204
- const targetId = selectAutoTarget("nearest", playerId, {
205
- candidates: () => enemies,
206
- distance: (from, to) => ctx.scene.entity.distance(from, to),
207
- });
208
- if (targetId === null)
209
- return;
210
- const target = ctx.scene.entity.get(targetId);
211
- if (target === null)
212
- return;
213
- const dx = target.position[0] - playerPos[0];
214
- const dz = target.position[2] - playerPos[2];
215
- const distance = Math.hypot(dx, dz);
216
- if (distance > weapon.range)
217
- return;
218
- run.kit.cast(weaponId);
219
- const level = run.weaponLevels[weaponId] ?? 1;
220
- const damage = leveled(weapon.damage, level) * damageMultiplier(run);
221
- const aim = aimToPoint(playerPos, target.position);
222
- const shotId = ctx.scene.entity.fireProjectile({ from: playerId, via: { amount: damage }, aim, effect: HIT_EFFECT });
223
- const travelSeconds = Math.min(1.1, Math.max(0.08, distance / weapon.speed));
224
- run.fxCounter += 1;
225
- run.bolts.push({
226
- id: run.fxCounter,
227
- weaponId,
228
- origin: playerPos,
229
- target: target.position,
230
- firedAt: ctx.time.now(),
231
- travelSeconds,
232
- });
233
- ctx.time.after(travelSeconds, () => {
234
- ctx.scene.entity.settleProjectile(shotId);
235
- });
236
- }
237
- function fireOrbit(ctx, run, weaponId, weapon, playerId, playerPos, enemies) {
238
- run.kit.cast(weaponId);
239
- const level = run.weaponLevels[weaponId] ?? 1;
240
- const damage = leveled(weapon.damage, level) * damageMultiplier(run);
241
- const blades = leveled(weapon.blades, level);
242
- const radius = leveled(weapon.radius, level);
243
- const angle = ctx.time.now() * weapon.angularSpeed;
244
- const alreadyHit = new Set();
245
- for (let blade = 0; blade < blades; blade += 1) {
246
- const theta = angle + (blade * Math.PI * 2) / blades;
247
- const bladePos = [
248
- playerPos[0] + Math.cos(theta) * radius,
249
- playerPos[1],
250
- playerPos[2] + Math.sin(theta) * radius,
251
- ];
252
- for (const instanceId of ctx.scene.entity.inRadius(bladePos, weapon.hitRadius, (id) => enemies.includes(id))) {
253
- if (alreadyHit.has(instanceId))
254
- continue;
255
- alreadyHit.add(instanceId);
256
- ctx.scene.entity.effect({ from: playerId, to: instanceId, effect: HIT_EFFECT, via: { amount: damage } });
257
- }
258
- }
259
- }
260
- function firePulse(ctx, run, weaponId, weapon, playerId, playerPos) {
261
- run.kit.cast(weaponId);
262
- const level = run.weaponLevels[weaponId] ?? 1;
263
- const damage = leveled(weapon.damage, level) * damageMultiplier(run);
264
- const radius = leveled(weapon.radius, level);
265
- ctx.scene.entity.effect({ from: playerId, effect: HIT_EFFECT, via: { amount: damage }, at: playerPos, radius, falloff: "linear" });
266
- run.fxCounter += 1;
267
- run.pulses.push({
268
- id: run.fxCounter,
269
- weaponId,
270
- at: playerPos,
271
- firedAt: ctx.time.now(),
272
- durationSeconds: weapon.durationSeconds,
273
- maxRadius: radius,
274
- });
275
- }
276
- function fireWeapons(ctx, run, dt) {
277
- run.kit.tick(dt);
278
- const playerId = ctx.player.userId;
279
- const player = ctx.scene.entity.get(playerId);
280
- if (player === null)
281
- return;
282
- const enemies = enemyIds(ctx);
283
- for (const [weaponId, weapon] of Object.entries(spec.weapons)) {
284
- const state = run.kit.state(weaponId);
285
- if (state === null || !state.ready)
286
- continue;
287
- if (weapon.kind === "projectile") {
288
- fireProjectile(ctx, run, weaponId, weapon, playerId, player.position, enemies);
289
- }
290
- else if (weapon.kind === "orbit") {
291
- fireOrbit(ctx, run, weaponId, weapon, playerId, player.position, enemies);
292
- }
293
- else if (weapon.kind === "pulse") {
294
- firePulse(ctx, run, weaponId, weapon, playerId, player.position);
295
- }
296
- else {
297
- run.kit.cast(weaponId);
298
- const level = run.weaponLevels[weaponId] ?? 1;
299
- weapon.fire(ctx, run.view, {
300
- weaponId,
301
- level,
302
- damage: leveled(weapon.damage, level) * damageMultiplier(run),
303
- playerId,
304
- playerPosition: player.position,
305
- enemyIds: enemies,
306
- dt,
307
- });
308
- }
309
- }
310
- }
311
- function maybeOpenDraft(ctx, run) {
312
- if (run.pendingOffers !== null || run.levelUpQueue <= 0 || run.phase !== "playing")
313
- return;
314
- run.levelUpQueue -= 1;
315
- run.pendingOffers = run.draft.present(spec.progression.draft.choices);
316
- ctx.time.pause();
317
- notify(run);
318
- }
319
- function onLevelUp(ctx, run, level) {
320
- ctx.game.events.emit("stat.levelUp", { userId: ctx.player.userId, stat: "level", level });
321
- run.levelUpQueue += 1;
322
- maybeOpenDraft(ctx, run);
323
- }
324
- function advancePickups(ctx, run, dt) {
325
- const playerId = ctx.player.userId;
326
- if (ctx.scene.entity.get(playerId) === null)
327
- return;
328
- const magnetRadius = run.fields["magnetRadius"] ?? 0;
329
- for (const record of ctx.scene.worldItem.list()) {
330
- if (record.baseType !== XP_GEM_BASE_TYPE)
331
- continue;
332
- const distance = ctx.scene.entity.distance(record.instanceId, playerId);
333
- if (distance === null)
334
- continue;
335
- if (distance <= spec.xpGems.collectRadius) {
336
- ctx.scene.worldItem.consume(record.instanceId);
337
- track.grantXp({
338
- get: (userId, statId) => ctx.scene.entity.stats.get(userId, statId),
339
- set: (userId, statId, patch) => ctx.scene.entity.stats.set(userId, statId, patch),
340
- }, playerId, record.count, (level) => onLevelUp(ctx, run, level));
341
- continue;
342
- }
343
- if (distance > magnetRadius)
344
- continue;
345
- const next = ctx.scene.entity.moveToward(record.instanceId, playerId, { speed: spec.xpGems.pullSpeed, dt });
346
- if (next !== null) {
347
- const grounded = [
348
- next[0],
349
- ctx.world.groundHeightAt(next[0], next[2]),
350
- next[2],
351
- ];
352
- ctx.scene.entity.setPose(record.instanceId, { position: grounded });
353
- }
354
- }
355
- }
356
- function pruneFx(ctx, run) {
357
- const now = ctx.time.now();
358
- run.bolts = run.bolts.filter((bolt) => now - bolt.firedAt <= bolt.travelSeconds + 0.15);
359
- run.pulses = run.pulses.filter((pulse) => now - pulse.firedAt <= pulse.durationSeconds + 0.05);
360
- }
361
- function applyUpgrade(ctx, run, offerId) {
362
- const upgrade = spec.progression.draft.upgrades.find((entry) => entry.id === offerId);
363
- if (upgrade === undefined)
364
- return;
365
- const stacks = run.draft.stack().count(offerId);
366
- const effect = upgrade.effect;
367
- switch (effect.kind) {
368
- case "weaponLevel": {
369
- run.weaponLevels[effect.weapon] = 1 + stacks;
370
- run.kit = buildKit(spec, run.weaponLevels);
371
- return;
372
- }
373
- case "statBonus": {
374
- const current = ctx.scene.entity.stats.get(ctx.player.userId, effect.stat);
375
- const max = (current?.max ?? 0) + effect.amount;
376
- const value = (current?.current ?? 0) + effect.amount;
377
- ctx.scene.entity.stats.set(ctx.player.userId, effect.stat, { max, current: value });
378
- return;
379
- }
380
- case "fieldAdd": {
381
- const base = spec.fields?.[effect.field] ?? 0;
382
- run.fields[effect.field] = base + effect.amount * stacks;
383
- return;
384
- }
385
- case "fieldMultiply": {
386
- const base = spec.fields?.[effect.field] ?? 1;
387
- run.fields[effect.field] = base * effect.factor ** stacks;
388
- return;
389
- }
390
- case "custom": {
391
- effect.apply(ctx, run.view, stacks);
392
- return;
393
- }
394
- }
395
- }
396
- function chooseUpgrade(ctx, offerId) {
397
- const run = getRun(ctx);
398
- if (run.pendingOffers === null)
399
- return;
400
- if (!run.draft.choose(offerId))
401
- return;
402
- applyUpgrade(ctx, run, offerId);
403
- run.pendingOffers = null;
404
- ctx.time.play();
405
- notify(run);
406
- maybeOpenDraft(ctx, run);
407
- }
408
- function registerEvents(ctx) {
409
- const run = getRun(ctx);
410
- syncPhase(ctx, run);
411
- if (spec.rules.killLeaderboardStat !== undefined) {
412
- ctx.game.leaderboard.track({ stat: spec.rules.killLeaderboardStat, scope: "profile" });
413
- }
414
- run.disposeEvents?.();
415
- run.disposeEvents = ctx.game.events.on("entity.died", (event) => {
416
- if (event.instanceId === ctx.player.userId) {
417
- if (spec.rules.lose?.kind === "playerDeath" && run.phase === "playing") {
418
- run.phase = "lost";
419
- syncPhase(ctx, run);
420
- notify(run);
421
- }
422
- return;
423
- }
424
- if (event.reason.kind !== "player_kill")
425
- return;
426
- const def = spec.enemies[event.catalogId];
427
- if (def === undefined)
428
- return;
429
- run.kills += 1;
430
- if (spec.rules.killLeaderboardStat !== undefined) {
431
- ctx.game.leaderboard.increment(ctx.player.userId, spec.rules.killLeaderboardStat, { scope: "profile" });
432
- }
433
- ctx.scene.worldItem.spawn({
434
- itemId: XP_GEM_BASE_TYPE,
435
- baseType: XP_GEM_BASE_TYPE,
436
- position: event.position,
437
- count: def.xp,
438
- rarity: gemRarity(spec, def.xp),
439
- });
440
- });
441
- }
442
- function checkOutcome(ctx, run) {
443
- const win = spec.rules.win;
444
- if (win !== undefined) {
445
- const won = win.kind === "survive" ? run.playingSeconds >= win.seconds : win.check(ctx, run.view);
446
- if (won) {
447
- run.phase = "won";
448
- syncPhase(ctx, run);
449
- notify(run);
450
- return;
451
- }
452
- }
453
- const lose = spec.rules.lose;
454
- if (lose?.kind === "custom" && lose.check(ctx, run.view)) {
455
- run.phase = "lost";
456
- syncPhase(ctx, run);
457
- notify(run);
458
- }
459
- }
460
- function begin(ctx) {
461
- const run = getRun(ctx);
462
- if (run.phase !== "start")
463
- return;
464
- run.phase = run.countdownRemaining > 0 ? "countdown" : "playing";
465
- syncPhase(ctx, run);
466
- notify(run);
467
- }
468
- function despawnCartridgeEntities(ctx) {
469
- for (const entity of ctx.scene.entity.list()) {
470
- if (spec.enemies[entity.name] !== undefined)
471
- ctx.scene.entity.despawn(entity.id);
472
- }
473
- for (const record of ctx.scene.worldItem.list()) {
474
- if (record.baseType === XP_GEM_BASE_TYPE)
475
- ctx.scene.entity.despawn(record.instanceId);
476
- }
477
- }
478
- function reset(ctx) {
479
- const run = getRun(ctx);
480
- Object.assign(run, seededState());
481
- despawnCartridgeEntities(ctx);
482
- if (ctx.scene.entity.get(ctx.player.userId) === null) {
483
- ctx.scene.entity.spawn(spec.player.kind, {
484
- id: ctx.player.userId,
485
- position: spec.player.spawnAt ?? [0, 0, 0],
486
- });
487
- }
488
- ctx.scene.entity.stats.set(ctx.player.userId, "health", { max: spec.player.health, current: spec.player.health });
489
- ctx.scene.entity.stats.set(ctx.player.userId, "xp", { max: track.xpForLevel(1), current: 0 });
490
- ctx.scene.entity.stats.set(ctx.player.userId, "level", { current: 1 });
491
- ctx.scene.entity.setPose(ctx.player.userId, { position: spec.player.spawnAt ?? [0, 0, 0] });
492
- ctx.time.play();
493
- syncPhase(ctx, run);
494
- notify(run);
495
- }
496
- function tick(ctx, dt) {
497
- const run = getRun(ctx);
498
- if (dt <= 0 || run.pendingOffers !== null)
499
- return;
500
- if (run.phase === "countdown") {
501
- run.countdownRemaining -= dt;
502
- if (run.countdownRemaining <= 0) {
503
- run.countdownRemaining = 0;
504
- run.phase = "playing";
505
- syncPhase(ctx, run);
506
- }
507
- notify(run);
508
- return;
509
- }
510
- if (run.phase !== "playing")
511
- return;
512
- run.playingSeconds += dt;
513
- advanceSpawning(ctx, run, dt);
514
- advanceEnemies(ctx, run, dt);
515
- fireWeapons(ctx, run, dt);
516
- advancePickups(ctx, run, dt);
517
- pruneFx(ctx, run);
518
- for (const system of spec.systems ?? [])
519
- system(ctx, run.view, dt);
520
- checkOutcome(ctx, run);
521
- }
522
- const loop = {
523
- onInit(ctx) {
524
- registerEvents(ctx);
525
- if (spec.flow?.restart === true && !ctx.game.commands.has("restart")) {
526
- ctx.game.commands.define("restart", {
527
- apply(state) {
528
- reset(ctx);
529
- return state;
530
- },
531
- });
532
- }
533
- },
534
- onNewPlayer(ctx) {
535
- ctx.scene.entity.spawn(spec.player.kind, {
536
- id: ctx.player.userId,
537
- position: spec.player.spawnAt ?? [0, 0, 0],
538
- });
539
- ctx.scene.entity.stats.set(ctx.player.userId, "xp", { max: track.xpForLevel(1), current: 0 });
540
- ctx.scene.entity.stats.set(ctx.player.userId, "level", { current: 1 });
541
- },
542
- onTick(ctx, dt) {
543
- tick(ctx, dt);
544
- },
545
- };
546
- return {
547
- content: { entityById: (id) => entities[id] ?? null },
548
- loop,
549
- run: (ctx) => getRun(ctx).view,
550
- weaponKit: (ctx) => getRun(ctx).kit,
551
- chooseUpgrade,
552
- begin,
553
- reset,
554
- spec,
555
- };
556
- }