@v12-engine/engine 0.1.0 → 0.4.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 (951) hide show
  1. package/dist/abilities/amounts.d.ts +28 -0
  2. package/dist/abilities/amounts.js +74 -0
  3. package/dist/abilities/amounts.js.map +1 -0
  4. package/dist/abilities/buffs.d.ts +106 -6
  5. package/dist/abilities/buffs.js +443 -0
  6. package/dist/abilities/buffs.js.map +1 -0
  7. package/dist/abilities/castTold.d.ts +2 -0
  8. package/dist/abilities/castTold.js +66 -0
  9. package/dist/abilities/castTold.js.map +1 -0
  10. package/dist/abilities/chance.d.ts +38 -0
  11. package/dist/abilities/chance.js +77 -0
  12. package/dist/abilities/chance.js.map +1 -0
  13. package/dist/abilities/charges.d.ts +18 -0
  14. package/dist/abilities/charges.js +101 -0
  15. package/dist/abilities/charges.js.map +1 -0
  16. package/dist/abilities/control.d.ts +28 -0
  17. package/dist/abilities/control.js +113 -0
  18. package/dist/abilities/control.js.map +1 -0
  19. package/dist/abilities/dispel.js +51 -0
  20. package/dist/abilities/dispel.js.map +1 -0
  21. package/dist/abilities/effectFields.d.ts +1 -1
  22. package/dist/abilities/effectFields.js +676 -0
  23. package/dist/abilities/effectFields.js.map +1 -0
  24. package/dist/abilities/effectIndex.d.ts +27 -0
  25. package/dist/abilities/effectIndex.js +64 -0
  26. package/dist/abilities/effectIndex.js.map +1 -0
  27. package/dist/abilities/effects/buff.d.ts +9 -3
  28. package/dist/abilities/effects/buff.js +84 -0
  29. package/dist/abilities/effects/buff.js.map +1 -0
  30. package/dist/abilities/effects/conditions.d.ts +2 -0
  31. package/dist/abilities/effects/conditions.js +41 -0
  32. package/dist/abilities/effects/conditions.js.map +1 -0
  33. package/dist/abilities/effects/core.js +54 -0
  34. package/dist/abilities/effects/core.js.map +1 -0
  35. package/dist/abilities/effects/damage.d.ts +1 -1
  36. package/dist/abilities/effects/damage.js +43 -0
  37. package/dist/abilities/effects/damage.js.map +1 -0
  38. package/dist/abilities/effects/heal.d.ts +2 -2
  39. package/dist/abilities/effects/heal.js +51 -0
  40. package/dist/abilities/effects/heal.js.map +1 -0
  41. package/dist/abilities/effects/missile.d.ts +13 -1
  42. package/dist/abilities/effects/missile.js +104 -0
  43. package/dist/abilities/effects/missile.js.map +1 -0
  44. package/dist/abilities/effects/morph.d.ts +5 -0
  45. package/dist/abilities/effects/morph.js +43 -0
  46. package/dist/abilities/effects/morph.js.map +1 -0
  47. package/dist/abilities/effects/moves.d.ts +16 -4
  48. package/dist/abilities/effects/moves.js +212 -0
  49. package/dist/abilities/effects/moves.js.map +1 -0
  50. package/dist/abilities/effects/passives.d.ts +19 -9
  51. package/dist/abilities/effects/passives.js +131 -0
  52. package/dist/abilities/effects/passives.js.map +1 -0
  53. package/dist/abilities/effects/proxy.d.ts +5 -0
  54. package/dist/abilities/effects/proxy.js +60 -0
  55. package/dist/abilities/effects/proxy.js.map +1 -0
  56. package/dist/abilities/effects/sight.d.ts +2 -2
  57. package/dist/abilities/effects/sight.js +39 -0
  58. package/dist/abilities/effects/sight.js.map +1 -0
  59. package/dist/abilities/effects/spawn.d.ts +5 -2
  60. package/dist/abilities/effects/spawn.js +40 -0
  61. package/dist/abilities/effects/spawn.js.map +1 -0
  62. package/dist/abilities/effects/timed.d.ts +2 -2
  63. package/dist/abilities/effects/timed.js +96 -0
  64. package/dist/abilities/effects/timed.js.map +1 -0
  65. package/dist/abilities/effects/trade.d.ts +1 -1
  66. package/dist/abilities/effects/trade.js +25 -0
  67. package/dist/abilities/effects/trade.js.map +1 -0
  68. package/dist/abilities/effects.d.ts +97 -23
  69. package/dist/abilities/effects.js +860 -0
  70. package/dist/abilities/effects.js.map +1 -0
  71. package/dist/abilities/land.d.ts +38 -4
  72. package/dist/abilities/land.js +189 -0
  73. package/dist/abilities/land.js.map +1 -0
  74. package/dist/abilities/recast.d.ts +45 -0
  75. package/dist/abilities/recast.js +118 -0
  76. package/dist/abilities/recast.js.map +1 -0
  77. package/dist/abilities/scaled.js +40 -0
  78. package/dist/abilities/scaled.js.map +1 -0
  79. package/dist/abilities/screen.d.ts +6 -0
  80. package/dist/abilities/screen.js +83 -0
  81. package/dist/abilities/screen.js.map +1 -0
  82. package/dist/abilities/shapes.d.ts +66 -0
  83. package/dist/abilities/shapes.js +122 -0
  84. package/dist/abilities/shapes.js.map +1 -0
  85. package/dist/abilities/text.d.ts +14 -2
  86. package/dist/abilities/text.js +204 -0
  87. package/dist/abilities/text.js.map +1 -0
  88. package/dist/abilities/triggers.d.ts +98 -0
  89. package/dist/abilities/triggers.js +351 -0
  90. package/dist/abilities/triggers.js.map +1 -0
  91. package/dist/abilityChanges.d.ts +131 -0
  92. package/dist/abilityChanges.js +345 -0
  93. package/dist/abilityChanges.js.map +1 -0
  94. package/dist/ai/area.d.ts +4 -1
  95. package/dist/ai/brain.d.ts +4 -1
  96. package/dist/ai/brain.js +844 -0
  97. package/dist/ai/brain.js.map +1 -0
  98. package/dist/ai/budget.js +74 -0
  99. package/dist/ai/budget.js.map +1 -0
  100. package/dist/ai/checks.d.ts +9 -1
  101. package/dist/ai/checks.js +242 -0
  102. package/dist/ai/checks.js.map +1 -0
  103. package/dist/ai/computer.d.ts +11 -4
  104. package/dist/ai/computer.js +251 -0
  105. package/dist/ai/computer.js.map +1 -0
  106. package/dist/ai/defence.d.ts +4 -0
  107. package/dist/ai/defence.js +430 -0
  108. package/dist/ai/defence.js.map +1 -0
  109. package/dist/ai/define.d.ts +3 -2
  110. package/dist/ai/define.js +31 -0
  111. package/dist/ai/define.js.map +1 -0
  112. package/dist/ai/economy.d.ts +10 -7
  113. package/dist/ai/economy.js +780 -0
  114. package/dist/ai/economy.js.map +1 -0
  115. package/dist/ai/geometry.js +38 -0
  116. package/dist/ai/geometry.js.map +1 -0
  117. package/dist/ai/goals.d.ts +1 -0
  118. package/dist/ai/goals.js +560 -0
  119. package/dist/ai/goals.js.map +1 -0
  120. package/dist/ai/knowledge.d.ts +72 -7
  121. package/dist/ai/knowledge.js +804 -0
  122. package/dist/ai/knowledge.js.map +1 -0
  123. package/dist/ai/lanes.d.ts +10 -2
  124. package/dist/ai/lanes.js +715 -0
  125. package/dist/ai/lanes.js.map +1 -0
  126. package/dist/ai/melee/build.js +264 -0
  127. package/dist/ai/melee/build.js.map +1 -0
  128. package/dist/ai/melee/goals.d.ts +7 -0
  129. package/dist/ai/melee/goals.js +720 -0
  130. package/dist/ai/melee/goals.js.map +1 -0
  131. package/dist/ai/melee/heroes.js +68 -0
  132. package/dist/ai/melee/heroes.js.map +1 -0
  133. package/dist/ai/melee/index.d.ts +1 -1
  134. package/dist/ai/melee/index.js +51 -0
  135. package/dist/ai/melee/index.js.map +1 -0
  136. package/dist/ai/melee/production.js +29 -0
  137. package/dist/ai/melee/production.js.map +1 -0
  138. package/dist/ai/melee/surrender.js +64 -0
  139. package/dist/ai/melee/surrender.js.map +1 -0
  140. package/dist/ai/micro.d.ts +9 -0
  141. package/dist/ai/micro.js +1316 -0
  142. package/dist/ai/micro.js.map +1 -0
  143. package/dist/ai/mission.d.ts +9 -2
  144. package/dist/ai/mission.js +538 -0
  145. package/dist/ai/mission.js.map +1 -0
  146. package/dist/ai/missionRules.d.ts +1 -1
  147. package/dist/ai/missionRules.js +26 -0
  148. package/dist/ai/missionRules.js.map +1 -0
  149. package/dist/ai/module.d.ts +6 -2
  150. package/dist/ai/module.js +37 -0
  151. package/dist/ai/module.js.map +1 -0
  152. package/dist/ai/options.d.ts +3 -3
  153. package/dist/ai/plans/build.d.ts +20 -1
  154. package/dist/ai/plans/build.js +608 -0
  155. package/dist/ai/plans/build.js.map +1 -0
  156. package/dist/ai/plans/placement.d.ts +4 -1
  157. package/dist/ai/plans/placement.js +295 -0
  158. package/dist/ai/plans/placement.js.map +1 -0
  159. package/dist/ai/plans/plans.d.ts +9 -0
  160. package/dist/ai/plans/plans.js +110 -0
  161. package/dist/ai/plans/plans.js.map +1 -0
  162. package/dist/ai/plans/production.d.ts +14 -2
  163. package/dist/ai/plans/production.js +434 -0
  164. package/dist/ai/plans/production.js.map +1 -0
  165. package/dist/ai/plans/purse.d.ts +6 -3
  166. package/dist/ai/plans/purse.js +139 -0
  167. package/dist/ai/plans/purse.js.map +1 -0
  168. package/dist/ai/plans/tech.d.ts +6 -0
  169. package/dist/ai/plans/tech.js +122 -0
  170. package/dist/ai/plans/tech.js.map +1 -0
  171. package/dist/ai/profiles.d.ts +4 -4
  172. package/dist/{profiles-B3NS9jwk.js → ai/profiles.js} +3 -98
  173. package/dist/ai/profiles.js.map +1 -0
  174. package/dist/ai/reach.js +54 -0
  175. package/dist/ai/reach.js.map +1 -0
  176. package/dist/ai/report.d.ts +8 -0
  177. package/dist/ai/report.js +87 -0
  178. package/dist/ai/report.js.map +1 -0
  179. package/dist/ai/roles.d.ts +4 -0
  180. package/dist/ai/roles.js +207 -0
  181. package/dist/ai/roles.js.map +1 -0
  182. package/dist/ai/rules.d.ts +8 -2
  183. package/dist/ai/rules.js +416 -0
  184. package/dist/ai/rules.js.map +1 -0
  185. package/dist/ai/scouting.d.ts +6 -0
  186. package/dist/ai/scouting.js +324 -0
  187. package/dist/ai/scouting.js.map +1 -0
  188. package/dist/ai/settings.js +99 -0
  189. package/dist/ai/settings.js.map +1 -0
  190. package/dist/ai/squads.d.ts +21 -2
  191. package/dist/ai/squads.js +916 -0
  192. package/dist/ai/squads.js.map +1 -0
  193. package/dist/ai/strength.js +320 -0
  194. package/dist/ai/strength.js.map +1 -0
  195. package/dist/ai/task.d.ts +3 -1
  196. package/dist/ai/task.js +17 -0
  197. package/dist/ai/task.js.map +1 -0
  198. package/dist/ai/tasks/attack.js +24 -0
  199. package/dist/ai/tasks/attack.js.map +1 -0
  200. package/dist/ai/tasks/capture.d.ts +3 -3
  201. package/dist/ai/tasks/capture.js +37 -0
  202. package/dist/ai/tasks/capture.js.map +1 -0
  203. package/dist/ai/tasks/creep.js +29 -0
  204. package/dist/ai/tasks/creep.js.map +1 -0
  205. package/dist/ai/tasks/defend.js +61 -0
  206. package/dist/ai/tasks/defend.js.map +1 -0
  207. package/dist/ai/tasks/drop.js +81 -0
  208. package/dist/ai/tasks/drop.js.map +1 -0
  209. package/dist/ai/tasks/escort.js +59 -0
  210. package/dist/ai/tasks/escort.js.map +1 -0
  211. package/dist/ai/tasks/gather.js +48 -0
  212. package/dist/ai/tasks/gather.js.map +1 -0
  213. package/dist/ai/tasks/harass.js +39 -0
  214. package/dist/ai/tasks/harass.js.map +1 -0
  215. package/dist/ai/tasks/hold.js +32 -0
  216. package/dist/ai/tasks/hold.js.map +1 -0
  217. package/dist/ai/tasks/index.js +34 -0
  218. package/dist/ai/tasks/index.js.map +1 -0
  219. package/dist/ai/tasks/move.js +26 -0
  220. package/dist/ai/tasks/move.js.map +1 -0
  221. package/dist/ai/tasks/patrol.js +59 -0
  222. package/dist/ai/tasks/patrol.js.map +1 -0
  223. package/dist/ai/tasks/retreat.js +28 -0
  224. package/dist/ai/tasks/retreat.js.map +1 -0
  225. package/dist/ai/tasks/scout.js +73 -0
  226. package/dist/ai/tasks/scout.js.map +1 -0
  227. package/dist/ai/tasks/shared.d.ts +1 -1
  228. package/dist/ai/tasks/shared.js +137 -0
  229. package/dist/ai/tasks/shared.js.map +1 -0
  230. package/dist/ai/team.d.ts +18 -1
  231. package/dist/ai/team.js +492 -0
  232. package/dist/ai/team.js.map +1 -0
  233. package/dist/ai/threat.d.ts +6 -0
  234. package/dist/ai/threat.js +206 -0
  235. package/dist/ai/threat.js.map +1 -0
  236. package/dist/ai/view.d.ts +21 -7
  237. package/dist/ai/view.js +677 -0
  238. package/dist/ai/view.js.map +1 -0
  239. package/dist/ai/waves.d.ts +6 -0
  240. package/dist/ai/waves.js +410 -0
  241. package/dist/ai/waves.js.map +1 -0
  242. package/dist/ai.js +54 -6239
  243. package/dist/aiTesting.d.ts +6 -3
  244. package/dist/aiTesting.js +229 -0
  245. package/dist/aiTesting.js.map +1 -0
  246. package/dist/areas.d.ts +4 -1
  247. package/dist/areas.js +295 -0
  248. package/dist/areas.js.map +1 -0
  249. package/dist/attacks.d.ts +3 -3
  250. package/dist/attacks.js +127 -0
  251. package/dist/attacks.js.map +1 -0
  252. package/dist/burning.d.ts +267 -0
  253. package/dist/burning.js +795 -0
  254. package/dist/burning.js.map +1 -0
  255. package/dist/bytes.js +21 -0
  256. package/dist/bytes.js.map +1 -0
  257. package/dist/callings.d.ts +71 -0
  258. package/dist/callings.js +157 -0
  259. package/dist/callings.js.map +1 -0
  260. package/dist/cameraOrders.d.ts +78 -0
  261. package/dist/cameraOrders.js +114 -0
  262. package/dist/cameraOrders.js.map +1 -0
  263. package/dist/camps.d.ts +70 -4
  264. package/dist/camps.js +501 -0
  265. package/dist/camps.js.map +1 -0
  266. package/dist/capture.d.ts +15 -3
  267. package/dist/capture.js +304 -0
  268. package/dist/capture.js.map +1 -0
  269. package/dist/cellLayers.d.ts +78 -13
  270. package/dist/cellLayers.js +275 -0
  271. package/dist/cellLayers.js.map +1 -0
  272. package/dist/cellPatches.d.ts +24 -0
  273. package/dist/cellPatches.js +73 -0
  274. package/dist/cellPatches.js.map +1 -0
  275. package/dist/cinematics.d.ts +10 -5
  276. package/dist/cinematics.js +161 -0
  277. package/dist/cinematics.js.map +1 -0
  278. package/dist/clock.d.ts +2 -2
  279. package/dist/clock.js +78 -0
  280. package/dist/clock.js.map +1 -0
  281. package/dist/commands.d.ts +36 -4
  282. package/dist/commands.js +636 -0
  283. package/dist/commands.js.map +1 -0
  284. package/dist/components.d.ts +31 -10
  285. package/dist/components.js +74 -0
  286. package/dist/components.js.map +1 -0
  287. package/dist/computers.d.ts +4 -4
  288. package/dist/computers.js +194 -0
  289. package/dist/computers.js.map +1 -0
  290. package/dist/concealment.d.ts +25 -2
  291. package/dist/concealment.js +409 -0
  292. package/dist/concealment.js.map +1 -0
  293. package/dist/coreComponents.js +130 -0
  294. package/dist/coreComponents.js.map +1 -0
  295. package/dist/createGame.d.ts +306 -0
  296. package/dist/createGame.js +405 -0
  297. package/dist/createGame.js.map +1 -0
  298. package/dist/dashing.d.ts +18 -2
  299. package/dist/dashing.js +41 -0
  300. package/dist/dashing.js.map +1 -0
  301. package/dist/debug.d.ts +8 -0
  302. package/dist/debug.js +5 -3
  303. package/dist/debug2.js +76 -0
  304. package/dist/debug2.js.map +1 -0
  305. package/dist/debugCommands.d.ts +6 -6
  306. package/dist/debugCommands.js +537 -0
  307. package/dist/debugCommands.js.map +1 -0
  308. package/dist/debugging.d.ts +1 -0
  309. package/dist/defaultSets.d.ts +183 -0
  310. package/dist/defaultSets.js +216 -0
  311. package/dist/defaultSets.js.map +1 -0
  312. package/dist/definitions.d.ts +6 -0
  313. package/dist/definitions.js +78 -0
  314. package/dist/definitions.js.map +1 -0
  315. package/dist/defs.d.ts +1895 -165
  316. package/dist/defs.js +380 -0
  317. package/dist/defs.js.map +1 -0
  318. package/dist/denying.d.ts +4 -4
  319. package/dist/denying.js +106 -0
  320. package/dist/denying.js.map +1 -0
  321. package/dist/destructibles.d.ts +2 -2
  322. package/dist/destructibles.js +36 -0
  323. package/dist/destructibles.js.map +1 -0
  324. package/dist/determinism.d.ts +4 -4
  325. package/dist/determinism.js +247 -0
  326. package/dist/determinism.js.map +1 -0
  327. package/dist/dialog.d.ts +17 -2
  328. package/dist/dialog.js +108 -0
  329. package/dist/dialog.js.map +1 -0
  330. package/dist/effectRefs.js +28 -0
  331. package/dist/effectRefs.js.map +1 -0
  332. package/dist/effects.d.ts +27 -11
  333. package/dist/effects.js +110 -0
  334. package/dist/effects.js.map +1 -0
  335. package/dist/endings.d.ts +1 -1
  336. package/dist/endings.js +78 -0
  337. package/dist/endings.js.map +1 -0
  338. package/dist/engagement.d.ts +40 -6
  339. package/dist/engagement.js +530 -0
  340. package/dist/engagement.js.map +1 -0
  341. package/dist/engineEvents.d.ts +72 -9
  342. package/dist/engineEvents.js +520 -0
  343. package/dist/engineEvents.js.map +1 -0
  344. package/dist/entity.d.ts +275 -26
  345. package/dist/entity.js +441 -0
  346. package/dist/entity.js.map +1 -0
  347. package/dist/entityIndex.d.ts +10 -3
  348. package/dist/entityIndex.js +149 -0
  349. package/dist/entityIndex.js.map +1 -0
  350. package/dist/errors.d.ts +6 -2
  351. package/dist/errors.js +59 -0
  352. package/dist/errors.js.map +1 -0
  353. package/dist/events.d.ts +11 -5
  354. package/dist/events.js +158 -0
  355. package/dist/events.js.map +1 -0
  356. package/dist/exactMath.js +273 -0
  357. package/dist/exactMath.js.map +1 -0
  358. package/dist/features.d.ts +1 -1
  359. package/dist/features.js +127 -0
  360. package/dist/features.js.map +1 -0
  361. package/dist/fields.d.ts +25 -5
  362. package/dist/fields.js +140 -0
  363. package/dist/fields.js.map +1 -0
  364. package/dist/fixture.d.ts +3 -3
  365. package/dist/fixture.js +512 -0
  366. package/dist/fixture.js.map +1 -0
  367. package/dist/fog.d.ts +26 -3
  368. package/dist/fog.js +333 -0
  369. package/dist/fog.js.map +1 -0
  370. package/dist/foliage.d.ts +476 -0
  371. package/dist/foliage.js +1478 -0
  372. package/dist/foliage.js.map +1 -0
  373. package/dist/foliageDebug.d.ts +57 -0
  374. package/dist/foliageDebug.js +172 -0
  375. package/dist/foliageDebug.js.map +1 -0
  376. package/dist/foliageRegrowth.d.ts +20 -0
  377. package/dist/foliageRegrowth.js +332 -0
  378. package/dist/foliageRegrowth.js.map +1 -0
  379. package/dist/formState.d.ts +67 -0
  380. package/dist/formState.js +65 -0
  381. package/dist/formState.js.map +1 -0
  382. package/dist/formation.d.ts +46 -8
  383. package/dist/formation.js +297 -0
  384. package/dist/formation.js.map +1 -0
  385. package/dist/forms.d.ts +58 -0
  386. package/dist/forms.js +146 -0
  387. package/dist/forms.js.map +1 -0
  388. package/dist/friendlyFire.d.ts +2 -2
  389. package/dist/friendlyFire.js +37 -0
  390. package/dist/friendlyFire.js.map +1 -0
  391. package/dist/game.d.ts +141 -48
  392. package/dist/game.js +834 -0
  393. package/dist/game.js.map +1 -0
  394. package/dist/gameData.d.ts +96 -22
  395. package/dist/gameData.js +1690 -0
  396. package/dist/gameData.js.map +1 -0
  397. package/dist/gameFiles.d.ts +3 -3
  398. package/dist/gameFiles.js +14 -0
  399. package/dist/gameFiles.js.map +1 -0
  400. package/dist/gates.js +92 -0
  401. package/dist/gates.js.map +1 -0
  402. package/dist/generate.d.ts +28 -1
  403. package/dist/generate.js +1062 -0
  404. package/dist/generate.js.map +1 -0
  405. package/dist/generateWorker.d.ts +7 -3
  406. package/dist/generateWorker.js +86 -0
  407. package/dist/generateWorker.js.map +1 -0
  408. package/dist/grid.d.ts +9 -0
  409. package/dist/grid.js +102 -0
  410. package/dist/grid.js.map +1 -0
  411. package/dist/ground.d.ts +17 -1
  412. package/dist/ground.js +375 -0
  413. package/dist/ground.js.map +1 -0
  414. package/dist/groundObjects.d.ts +70 -0
  415. package/dist/groundObjects.js +371 -0
  416. package/dist/groundObjects.js.map +1 -0
  417. package/dist/groundSpeed.d.ts +20 -3
  418. package/dist/groundSpeed.js +117 -0
  419. package/dist/groundSpeed.js.map +1 -0
  420. package/dist/hero.d.ts +126 -10
  421. package/dist/hero.js +432 -0
  422. package/dist/hero.js.map +1 -0
  423. package/dist/holds.d.ts +94 -0
  424. package/dist/holds.js +305 -0
  425. package/dist/holds.js.map +1 -0
  426. package/dist/home.d.ts +1 -1
  427. package/dist/home.js +30 -0
  428. package/dist/home.js.map +1 -0
  429. package/dist/hooks.d.ts +339 -57
  430. package/dist/hooks.js +105 -0
  431. package/dist/hooks.js.map +1 -0
  432. package/dist/hotReload.d.ts +6 -5
  433. package/dist/hotReload.js +145 -0
  434. package/dist/hotReload.js.map +1 -0
  435. package/dist/ids.d.ts +3 -3
  436. package/dist/ids.js +30 -0
  437. package/dist/ids.js.map +1 -0
  438. package/dist/idsFile.d.ts +36 -0
  439. package/dist/idsFile.js +134 -0
  440. package/dist/idsFile.js.map +1 -0
  441. package/dist/index.d.ts +105 -68
  442. package/dist/index.js +194 -4701
  443. package/dist/inspect.d.ts +29 -2
  444. package/dist/{inspect-D9dWHmZ0.js → inspect.js} +21 -12
  445. package/dist/inspect.js.map +1 -0
  446. package/dist/inventory.d.ts +14 -1
  447. package/dist/inventory.js +84 -0
  448. package/dist/inventory.js.map +1 -0
  449. package/dist/items.d.ts +136 -8
  450. package/dist/items.js +585 -0
  451. package/dist/items.js.map +1 -0
  452. package/dist/lanes.d.ts +12 -3
  453. package/dist/lanes.js +496 -0
  454. package/dist/lanes.js.map +1 -0
  455. package/dist/life.d.ts +6 -2
  456. package/dist/life.js +287 -0
  457. package/dist/life.js.map +1 -0
  458. package/dist/log.d.ts +26 -3
  459. package/dist/log.js +192 -0
  460. package/dist/log.js.map +1 -0
  461. package/dist/manaBurn.d.ts +2 -2
  462. package/dist/manaBurn.js +75 -0
  463. package/dist/manaBurn.js.map +1 -0
  464. package/dist/map/file.d.ts +56 -3
  465. package/dist/map/file.js +264 -0
  466. package/dist/map/file.js.map +1 -0
  467. package/dist/map/images.js +61 -0
  468. package/dist/map/images.js.map +1 -0
  469. package/dist/map/look.d.ts +1 -1
  470. package/dist/map/look.js +30 -0
  471. package/dist/map/look.js.map +1 -0
  472. package/dist/map/pathProfile.js +183 -0
  473. package/dist/map/pathProfile.js.map +1 -0
  474. package/dist/map/resize.d.ts +4 -0
  475. package/dist/map/resize.js +136 -0
  476. package/dist/map/resize.js.map +1 -0
  477. package/dist/map/schema.js +257 -0
  478. package/dist/map/schema.js.map +1 -0
  479. package/dist/map/terrain.js +214 -0
  480. package/dist/map/terrain.js.map +1 -0
  481. package/dist/map/types.d.ts +92 -13
  482. package/dist/map/types.js +251 -0
  483. package/dist/map/types.js.map +1 -0
  484. package/dist/mapCheck/cells.js +94 -0
  485. package/dist/mapCheck/cells.js.map +1 -0
  486. package/dist/mapCheck/rules/foliage.d.ts +9 -0
  487. package/dist/mapCheck/rules/foliage.js +83 -0
  488. package/dist/mapCheck/rules/foliage.js.map +1 -0
  489. package/dist/mapCheck/rules/names.js +39 -0
  490. package/dist/mapCheck/rules/names.js.map +1 -0
  491. package/dist/mapCheck/rules/objects.d.ts +1 -1
  492. package/dist/mapCheck/rules/objects.js +56 -0
  493. package/dist/mapCheck/rules/objects.js.map +1 -0
  494. package/dist/mapCheck/rules/paths.js +32 -0
  495. package/dist/mapCheck/rules/paths.js.map +1 -0
  496. package/dist/mapCheck/rules/players.js +20 -0
  497. package/dist/mapCheck/rules/players.js.map +1 -0
  498. package/dist/mapCheck/rules/races.js +56 -0
  499. package/dist/mapCheck/rules/races.js.map +1 -0
  500. package/dist/mapCheck/rules/random.js +47 -0
  501. package/dist/mapCheck/rules/random.js.map +1 -0
  502. package/dist/mapCheck/rules/regions.js +30 -0
  503. package/dist/mapCheck/rules/regions.js.map +1 -0
  504. package/dist/mapCheck/rules/targets.js +31 -0
  505. package/dist/mapCheck/rules/targets.js.map +1 -0
  506. package/dist/mapCheck/rules/walking.js +45 -0
  507. package/dist/mapCheck/rules/walking.js.map +1 -0
  508. package/dist/mapCheck.d.ts +2 -2
  509. package/dist/mapCheck.js +63 -0
  510. package/dist/mapCheck.js.map +1 -0
  511. package/dist/mapFields.d.ts +25 -2
  512. package/dist/mapFields.js +134 -0
  513. package/dist/mapFields.js.map +1 -0
  514. package/dist/mapFile.js +176 -0
  515. package/dist/mapFile.js.map +1 -0
  516. package/dist/mapMeasure.d.ts +8 -0
  517. package/dist/mapMeasure.js +283 -0
  518. package/dist/mapMeasure.js.map +1 -0
  519. package/dist/mapMerge.d.ts +1 -0
  520. package/dist/mapMerge.js +172 -0
  521. package/dist/mapMerge.js.map +1 -0
  522. package/dist/mapObjectives.js +138 -0
  523. package/dist/mapObjectives.js.map +1 -0
  524. package/dist/mapObjects.js +80 -0
  525. package/dist/mapObjects.js.map +1 -0
  526. package/dist/math.d.ts +37 -7
  527. package/dist/math.js +155 -0
  528. package/dist/math.js.map +1 -0
  529. package/dist/messages.d.ts +71 -4
  530. package/dist/messages.js +29 -0
  531. package/dist/messages.js.map +1 -0
  532. package/dist/missionRules.d.ts +10 -2
  533. package/dist/{missionRules-C-bGxm0Q.js → missionRules.js} +30 -150
  534. package/dist/missionRules.js.map +1 -0
  535. package/dist/mods.d.ts +39 -20
  536. package/dist/mods.js +271 -0
  537. package/dist/mods.js.map +1 -0
  538. package/dist/moves.d.ts +87 -0
  539. package/dist/moves.js +539 -0
  540. package/dist/moves.js.map +1 -0
  541. package/dist/names.d.ts +7 -0
  542. package/dist/names.js +122 -0
  543. package/dist/names.js.map +1 -0
  544. package/dist/navigation/agentParams.js +14 -0
  545. package/dist/navigation/agentParams.js.map +1 -0
  546. package/dist/navigation/air.d.ts +7 -3
  547. package/dist/navigation/air.js +401 -0
  548. package/dist/navigation/air.js.map +1 -0
  549. package/dist/navigation/builds.d.ts +34 -2
  550. package/dist/navigation/builds.js +287 -0
  551. package/dist/navigation/builds.js.map +1 -0
  552. package/dist/navigation/groundAreas.d.ts +59 -1
  553. package/dist/navigation/groundAreas.js +407 -0
  554. package/dist/navigation/groundAreas.js.map +1 -0
  555. package/dist/navigation/navigation.d.ts +98 -9
  556. package/dist/navigation/recast.d.ts +194 -18
  557. package/dist/navigation/recast.js +1379 -0
  558. package/dist/navigation/recast.js.map +1 -0
  559. package/dist/navigation/sidePaths.d.ts +8 -3
  560. package/dist/navigation/sidePaths.js +241 -0
  561. package/dist/navigation/sidePaths.js.map +1 -0
  562. package/dist/navigation/sized.js +243 -0
  563. package/dist/navigation/sized.js.map +1 -0
  564. package/dist/nearest.js +32 -0
  565. package/dist/nearest.js.map +1 -0
  566. package/dist/noise.js +59 -0
  567. package/dist/noise.js.map +1 -0
  568. package/dist/objectives.d.ts +12 -3
  569. package/dist/objectives.js +144 -0
  570. package/dist/objectives.js.map +1 -0
  571. package/dist/orders/basic.d.ts +5 -5
  572. package/dist/orders/basic.js +417 -0
  573. package/dist/orders/basic.js.map +1 -0
  574. package/dist/orders/build.js +278 -0
  575. package/dist/orders/build.js.map +1 -0
  576. package/dist/orders/cast.d.ts +13 -3
  577. package/dist/orders/cast.js +558 -0
  578. package/dist/orders/cast.js.map +1 -0
  579. package/dist/orders/facts.js +16 -0
  580. package/dist/orders/facts.js.map +1 -0
  581. package/dist/orders/harvest.d.ts +21 -5
  582. package/dist/orders/harvest.js +540 -0
  583. package/dist/orders/harvest.js.map +1 -0
  584. package/dist/orders/idle.d.ts +3 -1
  585. package/dist/orders/idle.js +234 -0
  586. package/dist/orders/idle.js.map +1 -0
  587. package/dist/orders/items.js +92 -0
  588. package/dist/orders/items.js.map +1 -0
  589. package/dist/orders/queue.js +108 -0
  590. package/dist/orders/queue.js.map +1 -0
  591. package/dist/orders/waiting.d.ts +39 -0
  592. package/dist/orders/waiting.js +149 -0
  593. package/dist/orders/waiting.js.map +1 -0
  594. package/dist/pack.schema.js +13 -0
  595. package/dist/pack.schema.js.map +1 -0
  596. package/dist/pack.schema.json +7622 -841
  597. package/dist/packs/director/index.d.ts +13 -5
  598. package/dist/packs/director/index.js +204 -0
  599. package/dist/packs/director/index.js.map +1 -0
  600. package/dist/packs/heroes/campaign.d.ts +3 -2
  601. package/dist/packs/heroes/campaign.js +241 -0
  602. package/dist/packs/heroes/campaign.js.map +1 -0
  603. package/dist/packs/heroes/carry.d.ts +6 -0
  604. package/dist/packs/heroes/carry.js +112 -0
  605. package/dist/packs/heroes/carry.js.map +1 -0
  606. package/dist/packs/heroes/commands.js +115 -0
  607. package/dist/packs/heroes/commands.js.map +1 -0
  608. package/dist/packs/heroes/fallen.d.ts +43 -0
  609. package/dist/packs/heroes/fallen.js +61 -0
  610. package/dist/packs/heroes/fallen.js.map +1 -0
  611. package/dist/packs/heroes/hire.js +60 -0
  612. package/dist/packs/heroes/hire.js.map +1 -0
  613. package/dist/packs/heroes/index.d.ts +7 -6
  614. package/dist/packs/heroes/index.js +130 -0
  615. package/dist/packs/heroes/index.js.map +1 -0
  616. package/dist/packs/heroes/loop.d.ts +95 -0
  617. package/dist/packs/heroes/loop.js +250 -0
  618. package/dist/packs/heroes/loop.js.map +1 -0
  619. package/dist/packs/heroes/making.d.ts +6 -3
  620. package/dist/packs/heroes/making.js +55 -0
  621. package/dist/packs/heroes/making.js.map +1 -0
  622. package/dist/packs/heroes/respawn.d.ts +3 -3
  623. package/dist/packs/heroes/respawn.js +87 -0
  624. package/dist/packs/heroes/respawn.js.map +1 -0
  625. package/dist/packs/heroes/sets.d.ts +32 -0
  626. package/dist/packs/heroes/sets.js +51 -0
  627. package/dist/packs/heroes/sets.js.map +1 -0
  628. package/dist/packs/heroes/spells.d.ts +16 -0
  629. package/dist/packs/heroes/spells.js +269 -0
  630. package/dist/packs/heroes/spells.js.map +1 -0
  631. package/dist/packs/items/defaults.d.ts +43 -0
  632. package/dist/packs/items/defaults.js +1504 -0
  633. package/dist/packs/items/defaults.js.map +1 -0
  634. package/dist/packs/items/index.d.ts +27 -0
  635. package/dist/packs/items/index.js +214 -0
  636. package/dist/packs/items/index.js.map +1 -0
  637. package/dist/packs/moba/index.d.ts +3 -3
  638. package/dist/packs/moba/index.js +174 -0
  639. package/dist/packs/moba/index.js.map +1 -0
  640. package/dist/packs/pack.d.ts +15 -15
  641. package/dist/packs/pack.js +14 -0
  642. package/dist/packs/pack.js.map +1 -0
  643. package/dist/packs.d.ts +15 -7
  644. package/dist/packs.js +222 -0
  645. package/dist/packs.js.map +1 -0
  646. package/dist/paths.d.ts +2 -0
  647. package/dist/paths.js +109 -0
  648. package/dist/paths.js.map +1 -0
  649. package/dist/plain.js +57 -0
  650. package/dist/plain.js.map +1 -0
  651. package/dist/player.d.ts +33 -10
  652. package/dist/player.js +159 -0
  653. package/dist/player.js.map +1 -0
  654. package/dist/portals.d.ts +1 -1
  655. package/dist/portals.js +194 -0
  656. package/dist/portals.js.map +1 -0
  657. package/dist/prefabs.d.ts +25 -2
  658. package/dist/prefabs.js +239 -0
  659. package/dist/prefabs.js.map +1 -0
  660. package/dist/presetBuildings.js +58 -0
  661. package/dist/presetBuildings.js.map +1 -0
  662. package/dist/presetFoliage.d.ts +27 -0
  663. package/dist/presetFoliage.js +98 -0
  664. package/dist/presetFoliage.js.map +1 -0
  665. package/dist/presetGround.js +65 -0
  666. package/dist/presetGround.js.map +1 -0
  667. package/dist/proxies.d.ts +12 -0
  668. package/dist/proxies.js +79 -0
  669. package/dist/proxies.js.map +1 -0
  670. package/dist/query.d.ts +56 -0
  671. package/dist/query.js +88 -0
  672. package/dist/query.js.map +1 -0
  673. package/dist/races.d.ts +15 -14
  674. package/dist/races.js +172 -0
  675. package/dist/races.js.map +1 -0
  676. package/dist/randomGroups.js +91 -0
  677. package/dist/randomGroups.js.map +1 -0
  678. package/dist/registry.d.ts +117 -53
  679. package/dist/registry.js +323 -0
  680. package/dist/registry.js.map +1 -0
  681. package/dist/remains.d.ts +11 -9
  682. package/dist/remains.js +188 -0
  683. package/dist/remains.js.map +1 -0
  684. package/dist/replication.d.ts +12 -7
  685. package/dist/replication.js +100 -0
  686. package/dist/replication.js.map +1 -0
  687. package/dist/rng.d.ts +2 -0
  688. package/dist/rng.js +40 -0
  689. package/dist/rng.js.map +1 -0
  690. package/dist/rules.d.ts +186 -99
  691. package/dist/rules.js +179 -0
  692. package/dist/rules.js.map +1 -0
  693. package/dist/rulesCheck.d.ts +5 -4
  694. package/dist/rulesCheck.js +693 -0
  695. package/dist/rulesCheck.js.map +1 -0
  696. package/dist/runes.d.ts +2 -2
  697. package/dist/runes.js +80 -0
  698. package/dist/runes.js.map +1 -0
  699. package/dist/save.d.ts +37 -12
  700. package/dist/save.js +532 -0
  701. package/dist/save.js.map +1 -0
  702. package/dist/scenario.d.ts +2 -2
  703. package/dist/scenario.js +99 -0
  704. package/dist/scenario.js.map +1 -0
  705. package/dist/scheduler.d.ts +3 -0
  706. package/dist/scheduler.js +156 -0
  707. package/dist/scheduler.js.map +1 -0
  708. package/dist/score.d.ts +19 -19
  709. package/dist/score.js +709 -0
  710. package/dist/score.js.map +1 -0
  711. package/dist/sequences.d.ts +10 -6
  712. package/dist/sequences.js +206 -0
  713. package/dist/sequences.js.map +1 -0
  714. package/dist/server/doorman.js +154 -0
  715. package/dist/server/doorman.js.map +1 -0
  716. package/dist/server/gameServer.d.ts +16 -1
  717. package/dist/server/gameServer.js +643 -0
  718. package/dist/server/gameServer.js.map +1 -0
  719. package/dist/server/index.d.ts +1 -1
  720. package/dist/server/lobby.js +199 -0
  721. package/dist/server/lobby.js.map +1 -0
  722. package/dist/server/log.js +18 -0
  723. package/dist/server/log.js.map +1 -0
  724. package/dist/server/match.js +267 -0
  725. package/dist/server/match.js.map +1 -0
  726. package/dist/server/mode.d.ts +18 -9
  727. package/dist/server/mode.js +220 -0
  728. package/dist/server/mode.js.map +1 -0
  729. package/dist/{navigation-worker.js → server/navigation-worker.js} +1 -1
  730. package/dist/server/navigation-worker.js.map +1 -0
  731. package/dist/server/navigation.js +39 -0
  732. package/dist/server/navigation.js.map +1 -0
  733. package/dist/server/ops.d.ts +4 -0
  734. package/dist/server/ops.js +137 -0
  735. package/dist/server/ops.js.map +1 -0
  736. package/dist/server/packs.d.ts +3 -3
  737. package/dist/server/packs.js +32 -0
  738. package/dist/server/packs.js.map +1 -0
  739. package/dist/server/ratings.d.ts +5 -0
  740. package/dist/server/ratings.js +104 -0
  741. package/dist/server/ratings.js.map +1 -0
  742. package/dist/server/relay.d.ts +12 -2
  743. package/dist/server/relay.js +144 -0
  744. package/dist/server/relay.js.map +1 -0
  745. package/dist/server/rooms.d.ts +9 -2
  746. package/dist/server/rooms.js +442 -0
  747. package/dist/server/rooms.js.map +1 -0
  748. package/dist/server/seat.js +116 -0
  749. package/dist/server/seat.js.map +1 -0
  750. package/dist/server/seatSettings.d.ts +3 -3
  751. package/dist/server/seatSettings.js +63 -0
  752. package/dist/server/seatSettings.js.map +1 -0
  753. package/dist/server/secret.js +13 -0
  754. package/dist/server/secret.js.map +1 -0
  755. package/dist/server/start.d.ts +13 -6
  756. package/dist/server/start.js +76 -0
  757. package/dist/server/start.js.map +1 -0
  758. package/dist/server/websocket.d.ts +9 -1
  759. package/dist/server/websocket.js +306 -0
  760. package/dist/server/websocket.js.map +1 -0
  761. package/dist/server.js +15 -2861
  762. package/dist/session/can.js +26 -0
  763. package/dist/session/can.js.map +1 -0
  764. package/dist/session/commandReplay.d.ts +8 -2
  765. package/dist/session/commandReplay.js +293 -0
  766. package/dist/session/commandReplay.js.map +1 -0
  767. package/dist/session/debug.js +151 -0
  768. package/dist/session/debug.js.map +1 -0
  769. package/dist/session/delay.js +62 -0
  770. package/dist/session/delay.js.map +1 -0
  771. package/dist/session/delta.d.ts +14 -1
  772. package/dist/session/delta.js +407 -0
  773. package/dist/session/delta.js.map +1 -0
  774. package/dist/session/entityState.js +415 -0
  775. package/dist/session/entityState.js.map +1 -0
  776. package/dist/session/local.d.ts +47 -5
  777. package/dist/session/local.js +670 -0
  778. package/dist/session/local.js.map +1 -0
  779. package/dist/session/memory.d.ts +20 -2
  780. package/dist/session/memory.js +131 -0
  781. package/dist/session/memory.js.map +1 -0
  782. package/dist/session/protocol.d.ts +325 -31
  783. package/dist/session/protocol.js +55 -0
  784. package/dist/session/protocol.js.map +1 -0
  785. package/dist/session/remote.d.ts +74 -12
  786. package/dist/session/remote.js +1394 -0
  787. package/dist/session/remote.js.map +1 -0
  788. package/dist/session/replay.d.ts +11 -2
  789. package/dist/session/replay.js +160 -0
  790. package/dist/session/replay.js.map +1 -0
  791. package/dist/session/seed.js +12 -0
  792. package/dist/session/seed.js.map +1 -0
  793. package/dist/session/share.d.ts +5 -1
  794. package/dist/session/share.js +94 -0
  795. package/dist/session/share.js.map +1 -0
  796. package/dist/session/socket.d.ts +1 -1
  797. package/dist/session/socket.js +29 -0
  798. package/dist/session/socket.js.map +1 -0
  799. package/dist/session/wire.d.ts +5 -0
  800. package/dist/session/wire.js +84 -0
  801. package/dist/session/wire.js.map +1 -0
  802. package/dist/session/worker.d.ts +77 -12
  803. package/dist/session/worker.js +499 -0
  804. package/dist/session/worker.js.map +1 -0
  805. package/dist/shared.d.ts +31 -5
  806. package/dist/shared.js +166 -0
  807. package/dist/shared.js.map +1 -0
  808. package/dist/sides.d.ts +9 -3
  809. package/dist/sides.js +149 -0
  810. package/dist/sides.js.map +1 -0
  811. package/dist/sight.js +85 -0
  812. package/dist/sight.js.map +1 -0
  813. package/dist/simulate-worker.js +1 -1
  814. package/dist/simulate.d.ts +12 -8
  815. package/dist/{simulate-oXBiw1Ff.js → simulate.js} +10 -11
  816. package/dist/simulate.js.map +1 -0
  817. package/dist/smart.js +77 -0
  818. package/dist/smart.js.map +1 -0
  819. package/dist/spatial.d.ts +32 -16
  820. package/dist/spatial.js +234 -0
  821. package/dist/spatial.js.map +1 -0
  822. package/dist/spawning.d.ts +1 -0
  823. package/dist/spawning.js +224 -0
  824. package/dist/spawning.js.map +1 -0
  825. package/dist/stances.d.ts +6 -3
  826. package/dist/stances.js +169 -0
  827. package/dist/stances.js.map +1 -0
  828. package/dist/start.d.ts +10 -10
  829. package/dist/start.js +75 -0
  830. package/dist/start.js.map +1 -0
  831. package/dist/stats.d.ts +42 -16
  832. package/dist/stats.js +290 -0
  833. package/dist/stats.js.map +1 -0
  834. package/dist/summoned.d.ts +52 -0
  835. package/dist/summoned.js +38 -0
  836. package/dist/summoned.js.map +1 -0
  837. package/dist/summons.d.ts +10 -13
  838. package/dist/summons.js +271 -0
  839. package/dist/summons.js.map +1 -0
  840. package/dist/systems/abilities.js +224 -0
  841. package/dist/systems/abilities.js.map +1 -0
  842. package/dist/systems/combat.d.ts +35 -1
  843. package/dist/systems/combat.js +677 -0
  844. package/dist/systems/combat.js.map +1 -0
  845. package/dist/systems/combatTold.d.ts +3 -1
  846. package/dist/systems/combatTold.js +85 -0
  847. package/dist/systems/combatTold.js.map +1 -0
  848. package/dist/systems/construction.js +80 -0
  849. package/dist/systems/construction.js.map +1 -0
  850. package/dist/systems/economy.d.ts +0 -6
  851. package/dist/systems/economy.js +128 -0
  852. package/dist/systems/economy.js.map +1 -0
  853. package/dist/systems/fog.d.ts +1 -1
  854. package/dist/systems/fog.js +120 -0
  855. package/dist/systems/fog.js.map +1 -0
  856. package/dist/systems/life.js +32 -0
  857. package/dist/systems/life.js.map +1 -0
  858. package/dist/systems/movement.d.ts +24 -12
  859. package/dist/systems/movement.js +1247 -0
  860. package/dist/systems/movement.js.map +1 -0
  861. package/dist/systems/orders.js +64 -0
  862. package/dist/systems/orders.js.map +1 -0
  863. package/dist/systems/production.js +322 -0
  864. package/dist/systems/production.js.map +1 -0
  865. package/dist/systems/productionQueue.js +120 -0
  866. package/dist/systems/productionQueue.js.map +1 -0
  867. package/dist/systems/victory.d.ts +1 -1
  868. package/dist/systems/victory.js +56 -0
  869. package/dist/systems/victory.js.map +1 -0
  870. package/dist/talk.d.ts +6 -6
  871. package/dist/talk.js +153 -0
  872. package/dist/talk.js.map +1 -0
  873. package/dist/targeting.d.ts +142 -0
  874. package/dist/targeting.js +49 -0
  875. package/dist/targeting.js.map +1 -0
  876. package/dist/tech.d.ts +20 -3
  877. package/dist/tech.js +239 -0
  878. package/dist/tech.js.map +1 -0
  879. package/dist/techTree.d.ts +7 -0
  880. package/dist/techTree.js +90 -0
  881. package/dist/techTree.js.map +1 -0
  882. package/dist/terrain.d.ts +59 -7
  883. package/dist/terrain.js +389 -0
  884. package/dist/terrain.js.map +1 -0
  885. package/dist/terrainSave.d.ts +6 -0
  886. package/dist/terrainSave.js +74 -0
  887. package/dist/terrainSave.js.map +1 -0
  888. package/dist/testing.d.ts +8 -7
  889. package/dist/testing.js +13 -739
  890. package/dist/testing.js.map +1 -1
  891. package/dist/tiles.d.ts +1 -1
  892. package/dist/tiles.js +43 -0
  893. package/dist/tiles.js.map +1 -0
  894. package/dist/timers.d.ts +29 -4
  895. package/dist/timers.js +242 -0
  896. package/dist/timers.js.map +1 -0
  897. package/dist/tomes.d.ts +4 -4
  898. package/dist/tomes.js +94 -0
  899. package/dist/tomes.js.map +1 -0
  900. package/dist/trade.js +103 -0
  901. package/dist/trade.js.map +1 -0
  902. package/dist/transport.d.ts +6 -1
  903. package/dist/transport.js +281 -0
  904. package/dist/transport.js.map +1 -0
  905. package/dist/tunables.d.ts +10 -3
  906. package/dist/tunables.js +56 -0
  907. package/dist/tunables.js.map +1 -0
  908. package/dist/unitResources.d.ts +67 -0
  909. package/dist/unitResources.js +266 -0
  910. package/dist/unitResources.js.map +1 -0
  911. package/dist/upkeep.d.ts +6 -1
  912. package/dist/upkeep.js +26 -0
  913. package/dist/upkeep.js.map +1 -0
  914. package/dist/veterancy.d.ts +8 -3
  915. package/dist/veterancy.js +131 -0
  916. package/dist/veterancy.js.map +1 -0
  917. package/dist/vision.d.ts +36 -0
  918. package/dist/vision.js +133 -0
  919. package/dist/vision.js.map +1 -0
  920. package/dist/walls.d.ts +1 -1
  921. package/dist/walls.js +278 -0
  922. package/dist/walls.js.map +1 -0
  923. package/dist/world.d.ts +606 -88
  924. package/dist/world.js +1263 -0
  925. package/dist/world.js.map +1 -0
  926. package/package.json +2 -2
  927. package/dist/ai.js.map +0 -1
  928. package/dist/attributes.d.ts +0 -66
  929. package/dist/brain-BvVdUhX8.js +0 -7659
  930. package/dist/brain-BvVdUhX8.js.map +0 -1
  931. package/dist/builds-C6LfgvEU.js +0 -460
  932. package/dist/builds-C6LfgvEU.js.map +0 -1
  933. package/dist/coreComponents-syuh2fPG.js +0 -5149
  934. package/dist/coreComponents-syuh2fPG.js.map +0 -1
  935. package/dist/debugCommands-CzjrSm66.js +0 -14739
  936. package/dist/debugCommands-CzjrSm66.js.map +0 -1
  937. package/dist/determinism-BCymQwiE.js +0 -518
  938. package/dist/determinism-BCymQwiE.js.map +0 -1
  939. package/dist/game-DiJEN-Ks.js +0 -5800
  940. package/dist/game-DiJEN-Ks.js.map +0 -1
  941. package/dist/index.js.map +0 -1
  942. package/dist/inspect-D9dWHmZ0.js.map +0 -1
  943. package/dist/local-Dkovq42k.js +0 -1379
  944. package/dist/local-Dkovq42k.js.map +0 -1
  945. package/dist/missionRules-C-bGxm0Q.js.map +0 -1
  946. package/dist/navigation-worker.js.map +0 -1
  947. package/dist/packs-g5thvmGn.js +0 -3199
  948. package/dist/packs-g5thvmGn.js.map +0 -1
  949. package/dist/profiles-B3NS9jwk.js.map +0 -1
  950. package/dist/server.js.map +0 -1
  951. package/dist/simulate-oXBiw1Ff.js.map +0 -1
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["BY_ID","LAYERS","isObject","mapCells","BY_ID","ID_LISTS","LAYERS","checkpointEvent","LOOKS","REACH","LOOKS"],"sources":["../src/map/schema.ts","../src/map/file.ts","../src/map/resize.ts","../src/map/images.ts","../src/mapFile.ts","../src/mapMerge.ts","../src/presetGround.ts","../src/presetBuildings.ts","../src/packs/heroes/respawn.ts","../src/friendlyFire.ts","../src/ids.ts","../src/gameFiles.ts","../src/packs/pack.ts","../src/packs/director/index.ts","../src/packs/moba/index.ts","../src/techTree.ts","../src/hotReload.ts","../src/session/worker.ts","../src/session/socket.ts","../src/session/share.ts","../src/generateWorker.ts","../src/rulesCheck.ts","../src/attributes.ts","../src/manaBurn.ts","../src/destructibles.ts","../src/portals.ts","../src/runes.ts","../src/tomes.ts","../src/walls.ts","../src/mapMeasure.ts","../src/scenario.ts","../src/packs/heroes/carry.ts","../src/packs/heroes/campaign.ts","../src/session/commandReplay.ts","../src/session/replay.ts"],"sourcesContent":["/*\n * The fields of a map, once (design review E8a): each with what it is (`kind`), when its file has it, what a map has\n * of it where the file has none, and the words a file that is wrong in it is told in. What reads and writes a map file\n * (`parseMap`, `serializeMap`, the parts it knows), copies one (`cloneMap`), grows one (`resizeMap`), merges two\n * (`mergeMaps`) and writes it for a person to read (`mapText`) goes by this table, so that a field is added in one place\n */\nimport type { GameMap } from './types'\n\n/**\n * What a field of a map is:\n * - `text`, `number`, `boolean`: one value\n * - `layer`: a layer of the ground, a value per cell (or per corner, `perVertex`, four bytes each: the heights), a\n * line of text a row in the file, merged cell by cell\n * - `layers`: the game's layers of cells, by id, each as a `layer` is written; merged whole\n * - `mask`: a layer that a map may have none of (what is kept off cells by hand), written where anything is set\n * - `list`: a list of plain objects, those of `byId` with an id each (merged thing by thing, a line each in `mapText`)\n * - `names`: a list of names\n * - `object`: plain data, kept as it is\n *\n * @internal\n */\nexport type MapFieldKind = 'text' | 'number' | 'boolean' | 'layer' | 'layers' | 'mask' | 'list' | 'names' | 'object'\n\n/**\n * A field of a map, as the table has it\n *\n * @internal\n */\nexport interface MapFieldSpec {\n\tkey: keyof GameMap\n\tkind: MapFieldKind\n\t/**\n\t * When the file has it: `always`; `defined` where the map has it; `filled` where it holds anything (text not empty,\n\t * a list or an object with something in it, a mask with a cell set)\n\t */\n\twritten: 'always' | 'defined' | 'filled'\n\t/**\n\t * What a map has where the file has none, or nothing of the kind asked: none (the field left out) when left out. A\n\t * `list` or a `layer` the file must have where `required`\n\t */\n\tempty?: () => unknown\n\t/** A file without it, or with something else in its place, is no map (`Map file: ... is missing`) */\n\trequired?: boolean\n\t/** For a layer: one by corner of the ground (the heights, four bytes each), not by cell */\n\tperVertex?: boolean\n\t/** For a list: of things with an id each */\n\tbyId?: boolean\n\t/** What a file that is wrong in it is told it is, for a layer: `Map file: the ground does not match the size of the map` */\n\twhat?: string\n\t/** A field kept as plain data only, said where it is not: what the game and the editor keep with a map */\n\tplain?: boolean\n}\n\n/**\n * Every field of a map, in the order its file has them (`format` before them, what the reader does not know of the\n * file before that). `satisfies` checks that none of `GameMap` is left out\n *\n * @internal\n */\nexport const MAP_FIELDS = [\n\t{ key: 'name', kind: 'text', written: 'always', empty: () => 'Untitled' },\n\t{ key: 'description', kind: 'text', written: 'always', empty: () => '' },\n\t{ key: 'game', kind: 'text', written: 'defined' },\n\t{ key: 'width', kind: 'number', written: 'always', required: true },\n\t{ key: 'depth', kind: 'number', written: 'always', required: true },\n\t{ key: 'cliffHeight', kind: 'number', written: 'always', empty: () => 3 },\n\t{ key: 'ground', kind: 'layer', written: 'always', required: true, perVertex: true, what: 'the ground' },\n\t{ key: 'levels', kind: 'layer', written: 'always', required: true, what: 'the levels' },\n\t{ key: 'ramps', kind: 'layer', written: 'always', required: true, what: 'the ramps' },\n\t{ key: 'water', kind: 'layer', written: 'always', required: true, what: 'the water' },\n\t{ key: 'tiles', kind: 'layer', written: 'always', required: true, what: 'the paint' },\n\t{ key: 'cells', kind: 'layers', written: 'filled' },\n\t{ key: 'pathing', kind: 'mask', written: 'filled', what: 'what is kept off cells' },\n\t{ key: 'tileset', kind: 'names', written: 'always', required: true, what: 'the tileset' },\n\t{ key: 'players', kind: 'list', written: 'always', required: true, byId: true },\n\t{ key: 'objects', kind: 'list', written: 'always', required: true, byId: true },\n\t{ key: 'camps', kind: 'list', written: 'always', required: true, byId: true },\n\t{ key: 'regions', kind: 'list', written: 'filled', byId: true, empty: () => [] },\n\t{ key: 'points', kind: 'list', written: 'filled', byId: true, empty: () => [] },\n\t{ key: 'paths', kind: 'list', written: 'filled', byId: true, empty: () => [] },\n\t{ key: 'doodads', kind: 'list', written: 'filled', byId: true, empty: () => [] },\n\t{ key: 'cameras', kind: 'list', written: 'filled', byId: true, empty: () => [] },\n\t{ key: 'randomGroups', kind: 'list', written: 'filled' },\n\t{ key: 'itemTables', kind: 'list', written: 'filled' },\n\t{ key: 'forces', kind: 'list', written: 'filled' },\n\t{ key: 'races', kind: 'names', written: 'filled' },\n\t{ key: 'author', kind: 'text', written: 'filled' },\n\t{ key: 'silence', kind: 'names', written: 'filled' },\n\t{ key: 'meantFor', kind: 'text', written: 'filled' },\n\t{ key: 'explored', kind: 'boolean', written: 'defined' },\n\t{ key: 'loading', kind: 'text', written: 'filled' },\n\t{ key: 'preview', kind: 'text', written: 'filled' },\n\t{ key: 'environment', kind: 'object', written: 'filled' },\n\t{ key: 'definitions', kind: 'object', written: 'filled', plain: true },\n\t{ key: 'generated', kind: 'object', written: 'defined' },\n\t{ key: 'day', kind: 'object', written: 'filled' },\n\t{ key: 'bounds', kind: 'object', written: 'defined' },\n\t{ key: 'data', kind: 'object', written: 'filled', empty: () => ({}), plain: true },\n\t{ key: 'editor', kind: 'object', written: 'filled', plain: true }\n] as const satisfies readonly MapFieldSpec[]\n\n/** The keys of `GameMap` the table has, and those it has not: none but what the reader keeps of the file (`extra`) */\ntype Missing = Exclude<keyof GameMap, (typeof MAP_FIELDS)[number]['key'] | 'extra'>\n// a field of GameMap the table does not have is a type error here\nconst everyField: [Missing] extends [never] ? true : Missing = true\nvoid everyField\n\n/** The fields as specs, for what walks them */\nexport const MAP_FIELD_SPECS: readonly MapFieldSpec[] = MAP_FIELDS\n\n/** What a reader of this format knows in a file: `format` and every field. The rest is carried along (`GameMap.extra`) */\nexport const KNOWN: ReadonlySet<string> = new Set(['format', ...MAP_FIELDS.map((field) => field.key)])\n\n/** The fields of a kind */\nexport const fieldsOf = (...kinds: MapFieldKind[]): readonly MapFieldSpec[] => MAP_FIELD_SPECS.filter((field) => kinds.includes(field.kind))\n\n/** The lists of things with ids: merged thing by thing (`mergeMaps`), an entry to a line (`mapText`) */\nexport const BY_ID: readonly string[] = MAP_FIELD_SPECS.filter((field) => field.byId).map((field) => field.key)\n\n/** The layers of the ground every map has: merged cell by cell (`mergeMaps`), a row to a line (`mapText`) */\nexport const LAYERS: readonly ('ground' | 'levels' | 'ramps' | 'water' | 'tiles')[] = fieldsOf('layer').map(\n\t(field) => field.key as 'ground' | 'levels' | 'ramps' | 'water' | 'tiles'\n)\n","import type { GameData } from '../gameData'\n/*\n * A map as its file: written, read, brought up from an older format, copied (design review E8a: `map.ts` in parts)\n */\nimport { packBytes, unpackBytes } from '../bytes'\nimport type { GeneratedWith } from '../generate'\nimport { plain } from '../plain'\nimport { LEGACY_TILESET, MAX_TILES } from '../tiles'\nimport type { MapEnvironment } from './look'\nimport { KNOWN, MAP_FIELD_SPECS, type MapFieldSpec } from './schema'\nimport {\n\ttype CellRect,\n\ttype GameMap,\n\tMAP_FORMAT,\n\tMAX_MAP_SIZE,\n\tMIN_MAP_SIZE,\n\ttype MapCamera,\n\ttype MapCamp,\n\ttype MapDay,\n\ttype MapDoodad,\n\ttype MapForce,\n\ttype MapItemTable,\n\ttype MapObject,\n\ttype MapPath,\n\ttype MapPlayer,\n\ttype MapPoint,\n\ttype MapRandomGroup,\n\ttype MapRegion\n} from './types'\n\n// ---- files\n\n/**\n * A map the way it is written to a file: JSON, with the layers packed\n *\n * @beta\n */\nexport interface MapFile {\n\tformat: number\n\tname: string\n\tdescription: string\n\tgame?: string\n\twidth: number\n\tdepth: number\n\tcliffHeight: number\n\t/**\n\t * The layers of the ground, a line of text for each row (since format 3: before, one line for the whole layer): two\n\t * people who change different rows change different lines, which git merges. The heights by corner, a row of the\n\t * corners along x for each z; the rest by cell, a row of cells for each z\n\t */\n\tground: string[]\n\tlevels: string[]\n\tramps: string[]\n\twater: string[]\n\ttiles: string[]\n\t/** The game's layers of cells (`GameMap.cells`), by id, a line of text for each row as the layers above. Left out for none */\n\tcells?: Record<string, string[]>\n\t/** What is kept off cells by hand (`GameMap.pathing`), a line of text for each row as the layers above. Left out for none */\n\tpathing?: string[]\n\t/** See `GameMap.tileset`. Since format 2 */\n\ttileset: string[]\n\tplayers: MapPlayer[]\n\tobjects: MapObject[]\n\tcamps: MapCamp[]\n\t/** Left out when there are none, as files made before regions were have none */\n\tregions?: MapRegion[]\n\t/** Left out when there are none */\n\tpoints?: MapPoint[]\n\tpaths?: MapPath[]\n\tdoodads?: MapDoodad[]\n\tcameras?: MapCamera[]\n\trandomGroups?: MapRandomGroup[]\n\titemTables?: MapItemTable[]\n\t/** The map's own definitions (`GameMap.definitions`) */\n\tdefinitions?: GameData\n\tforces?: MapForce[]\n\traces?: string[]\n\tauthor?: string\n\tsilence?: string[]\n\tmeantFor?: string\n\texplored?: boolean\n\tloading?: string\n\tpreview?: string\n\tenvironment?: MapEnvironment\n\tday?: MapDay\n\tgenerated?: GeneratedWith\n\tbounds?: CellRect\n\t/** Left out when the game keeps nothing with the map */\n\tdata?: Record<string, unknown>\n\t/** Left out when the editor keeps nothing with the map */\n\teditor?: Record<string, unknown>\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null\n\n/**\n * Brings a file of one format up to the next\n *\n * @beta\n */\nexport type MapMigration = (file: Record<string, unknown>) => Record<string, unknown>\n\n/** The steps from each format to the one after it, by the format they start from */\nconst MIGRATIONS: Record<number, MapMigration> = {\n\t// format 2 says which tile each index of the paint is. Before, the index was into the client's own list\n\t1: (file) => ({ ...file, tileset: [...LEGACY_TILESET] }),\n\t// format 3 writes each layer of the ground a row to a line, for git to merge. Before, a layer was one line\n\t2: (file) => {\n\t\tconst width = Number(file.width)\n\t\tconst depth = Number(file.depth)\n\t\tconst split = (key: string, count: number, bytes: number) => {\n\t\t\tconst packed = file[key]\n\t\t\tconst whole = typeof packed === 'string' ? unpackBytes(packed, count * bytes) : undefined\n\t\t\t// what does not match is left for the reader to say so\n\t\t\treturn whole ? rowsOf(whole, bytes) : packed\n\t\t}\n\t\treturn {\n\t\t\t...file,\n\t\t\tground: split('ground', depth + 1, (width + 1) * 4),\n\t\t\tlevels: split('levels', depth, width),\n\t\t\tramps: split('ramps', depth, width),\n\t\t\twater: split('water', depth, width),\n\t\t\ttiles: split('tiles', depth, width)\n\t\t}\n\t}\n}\n\n/** The layers of cells of a map with anything in them, as the file has them: none when there are none */\nfunction mapCells(map: GameMap): Record<string, string[]> | undefined {\n\tconst layers = Object.entries(map.cells ?? {}).filter(([, cells]) => cells.some((value) => value !== 0))\n\treturn layers.length\n\t\t? Object.fromEntries(layers.sort(([a], [b]) => (a < b ? -1 : 1)).map(([id, cells]) => [id, rowsOf(cells, map.width)]))\n\t\t: undefined\n}\n\n/** Bytes as a line of text for each row of `bytes` of them */\nfunction rowsOf(bytes: Uint8Array, row: number): string[] {\n\tconst lines: string[] = []\n\tfor (let at = 0; at < bytes.length; at += row) lines.push(pack(bytes.subarray(at, at + row)))\n\treturn lines\n}\n\n/**\n * A map file brought up to the format this reader knows, step by step. Throws for what is not a map file, and for\n * one of a newer format: what changed in it cannot be known here. `to` and `steps` are the reader's own when left out\n *\n * @beta\n */\nexport function migrateMap(data: unknown, to: number = MAP_FORMAT, steps: Record<number, MapMigration> = MIGRATIONS): Record<string, unknown> {\n\tif (!isObject(data)) throw new Error('Map file: not a map')\n\tlet file = data\n\tconst format = file.format\n\tif (typeof format !== 'number' || !Number.isInteger(format) || format < 1)\n\t\tthrow new Error(`Map file: format ${String(format)} is not one this game reads`)\n\tif (format > to) throw new Error(`Map file: format ${format} is newer than this game reads (${to}): it was saved by a newer version of the editor`)\n\tfor (let from = format; from < to; from++) {\n\t\tconst step = steps[from]\n\t\tif (!step) throw new Error(`Map file: there is no way from format ${from} to ${from + 1}`)\n\t\tfile = { ...step(file), format: from + 1 }\n\t}\n\treturn file\n}\n\nconst pack = packBytes\n\nfunction unpack(text: string, length: number, what: string): Uint8Array {\n\tconst bytes = unpackBytes(text, length)\n\tif (!bytes) throw new Error(`Map file: ${what} does not match the size of the map`)\n\treturn bytes\n}\n\n/** Whether a value holds anything: text not empty, a list or an object with something in it, a layer with a cell set */\nfunction filled(value: unknown): boolean {\n\tif (value === undefined || value === null || value === '' || value === false) return false\n\tif (value instanceof Uint8Array) return value.some((each) => each !== 0)\n\tif (Array.isArray(value)) return value.length > 0\n\tif (typeof value === 'object') return Object.keys(value).length > 0\n\treturn true\n}\n\n/** The bytes of a layer, and how many to a row: the heights by corner (four bytes each), the rest by cell */\nfunction layerBytes(map: GameMap, field: MapFieldSpec, layer: Float32Array | Uint8Array): { bytes: Uint8Array; row: number } {\n\treturn field.perVertex\n\t\t? { bytes: new Uint8Array(layer.buffer, layer.byteOffset, layer.byteLength), row: (map.width + 1) * 4 }\n\t\t: { bytes: layer as Uint8Array, row: map.width }\n}\n\n/** A field as its file has it, or none where the file leaves it out (`MapFieldSpec.written`) */\nfunction written(map: GameMap, field: MapFieldSpec): unknown {\n\tconst value = map[field.key] as unknown\n\tif (field.written === 'defined' && value === undefined) return undefined\n\tif (field.kind === 'layers') return mapCells(map)\n\tif (field.written === 'filled' && !filled(value)) return undefined\n\tswitch (field.kind) {\n\t\tcase 'layer':\n\t\tcase 'mask': {\n\t\t\tconst { bytes, row } = layerBytes(map, field, value as Float32Array | Uint8Array)\n\t\t\treturn rowsOf(bytes, row)\n\t\t}\n\t\tcase 'names':\n\t\t\t// a list of names asked only where it holds any is a copy; the tileset is the map's own\n\t\t\treturn field.written === 'filled' ? [...(value as string[])] : value\n\t\tcase 'object':\n\t\t\treturn field.plain ? plain(value, field.key, 'Map', 'keep numbers, text, lists and plain objects with a map') : value\n\t\tdefault:\n\t\t\treturn value\n\t}\n}\n\n/**\n * A map as its file. Throws when what the game keeps with it (`data`) is not plain data, saying where\n *\n * @beta\n */\nexport function serializeMap(map: GameMap): MapFile {\n\t// first, so that nothing in it stands in for what this reader does know\n\tconst file: Record<string, unknown> = { ...map.extra, format: MAP_FORMAT }\n\tfor (const field of MAP_FIELD_SPECS) {\n\t\tconst value = written(map, field)\n\t\t// plain data that comes to nothing is left out, as an empty object is\n\t\tif (value === undefined || (field.kind === 'object' && field.written === 'filled' && !filled(value))) continue\n\t\tfile[field.key] = value\n\t}\n\treturn file as unknown as MapFile\n}\n\n/**\n * The maps of map files, by the name of each file without its folder and `.vgmap.json`: `./maps/field.vgmap.json` is\n * `field`. The files by their paths, read (`parseMap`): imported one by one, or Vite's\n * `import.meta.glob('./maps/*.vgmap.json', { eager: true, import: 'default' })` where only a page reads them\n *\n * export const maps = mapsFrom({ './maps/field.vgmap.json': field, './maps/hills.vgmap.json': hills })\n *\n * Throws for two files of one name, and with the path of a file that cannot be read\n *\n * @beta\n */\nexport function mapsFrom(files: Readonly<Record<string, unknown>>): Record<string, GameMap> {\n\tconst maps: Record<string, GameMap> = {}\n\tfor (const [path, file] of Object.entries(files)) {\n\t\tconst name = (path.split('/').pop() ?? path).replace(/\\.vgmap\\.json$|\\.json$/, '')\n\t\tif (name in maps) throw new Error(`mapsFrom: two files are named \"${name}\"`)\n\t\ttry {\n\t\t\tmaps[name] = parseMap(file)\n\t\t} catch (error) {\n\t\t\tthrow new Error(`${path}: ${(error as Error).message}`)\n\t\t}\n\t}\n\treturn maps\n}\n\n/**\n * Reads a map file, of this format or an older one. Throws with what is wrong with it\n *\n * @beta\n */\nexport function parseMap(file: unknown): GameMap {\n\tconst data = migrateMap(file)\n\tconst width = Number(data.width)\n\tconst depth = Number(data.depth)\n\tconst inRange = (size: number) => Number.isInteger(size) && size >= MIN_MAP_SIZE && size <= MAX_MAP_SIZE\n\tif (!inRange(width) || !inRange(depth)) {\n\t\tthrow new Error(`Map file: the size is out of range, between ${MIN_MAP_SIZE} and ${MAX_MAP_SIZE} cells each way`)\n\t}\n\t/** A layer of the ground as its rows have it, back in one piece: `bytes` to a row */\n\tconst rows = (lines: unknown, count: number, bytes: number, what: string) => {\n\t\tif (!Array.isArray(lines) || lines.length !== count || lines.some((line) => typeof line !== 'string'))\n\t\t\tthrow new Error(`Map file: ${what} does not match the size of the map`)\n\t\tconst whole = new Uint8Array(count * bytes)\n\t\tlines.forEach((line: string, row) => whole.set(unpack(line, bytes, what), row * bytes))\n\t\treturn whole\n\t}\n\tconst layer = (field: MapFieldSpec, lines: unknown, what = field.what ?? field.key) =>\n\t\tfield.perVertex ? new Float32Array(rows(lines, depth + 1, (width + 1) * 4, what).buffer) : rows(lines, depth, width, what)\n\t/** A list's entries, each an object, with an id where the list is of things with ids (`byId`) */\n\tconst entries = (field: MapFieldSpec, list: unknown[]) => {\n\t\tlist.forEach((entry, at) => {\n\t\t\tif (!isObject(entry) || Array.isArray(entry)) throw new Error(`Map file: ${field.key}[${at}] is not an object`)\n\t\t\tif (field.byId && !Number.isFinite((entry as { id?: unknown }).id)) throw new Error(`Map file: ${field.key}[${at}] has no id`)\n\t\t})\n\t\treturn list\n\t}\n\tconst map: Record<string, unknown> = {}\n\tfor (const field of MAP_FIELD_SPECS) {\n\t\tconst value = data[field.key]\n\t\tlet read: unknown\n\t\tswitch (field.kind) {\n\t\t\tcase 'text':\n\t\t\t\tread = typeof value === 'string' ? value : undefined\n\t\t\t\tbreak\n\t\t\tcase 'number':\n\t\t\t\tread = field.key === 'width' ? width : field.key === 'depth' ? depth : Number(value) || undefined\n\t\t\t\tbreak\n\t\t\tcase 'boolean':\n\t\t\t\tread = typeof value === 'boolean' ? value : undefined\n\t\t\t\tbreak\n\t\t\tcase 'layer':\n\t\t\t\tread = layer(field, value)\n\t\t\t\tbreak\n\t\t\tcase 'mask':\n\t\t\t\tread = value === undefined ? undefined : layer(field, value)\n\t\t\t\tbreak\n\t\t\tcase 'layers':\n\t\t\t\tread = isObject(value) ? Object.fromEntries(Object.keys(value).map((id) => [id, layer(field, value[id], `the cells of ${id}`)])) : undefined\n\t\t\t\tbreak\n\t\t\tcase 'names':\n\t\t\t\tif (field.required) {\n\t\t\t\t\tif (!Array.isArray(value)) throw new Error(`Map file: ${field.key} is missing`)\n\t\t\t\t\tif (value.length > MAX_TILES || value.some((id) => typeof id !== 'string'))\n\t\t\t\t\t\tthrow new Error('Map file: the tileset is not a list of tile names')\n\t\t\t\t\tread = value\n\t\t\t\t} else read = Array.isArray(value) ? value.filter((name): name is string => typeof name === 'string') : undefined\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tif (field.required && !Array.isArray(value)) throw new Error(`Map file: ${field.key} is missing`)\n\t\t\t\tread = Array.isArray(value) ? entries(field, value) : undefined\n\t\t\t\tbreak\n\t\t\tcase 'object':\n\t\t\t\tread = isObject(value) && !(field.plain && Array.isArray(value)) ? value : undefined\n\t\t\t\tbreak\n\t\t}\n\t\tif (read === undefined) read = field.empty?.()\n\t\tif (read !== undefined) map[field.key] = read\n\t}\n\t// a thing placed is as big as its type unless the file says otherwise\n\tmap.objects = (map.objects as MapObject[]).map((object) => ({ ...object, scale: object.scale ?? 1 }))\n\tconst extra = Object.fromEntries(Object.entries(data).filter(([key]) => !KNOWN.has(key)))\n\tif (Object.keys(extra).length > 0) map.extra = extra\n\treturn map as unknown as GameMap\n}\n\n/** A copy of a field's value that shares nothing with it */\nfunction copied(field: MapFieldSpec, value: unknown): unknown {\n\tswitch (field.kind) {\n\t\tcase 'layer':\n\t\tcase 'mask':\n\t\t\treturn (value as Uint8Array | Float32Array).slice()\n\t\tcase 'layers':\n\t\t\treturn Object.fromEntries(Object.entries(value as Record<string, Uint8Array>).map(([id, cells]) => [id, cells.slice()]))\n\t\tcase 'names':\n\t\t\treturn [...(value as string[])]\n\t\tcase 'list':\n\t\tcase 'object':\n\t\t\treturn structuredClone(value)\n\t\tdefault:\n\t\t\treturn value\n\t}\n}\n\n/**\n * A copy that shares nothing with the original\n *\n * @beta\n */\nexport function cloneMap(map: GameMap): GameMap {\n\tconst copy: Record<string, unknown> = { ...map }\n\tfor (const field of MAP_FIELD_SPECS) {\n\t\tconst value = map[field.key] as unknown\n\t\tif (value !== undefined) copy[field.key] = copied(field, value)\n\t}\n\treturn copy as unknown as GameMap\n}\n\n/**\n * The map without what its editor keeps of its own (`GameMap.editor`): what a game is given to play. The very map\n * where it has none\n *\n * @beta\n */\nexport function withoutEditor(map: GameMap): GameMap {\n\tif (!map.editor) return map\n\tconst { editor: _, ...rest } = map\n\treturn rest\n}\n","/*\n * A map grown or cut on its sides (design review E8a: `map.ts` in parts)\n */\nimport type { AreaShape } from '../areas'\nimport { clamp, type Vec2 } from '../math'\nimport { cloneMap } from './file'\nimport { fieldsOf } from './schema'\nimport type { MapThing } from '../mapFields'\nimport { type GameMap, type MapRegion, MAX_MAP_SIZE, MIN_MAP_SIZE } from './types'\n\n/**\n * How many cells a map gains on each side, or loses where it is less than 0 (see `resizeMap`)\n *\n * @beta\n */\nexport interface MapSides {\n\t/** Towards x 0, and towards x of the width */\n\tleft: number\n\tright: number\n\t/** Towards z 0, and towards z of the depth */\n\ttop: number\n\tbottom: number\n}\n\n/**\n * How a map is being grown or cut (`resizeMap`), for what moves along with it: where a place goes, whether it is\n * still on the map, and a shape moved and cut to the map\n *\n * @beta\n */\nexport interface MapResize {\n\treadonly sides: MapSides\n\t/** The new size, in cells */\n\treadonly width: number\n\treadonly depth: number\n\t/** A place where it is on the grown map (the old place, moved by the cells gained on the left and the top) */\n\tmoved<P extends Vec2>(place: P): P\n\t/** Whether a place is on the grown map */\n\ton(place: Vec2): boolean\n\t/** A place kept on the grown map: at its edge where it is past it */\n\tinside<P extends Vec2>(place: P): P\n\t/** A shape moved: a circle while its middle is on the map, what is left of a rectangle on it; none when it is gone */\n\tshape<S extends AreaShape>(shape: S): S | undefined\n}\n\n/**\n * What moves along with a map grown or cut, of what others than the engine keep with it (`resizeMap`): the client's\n * looks under `map.environment` (`mapLooksResizer` of `@v12-engine/client`), the editor's own. Changes the copy it is\n * given, as `resizeMap` hands it on\n *\n * @beta\n */\nexport type MapResizer = (map: GameMap, resize: MapResize) => void\n\n/**\n * A map grown or cut on any side: the ground, cliffs, water and paint go on as they were at the old edge where it\n * grows; everything on it moves along, and what is no longer on the map is gone. The map itself is left as it was.\n * What the engine keeps moves (objects, camps, regions, points, paths, doodads, cameras, the players' starts, the bounds,\n * the game's own kinds' things in `data`); what others keep moves with the `resizers` given (the client's looks:\n * `mapLooksResizer`)\n *\n * @beta\n */\nexport function resizeMap(map: GameMap, sides: MapSides, resizers: readonly MapResizer[] = []): GameMap {\n\tconst { left, right, top, bottom } = sides\n\tconst width = map.width + left + right\n\tconst depth = map.depth + top + bottom\n\tif (width < MIN_MAP_SIZE || depth < MIN_MAP_SIZE || width > MAX_MAP_SIZE || depth > MAX_MAP_SIZE)\n\t\tthrow new Error(`A map is between ${MIN_MAP_SIZE} and ${MAX_MAP_SIZE} cells each way, not ${width} × ${depth}`)\n\tconst copy = cloneMap(map)\n\t// each new cell, or corner of the ground, takes what is nearest to it on the old map\n\tconst layer = <T extends Float32Array | Uint8Array>(old: T, oldRow: number, oldColumn: number, row: number, column: number): T => {\n\t\tconst out = new (old.constructor as new (length: number) => T)(row * column)\n\t\tfor (let z = 0; z < column; z++) {\n\t\t\tconst from = clamp(z - top, 0, oldColumn - 1) * oldRow\n\t\t\tfor (let x = 0; x < row; x++) out[z * row + x] = old[from + clamp(x - left, 0, oldRow - 1)]\n\t\t}\n\t\treturn out\n\t}\n\tcopy.width = width\n\tcopy.depth = depth\n\t// every layer the map's table has (`MAP_FIELDS`): by corner for the heights, by cell for the rest\n\tconst grown = <T extends Float32Array | Uint8Array>(old: T, perVertex = false): T =>\n\t\tperVertex ? layer(old, map.width + 1, map.depth + 1, width + 1, depth + 1) : layer(old, map.width, map.depth, width, depth)\n\tconst into = copy as unknown as Record<string, unknown>\n\tfor (const field of fieldsOf('layer', 'mask', 'layers')) {\n\t\tconst value = map[field.key] as Float32Array | Uint8Array | Record<string, Uint8Array> | undefined\n\t\tif (!value) continue\n\t\tinto[field.key] =\n\t\t\tfield.kind === 'layers'\n\t\t\t\t? Object.fromEntries(Object.entries(value as Record<string, Uint8Array>).map(([id, cells]) => [id, grown(cells)]))\n\t\t\t\t: grown(value as Float32Array | Uint8Array, field.perVertex)\n\t}\n\tconst on = (p: Vec2) => p.x >= 0 && p.z >= 0 && p.x <= width && p.z <= depth\n\tconst moved = <P extends Vec2>(p: P): P => ({ ...p, x: p.x + left, z: p.z + top })\n\tconst inside = <P extends Vec2>(p: P): P => ({ ...p, x: clamp(p.x, 0, width), z: clamp(p.z, 0, depth) })\n\tconst shape = <S extends AreaShape>(shape: S): S | undefined => {\n\t\t// a circle, and a polygon (by its corners round its middle): where its middle is\n\t\tif (shape.kind !== 'rect') {\n\t\t\tconst center = moved(shape)\n\t\t\treturn on(center) ? center : undefined\n\t\t}\n\t\t// a rectangle is by its middle: what is left of it on the map, and its middle again\n\t\tconst x0 = Math.max(shape.x - shape.width / 2 + left, 0)\n\t\tconst z0 = Math.max(shape.z - shape.depth / 2 + top, 0)\n\t\tconst x1 = Math.min(shape.x + shape.width / 2 + left, width)\n\t\tconst z1 = Math.min(shape.z + shape.depth / 2 + top, depth)\n\t\treturn x1 > x0 && z1 > z0 ? { ...shape, x: (x0 + x1) / 2, z: (z0 + z1) / 2, width: x1 - x0, depth: z1 - z0 } : undefined\n\t}\n\tcopy.objects = copy.objects.map((object) => ({ ...object, ...moved(object) })).filter(on)\n\tcopy.camps = copy.camps.map((camp) => ({ ...camp, ...moved(camp) })).filter(on)\n\tcopy.points = copy.points.map((point) => ({ ...point, ...moved(point) })).filter(on)\n\tcopy.doodads = copy.doodads.map((doodad) => ({ ...doodad, ...moved(doodad) })).filter(on)\n\tcopy.cameras = copy.cameras.map((camera) => ({ ...camera, ...inside(moved(camera)) }))\n\tcopy.paths = copy.paths.map((path) => ({ ...path, points: path.points.map((p) => inside(moved(p))) }))\n\tcopy.players = copy.players.map((player) => {\n\t\tif (!player.start) return player\n\t\tconst start = moved(player.start)\n\t\tconst { start: _, ...rest } = player\n\t\treturn on(start) ? { ...player, start } : rest\n\t})\n\tcopy.regions = copy.regions.flatMap((region): MapRegion[] => {\n\t\tconst moved = shape(region.shape)\n\t\treturn moved ? [{ ...region, shape: moved }] : []\n\t})\n\t// the game's own kinds' things (`MapThing`, kept in `data` under each kind): a list of them moves as the engine's do\n\tfor (const [kind, kept] of Object.entries(copy.data)) {\n\t\tif (Array.isArray(kept) && kept.length && kept.every(isThing)) copy.data[kind] = kept.map((thing) => moved(thing)).filter(on)\n\t}\n\tif (map.bounds) {\n\t\tconst x = Math.max(map.bounds.x + left, 0)\n\t\tconst z = Math.max(map.bounds.z + top, 0)\n\t\tconst bounds = {\n\t\t\tx,\n\t\t\tz,\n\t\t\twidth: Math.min(map.bounds.x + left + map.bounds.width, width) - x,\n\t\t\tdepth: Math.min(map.bounds.z + top + map.bounds.depth, depth) - z\n\t\t}\n\t\tif (bounds.width > 0 && bounds.depth > 0) copy.bounds = bounds\n\t\telse delete copy.bounds\n\t}\n\tconst resize: MapResize = { sides, width, depth, moved, on, inside, shape }\n\tfor (const resizer of resizers) resizer(copy, resize)\n\treturn copy\n}\n\n/** A thing of a game's own kind, as `mapThings` reads one: an id, and a place */\nconst isThing = (thing: unknown): thing is MapThing =>\n\ttypeof thing === 'object' &&\n\tthing !== null &&\n\tNumber.isInteger((thing as MapThing).id) &&\n\tNumber.isFinite((thing as MapThing).x) &&\n\tNumber.isFinite((thing as MapThing).z)\n","/*\n * Heights to and from the pixels of a picture (design review E8a: `map.ts` in parts)\n */\nimport { clamp } from '../math'\nimport type { GameMap } from './types'\n\n/**\n * Heights from the pixels of a picture (RGBA, as a canvas gives them): dark is `low`, light is `high`, the picture\n * stretched over the corners of the map's ground. A heightmap made elsewhere, read into a map\n *\n * @beta\n */\nexport function heightsFromPixels(\n\tpixels: ArrayLike<number>,\n\timageWidth: number,\n\timageHeight: number,\n\tmap: Pick<GameMap, 'width' | 'depth'>,\n\tlow: number,\n\thigh: number\n): Float32Array {\n\tconst row = map.width + 1\n\tconst ground = new Float32Array(row * (map.depth + 1))\n\tconst at = (x: number, y: number) => {\n\t\tconst i = (clamp(y, 0, imageHeight - 1) * imageWidth + clamp(x, 0, imageWidth - 1)) * 4\n\t\t// the brightness of it, as the eye sees it\n\t\treturn (pixels[i] * 0.299 + pixels[i + 1] * 0.587 + pixels[i + 2] * 0.114) / 255\n\t}\n\tfor (let iz = 0; iz <= map.depth; iz++) {\n\t\tfor (let ix = 0; ix <= map.width; ix++) {\n\t\t\t// between the four pixels around where this corner falls\n\t\t\tconst fx = (ix / map.width) * (imageWidth - 1)\n\t\t\tconst fy = (iz / map.depth) * (imageHeight - 1)\n\t\t\tconst x = Math.floor(fx)\n\t\t\tconst y = Math.floor(fy)\n\t\t\tconst tx = fx - x\n\t\t\tconst ty = fy - y\n\t\t\tconst top = at(x, y) * (1 - tx) + at(x + 1, y) * tx\n\t\t\tconst bottom = at(x, y + 1) * (1 - tx) + at(x + 1, y + 1) * tx\n\t\t\tground[iz * row + ix] = low + (top * (1 - ty) + bottom * ty) * (high - low)\n\t\t}\n\t}\n\treturn ground\n}\n\n/**\n * The heights of a terrain as the pixels of a picture (RGBA), a pixel a corner: the lowest black, the highest white\n *\n * @beta\n */\nexport function heightsToPixels(heights: Float32Array, width: number, depth: number): { pixels: Uint8ClampedArray; low: number; high: number } {\n\tlet low = Infinity\n\tlet high = -Infinity\n\tfor (const h of heights) {\n\t\tlow = Math.min(low, h)\n\t\thigh = Math.max(high, h)\n\t}\n\tconst span = high - low || 1\n\tconst pixels = new Uint8ClampedArray((width + 1) * (depth + 1) * 4)\n\tfor (let i = 0; i < heights.length; i++) {\n\t\tconst value = Math.round(((heights[i] - low) / span) * 255)\n\t\tpixels.set([value, value, value, 255], i * 4)\n\t}\n\treturn { pixels, low, high }\n}\n","import { type GameMap, type MapFile, serializeMap } from './map'\nimport { BY_ID, fieldsOf } from './map/schema'\n\n/** The order the parts of a map come in in its file. What is not listed comes after, by name */\nconst PARTS: (keyof MapFile)[] = [\n\t'format',\n\t'name',\n\t'description',\n\t'author',\n\t'meantFor',\n\t'loading',\n\t'explored',\n\t'silence',\n\t'game',\n\t'width',\n\t'depth',\n\t'cliffHeight',\n\t'data',\n\t'editor',\n\t'players',\n\t'regions',\n\t'points',\n\t'paths',\n\t'doodads',\n\t'cameras',\n\t'randomGroups',\n\t'itemTables',\n\t'definitions',\n\t'forces',\n\t'races',\n\t'environment',\n\t'day',\n\t'camps',\n\t'objects',\n\t'tileset',\n\t'preview'\n]\n/** The layers come last: lines nobody reads, a row of the ground to each (the map's table says which: `MAP_FIELDS`) */\nconst LAYERS: (keyof MapFile)[] = [...fieldsOf('layer', 'layers').map((field) => field.key as keyof MapFile)]\n/** Lists with one entry to a line, in the order of their ids */\nconst LISTS = new Set<string>(BY_ID)\n/** The order of what an entry holds. What is not listed comes after, by name */\nconst FIELDS = [\n\t'id',\n\t'name',\n\t'type',\n\t'owner',\n\t'team',\n\t'color',\n\t'race',\n\t'start',\n\t'x',\n\t'z',\n\t'facing',\n\t'scale',\n\t'look',\n\t'units',\n\t'shape',\n\t'points',\n\t'width',\n\t'paint',\n\t'keepClear',\n\t'profile',\n\t'health',\n\t'mana',\n\t'level',\n\t'abilities',\n\t'items',\n\t'amount',\n\t'underConstruction',\n\t'lifetime',\n\t'orders',\n\t'data'\n]\n\n/** The keys of something in a set order: those listed first, in that order, then the rest by name */\nfunction inOrder(value: object, first: readonly string[]): string[] {\n\tconst keys = Object.keys(value)\n\tconst listed = first.filter((key) => keys.includes(key))\n\treturn [...listed, ...keys.filter((key) => !first.includes(key)).sort()]\n}\n\nconst entryText = (entry: Record<string, unknown>): string =>\n\t`{ ${inOrder(entry, FIELDS)\n\t\t.filter((key) => entry[key] !== undefined)\n\t\t.map((key) => `${JSON.stringify(key)}: ${JSON.stringify(entry[key])}`)\n\t\t.join(', ')} }`\n\n/**\n * A map as the text of its file, written to be read by a person comparing two versions of it: every part on a line\n * of its own in a set order, one object to a line in the order of their ids with what each holds in a set order\n * too, and the layers last. Moving one object changes one line, whatever was done before\n *\n * @beta\n */\nexport function mapText(map: GameMap): string {\n\tconst file = serializeMap(map) as unknown as Record<string, unknown>\n\tconst lines = inOrder(file, [...PARTS, ...LAYERS])\n\t\t// the rest, which this version does not know, goes between what it knows and the layers\n\t\t.sort((a, b) => Number(LAYERS.includes(a as keyof MapFile)) - Number(LAYERS.includes(b as keyof MapFile)))\n\t\t.map((key) => {\n\t\t\tconst value = file[key]\n\t\t\t// the game's layers of cells: a row to a line, as the layers of the ground\n\t\t\tif (key === 'cells' && value && typeof value === 'object')\n\t\t\t\treturn `\\t\"cells\": {\\n${Object.entries(value as Record<string, string[]>)\n\t\t\t\t\t.map(([id, rows]) => `\\t\\t${JSON.stringify(id)}: [\\n${rows.map((row) => `\\t\\t\\t${JSON.stringify(row)}`).join(',\\n')}\\n\\t\\t]`)\n\t\t\t\t\t.join(',\\n')}\\n\\t}`\n\t\t\t// a layer of the ground: a row to a line, so that a change to one row changes one line, which git merges\n\t\t\tif (LAYERS.includes(key as keyof MapFile) && Array.isArray(value))\n\t\t\t\treturn `\\t${JSON.stringify(key)}: [\\n${value.map((row) => `\\t\\t${JSON.stringify(row)}`).join(',\\n')}\\n\\t]`\n\t\t\tif (!LISTS.has(key) || !Array.isArray(value)) return `\\t${JSON.stringify(key)}: ${JSON.stringify(value)}`\n\t\t\tif (!value.length) return `\\t${JSON.stringify(key)}: []`\n\t\t\tconst entries = [...(value as { id: number }[])].sort((a, b) => a.id - b.id)\n\t\t\treturn `\\t${JSON.stringify(key)}: [\\n${entries.map((entry) => `\\t\\t${entryText(entry as unknown as Record<string, unknown>)}`).join(',\\n')}\\n\\t]`\n\t\t})\n\treturn `{\\n${lines.join(',\\n')}\\n}\\n`\n}\n\n/**\n * What a map file is called, without what comes after the first dot: the name of the map in small letters, with a\n * dash for whatever is not a letter or a number. `The Pass!` is `the-pass`\n *\n * @beta\n */\nexport function mapFileStem(name: string): string {\n\treturn (\n\t\tname\n\t\t\t.trim()\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t\t.replace(/^-|-$/g, '') || 'map'\n\t)\n}\n\n/** A stem as the start of the name of a type: `the-pass` is `ThePass` */\nconst typeName = (stem: string) => {\n\tconst name = stem.replace(/(^|-)([a-z0-9])/g, (_, __, letter: string) => letter.toUpperCase())\n\t// a type does not start with a number\n\treturn /^[0-9]/.test(name) ? `Map${name}` : name\n}\n\n/** A name as TypeScript writes text, in single quotes as the rest of the code has it. Whatever is in it stays inside */\nconst quoted = (name: string) => `'${JSON.stringify(name).slice(1, -1).replace(/\\\\\"/g, '\"').replace(/'/g, \"\\\\'\")}'`\n\n/** The names as a type: one to a line, so that naming one more thing changes one line */\nconst union = (names: string[]) =>\n\tnames.length\n\t\t? [...names]\n\t\t\t\t.sort()\n\t\t\t\t.map((name) => `\\n\\t| ${quoted(name)}`)\n\t\t\t\t.join('')\n\t\t: ' never'\n\n/**\n * The names of what is on a map as TypeScript, for a game's code to use: `world.named<RoadNames>('gaet')` does not\n * compile. The editor writes it next to the map (`road.names.ts` for `road.vgmap.json`), anew with every save\n *\n * @beta\n */\nexport function mapNamesSource(stem: string, map: GameMap): string {\n\tconst type = typeName(stem)\n\tconst objects = map.objects.flatMap((object) => (object.name ? [object.name] : []))\n\tconst camps = map.camps.flatMap((camp) => (camp.name ? [camp.name] : []))\n\tconst regions = map.regions.map((region) => region.name)\n\tconst points = map.points.map((point) => point.name)\n\tconst paths = map.paths.map((path) => path.name)\n\t// what the client draws (its lights and effects) by name, as plain data: the engine knows nothing more of them\n\tconst lights = namesIn(map.environment, 'lights')\n\tconst effects = namesIn(map.environment, 'effects')\n\treturn [\n\t\t`// Written by the map editor with ${stem}.vgmap.json, anew with every save: not to be changed by hand`,\n\t\t'',\n\t\t`/** What is named on the map, for \\`world.named<${type}Names>(...)\\` */`,\n\t\t`export type ${type}Names =${union(objects)}`,\n\t\t'',\n\t\t`/** The camps that are named on the map, for \\`campNamed(world, ...)\\` */`,\n\t\t`export type ${type}Camps =${union(camps)}`,\n\t\t'',\n\t\t`/** The regions of the map, for \\`world.areas\\` and \\`enteredArea\\` */`,\n\t\t`export type ${type}Regions =${union(regions)}`,\n\t\t'',\n\t\t`/** The points of the map, for \\`world.map.point(...)\\` */`,\n\t\t`export type ${type}Points =${union(points)}`,\n\t\t'',\n\t\t`/** The paths of the map, for \\`world.map.path(...)\\` */`,\n\t\t`export type ${type}Paths =${union(paths)}`,\n\t\t'',\n\t\t`/** The lights of the map that are named, for \\`client.lights.named(...)\\` */`,\n\t\t`export type ${type}Lights =${union(lights)}`,\n\t\t'',\n\t\t`/** The effects of the map that are named, for \\`client.mapEffects.named(...)\\` */`,\n\t\t`export type ${type}Effects =${union(effects)}`,\n\t\t'',\n\t\t`/** The ids of the regions, points and paths by name: what a field that names one keeps (it is handed the name) */`,\n\t\t`export const ${type}Ids = ${idsOf(map)} as const`,\n\t\t''\n\t].join('\\n')\n}\n\n/** The names of the things of a list of a map's environment that have one (`lights`, `effects`), as plain data */\nfunction namesIn(environment: object | undefined, list: string): string[] {\n\tconst things = (environment as Record<string, unknown> | undefined)?.[list]\n\tif (!Array.isArray(things)) return []\n\treturn things.flatMap((thing) =>\n\t\ttypeof (thing as { name?: unknown })?.name === 'string' && (thing as { name: string }).name ? [(thing as { name: string }).name] : []\n\t)\n}\n\n/** The ids of a map's regions, points and paths by name, as the text of an object */\nfunction idsOf(map: GameMap): string {\n\tconst part = (things: readonly { id: number; name: string }[]) =>\n\t\t`{ ${things.map((thing) => `${JSON.stringify(thing.name)}: ${thing.id}`).join(', ')} }`\n\treturn `{ regions: ${part(map.regions)}, points: ${part(map.points)}, paths: ${part(map.paths)} }`\n}\n","import { type GameMap, parseMap, serializeMap } from './map'\nimport { BY_ID as ID_LISTS, LAYERS } from './map/schema'\n\n/*\n * Map files that merge (S26). Git merges a map file line by line, which goes a long way since format 3 (an object to a\n * line, a row of the ground to a line): what it cannot, two changes to the same row or the same object, comes here,\n * as the three files git gives a merge driver (what both came from, ours, theirs). What only one side changed is\n * taken; what both changed alike is taken once; what both changed otherwise is ours, and said, for a person to see to.\n */\n\n/**\n * A merge of two versions of a map from the one they came from\n *\n * @beta\n */\nexport interface MapMerge {\n\tmap: GameMap\n\t/** What both sides changed otherwise, in words: ours was kept for each */\n\tconflicts: string[]\n}\n\n/** The parts of a map file that are lists of things with ids, merged thing by thing: the map's table says (`MAP_FIELDS`) */\nconst BY_ID = new Set(ID_LISTS)\n\n/** What they are as text, to be compared: the same value, the same text */\nconst same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b)\n\n/**\n * The three-way choice of one value: what only one side changed is that side's; both alike, either; both otherwise,\n * ours, and a conflict. `undefined` is a value too: a part one side took out\n */\nfunction pick<T>(base: T, ours: T, theirs: T): { value: T; conflict: boolean } {\n\tif (same(ours, theirs)) return { value: ours, conflict: false }\n\tif (same(ours, base)) return { value: theirs, conflict: false }\n\tif (same(theirs, base)) return { value: ours, conflict: false }\n\treturn { value: ours, conflict: true }\n}\n\n/** What a thing of a list is called in what is said: its kind and its id, and its name or type where it has one */\nfunction nameOf(list: string, entry: { id: number; name?: unknown; type?: unknown } | undefined, id: number): string {\n\tconst kind = list === 'objects' ? 'object' : list.replace(/s$/, '')\n\tconst called = typeof entry?.name === 'string' ? ` \"${entry.name}\"` : typeof entry?.type === 'string' ? ` (${entry.type})` : ''\n\treturn `${kind} ${id}${called}`\n}\n\n/** Merges two lists of things by their ids: each thing chosen as a value of its own, in the order of their ids */\nfunction mergeList(list: string, base: unknown[], ours: unknown[], theirs: unknown[], conflicts: string[]): unknown[] {\n\tconst byId = (entries: unknown[]) => new Map(entries.map((entry) => [(entry as { id: number }).id, entry]))\n\tconst [b, o, t] = [byId(base), byId(ours), byId(theirs)]\n\tconst ids = [...new Set([...b.keys(), ...o.keys(), ...t.keys()])].sort((x, y) => x - y)\n\tconst merged: unknown[] = []\n\tfor (const id of ids) {\n\t\tconst chosen = pick(b.get(id), o.get(id), t.get(id))\n\t\tif (chosen.conflict) {\n\t\t\tconst what = nameOf(list, (o.get(id) ?? t.get(id)) as { id: number }, id)\n\t\t\tconflicts.push(\n\t\t\t\to.has(id) && t.has(id)\n\t\t\t\t\t? `${what} was changed on both sides: ours is kept`\n\t\t\t\t\t: `${what} was changed on one side and taken out on the other: ours is kept`\n\t\t\t)\n\t\t}\n\t\tif (chosen.value !== undefined) merged.push(chosen.value)\n\t}\n\treturn merged\n}\n\n/** Whether a value is a list of things with ids: what of a map's look is merged thing by thing (its lights, effects, decals) */\nconst listOfIds = (value: unknown): value is { id: number }[] =>\n\tArray.isArray(value) && value.every((entry) => !!entry && typeof entry === 'object' && typeof (entry as { id?: unknown }).id === 'number')\n\n/**\n * Merges what a map looks like (`GameMap.environment`, the client's to read) part by part: a list of things with ids\n * (its lights, effects, decals, sounds) thing by thing, as the map's own lists are, and each other part as a value\n */\nfunction mergeEnvironment(base: unknown, ours: unknown, theirs: unknown, conflicts: string[]): { value: unknown; conflict: boolean } {\n\tconst plain = (value: unknown): value is Record<string, unknown> => !!value && typeof value === 'object' && !Array.isArray(value)\n\tif (![base, ours, theirs].every((value) => value === undefined || plain(value))) return pick(base, ours, theirs)\n\tconst [b, o, t] = [base, ours, theirs].map((value) => (value ?? {}) as Record<string, unknown>)\n\tconst merged: Record<string, unknown> = {}\n\tfor (const key of new Set([...Object.keys(b), ...Object.keys(o), ...Object.keys(t)])) {\n\t\tif ([b[key], o[key], t[key]].every((value) => value === undefined || listOfIds(value))) {\n\t\t\tconst list = mergeList(key, (b[key] ?? []) as unknown[], (o[key] ?? []) as unknown[], (t[key] ?? []) as unknown[], conflicts)\n\t\t\tif (list.length || o[key] !== undefined) merged[key] = list\n\t\t\tcontinue\n\t\t}\n\t\tconst chosen = pick(b[key], o[key], t[key])\n\t\tif (chosen.conflict) conflicts.push(`the map's look's ${key} was changed on both sides: ours is kept`)\n\t\tif (chosen.value !== undefined) merged[key] = chosen.value\n\t}\n\treturn { value: Object.keys(merged).length || ours !== undefined ? merged : undefined, conflict: false }\n}\n\n/**\n * Merges two versions of a map from the one they came from: parts and things by their ids (those of its look too: its\n * lights, effects, decals), the ground cell by cell. Never throws for what both changed: ours is kept there, and said\n * (`conflicts`). Maps of different sizes are not merged (ours, and said)\n *\n * @beta\n */\nexport function mergeMaps(base: GameMap, ours: GameMap, theirs: GameMap): MapMerge {\n\tconst conflicts: string[] = []\n\tif (ours.width !== theirs.width || ours.depth !== theirs.depth || base.width !== ours.width || base.depth !== ours.depth) {\n\t\treturn { map: ours, conflicts: ['the size of the map changed: ours is kept whole'] }\n\t}\n\tconst [b, o, t] = [base, ours, theirs].map((map) => serializeMap(map) as unknown as Record<string, unknown>)\n\tconst merged: Record<string, unknown> = { ...o }\n\tconst keys = new Set([...Object.keys(b), ...Object.keys(o), ...Object.keys(t)])\n\tfor (const key of keys) {\n\t\tif (key === 'format' || (LAYERS as readonly string[]).includes(key)) continue\n\t\tif (BY_ID.has(key) && [b[key] ?? [], o[key] ?? [], t[key] ?? []].every(Array.isArray)) {\n\t\t\tconst list = mergeList(key, (b[key] ?? []) as unknown[], (o[key] ?? []) as unknown[], (t[key] ?? []) as unknown[], conflicts)\n\t\t\tif (list.length || o[key] !== undefined) merged[key] = list\n\t\t\telse delete merged[key]\n\t\t\tcontinue\n\t\t}\n\t\tconst chosen = key === 'environment' ? mergeEnvironment(b[key], o[key], t[key], conflicts) : pick(b[key], o[key], t[key])\n\t\tif (chosen.conflict) conflicts.push(`the map's ${key} was changed on both sides: ours is kept`)\n\t\tif (chosen.value === undefined) delete merged[key]\n\t\telse merged[key] = chosen.value\n\t}\n\tconst map = parseMap(merged)\n\t// the paint by cell only where both name their tiles alike: an index means another tile otherwise\n\tconst paintable = same(o.tileset, t.tileset) && same(b.tileset, o.tileset)\n\tfor (const layer of LAYERS) {\n\t\tif (layer === 'tiles' && !paintable) {\n\t\t\tif (!same(Array.from(ours.tiles), Array.from(theirs.tiles)))\n\t\t\t\tconflicts.push('the paint was changed on both sides with different tiles: ours is kept')\n\t\t\tmap.tiles = ours.tiles.slice()\n\t\t\tcontinue\n\t\t}\n\t\tconst [from, mine, yours] = [base[layer], ours[layer], theirs[layer]]\n\t\tconst into = mine.slice()\n\t\tlet both = 0\n\t\tfor (let i = 0; i < into.length; i++) {\n\t\t\tif (mine[i] === yours[i]) continue\n\t\t\tif (mine[i] === from[i]) into[i] = yours[i]\n\t\t\telse if (yours[i] !== from[i]) both++\n\t\t}\n\t\tif (both)\n\t\t\tconflicts.push(\n\t\t\t\t`${both} ${layer === 'ground' ? 'corners of the ground' : `cells of the ${layer === 'tiles' ? 'paint' : layer}`} were changed on both sides: ours is kept there`\n\t\t\t)\n\t\t;(map as unknown as Record<string, unknown>)[layer] = into\n\t}\n\treturn { map, conflicts }\n}\n","import { type CellLayerDef, defineCellLayer } from './cellLayers'\nimport { type TileDef, defineTile } from './tiles'\n\n/**\n * Ready-made grounds a game takes or leaves, beside its own: the tiles of an RTS's ground (grass, dark grass, dirt,\n * road, sand, rock, snow), which the client draws with its `TILE_LOOKS`, and the blight a race spoils ground with,\n * which the client draws with its `blightLook`. They say only what there is; what they do is the game's\n */\n\n/**\n * The tiles of an RTS's ground, by the ids the client's `TILE_LOOKS` has looks for: `tiles: presetTiles` in the rules,\n * `tiles: TILE_LOOKS` in the view. A game adds its own beside them, or takes some (`presetTiles.filter(...)`)\n *\n * @beta\n */\nexport const presetTiles: readonly TileDef[] = [\n\tdefineTile({ id: 'grass', name: 'Grass' }),\n\tdefineTile({ id: 'darkGrass', name: 'Dark grass' }),\n\tdefineTile({ id: 'dirt', name: 'Dirt' }),\n\tdefineTile({ id: 'road', name: 'Road' }),\n\tdefineTile({ id: 'sand', name: 'Sand' }),\n\tdefineTile({ id: 'rock', name: 'Rock' }),\n\tdefineTile({ id: 'snow', name: 'Snow' })\n]\n\n/**\n * Blight: ground spoiled, a layer of cells a map's maker paints and the rules spread (`world.setCells('blight', …)`),\n * drawn by the client's `blightLook`. What it does (who builds on it, who heals on it) is the game's: melee's\n * undead in the example\n *\n * @beta\n */\nexport const presetBlight: CellLayerDef = defineCellLayer({\n\tid: 'blight',\n\tname: 'Blight',\n\tdescription: 'Spoiled ground: what the game says of it, a race that builds on it, one that heals on it',\n\tcolor: [0.45, 0.3, 0.55]\n})\n","import type { AbilityDef, UnitTypeDef } from './defs'\n\n/*\n * Ready-made places a game takes or leaves, beside its own (campaign plan GP4): a fountain, a building whose aura is\n * the game's, and a marketplace's abilities, one resource traded for another at a rate (`exchange` in `trade.ts`).\n * They say only what there is; the looks, the numbers and who stands where are the game's\n */\n\n/**\n * A fountain: a building that keeps the game's aura on who is around it (`aura`, the id of a passive ability with an\n * `aura` effect: a fountain of health's regeneration, a fountain of mana's). It cannot be hurt; a map puts it down\n * for the neutral player, so the aura says `affects: 'all'` to reach everyone (the neutral player is nobody's ally).\n * What is given over the fountain's own goes over it: `presetFountain('healingWaters', { id: 'fountainOfHealth' })`\n *\n * @beta\n */\nexport function presetFountain(aura: string, over: Partial<UnitTypeDef> = {}): UnitTypeDef {\n\treturn {\n\t\tid: 'fountain',\n\t\tname: 'Fountain',\n\t\tkind: 'building',\n\t\tradius: 1.5,\n\t\tfootprint: { w: 3, d: 3 },\n\t\tstats: { health: 1000 },\n\t\tsight: 6,\n\t\tinvulnerable: true,\n\t\tabilities: [aura],\n\t\t...over\n\t}\n}\n\n/**\n * One trade of a marketplace (`presetMarket`): `amount` of `sell` for `rate` of `buy` for each one sold\n *\n * @beta\n */\nexport interface MarketRate {\n\t/** The resource traded away, by id */\n\tsell: string\n\t/** The resource traded for, by id */\n\tbuy: string\n\t/** How much of `buy` comes for each one of `sell`: 0.5 is 100 lumber for 50 gold */\n\trate: number\n\t/** How much is sold at a time: 100 when left out */\n\tamount?: number\n\t/** The ability's id: `sell-<sell>-for-<buy>` when left out */\n\tid?: string\n\t/** The ability's name: `Sell <sell> for <buy>` when left out */\n\tname?: string\n\t/** The key the ability's button is pressed with */\n\thotkey?: string\n}\n\n/**\n * What `presetMarket` is given: the trades, and the seconds between two of each (none when left out)\n *\n * @beta\n */\nexport interface PresetMarketOptions {\n\t/** The trades, an ability each, in the order of the buttons */\n\trates: readonly MarketRate[]\n\t/** Seconds between two trades of each: none when left out */\n\tcooldown?: number\n}\n\n/**\n * A marketplace's abilities: one for each trade (`MarketRate`), cast at once (`target: 'none'`), with an `exchange`\n * effect that trades the caster's owner's resources at its rate. A building of the game's lists their ids in its\n * `abilities` (`abilities: market.map((ability) => ability.id)`), the abilities go in the rules' `abilities`. With\n * less than the amount to sell, the player is told and nothing goes. The computer player does not cast them in a\n * fight (their `ai` says not now); its brain's `spells` may\n *\n * @beta\n */\nexport function presetMarket(options: PresetMarketOptions): AbilityDef[] {\n\treturn options.rates.map(({ sell, buy, rate, amount = 100, id, name, hotkey }) => ({\n\t\tid: id ?? `sell-${sell}-for-${buy}`,\n\t\tname: name ?? `Sell ${sell} for ${buy}`,\n\t\tdescription: `Trades ${amount} ${sell} for ${Math.floor(amount * rate + 1e-9)} ${buy}`,\n\t\ttarget: 'none',\n\t\tmaxLevel: 1,\n\t\t...(hotkey !== undefined && { hotkey }),\n\t\t...(options.cooldown !== undefined && { cooldown: options.cooldown }),\n\t\teffects: [{ type: 'exchange', sell, buy, rate, amount }],\n\t\t// not a spell for a fight: the computer player trades as its brain says, not as the engine works out of effects\n\t\tai: () => null\n\t}))\n}\n","import { entityDied } from '#engine/engineEvents'\nimport type { AbilityDef } from '#engine/defs'\nimport type { GamePack } from '#engine/packs/pack'\nimport type { Entity, PlayerId } from '#engine/entity'\nimport { HEROES, heroOf, heroState, respawning, reviveHero } from '#engine/hero'\nimport { defineListener } from '#engine/events'\nimport type { Vec2 } from '#engine/math'\nimport { homeOf } from '#engine/home'\nimport { defineTimer } from '#engine/timers'\nimport type { World } from '#engine/world'\n\n/*\n * Heroes that come back by themselves (features-plan F1), as in a MOBA, and the home they come back to and are\n * recalled to (F2)\n */\n\n/**\n * What a game's heroes do once fallen (`withRespawn`)\n *\n * @beta\n */\nexport interface RespawnOptions {\n\t/** Seconds a fallen hero waits to come back: 4 and 2 more a level when left out (6 at level 1, 24 at level 10) */\n\ttime?: (world: World, hero: Entity) => number\n\t/** Where it comes back: its side's home (`homeOf`) when left out, where it fell when there is none */\n\tat?: (world: World, hero: Entity) => Vec2 | undefined\n\t/** Which heroes come back by themselves: all of them when left out */\n\theroes?: (world: World, hero: Entity) => boolean\n}\n\n/**\n * A game whose heroes come back by themselves after a while, at their side's home (see `RespawnOptions`): a saved timer\n * each, shown on the HUD as a revive is, and waited for by the computer player in place of reviving at an altar.\n * Revived at an altar in the meantime, it is back then, and the timer comes to nothing. For a game with the heroes pack\n * on (`withHeroes()`): one without it is refused\n *\n * @beta\n */\nexport function withRespawn(options: RespawnOptions = {}): GamePack {\n\tconst time = options.time ?? ((_world: World, hero: Entity) => 4 + 2 * (heroOf(hero)?.level ?? 1))\n\tconst comeBack = defineTimer<{ hero: number; player: PlayerId; since?: number }>('respawn', (world, data) => {\n\t\t// a fallen hero waits out of the world: among its player's heroes\n\t\tconst hero = world.get(data.hero) ?? [...world.index.with(heroState, data.player)].find((each) => each.id === data.hero)\n\t\t// the wait of this death, not of one before it the hero came back from at an altar\n\t\tconst waiting = hero?.get(respawning)\n\t\tif (!hero || !waiting || (data.since !== undefined && waiting.since !== data.since)) return\n\t\thero.remove(respawning)\n\t\t// revived at an altar in the meantime: back already\n\t\tif (hero.alive || !hero.has(heroState)) return\n\t\tconst at = options.at?.(world, hero) ?? homeOf(world, hero.owner, hero.pos) ?? hero.pos\n\t\treviveHero(world, hero, at)\n\t})\n\tconst fell = defineListener({\n\t\tid: 'respawn.fell',\n\t\tevent: entityDied,\n\t\trun(world, { entity }) {\n\t\t\tif (!entity.has(heroState) || (options.heroes && !options.heroes(world, entity))) return\n\t\t\tconst wait = Math.max(0, time(world, entity))\n\t\t\tentity.set(respawning, { since: world.time, wait })\n\t\t\tworld.timers.after(wait, comeBack, { hero: entity.id, player: entity.owner, since: world.time })\n\t\t}\n\t})\n\treturn {\n\t\tid: 'respawn',\n\t\toptions,\n\t\t// heroes are the heroes pack's: a game with this has that on too, or is refused\n\t\trequires: [HEROES],\n\t\tcomponents: [respawning],\n\t\ttimers: [comeBack],\n\t\tlisteners: [fell]\n\t}\n}\n\n/**\n * Recall (features-plan F2): a hero stands and channels for a few seconds, then is at its side's home (`homeOf`),\n * however far; hurt in the meantime, or told to do something else, and it stays where it is. An ability to give heroes\n * (`UnitTypeDef.abilities`), made of the engine's parts: a channel (`AbilityDef.channel`) that `breaksOnDamage`, and the\n * `teleport` effect when it is `finished`. Its id, name, how long it takes, its cooldown and key are the game's to say\n *\n * @beta\n */\nexport function recallAbility(options: { id?: string; name?: string; duration?: number; cooldown?: number; hotkey?: string } = {}): AbilityDef {\n\tconst duration = options.duration ?? 6\n\treturn {\n\t\tid: options.id ?? 'recall',\n\t\tname: options.name ?? 'Recall',\n\t\tdescription: `After ${duration} seconds standing still, unhurt, the hero is back home.`,\n\t\thotkey: options.hotkey ?? 'B',\n\t\ttarget: 'none',\n\t\tcooldown: options.cooldown ?? 20,\n\t\tmaxLevel: 1,\n\t\teffects: [],\n\t\tchannel: { duration, breaksOnDamage: true, finished: [{ type: 'teleport', to: 'home' }] }\n\t}\n}\n","import type { Entity } from './entity'\nimport { defineHook } from './hooks'\nimport type { GamePack } from './packs/pack'\nimport { attackReaches } from './systems/combat'\nimport type { World } from './world'\n\n/*\n * Friendly fire, an opt-in pack: as in classic RTS games, a unit told to attack one of its own side's does\n */\n\n/**\n * The friendly fire pack's id\n *\n * @beta\n */\nexport const FRIENDLY_FIRE = 'core.friendlyFire'\n\n/**\n * What the friendly fire pack is made with (`withFriendlyFire`)\n *\n * @beta\n */\nexport interface FriendlyFireOptions {\n\t/** What of its own side's, and its allies', a unit may be told to attack: anything its attack reaches when left out */\n\tattacks?: (world: World, attacker: Entity, target: Entity) => boolean\n}\n\n/**\n * Friendly fire, as in classic RTS games: a unit told to attack (the attack command, never a right click) one of its own or\n * an ally's attacks it. Never of its own accord: units do not pick their own side to attack, nor fight back at it.\n * Nothing of a neutral player's (a rock, a critter) is made a target by it\n *\n * @beta\n */\nexport function withFriendlyFire(options: FriendlyFireOptions = {}): GamePack {\n\tconst attacks = options.attacks ?? (() => true)\n\tconst friendly = defineHook({\n\t\thook: 'canAttack',\n\t\tid: 'friendlyFire',\n\t\trun(world, event) {\n\t\t\tconst { attacker, target } = event\n\t\t\tif (event.allowed || !event.ordered || world.player(target.owner).neutral) return\n\t\t\tif (world.areEnemies(attacker.owner, target.owner)) return\n\t\t\tif (attackReaches(world, attacker, target) && attacks(world, attacker, target)) event.allowed = true\n\t\t}\n\t})\n\treturn { id: FRIENDLY_FIRE, options, hooks: [friendly] }\n}\n","/**\n * Ids the compiler knows. A game's ids are text to the engine (`world.spawn('skeleton', ...)`), and a slip of the\n * finger in one is found when the game runs, if it is found. Named once with `defineIds`, they are checked as they are\n * written, completed by the editor, and renamed in one place:\n *\n * export const UNIT = defineIds('skeleton', 'runner', 'brute')\n * export type TdUnit = IdOf<typeof UNIT> // 'skeleton' | 'runner' | 'brute'\n *\n * { id: UNIT.skeleton, ... } // in the unit's definition\n * world.spawn(UNIT.skeletn, ...) // does not compile\n * const view: GameView<TdUnit> = { units: { looks: { skeletn: ... } } } // nor does this\n *\n * It is a help, not a rule: plain text works wherever an id goes, and what the compiler cannot see is checked when the\n * game is put together (`defineGame`)\n *\n * @beta\n */\nexport function defineIds<const T extends string>(...names: T[]): { readonly [K in T]: K } {\n\tconst out: Record<string, string> = {}\n\tfor (const name of names) {\n\t\tif (name in out) throw new Error(`defineIds: \"${name}\" is there twice`)\n\t\tout[name] = name\n\t}\n\treturn Object.freeze(out) as { readonly [K in T]: K }\n}\n\n/**\n * The ids of a list made with `defineIds`, as a type: `IdOf<typeof UNIT>`\n *\n * @beta\n */\nexport type IdOf<T extends Readonly<Record<string, string>>> = keyof T & string\n","/**\n * A file of a game's own data that its rules read as they run and a panel edits (`defineGameFile`): a campaign's waves,\n * a tower defence's paths. Each world's registry holds what it was read as (`registry.file`), so two games on one page\n * or two rooms of a server each play their own, and the editor's panel changes the one its game plays\n * (`registry.setFile`); the file itself is the game's, written by the editor and taken again as code is (`hotRules`)\n */\n\n/**\n * A file of the game's own data, and how it is read\n *\n * @beta\n */\nexport interface GameFileDef<T> {\n\t/** Unique in the game: the file's name, as the editor writes it (`waves.json`) */\n\treadonly id: string\n\t/** What the file says, as the game was built with it (an imported JSON file) */\n\treadonly data: unknown\n\t/** What the rules read of it: checked, with what is not of its shape left out */\n\tread(data: unknown): T\n}\n\n/**\n * A file of the game's own data, for `GameModule.files`: `defineGameFile('waves.json', wavesFile, readWaves)`, read by\n * the rules with `world.registry.file(waves)`\n *\n * @beta\n */\nexport function defineGameFile<T>(id: string, data: unknown, read: (data: unknown) => T): GameFileDef<T> {\n\treturn { id, data, read }\n}\n","import type { EffectKind } from '#engine/abilities/effects'\nimport type { CommandDef } from '#engine/commands'\nimport type { Component } from '#engine/components'\nimport type { ListenerDef } from '#engine/events'\nimport type { HookDef } from '#engine/hooks'\nimport type { OrderBehavior, SystemDef } from '#engine/registry'\nimport type { StatPart } from '#engine/stats'\nimport type { StatDef } from '#engine/defs'\nimport type { EventKey } from '#engine/events'\nimport type { ReplicatedEvent, SnapshotPart } from '#engine/replication'\nimport type { PlayerId } from '#engine/entity'\nimport type { GameMap } from '#engine/map'\nimport type { MapProblem } from '#engine/mapFields'\nimport type { Registry } from '#engine/registry'\nimport type { GameRules, RulesInit } from '#engine/rules'\nimport type { World } from '#engine/world'\nimport type { TimerDef } from '#engine/timers'\n\n/**\n * A part of the rules a game opts into (`GameModule.packs`): commands, orders, systems, hooks and the state it keeps,\n * which a game without it pays nothing for. The engine's heroes, camps and shops are one (`withHeroes`). A game's\n * own lists come after a pack's, so a command, an order, a hook or a system of the same id or name takes its place;\n * `withoutCommands`, `withoutOrders`, `withoutSystems` and `withoutHooks` take one of a pack's out as they do the\n * engine's\n *\n * @beta\n */\nexport interface GamePack {\n\t/** Unique among a game's packs: how a game, a mod or the editor asks whether it is on (`hasPack`) */\n\tid: string\n\t/** Commands it takes, beside the engine's (`defineCommand`) */\n\tcommands?: CommandDef[]\n\t/** Orders its units can be given, beside the engine's */\n\torders?: OrderBehavior[]\n\t/** Systems, run with the engine's in the phase each says (see `System`) */\n\tsystems?: SystemDef[]\n\t/** Its handlers of hooks, after the engine's and before the game's (`defineHook`) */\n\thooks?: HookDef[]\n\t/** Kinds of ability effects it brings (`defineEffect`), beside the engine's: one of the game's of the same type takes its place */\n\teffects?: EffectKind[]\n\t/** How it reacts to events (`defineListener`) */\n\tlisteners?: ListenerDef[]\n\t/** The state it keeps on entities, players and the world (`defineComponent`) */\n\tcomponents?: Component<any>[]\n\t/** What it sets to go off later (`defineTimer`): listed, so that a save finds them by id */\n\ttimers?: TimerDef[]\n\t/** The stats it brings, next to the engine's and the game's own (`StatDef`, as `GameModule.stats`) */\n\tstats?: StatDef[]\n\t/** What it adds to a unit's stats, kept up to date as the engine keeps the rest (`StatPart`) */\n\tstatParts?: StatPart[]\n\t/** The events it tells of (`defineEvent`), listed as a game's are */\n\tevents?: EventKey<any>[]\n\t/** How events of the world of its own are told to the players (`replicateEvent`), after the engine's */\n\treplications?: ReplicatedEvent[]\n\t/** Parts of the players' snapshots of its own (`SnapshotPart`), after the engine's */\n\tsnapshotParts?: SnapshotPart[]\n\t/** What it adds to the game's report of a player at the end (`GameModule.report`), beside the game's own */\n\treport?(world: World, player: PlayerId): Record<string, unknown>\n\t/** How a game with it is won, where the game says nothing of its own (`GameModule.victory`): the last pack's that says */\n\tvictory?: SystemDef | null\n\t/**\n\t * The rules it changes: handed the game's as they come out (the engine's, the game's over them, the packs' before it),\n\t * it gives what it lays over them. A function of them, so that what it says can be made of what was there (the lanes'\n\t * supply: none for a minion, the game's own for the rest)\n\t */\n\trules?(rules: Readonly<GameRules>): RulesInit\n\t/** What it finds wrong with a map in the editor, beside what the game finds (`MapEditorDef.check`) */\n\tcheck?(map: GameMap, registry: Registry): MapProblem[]\n\t/** The packs it is made to go with, by id: a game with it and without one of them is refused */\n\trequires?: string[]\n\t/**\n\t * What it was made with, as plain data: what a game's hash names it by, beside its id (`gameHash`), so that one pack\n\t * made two ways is two games\n\t */\n\toptions?: unknown\n}\n\n/**\n * Whether a game has a pack on, by its id: `hasPack(game, HEROES)`, what the editor asks before it shows a hero's\n * fields\n *\n * @beta\n */\nexport function hasPack(game: { packs?: readonly GamePack[] } | null | undefined, id: string): boolean {\n\treturn !!game?.packs?.some((pack) => pack.id === id)\n}\n","import { defineComponent } from '#engine/components'\nimport { type CommandDef, defineCommand } from '#engine/commands'\nimport { commandRejected } from '#engine/engineEvents'\nimport type { Entity, PlayerId } from '#engine/entity'\nimport { bool, id, number, oneOf, optional, point, string } from '#engine/fields'\nimport { defineHook, type HookDef } from '#engine/hooks'\nimport { createOrder, giveOrder } from '#engine/orders/queue'\nimport type { GamePack } from '#engine/packs/pack'\nimport type { World } from '#engine/world'\n\n/*\n * The director (campaign plan CI1): a cinematic that changes the game itself, for any player's units, as a film's\n * director does. A cinematic plays on a player's screen, and the rules change only by commands, so that every machine\n * and a replay have the same game: the screen says a cinematic began and ended (`cinematicPlaying`), and while one\n * plays on it, its `director` commands are taken: a unit put down, taken away, killed, put elsewhere, sized, made\n * invulnerable, given to another player, ordered, turned. Outside a cinematic they are turned away and counted\n * (`commandRejected`, `notDirecting`), as a server counts what a player's own client never sends. A game takes them\n * where it says so (`packs: [withDirector()]`)\n */\n\n/** @beta */\nexport const DIRECTOR = 'director'\n\n/**\n * The cinematic playing on each player's screen, by its id, as their screen said (`cinematicPlaying`): whose\n * director's commands are taken\n *\n * @beta\n */\nexport const directing = defineComponent<Record<number, string>>('director.playing', { default: () => ({}) })\n\n/**\n * The units a cinematic made invulnerable (`director` with `invulnerable`): nothing hurts or kills them until it says\n * otherwise\n *\n * @beta\n */\nexport const directorInvulnerable = defineComponent<true>('director.invulnerable')\n\n/**\n * What a director's command does (`DirectorCommand.action`)\n *\n * @beta\n */\nexport const DIRECTOR_ACTIONS = ['spawn', 'remove', 'kill', 'teleport', 'scale', 'invulnerable', 'owner', 'order', 'facing'] as const\n\n/** @beta */\nexport type DirectorAction = (typeof DIRECTOR_ACTIONS)[number]\n\n/**\n * The orders a director's command gives (`order`): to a spot, or at a unit\n *\n * @beta\n */\nexport const DIRECTOR_ORDERS = ['move', 'attack', 'attackMove', 'patrol', 'stop', 'hold'] as const\n\n/**\n * A player's screen says a cinematic began on it (`playing: true`, its id) or ended: while one plays there, the\n * director's commands it sends are taken\n *\n * @beta\n */\nexport const cinematicPlayingCommand = defineCommand('cinematicPlaying', { cinematic: string, playing: bool }, (world, player, command) => {\n\t// a cinematic the game says its director plays in, where it says\n\tconst known = directorOptions(world).cinematics\n\tif (command.playing && known && !known.includes(command.cinematic))\n\t\treturn refuse(world, player, `\"${command.cinematic}\" is no cinematic the director plays in (withDirector's cinematics)`)\n\tconst now = { ...world.state(directing) }\n\tif (command.playing) now[player] = command.cinematic\n\telse if (now[player] === command.cinematic) delete now[player]\n\tworld.setState(directing, now)\n})\n\n/**\n * What a game's director takes (`withDirector(options)`)\n *\n * @beta\n */\nexport interface DirectorOptions {\n\t/**\n\t * The cinematics it plays in, by id: a screen that says another began is turned away (and counted), so that on a\n\t * server a player's own client cannot direct a game with a cinematic made up. Any when left out\n\t */\n\tcinematics?: readonly string[]\n}\n\n/** The options the game's director pack was made with */\nconst directorOptions = (world: World): DirectorOptions =>\n\t(world.registry.module?.packs?.find((pack) => pack.id === DIRECTOR)?.options as DirectorOptions | undefined) ?? {}\n\n/** Turned away, and counted as what the player's own client never sends */\nconst refuse = (world: World, player: PlayerId, reason: string) =>\n\tworld.events.emit(commandRejected, { player, type: 'director', kind: 'notDirecting', reason })\n\n/**\n * A cinematic's say over the game (see the top of this file): `action` with what it takes. `unit` is the one it is\n * done to (any player's); `spawn` puts one of `unitType` down for `owner` at `at`, turned to `facing`, named `name` for\n * what comes after it in the cinematic (`world.named`)\n *\n * @beta\n */\nexport const directorCommand = defineCommand(\n\t'director',\n\t{\n\t\tcinematic: string,\n\t\taction: oneOf(...DIRECTOR_ACTIONS),\n\t\tunit: optional(id),\n\t\tunitType: optional(string),\n\t\towner: optional(id),\n\t\tat: optional(point),\n\t\tfacing: optional(number),\n\t\tscale: optional(number),\n\t\ton: optional(bool),\n\t\tname: optional(string),\n\t\torder: optional(oneOf(...DIRECTOR_ORDERS)),\n\t\ttarget: optional(id)\n\t},\n\t(world, player, command) => {\n\t\tconst playing = world.state(directing)[player]\n\t\tif (playing !== command.cinematic) {\n\t\t\trefuse(world, player, playing ? `the cinematic playing is \"${playing}\", not \"${command.cinematic}\"` : 'no cinematic plays on their screen')\n\t\t\treturn\n\t\t}\n\t\tconst { action } = command\n\t\tif (action === 'spawn') {\n\t\t\tif (!command.unitType || !world.registry.units.has(command.unitType))\n\t\t\t\treturn refuse(world, player, `there is no unit type \"${command.unitType}\"`)\n\t\t\tconst owner = command.owner ?? player\n\t\t\tif (!world.players.has(owner)) return refuse(world, player, `there is no player ${owner}`)\n\t\t\tif (!command.at) return refuse(world, player, 'a unit put down needs where (at)')\n\t\t\tworld.spawn(command.unitType, owner, command.at, {\n\t\t\t\t...(command.facing !== undefined && { facing: command.facing }),\n\t\t\t\t...(command.name && { name: command.name })\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tconst entity = command.unit === undefined ? undefined : world.get(command.unit)\n\t\tif (!entity?.alive) return refuse(world, player, `there is no unit ${command.unit}`)\n\t\tact(world, entity, command)\n\t}\n)\n\n/** What a director's command does to a unit there is */\nfunction act(world: World, entity: Entity, command: Parameters<typeof directorCommand.execute>[2]): void {\n\tswitch (command.action) {\n\t\tcase 'remove':\n\t\t\tworld.kill(entity, undefined, false, 'removed')\n\t\t\tbreak\n\t\tcase 'kill':\n\t\t\tworld.kill(entity)\n\t\t\tbreak\n\t\tcase 'teleport':\n\t\t\tif (command.at) world.place(entity, command.at)\n\t\t\tbreak\n\t\tcase 'scale':\n\t\t\tif (command.scale !== undefined && command.scale > 0) entity.scale = command.scale\n\t\t\tbreak\n\t\tcase 'invulnerable':\n\t\t\tif (command.on === false) entity.remove(directorInvulnerable)\n\t\t\telse entity.set(directorInvulnerable, true)\n\t\t\tbreak\n\t\tcase 'owner':\n\t\t\tif (command.owner !== undefined && world.players.has(command.owner)) world.setOwner(entity, command.owner)\n\t\t\tbreak\n\t\tcase 'facing':\n\t\t\tif (command.facing !== undefined) entity.facing = command.facing\n\t\t\tbreak\n\t\tcase 'order': {\n\t\t\tconst kind = command.order ?? 'move'\n\t\t\tconst target = command.target === undefined ? undefined : world.get(command.target)\n\t\t\tconst init =\n\t\t\t\tkind === 'stop' || kind === 'hold'\n\t\t\t\t\t? { type: kind }\n\t\t\t\t\t: kind === 'attack' && target\n\t\t\t\t\t\t? { type: 'attack', target: target.id }\n\t\t\t\t\t\t: command.at\n\t\t\t\t\t\t\t? { type: kind === 'attack' ? 'attackMove' : kind, point: command.at }\n\t\t\t\t\t\t\t: undefined\n\t\t\tif (init) giveOrder(world, entity, createOrder(world, init as never))\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n/** Nothing hurts or kills a unit a cinematic made invulnerable */\nconst invulnerableHooks: HookDef[] = [\n\tdefineHook({\n\t\thook: 'beforeDamage',\n\t\tid: 'director',\n\t\trun(_world, damage) {\n\t\t\tif (damage.target.has(directorInvulnerable)) damage.cancelled = true\n\t\t}\n\t}),\n\tdefineHook({\n\t\thook: 'beforeDeath',\n\t\tid: 'director',\n\t\trun(_world, death) {\n\t\t\tif (death.entity.has(directorInvulnerable) && death.reason !== 'removed') death.prevented = true\n\t\t}\n\t})\n]\n\n/**\n * The director's pack (see the top of this file): its commands, what it keeps, and what keeps a unit it made\n * invulnerable so. `packs: [withDirector()]`, or `withDirector({ cinematics: ['intro'] })` for those alone\n *\n * @beta\n */\nexport function withDirector(options: DirectorOptions = {}): GamePack {\n\treturn {\n\t\tid: DIRECTOR,\n\t\toptions,\n\t\tcommands: [cinematicPlayingCommand, directorCommand] as unknown as CommandDef[],\n\t\tcomponents: [directing, directorInvulnerable],\n\t\thooks: invulnerableHooks\n\t}\n}\n","/**\n * The stats of a MOBA (`withMobaStats`): ability power, critical strikes, armor and magic penetration, life steal and\n * omnivamp, tenacity, slow resistance, heal and shield power, ability haste. The hero arena games' vocabulary and their\n * formulas, a pack a game opts into: one without it has none of these stats, and the engine's rules are the plainer\n * ones (no crits, mitigation by armor and magic resist alone, cooldowns as they are)\n */\nimport { isCrowdControl } from '#engine/abilities/buffs'\nimport type { DamageType, StatDef, Stats } from '#engine/defs'\nimport { clamp } from '#engine/math'\nimport { defineHook } from '#engine/hooks'\nimport type { GamePack } from '#engine/packs/pack'\nimport { type CombatRules, defaultRules, type GameRules } from '#engine/rules'\nimport { resisted, statsOf } from '#engine/stats'\n\n/**\n * The MOBA stats pack's id\n *\n * @beta\n */\nexport const MOBA_STATS = 'core.mobaStats'\n\n/**\n * What the MOBA stats pack is made with (`withMobaStats`)\n *\n * @beta\n */\nexport interface MobaStatsOptions {\n\t/** What a critical strike multiplies the damage by, for units that do not say: 1.75 when left out */\n\tcritDamage?: number\n\t/** Tenacity no unit goes past: what is left of a stun or a slow at the very least. 0.9 when left out */\n\tmaxTenacity?: number\n}\n\n/** The stats the pack brings, in the order a stat sheet shows them; `critDamage`'s default is the pack's option */\nconst mobaStatDefs = (critDamage: number): StatDef[] => [\n\t{ id: 'abilityPower', name: 'Ability power', description: 'Makes abilities stronger, as far as they scale with it' },\n\t{ id: 'critChance', name: 'Critical chance', description: 'Chance of a basic attack to strike critically, 0..1', format: 'percent' },\n\t{\n\t\tid: 'critDamage',\n\t\tname: 'Critical damage',\n\t\tdescription: 'What a critical strike multiplies the damage with',\n\t\tdefault: critDamage,\n\t\tformat: 'percent'\n\t},\n\t{ id: 'armorPenetration', name: 'Armor penetration', description: \"Part of the target's armor that is ignored, 0..1\", format: 'percent' },\n\t{ id: 'lethality', name: 'Lethality', description: 'Armor of the target that is ignored, taken off after the part above' },\n\t{\n\t\tid: 'magicPenetrationPercent',\n\t\tname: 'Magic penetration %',\n\t\tdescription: \"Part of the target's magic resist that is ignored, 0..1\",\n\t\tformat: 'percent'\n\t},\n\t{ id: 'magicPenetration', name: 'Magic penetration', description: 'Magic resist of the target that is ignored, taken off after the part above' },\n\t{ id: 'lifeSteal', name: 'Life steal', description: 'Part of the damage of basic attacks that comes back as health', format: 'percent' },\n\t{ id: 'omnivamp', name: 'Omnivamp', description: 'Part of all damage dealt that comes back as health', format: 'percent' },\n\t{ id: 'tenacity', name: 'Tenacity', description: 'Part by which stuns, slows and the like are cut short, 0..1', format: 'percent' },\n\t{ id: 'slowResist', name: 'Slow resist', description: 'Part by which slows are weakened, 0..1', format: 'percent' },\n\t{\n\t\tid: 'healShieldPower',\n\t\tname: 'Heal and shield power',\n\t\tdescription: 'Part by which the heals and shields this unit gives are stronger',\n\t\tformat: 'percent'\n\t},\n\t{ id: 'abilityHaste', name: 'Ability haste', description: 'Shortens cooldowns: 100 of it halve them' }\n]\n\n/**\n * What is left of damage once the target's armor or magic resist, less what the source's penetration ignores, had its\n * say: the pack's `rules.combat.mitigation`\n *\n * @beta\n */\nexport function penetratingMitigation(type: DamageType, target: Readonly<Stats>, source?: Readonly<Stats>): number {\n\tif (type === 'true') return 1\n\tlet resist = type === 'physical' ? target.armor : target.magicResist\n\tif (source && resist > 0) {\n\t\tconst part = type === 'physical' ? source.armorPenetration : source.magicPenetrationPercent\n\t\tconst flat = type === 'physical' ? source.lethality : source.magicPenetration\n\t\t// what is ignored can take the resistance away, not turn it into a weakness\n\t\tresist = Math.max(resist * (1 - part) - flat, 0)\n\t}\n\treturn resisted(resist)\n}\n\n/** Health back for damage dealt: omnivamp of everything, life steal of basic attacks. Before the engine's own handlers */\nconst lifeSteal = defineHook({\n\thook: 'afterDamage',\n\tid: 'mobaStats.lifeSteal',\n\tpriority: -1,\n\trun(world, { target, source, taken, attack }) {\n\t\tif (!source?.alive || taken <= 0 || source === target) return\n\t\tconst stats = statsOf(world, source)\n\t\t// omnivamp works on everything, life steal on basic attacks only\n\t\tconst back = taken * (stats.omnivamp + (attack ? stats.lifeSteal : 0))\n\t\tif (back > 0) world.heal(source, back)\n\t}\n})\n\n/** Stuns, slows and the like cut short by the target's tenacity: before what the game decides of a buff */\nconst tenacity = defineHook({\n\thook: 'beforeBuff',\n\tid: 'mobaStats.tenacity',\n\tpriority: -1,\n\trun(world, event) {\n\t\tif (event.duration !== Infinity && isCrowdControl(event.buff)) event.duration *= 1 - statsOf(world, event.target).tenacity\n\t}\n})\n\n/**\n * The stats of a MOBA, for a game that has them: ability power (what `scaling: { abilityPower }` reads), critical\n * strikes, armor and magic penetration, life steal and omnivamp, tenacity, slow resistance, heal and shield power,\n * ability haste, with the hero arena games' formulas for each. A game without it has none of these stats\n *\n * @beta\n */\nexport function withMobaStats(options: MobaStatsOptions = {}): GamePack {\n\tconst { critDamage = 1.75, maxTenacity = 0.9 } = options\n\treturn {\n\t\tid: MOBA_STATS,\n\t\toptions,\n\t\tstats: mobaStatDefs(critDamage),\n\t\thooks: [lifeSteal, tenacity],\n\t\t// what the game says of its own wins: the pack's formulas go where the engine's would be\n\t\trules: (rules: Readonly<GameRules>) => {\n\t\t\tconst { combat } = rules\n\t\t\tconst engine = defaultRules.combat\n\t\t\tconst own = <K extends keyof CombatRules>(key: K, pack: CombatRules[K]): CombatRules[K] => (combat[key] === engine[key] ? pack : combat[key])\n\t\t\tconst keep = combat.clampStats\n\t\t\treturn {\n\t\t\t\tcombat: {\n\t\t\t\t\t// the dice are only rolled for those who have a chance\n\t\t\t\t\tcritical: own('critical', (world, _attacker, stats) =>\n\t\t\t\t\t\tstats.critChance > 0 && world.rng.next() < stats.critChance ? stats.critDamage : undefined\n\t\t\t\t\t),\n\t\t\t\t\tmitigation: own('mitigation', penetratingMitigation),\n\t\t\t\t\t// the game's own limits kept, the pack's put on them\n\t\t\t\t\tclampStats(stats, all) {\n\t\t\t\t\t\tstats.critChance = clamp(stats.critChance, 0, 1)\n\t\t\t\t\t\tstats.tenacity = clamp(stats.tenacity, 0, maxTenacity)\n\t\t\t\t\t\tstats.slowResist = clamp(stats.slowResist, 0, 1)\n\t\t\t\t\t\tstats.armorPenetration = clamp(stats.armorPenetration, 0, 1)\n\t\t\t\t\t\tstats.magicPenetrationPercent = clamp(stats.magicPenetrationPercent, 0, 1)\n\t\t\t\t\t\tkeep(stats, all)\n\t\t\t\t\t},\n\t\t\t\t\tcooldown: own('cooldown', (seconds, stats) => (stats.abilityHaste > 0 ? (seconds * 100) / (100 + stats.abilityHaste) : seconds)),\n\t\t\t\t\tslowTaken: own('slowTaken', (stats, slow) => slow * (1 - stats.slowResist)),\n\t\t\t\t\thealPower: own('healPower', (world, source) => 1 + statsOf(world, source).healShieldPower)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","import { upgradesOf } from './defs'\nimport type { Registry } from './registry'\n\n/*\n * The tech tree of a game (master plan OH13): what makes what (a building trains a unit, a worker builds a building, a\n * building researches an upgrade, a type upgrades to another) and what needs what (`requires`), each thing on a tier:\n * how far from the start it is. For the editor's drawing of it, and for a game's own (a help screen)\n */\n\n/**\n * A thing of a tech tree: a unit or building type, or an upgrade, on its tier (0: made from the start)\n *\n * @beta\n */\nexport interface TechNode {\n\tid: string\n\tkind: 'unit' | 'building' | 'upgrade'\n\tname: string\n\ttier: number\n\t/** The race it is of, where it says */\n\trace?: string\n}\n\n/**\n * How one thing of a tech tree leads to another: `from` makes `to` (trains, builds, hires, researches, upgrades to),\n * or `to` requires `from`\n *\n * @beta\n */\nexport interface TechEdge {\n\tfrom: string\n\tto: string\n\tkind: 'trains' | 'builds' | 'hires' | 'researches' | 'upgradesTo' | 'requires'\n}\n\n/**\n * The tech tree of a game's rules: its things that are made or make something (scenery and the map's creeps left\n * out), the edges between them, and each one's tier. Tiers go by what makes what from what nothing makes and from the\n * buildings that make the builders, require nothing and are no other's upgrade (a hall; else, where everything is\n * made of something, the buildings that require nothing, are no upgrade and make something),\n * each thing after what it requires; a loop of requirements stops at the number of things\n *\n * @beta\n */\nexport function techTree(registry: Pick<Registry, 'units' | 'upgrades'>): { nodes: TechNode[]; edges: TechEdge[] } {\n\tconst units = registry.units.all()\n\tconst upgrades = registry.upgrades.all()\n\tconst edges: TechEdge[] = []\n\tconst known = new Set([...units.map((unit) => unit.id), ...upgrades.map((upgrade) => upgrade.id)])\n\tconst add = (from: string, to: string, kind: TechEdge['kind']) => {\n\t\tif (known.has(from) && known.has(to) && from !== to) edges.push({ from, to, kind })\n\t}\n\tfor (const unit of units) {\n\t\tfor (const id of unit.trains ?? []) add(unit.id, id, 'trains')\n\t\tfor (const id of unit.builds ?? []) add(unit.id, id, 'builds')\n\t\tfor (const id of unit.hires ?? []) add(unit.id, id, 'hires')\n\t\tfor (const id of unit.researches ?? []) add(unit.id, id, 'researches')\n\t\tfor (const id of upgradesOf(unit)) add(unit.id, id, 'upgradesTo')\n\t\tfor (const id of unit.requires ?? []) add(id, unit.id, 'requires')\n\t}\n\tfor (const upgrade of upgrades) for (const id of upgrade.requires?.[0] ?? []) add(id, upgrade.id, 'requires')\n\n\t// what is in the tree: what makes, is made, or requires or is required\n\tconst inTree = new Set(edges.flatMap((edge) => [edge.from, edge.to]))\n\tconst makes = edges.filter((edge) => edge.kind !== 'requires')\n\tconst made = new Set(makes.map((edge) => edge.to))\n\tconst needs = new Map<string, string[]>()\n\tfor (const edge of edges) if (edge.kind === 'requires') needs.set(edge.to, [...(needs.get(edge.to) ?? []), edge.from])\n\t// the start: what nothing makes; where all is made of something (a hall and its workers), the buildings that require\n\t// nothing and are no other's upgrade (a game starts with a hall), else what requires nothing\n\tconst buildings = new Set(units.filter((unit) => unit.kind !== 'unit').map((unit) => unit.id))\n\tconst upgraded = new Set(edges.filter((edge) => edge.kind === 'upgradesTo').map((edge) => edge.to))\n\tlet start = [...inTree].filter((id) => !made.has(id))\n\t// (of those, the ones that make the builders: a town hall, not a barracks)\n\tconst builders = new Set(units.filter((unit) => unit.builds?.length).map((unit) => unit.id))\n\tconst first = [...inTree].filter((id) => buildings.has(id) && !needs.has(id) && !upgraded.has(id))\n\t// and those halls beside what nothing makes, which may be no player's to make at all (a neutral shipyard that hires)\n\tconst halls = first.filter((id) => makes.some((edge) => edge.from === id && builders.has(edge.to)))\n\tstart = [...new Set([...start, ...halls])]\n\tif (!start.length) start = first.filter((id) => makes.some((edge) => edge.from === id))\n\tif (!start.length) start = [...inTree].filter((id) => !needs.has(id))\n\tconst tier = new Map<string, number>(start.map((id) => [id, 0]))\n\t// out along what makes what, nearest first\n\tfor (let queue = [...start]; queue.length;) {\n\t\tconst next: string[] = []\n\t\tfor (const id of queue)\n\t\t\tfor (const edge of makes)\n\t\t\t\tif (edge.from === id && !tier.has(edge.to)) {\n\t\t\t\t\ttier.set(edge.to, tier.get(id)! + 1)\n\t\t\t\t\tnext.push(edge.to)\n\t\t\t\t}\n\t\tqueue = next\n\t}\n\t// then after what each requires, as long as that moves anything, and no more often than there are things\n\tfor (let pass = 0; pass < inTree.size; pass++) {\n\t\tlet moved = false\n\t\tfor (const [id, required] of needs) {\n\t\t\tconst after = Math.max(...required.map((other) => (tier.get(other) ?? 0) + 1))\n\t\t\tif (after > (tier.get(id) ?? 0)) {\n\t\t\t\ttier.set(id, after)\n\t\t\t\tmoved = true\n\t\t\t}\n\t\t}\n\t\tif (!moved) break\n\t}\n\tconst nodes: TechNode[] = []\n\tfor (const unit of units)\n\t\tif (inTree.has(unit.id))\n\t\t\tnodes.push({\n\t\t\t\tid: unit.id,\n\t\t\t\tkind: unit.kind === 'unit' ? 'unit' : 'building',\n\t\t\t\tname: unit.name,\n\t\t\t\ttier: tier.get(unit.id) ?? 0,\n\t\t\t\t...(unit.race && { race: unit.race })\n\t\t\t})\n\tfor (const upgrade of upgrades)\n\t\tif (inTree.has(upgrade.id))\n\t\t\tnodes.push({\n\t\t\t\tid: upgrade.id,\n\t\t\t\tkind: 'upgrade',\n\t\t\t\tname: upgrade.name,\n\t\t\t\ttier: tier.get(upgrade.id) ?? 0,\n\t\t\t\t...(upgrade.race && { race: upgrade.race })\n\t\t\t})\n\treturn { nodes, edges }\n}\n","import { defineEvent } from './events'\nimport { createRegistry, type GameModule } from './game'\nimport { redefinitions, restoreRedefinitions } from './gameData'\nimport { rootLogger } from './log'\nimport type { ModDef } from './mods'\nimport type { World } from './world'\n\n/**\n * A world took a new version of its game while it ran (`reloadGame`, hot reload): what the rules hear\n * (`world.events.on(gameReloaded, …)`), and every screen (`GameView.on`), to make again what it made of the old one\n *\n * @beta\n */\nexport const gameReloaded = defineEvent<{ game: string }>('core.gameReloaded', { replicate: 'everyone' })\n\n/**\n * Puts a new version of a world's game into it while it runs, as a game's files are saved during development (hot\n * reload): its unit types, abilities, buffs, items, upgrades and races, the code of their effects and of its orders,\n * and its rules. What `world.redefine` changed while it ran stays over them, and its units take their types as they\n * are now. What the world was made of otherwise (its systems, hooks, components, resources) is not: a change to those\n * wants a new game, which is said (`hotRules` loads the page again for one). Throws for another game, or a module that is no game (as `createRegistry`)\n *\n * @beta\n */\nexport function reloadGame(world: World, game: GameModule): void {\n\tconst { registry } = world\n\tif (game.id !== registry.game) throw new Error(`The world plays \"${registry.game}\", not \"${game.id}\"`)\n\tregistry.takeFrom(createRegistry(game))\n\t// what was changed while it ran, over the new version (looked at, not made: a world nothing was changed of has none)\n\tif (world.states.has(redefinitions)) restoreRedefinitions(registry, world.state(redefinitions))\n\tworld.retype()\n\t// the score's stats, as the new version counts them\n\tworld.score.listen()\n\t// what the game does of its own as it takes a new version: what it made of the old one, made again\n\ttry {\n\t\tgame.onReload?.(world)\n\t} catch (error) {\n\t\tworld.log.error('game', `${game.id}'s onReload threw: ${error instanceof Error ? error.message : String(error)}`)\n\t}\n\tworld.log.info(\n\t\t'game',\n\t\t`Took a new version of ${game.name ?? game.id}: its definitions and rules (its systems and hooks are the game's as it began)`\n\t)\n\tworld.events.emit(gameReloaded, { game: game.id })\n}\n\n/**\n * What a module's `import.meta.hot` gives for hot reload, as Vite has it: what loads the page again\n *\n * @beta\n */\nexport interface HotContext {\n\tinvalidate(message?: string): void\n}\n\n/** What of a game a running world keeps as it was made (`reloadGame`): a new version that changes any loads the page again */\nconst NOT_RELOADED = [\n\t'systems',\n\t'withoutSystems',\n\t'hooks',\n\t'withoutHooks',\n\t'components',\n\t'resources'\n] as const satisfies readonly (keyof GameModule)[]\n\n/**\n * What a part of a game is, in words, to tell a new version's from the old: its code by its source, its data by its\n * values, so that a module evaluated again with the same code is the same\n */\nfunction shapeOf(value: unknown, depth = 0, seen = new Set<object>()): string {\n\tif (typeof value === 'function') return `f:${String(value)}`\n\tif (value === null || typeof value !== 'object') return value === undefined ? 'u' : JSON.stringify(value)\n\tif (seen.has(value) || depth > 8) return '…'\n\tseen.add(value)\n\tconst shape = Array.isArray(value)\n\t\t? `[${value.map((each) => shapeOf(each, depth + 1, seen)).join(',')}]`\n\t\t: `{${Object.keys(value)\n\t\t\t\t.sort()\n\t\t\t\t.map((key) => `${key}:${shapeOf((value as Record<string, unknown>)[key], depth + 1, seen)}`)\n\t\t\t\t.join(',')}}`\n\tseen.delete(value)\n\treturn shape\n}\n\n/** Who hears of a new version of a game's rules or of a mod: the client, which tells the games and editors of the page */\nconst listeners = new Set<(game: GameModule) => void>()\nconst modListeners = new Set<(mod: ModDef) => void>()\n\n/**\n * Hears of every new version of a game's rules taken in the page (`hotRules`). Returns what stops it\n *\n * @beta\n */\nexport function onNewGameVersion(listener: (game: GameModule) => void): () => void {\n\tlisteners.add(listener)\n\treturn () => listeners.delete(listener)\n}\n\n/**\n * Hears of every new version of a mod taken in the page (`hotMod`). Returns what stops it\n *\n * @beta\n */\nexport function onNewModVersion(listener: (mod: ModDef) => void): () => void {\n\tmodListeners.add(listener)\n\treturn () => modListeners.delete(listener)\n}\n\n/**\n * A mod's module's new version, taken while it runs (hot reload), as `hotRules` takes a game's: at its end,\n *\n * if (import.meta.hot) import.meta.hot.accept((module) => hotMod(import.meta.hot, goldRush, module?.goldRush))\n *\n * The mod given is made the new one in place, and every game of the page played with it is made again of its parts as\n * they are now (`recompose`) and takes that. What does not go (no new module, another mod, mods that no longer go\n * together) loads the page again\n *\n * @beta\n */\nexport function hotMod(hot: HotContext | undefined, current: ModDef, next: unknown): void {\n\tconst mod = next as ModDef | undefined\n\tif (!mod || typeof mod !== 'object' || mod.id !== current.id) return hot?.invalidate(`${current.id}: its module is not there as it was`)\n\ttry {\n\t\treplaceIn(current, mod)\n\t\tfor (const listener of modListeners) listener(current)\n\t} catch (error) {\n\t\trootLogger.warn('game', `The mod ${current.id}'s new version could not be taken while it runs: the page loads again`, { error: String(error) })\n\t\thot?.invalidate()\n\t}\n}\n\n/**\n * Puts what `next` has into `current`, in its place: everything that holds `current` has the new version\n *\n * @beta\n */\nexport function replaceIn(current: object, next: object): void {\n\tfor (const key of Object.keys(current)) if (!(key in next)) delete (current as Record<string, unknown>)[key]\n\tObject.assign(current, next)\n}\n\n/**\n * A game's entry module's new version, taken while it runs (hot reload). At the module's end, the call to Vite written\n * out as it is (Vite finds a module that takes its own new versions by it):\n *\n * if (import.meta.hot) import.meta.hot.accept((module) => hotRules(import.meta.hot, melee, module?.melee))\n *\n * As it or a file it reads (its units, its `data.json`) is saved in the dev server, the module given is made the new\n * one in place, so that what holds it has the new one, and the games and editors of the page playing it take its\n * definitions and rules (`reloadGame`, through `onNewGameVersion`). What does not go loads the page again, saying why\n * (`hot.invalidate(reason)`): no new module, another game, a component defined another way, or a change to what a\n * running world keeps as it was made (its `systems`, `hooks`, `components`, `resources`, and `withoutSystems` and\n * `withoutHooks`, compared by their code and values). No client is pulled into the rules, which a server reads too\n *\n * @beta\n */\nexport function hotRules(hot: HotContext | undefined, current: GameModule, next: unknown): void {\n\tconst game = next as GameModule | undefined\n\tif (!game || typeof game !== 'object' || game.id !== current.id) return hot?.invalidate(`${current.id}: its module is not there as it was`)\n\t// what a running world keeps as it was made: changed, only a new game has it\n\tconst kept = NOT_RELOADED.filter((key) => shapeOf(current[key]) !== shapeOf(game[key]))\n\tif (kept.length) return hot?.invalidate(`${current.id}: its ${kept.join(', ')} changed, which a running game does not take`)\n\ttry {\n\t\treplaceIn(current, game)\n\t\tfor (const listener of listeners) listener(current)\n\t} catch (error) {\n\t\trootLogger.warn('game', `${current.id}'s new version could not be taken while it runs: the page loads again`, { error: String(error) })\n\t\thot?.invalidate()\n\t}\n}\n","import { checkpoint as checkpointEvent } from '#engine/engineEvents'\nimport { reloadGame } from '#engine/hotReload'\nimport { randomSeed } from '#engine/session/seed'\nimport { paceOf, savesOf } from './can'\nimport type { PlayerId } from '#engine/entity'\nimport { createWorldFromMap, type GameModule, loadWorld } from '#engine/game'\nimport { errorFields, type LogEntry, Logger, rootLogger } from '#engine/log'\nimport type { GameMap } from '#engine/map'\nimport type { Message } from '#engine/messages'\nimport { type NavigationBuild, navigationData } from '#engine/navigation/builds'\nimport { saveWorld, type WorldSave } from '#engine/save'\nimport type { World } from '#engine/world'\nimport type { SystemTiming } from '#engine/scheduler'\nimport type { SessionCan, SessionDebug } from './protocol'\nimport { type ConnectOptions, connectAs, MAX_JITTER, RemoteSession, SessionHost, type Transport } from './remote'\n\n/*\n * The simulation off the page's thread (S54). A game played alone steps its world on the thread that draws: a tick that\n * takes long is a frame that is late. Here the world runs in a worker the page gives, and the page has a seat at it as\n * it would at a server's game: snapshots one way, commands the other, over the worker's messages. The game's code has to\n * be in the worker, and only the game's developer can put it there: the worker's file is theirs, one call\n * (`serveWorld(game, { start })`), made into a worker the way their bundler wants it; the library makes none. What\n * the page did by reaching into the world (holding the game for a menu, a step, a save, the checkpoint to retry from,\n * the debug tools' view, what the game says in its log) goes over the same messages.\n */\n\n/**\n * What a worker is, as far as a game goes: a page's `Worker`, or Node's `worker_threads` one\n *\n * @beta\n */\nexport interface WorldWorkerLike {\n\tpostMessage(message: unknown, transfer?: unknown[]): void\n\taddEventListener?(type: 'message' | 'error', listener: (event: { data?: unknown; message?: string }) => void): void\n\tremoveEventListener?(type: 'message' | 'error', listener: (event: { data?: unknown; message?: string }) => void): void\n\ton?(type: 'message' | 'error', listener: (value: unknown) => void): void\n\toff?(type: 'message' | 'error', listener: (value: unknown) => void): void\n}\n\n/**\n * Where a worker hears and answers: a page's worker scope, or Node's `parentPort`\n *\n * @beta\n */\nexport interface WorldPort {\n\tpostMessage(message: unknown, transfer?: unknown[]): void\n\taddEventListener?(type: 'message', listener: (event: { data: unknown }) => void): void\n\ton?(type: 'message', listener: (value: unknown) => void): void\n}\n\n/**\n * What the page says a game in a worker is made from: plain data, which is all that crosses\n *\n * @beta\n */\nexport interface WorkerGame {\n\t/** A map of the game: the world is made from it. Or a save to go on from (`from`); or neither, where the worker makes its world in code */\n\tmap?: GameMap\n\tfrom?: WorldSave\n\t/** Who the player at the screen is: as the worker says (`ServeWorldOptions.player`), then the map's first with a start, when left out */\n\tplayer?: PlayerId\n\tseed?: number\n\t/** Whether the player may use the debug tools, and sees everything from the start */\n\tdebug?: boolean\n\treveal?: boolean\n\t/** Anything else the worker's own code is to know (`start`, `world`): plain data */\n\targs?: unknown\n}\n\n/**\n * What the worker's file gives besides the game: its code that runs on the world, which cannot be sent\n *\n * @beta\n */\nexport interface ServeWorldOptions {\n\t/** A world made in code, where the page gives neither a map nor a save: generated ground, players of its own */\n\tworld?: (context: { rules: GameModule; seed: number; args: unknown; log: Logger }) => World | Promise<World>\n\t/** What the game does once a new world is made, before anyone plays: as `launch`'s `start`, which a worker's game has here */\n\tstart?: (world: World, context: { player: PlayerId; map?: GameMap; args: unknown }) => void | Promise<void>\n\t/** Who the player at the screen is, where the page does not say */\n\tplayer?: (world: World, map?: GameMap) => PlayerId\n\t/** Where it hears: the worker's own scope when left out (a page's worker); Node's `parentPort` in a worker thread */\n\tport?: WorldPort\n\t/**\n\t * A new version of the game, loaded again in the worker as the page asks (hot reload: the page's game took one, and\n\t * a worker has no hot reload of its own). The game's module imported anew, so that the dev server gives it as it is\n\t * now: `(version) => import(/* @vite-ignore *\\/ `./index.ts?t=${version}`).then((module) => module.myGame)` (a path\n\t * from the worker's file). Only ever asked for in the dev server. Without it, a game in the worker keeps the version it began with\n\t */\n\treload?: (version: number) => Promise<GameModule | undefined> | GameModule | undefined\n}\n\n/** What goes between the page and the worker besides the session's own text */\ntype ToWorker =\n\t| ({ vg: 'start' } & WorkerGame)\n\t| { vg: 'stop' }\n\t| { vg: 'reload' }\n\t| { vg: 'speed'; speed: number }\n\t| { vg: 'advance'; ticks: number }\n\t| { vg: 'save'; id: number }\n\t| { vg: 'navigation'; id: number; build: NavigationBuild }\n\t| { vg: 'profile'; on: boolean }\n\ntype FromWorker =\n\t| { vg: 'ready'; player: PlayerId }\n\t| { vg: 'refused'; message: string; stack?: string }\n\t| { vg: 'saved'; id: number; save?: WorldSave; error?: string }\n\t| { vg: 'built'; id: number; data?: Uint8Array; error?: string }\n\t| { vg: 'checkpoint'; label: Message; save: WorldSave }\n\t| { vg: 'log'; entry: LogEntry }\n\t| { vg: 'timing'; tick: number; tickMax: number; send: number; systems: SystemTiming[] }\n\n/** Milliseconds between two words of where the time went */\nconst TIMING_EVERY = 1000\n\nconst firstOfMap = (map: GameMap): PlayerId | undefined => (map.players.find((player) => player.start) ?? map.players[0])?.id\n\nfunction firstOfWorld(world: World): PlayerId {\n\tfor (const player of world.players.values()) if (!player.neutral && !player.creeps) return player.id\n\tthrow new Error('The world has no player to play: every one of its players is neutral')\n}\n\n/**\n * What a game's worker file does: `serveWorld(game, { start })`. It waits for the page to say what to play (a map, a\n * save, or nothing for a world made here in code), makes the world, runs it by the clock, and seats the page's player\n * at it. A new game asked for ends the one before: a restart is the same worker, its navigation built already\n *\n * @beta\n */\nexport function serveWorld(first: GameModule, options: ServeWorldOptions = {}): void {\n\t/** The game's version now: the one it began with, or the one it took last (`reload`) */\n\tlet game = first\n\tconst port = options.port ?? (globalThis as unknown as WorldPort)\n\tconst post = (message: FromWorker | string, transfer?: unknown[]) => port.postMessage(message, transfer)\n\t/** The game running now, and what ends it */\n\tlet running: { host: SessionHost; hear: (text: string) => void; end: () => void } | undefined\n\t/** Whether the systems are measured, as the page's stats ask: off until they do */\n\tlet profiling = false\n\t/** Each start has a number: one overtaken while its world was made is let go */\n\tlet starts = 0\n\n\tconst start = async (asked: WorkerGame) => {\n\t\tconst mine = ++starts\n\t\trunning?.end()\n\t\trunning = undefined\n\t\t// what the world says goes to the page, which says it where it says its own: not twice, here too\n\t\tconst log = new Logger()\n\t\tconst stopLog = log.to((entry) => post({ vg: 'log', entry }))\n\t\tlet world: World | undefined\n\t\ttry {\n\t\t\tconst seed = asked.seed ?? randomSeed()\n\t\t\tworld = asked.from\n\t\t\t\t? await loadWorld(asked.from, { game, log })\n\t\t\t\t: asked.map\n\t\t\t\t\t? await createWorldFromMap({ map: asked.map, game, seed, log })\n\t\t\t\t\t: options.world\n\t\t\t\t\t\t? await options.world({ rules: game, seed, args: asked.args, log })\n\t\t\t\t\t\t: undefined\n\t\t\tif (!world) throw new Error('A game in a worker needs a map, a save to go on from, or a world made in the worker (serveWorld world)')\n\t\t\tif (mine !== starts) return world.dispose()\n\t\t\tworld.errorPolicy ??= 'end'\n\t\t\tconst player = asked.player ?? options.player?.(world, asked.map) ?? (asked.map && firstOfMap(asked.map)) ?? firstOfWorld(world)\n\t\t\t// only a new game is started: one loaded goes on as it was\n\t\t\tif (!asked.from) await options.start?.(world, { player, map: asked.map, args: asked.args })\n\t\t\tif (mine !== starts) return world.dispose()\n\t\t\tif (asked.reveal) world.fog.setRevealed(world.player(player).team, true)\n\t\t\tif (asked.debug) world.debugPlayers.add(player)\n\n\t\t\tconst made = world\n\t\t\t// every tick goes to the page: there is no wire to spare, and the screen is as close to the world as it gets\n\t\t\tconst host = new SessionHost(made, { ownsWorld: true, sendRate: made.tickRate, dropSilentAfter: Infinity })\n\t\t\tlet hear: (text: string) => void = () => {}\n\t\t\tconst transport: Transport = { send: (text) => post(text), onMessage: (handler) => (hear = handler), onClose: () => {}, close: () => {} }\n\t\t\t// the checkpoint to start again from, as the world stood at the end of the tick that marked it\n\t\t\tconst stopCheckpoint = made.events.on(checkpointEvent, ({ label }) => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (running?.host === host) post({ vg: 'checkpoint', label, save: saveWorld(made) })\n\t\t\t\t}, 0)\n\t\t\t})\n\t\t\t// measured as the page's stats ask (`profile`): the next game as the one before\n\t\t\tmade.scheduler.profiling = profiling\n\t\t\tconst timingTimer = setInterval(() => {\n\t\t\t\tconst timing = host.takeTiming()\n\t\t\t\tpost({\n\t\t\t\t\tvg: 'timing',\n\t\t\t\t\ttick: timing.ticks ? timing.tickTime / timing.ticks : 0,\n\t\t\t\t\ttickMax: timing.tickMax,\n\t\t\t\t\tsend: timing.sends ? timing.sendTime / timing.sends : 0,\n\t\t\t\t\tsystems: made.scheduler.timing()\n\t\t\t\t})\n\t\t\t}, TIMING_EVERY)\n\t\t\trunning = {\n\t\t\t\thost,\n\t\t\t\thear: (text) => hear(text),\n\t\t\t\tend: () => {\n\t\t\t\t\tclearInterval(timingTimer)\n\t\t\t\t\tstopCheckpoint()\n\t\t\t\t\tstopLog()\n\t\t\t\t\thost.dispose()\n\t\t\t\t}\n\t\t\t}\n\t\t\tpost({ vg: 'ready', player })\n\t\t\thost.connect(player, transport)\n\t\t\thost.start()\n\t\t} catch (error) {\n\t\t\tstopLog()\n\t\t\tworld?.dispose()\n\t\t\tif (mine === starts)\n\t\t\t\tpost({\n\t\t\t\t\tvg: 'refused',\n\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined\n\t\t\t\t})\n\t\t}\n\t}\n\n\tconst heard = (message: unknown) => {\n\t\t// the session's own words are text; everything else is said as an object\n\t\tif (typeof message === 'string') return running?.hear(message)\n\t\tconst said = message as ToWorker\n\t\tif (typeof said !== 'object' || said === null) return\n\t\tswitch (said.vg) {\n\t\t\tcase 'start':\n\t\t\t\treturn void start(said)\n\t\t\tcase 'reload':\n\t\t\t\treturn void (async () => {\n\t\t\t\t\tconst world = running?.host.world\n\t\t\t\t\tif (!options.reload) {\n\t\t\t\t\t\tworld?.log.warn('game', `${game.id} in a worker has no reload (serveWorld reload): it keeps the version it began with`)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst next = await options.reload(Date.now())\n\t\t\t\t\t\tif (!next) return\n\t\t\t\t\t\tgame = next\n\t\t\t\t\t\tif (world && running?.host.world === world) reloadGame(world, next)\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tworld?.log.error(\n\t\t\t\t\t\t\t'game',\n\t\t\t\t\t\t\t`${game.id}'s new version could not be taken in the worker: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t})()\n\t\t\tcase 'stop':\n\t\t\t\tstarts++\n\t\t\t\trunning?.end()\n\t\t\t\trunning = undefined\n\t\t\t\treturn\n\t\t\tcase 'speed':\n\t\t\t\tif (running) running.host.speed = said.speed\n\t\t\t\treturn\n\t\t\tcase 'advance':\n\t\t\t\treturn running?.host.advance(said.ticks)\n\t\t\tcase 'save':\n\t\t\t\ttry {\n\t\t\t\t\tif (!running) throw new Error('There is no game to save')\n\t\t\t\t\tpost({ vg: 'saved', id: said.id, save: saveWorld(running.host.world) })\n\t\t\t\t} catch (error) {\n\t\t\t\t\tpost({ vg: 'saved', id: said.id, error: error instanceof Error ? error.message : String(error) })\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\tcase 'navigation':\n\t\t\t\t// the page's own navigation (the ways it shows): built here, where the world's was, or kept from it\n\t\t\t\treturn void navigationData(said.build).then(\n\t\t\t\t\t(data) => post({ vg: 'built', id: said.id, data }),\n\t\t\t\t\t(error: unknown) => post({ vg: 'built', id: said.id, error: error instanceof Error ? error.message : String(error) })\n\t\t\t\t)\n\t\t\tcase 'profile':\n\t\t\t\tprofiling = said.on\n\t\t\t\tif (running) running.host.world.scheduler.profiling = said.on\n\t\t\t\treturn\n\t\t}\n\t}\n\tif (port.on) port.on('message', heard)\n\telse port.addEventListener?.('message', (event) => heard(event.data))\n}\n\n/**\n * A seat at a game run in a worker of this page (`workerSession`): a `RemoteSession` whose host is a message away,\n * with what a game played in the page has besides: its pace held and stepped (`speed`, `advance`), a save of it\n * (`save`), the checkpoint to start again from, what it says in its log, the debug tools' view, and where its time went\n *\n * @beta\n */\nexport class WorkerSession extends RemoteSession {\n\t/** What the world says (`World.log`), said again here: the page shows it with its own */\n\tlog!: Logger\n\tcheckpoint?: { label: Message; save: WorldSave }\n\t/** The debug tools' view of the world, where they are on: over the session's own words, as a server's is */\n\tget debug(): SessionDebug | undefined {\n\t\treturn this.debugView\n\t}\n\t/** Its pace held and stepped, saves of it, the debug tools' view where they are on, and where its time went and in which systems */\n\toverride readonly can: SessionCan = {\n\t\tpace: paceOf(this),\n\t\tsaves: savesOf(this),\n\t\tinspect: this.debugView,\n\t\ttiming: { timing: () => this.timing(), profile: (on) => this.postToWorker({ vg: 'profile', on }) }\n\t}\n\tprivate pace = 1\n\tprivate timed?: { tick: number; tickMax: number; send: number; systems: SystemTiming[] }\n\t/** Milliseconds the page took to take in what the worker sent, each time, evened out: its share of a game run there */\n\treceived = 0\n\tprivate postToWorker: (message: ToWorker) => void = () => {}\n\tprivate readonly saves = new Map<number, { done: (save: WorldSave) => void; failed: (error: Error) => void }>()\n\tprivate nextSave = 0\n\tprivate stopHearing: () => void = () => {}\n\n\t/** What `workerSession` gives it once it is made: the way to the worker, and what stops hearing it */\n\twire(post: (message: ToWorker) => void, log: Logger, stop: () => void): void {\n\t\tthis.postToWorker = post\n\t\tthis.log = log\n\t\tthis.stopHearing = stop\n\t}\n\n\t/** What the worker said that is not the session's own text */\n\theard(said: FromWorker): void {\n\t\tif (said.vg === 'checkpoint') this.checkpoint = { label: said.label, save: said.save }\n\t\telse if (said.vg === 'timing') this.timed = { tick: said.tick, tickMax: said.tickMax, send: said.send, systems: said.systems }\n\t\telse if (said.vg === 'saved') {\n\t\t\tconst waiting = this.saves.get(said.id)\n\t\t\tthis.saves.delete(said.id)\n\t\t\tif (said.save) waiting?.done(said.save)\n\t\t\telse waiting?.failed(new Error(said.error ?? 'The game could not be saved'))\n\t\t}\n\t}\n\n\t/**\n\t * How far behind the newest tick the screen is shown, in ticks: one, and room for how unevenly they come (a tick\n\t * that took long comes late). Less than over a wire, where two are kept in hand: there is no line to stall here\n\t */\n\toverride get delay(): number {\n\t\treturn this.interval + Math.min(this.jitter, this.limits.maxJitter ?? MAX_JITTER) * this.tickRate * 2\n\t}\n\n\tget speed(): number {\n\t\treturn this.pace\n\t}\n\n\tset speed(speed: number) {\n\t\tthis.pace = speed\n\t\tthis.postToWorker({ vg: 'speed', speed })\n\t}\n\n\tadvance(ticks = 1): void {\n\t\tthis.postToWorker({ vg: 'advance', ticks })\n\t}\n\n\t/**\n\t * Asks the worker to take a new version of the game (hot reload): it loads the game again itself, as its file says\n\t * (`serveWorld` `reload`), and puts it into its world\n\t */\n\treloadGame(): void {\n\t\tthis.postToWorker({ vg: 'reload' })\n\t}\n\n\tsave(): Promise<WorldSave> {\n\t\treturn new Promise((done, failed) => {\n\t\t\tconst id = ++this.nextSave\n\t\t\tthis.saves.set(id, { done, failed })\n\t\t\tthis.postToWorker({ vg: 'save', id })\n\t\t})\n\t}\n\n\ttiming(): { tick: number; tickMax: number; send: number; receive: number; systems: SystemTiming[] } | undefined {\n\t\treturn this.timed && { ...this.timed, receive: this.received }\n\t}\n\n\t/** Ends the game in the worker. The worker is the page's: it stays, for the next game, until the page ends it */\n\toverride dispose(): void {\n\t\tthis.postToWorker({ vg: 'stop' })\n\t\tthis.stopHearing()\n\t\tfor (const waiting of this.saves.values()) waiting.failed(new Error('The game ended'))\n\t\tthis.saves.clear()\n\t\tsuper.dispose()\n\t}\n}\n\n/**\n * What a seat at a worker's game is asked for: what to play (`WorkerGame`), and what `connect` takes\n *\n * @beta\n */\nexport interface WorkerSessionOptions extends WorkerGame, Pick<ConnectOptions, 'navigation' | 'maps'> {\n\tgame: GameModule\n\t/** The logger what the world says is said under, in the page: the root one when left out */\n\tlog?: Logger\n}\n\n/**\n * Plays a game in a worker, and seats this page's player at it: the worker's file calls `serveWorld` with the same\n * game. Settles once the world is made there and its welcome is in; fails with what the worker said went wrong\n *\n * const session = await workerSession(new Worker(new URL('./game.worker.ts', import.meta.url), { type: 'module' }), { game, map })\n *\n * @beta\n */\nexport async function workerSession(worker: WorldWorkerLike, options: WorkerSessionOptions): Promise<WorkerSession> {\n\tconst { game, navigation, maps, log: under, ...asked } = options\n\tlet toSession: (text: string) => void = () => {}\n\tlet closed: () => void = () => {}\n\tlet session: WorkerSession | undefined\n\tconst builds = new Map<number, { done: (data: Uint8Array) => void; failed: (error: Error) => void }>()\n\tlet nextBuild = 0\n\t// what the world says, with the game and the tick it said it in\n\tlet saying: LogEntry | undefined\n\tconst log = (under ?? rootLogger).child({ context: () => ({ game: saying?.game, tick: saying?.tick }) })\n\tconst post = (message: ToWorker | string) => worker.postMessage(message)\n\n\tlet refuse: (error: Error) => void = () => {}\n\tconst refused = new Promise<never>((_, reject) => (refuse = reject))\n\t// nobody may be waiting on it: a game that started is not refused\n\trefused.catch(() => {})\n\n\tconst heard = (message: unknown) => {\n\t\tif (typeof message === 'string') {\n\t\t\tconst began = performance.now()\n\t\t\ttoSession(message)\n\t\t\tif (session) session.received += (performance.now() - began - session.received) * 0.1\n\t\t\treturn\n\t\t}\n\t\tconst said = message as FromWorker\n\t\tif (typeof said !== 'object' || said === null) return\n\t\tif (said.vg === 'refused') {\n\t\t\tconst error = new Error(said.message)\n\t\t\tif (said.stack) error.stack = said.stack\n\t\t\trefuse(error)\n\t\t} else if (said.vg === 'log') {\n\t\t\tsaying = said.entry\n\t\t\tlog.log(said.entry.level, said.entry.category, said.entry.message, said.entry.fields)\n\t\t\tsaying = undefined\n\t\t} else if (said.vg === 'built') {\n\t\t\tconst waiting = builds.get(said.id)\n\t\t\tbuilds.delete(said.id)\n\t\t\tif (said.data) waiting?.done(said.data)\n\t\t\telse waiting?.failed(new Error(said.error ?? 'The navigation could not be built'))\n\t\t} else session?.heard(said)\n\t}\n\tconst broke = (error: unknown) => {\n\t\tconst reason = new Error(\n\t\t\t`The game's worker stopped: ${error instanceof Error ? error.message : String((error as { message?: string })?.message ?? error)}`\n\t\t)\n\t\tlog.error('game', reason.message, { error: errorFields(error) })\n\t\trefuse(reason)\n\t\tclosed()\n\t}\n\tconst onMessage = (event: { data?: unknown }) => heard(event.data)\n\tif (worker.on) {\n\t\tworker.on('message', heard)\n\t\tworker.on('error', broke)\n\t} else {\n\t\tworker.addEventListener?.('message', onMessage)\n\t\tworker.addEventListener?.('error', broke)\n\t}\n\tconst stop = () => {\n\t\tif (worker.off) {\n\t\t\tworker.off('message', heard)\n\t\t\tworker.off('error', broke)\n\t\t} else {\n\t\t\tworker.removeEventListener?.('message', onMessage)\n\t\t\tworker.removeEventListener?.('error', broke)\n\t\t}\n\t}\n\n\tconst transport: Transport = {\n\t\tsend: (text) => post(text),\n\t\tonMessage: (handler) => (toSession = handler),\n\t\tonClose: (handler) => (closed = handler),\n\t\tclose: () => {}\n\t}\n\tpost({ vg: 'start', ...asked })\n\ttry {\n\t\tsession = await Promise.race([\n\t\t\tconnectAs(\n\t\t\t\ttransport,\n\t\t\t\t{\n\t\t\t\t\tgame,\n\t\t\t\t\tmaps,\n\t\t\t\t\t// the page's own navigation is built in the worker, where the world's was: the page is never held for it\n\t\t\t\t\tnavigation: {\n\t\t\t\t\t\t...navigation,\n\t\t\t\t\t\tbuilds: {\n\t\t\t\t\t\t\tbuilder: (build) =>\n\t\t\t\t\t\t\t\tnew Promise<Uint8Array>((done, failed) => {\n\t\t\t\t\t\t\t\t\tconst id = ++nextBuild\n\t\t\t\t\t\t\t\t\tbuilds.set(id, { done, failed })\n\t\t\t\t\t\t\t\t\tpost({\n\t\t\t\t\t\t\t\t\t\tvg: 'navigation',\n\t\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\t\tbuild: {\n\t\t\t\t\t\t\t\t\t\t\tpositions: build.positions.slice(),\n\t\t\t\t\t\t\t\t\t\t\tindices: build.indices.slice(),\n\t\t\t\t\t\t\t\t\t\t\tconfig: build.config,\n\t\t\t\t\t\t\t\t\t\t\t...(build.speeds && { speeds: { ...build.speeds, values: build.speeds.values.slice() } })\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(...made) => new WorkerSession(...made)\n\t\t\t),\n\t\t\trefused\n\t\t])\n\t} catch (error) {\n\t\tpost({ vg: 'stop' })\n\t\tstop()\n\t\tthrow error\n\t}\n\tsession.wire(post, log, stop)\n\treturn session\n}\n","import type { Transport } from './remote'\n\n/**\n * The player's end of a connection to a server, over a WebSocket: what `connect` and a server's lobby talk through.\n * Resolves once the connection is open; fails when it cannot be made\n *\n * @beta\n */\nexport function openSocket(url: string): Promise<Transport> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst socket = new WebSocket(url)\n\t\tlet handler: (message: string) => void = () => {}\n\t\tlet closed: () => void = () => {}\n\t\tsocket.onmessage = (event) => handler(String(event.data))\n\t\tsocket.onclose = () => closed()\n\t\tsocket.onerror = () => reject(new Error(`Could not connect to ${url}`))\n\t\tsocket.onopen = () =>\n\t\t\tresolve({\n\t\t\t\tsend: (message) => {\n\t\t\t\t\tif (socket.readyState === WebSocket.OPEN) socket.send(message)\n\t\t\t\t},\n\t\t\t\tonMessage: (next) => (handler = next),\n\t\t\t\tonClose: (next) => (closed = next),\n\t\t\t\tclose: () => socket.close()\n\t\t\t})\n\t})\n}\n","import type { PlayerId } from '#engine/entity'\nimport type { World } from '#engine/world'\nimport { SessionHost, type Transport } from './remote'\nimport { openSocket } from './socket'\n\n/*\n * A game played in the page, watched from others: through a relay (the server's `WatchRelay`), as a page cannot take\n * connections. The page shares its world under a key; the relay tells it of each watcher, and the page's own host\n * seats them at the world as observers, the way a server seats those who watch its games. The world is stepped by the\n * page's game as it always is: the host only sends (`SessionHost.publish`)\n */\n\n/**\n * What a page says to the relay, before it watches; and what a sharing page says all along\n *\n * @internal\n */\nexport type RelayRequest =\n\t/** The page plays a game under `key`, and lets others watch it */\n\t| { type: 'share'; key: string; name: string }\n\t/** The sharing page's game, for one watcher */\n\t| { type: 'send'; to: number; text: string }\n\t/** Watches what is shared under `key`, now or once it is */\n\t| { type: 'watch'; key: string }\n\n/**\n * What the relay tells pages besides the game itself\n *\n * @beta\n */\nexport type RelayNotice =\n\t/** To a sharing page: it shares under `key` now */\n\t| { type: 'shared'; key: string }\n\t/** To a sharing page: another page shares under that key already */\n\t| { type: 'taken'; key: string }\n\t/** To a sharing page: someone watches, by the id the relay gave them */\n\t| { type: 'watcher'; id: number }\n\t/** To a sharing page: what a watcher said (that it got a tick, a ping) */\n\t| { type: 'from'; watcher: number; text: string }\n\t/** To a sharing page: a watcher left */\n\t| { type: 'gone'; watcher: number }\n\t/** To a watcher: nothing is shared under the key right now. The game comes once it is */\n\t| { type: 'waiting'; key: string }\n\t/** To a watcher: the game shared ended. The next one under the key comes when it is shared */\n\t| { type: 'ended'; key: string }\n\n/** @beta */\nexport interface ShareOptions {\n\t/** The relay's address, `ws://host:port` */\n\turl: string\n\t/** What watchers ask for: the same for every game of a campaign, so they stay from one mission to the next */\n\tkey: string\n\t/** What it is, for the relay's log */\n\tname: string\n\t/** Whose side watchers see it from: they get that player's lines and cinematics, and see everything besides */\n\tplayer: PlayerId\n\t/** Snapshots a second to each watcher. 20 when left out */\n\tsendRate?: number\n}\n\n/**\n * A game shared for watching (`shareGame`)\n *\n * @beta\n */\nexport interface SharedGame {\n\t/** `shared` once the relay has it; `taken` when another page shares under the key; `closed` once it is over */\n\treadonly state: 'shared' | 'taken' | 'closed'\n\t/** How many watch it now */\n\treadonly watchers: number\n\t/** Told whenever the state or the number of watchers changes */\n\tonChange(handler: () => void): void\n\t/** Stops sharing: the watchers are told it ended */\n\tclose(): void\n}\n\n/** How often the host looks whether the world went on, a second: it sends at its own rate */\nconst LOOKS = 30\n\n/**\n * Shares the page's world through a relay, for others to watch. Fails when the relay cannot be reached\n *\n * @beta\n */\nexport async function shareGame(world: World, options: ShareOptions): Promise<SharedGame> {\n\tconst relay = await openSocket(options.url)\n\tconst host = new SessionHost(world, { sendRate: options.sendRate })\n\t/** Each watcher's end of the connection, as the host holds it: what the relay brings from them goes to it */\n\tconst ends = new Map<number, { message: (text: string) => void; closed: () => void }>()\n\tlet state: SharedGame['state'] = 'shared'\n\tlet changed: () => void = () => {}\n\tconst ask = (request: RelayRequest) => relay.send(JSON.stringify(request))\n\n\tconst seat = (id: number) => {\n\t\tconst end = { message: (_text: string) => {}, closed: () => {} }\n\t\tends.set(id, end)\n\t\tconst transport: Transport = {\n\t\t\tsend: (text) => ask({ type: 'send', to: id, text }),\n\t\t\tonMessage: (handler) => (end.message = handler),\n\t\t\tonClose: (handler) => (end.closed = handler),\n\t\t\t// a watcher leaves by closing their own connection: the relay says so\n\t\t\tclose: () => {}\n\t\t}\n\t\thost.connect(options.player, transport, { readOnly: true, observer: true })\n\t}\n\n\tlet last = performance.now()\n\tconst timer = setInterval(() => {\n\t\tconst now = performance.now()\n\t\thost.publish((now - last) / 1000)\n\t\tlast = now\n\t}, 1000 / LOOKS)\n\n\t/** Over once: closed, or never shared as the key was taken */\n\tconst stop = (next: 'closed' | 'taken' = 'closed') => {\n\t\tif (state !== 'shared') return\n\t\tclearInterval(timer)\n\t\thost.dispose()\n\t\tends.clear()\n\t\tstate = next\n\t\tchanged()\n\t}\n\n\trelay.onMessage((text) => {\n\t\tconst notice = JSON.parse(text) as RelayNotice\n\t\tif (notice.type === 'taken') {\n\t\t\tstop('taken')\n\t\t\trelay.close()\n\t\t} else if (notice.type === 'watcher') {\n\t\t\tseat(notice.id)\n\t\t\tchanged()\n\t\t} else if (notice.type === 'from') ends.get(notice.watcher)?.message(notice.text)\n\t\telse if (notice.type === 'gone') {\n\t\t\tends.get(notice.watcher)?.closed()\n\t\t\tends.delete(notice.watcher)\n\t\t\tchanged()\n\t\t}\n\t})\n\trelay.onClose(() => stop())\n\task({ type: 'share', key: options.key, name: options.name })\n\n\treturn {\n\t\tget state() {\n\t\t\treturn state\n\t\t},\n\t\tget watchers() {\n\t\t\treturn ends.size\n\t\t},\n\t\tonChange(handler) {\n\t\t\tchanged = handler\n\t\t},\n\t\tclose() {\n\t\t\tstop()\n\t\t\trelay.close()\n\t\t}\n\t}\n}\n","import { generateMap, type GeneratorOptions } from './generate'\nimport { createRegistry, type GameModule } from './game'\nimport type { GameMap } from './map'\nimport type { MapProblem } from './mapFields'\nimport type { NavigationPort, NavigationWorkerLike } from './navigation/builds'\nimport type { Registry } from './registry'\n\n/**\n * A map a generator made (`generateMap`): the map, what is wrong with it, and the seed it came out of\n *\n * @beta\n */\nexport interface GeneratedMap {\n\tmap: GameMap\n\tproblems: MapProblem[]\n\tseed: number\n}\n\n/**\n * Makes a map of options somewhere else than this thread (`mapGeneratorWorker`): a menu's preview of a random map that\n * does not stop the page while it is made\n *\n * @beta\n */\nexport type MapGenerating = (options: GeneratorOptions) => Promise<GeneratedMap>\n\ninterface GenerateAnswer {\n\tid: number\n\tmade?: GeneratedMap\n\terror?: string\n}\n\n/**\n * What a worker's file of a game's maps does: it makes, with the game's generator (`GameModule.generator`) and its\n * registry, the map of each set of options it is sent, and sends it back. A worker's file of two lines, the game's rules\n * imported and this called with them; `port` is where it hears, as for `serveNavigationBuilds`: the worker's own scope\n * when left out\n *\n * @beta\n */\nexport function serveMapGenerator(rules: GameModule, port: NavigationPort = globalThis as unknown as NavigationPort): void {\n\tlet registry: Registry | undefined\n\tconst asked = (message: unknown) => {\n\t\tconst { id, options } = message as { id: number; options: GeneratorOptions }\n\t\ttry {\n\t\t\tif (!rules.generator) throw new Error(`${rules.name} has no generator of maps (GameModule.generator)`)\n\t\t\tregistry ??= createRegistry(rules)\n\t\t\tport.postMessage({ id, made: generateMap(rules.generator, options, registry) } satisfies GenerateAnswer)\n\t\t} catch (error) {\n\t\t\tport.postMessage({ id, error: error instanceof Error ? error.message : String(error) } satisfies GenerateAnswer)\n\t\t}\n\t}\n\tif (port.on) port.on('message', asked)\n\telse port.addEventListener?.('message', (event) => asked(event.data))\n}\n\n/**\n * Maps made in a worker whose file serves them (`serveMapGenerator`): the page makes the worker as its bundler wants it,\n * `mapGeneratorWorker(() => new Worker(new URL('./generate.worker.ts', import.meta.url), { type: 'module' }))`. Given\n * as a function, the worker is made at the first map asked for: a menu that is never opened fetches none of it\n *\n * @beta\n */\nexport function mapGeneratorWorker(given: NavigationWorkerLike | (() => NavigationWorkerLike)): MapGenerating {\n\tlet next = 0\n\tconst waiting = new Map<number, { done: (made: GeneratedMap) => void; failed: (error: Error) => void }>()\n\tconst answered = (answer: GenerateAnswer) => {\n\t\tconst wait = waiting.get(answer.id)\n\t\tif (!wait) return\n\t\twaiting.delete(answer.id)\n\t\tif (answer.made) wait.done(answer.made)\n\t\telse wait.failed(new Error(answer.error ?? 'The map could not be made'))\n\t}\n\tconst broke = (error: unknown) => {\n\t\tconst reason = new Error(\n\t\t\t`The maps' worker stopped: ${error instanceof Error ? error.message : String((error as { message?: string })?.message ?? error)}`\n\t\t)\n\t\tfor (const wait of waiting.values()) wait.failed(reason)\n\t\twaiting.clear()\n\t}\n\tlet made: NavigationWorkerLike | undefined\n\tconst worker = () => {\n\t\tif (made) return made\n\t\tmade = typeof given === 'function' ? given() : given\n\t\tif (made.on) {\n\t\t\tmade.on('message', (value) => answered(value as GenerateAnswer))\n\t\t\tmade.on('error', broke)\n\t\t} else {\n\t\t\tmade.addEventListener?.('message', (event) => answered(event.data as GenerateAnswer))\n\t\t\tmade.addEventListener?.('error', broke)\n\t\t}\n\t\treturn made\n\t}\n\tif (typeof given !== 'function') worker()\n\treturn (options) =>\n\t\tnew Promise<GeneratedMap>((done, failed) => {\n\t\t\tconst id = ++next\n\t\t\twaiting.set(id, { done, failed })\n\t\t\tworker().postMessage({ id, options })\n\t\t})\n}\n","import { type AbilityDef, anyEffect, type EffectDef, type Scaled, upgradesOf } from './defs'\nimport { DATA_KINDS, type DataKind } from './gameData'\nimport { coreEffects } from './abilities/effects/core'\nimport { dispelEffects } from './abilities/dispel'\nimport type { GameModule } from './game'\nimport { nearestId } from './nearest'\nimport { summonEffects } from './summons'\n\n/**\n * What of a game's rules does not fit together (`checkRules`): an id that names nothing (an ability's buff, a unit's\n * `trains`, an upgrade's `requires`, a shop's items), an effect of a type nobody handles, requirements that wait on\n * each other, and, as warnings, what nothing makes, abilities nothing has, and numbers that do not do what they are\n * there for (an `arc` or a `bounce` not of a missile, or of nothing, `charges` of none). Ids are text to the compiler, so a slip\n * in one shows only when the game runs into it (\"Unknown unit type\") or never (a button that is not there)\n *\n * @beta\n */\nexport interface RulesProblem {\n\t/** `error`: the game will throw or misbehave when it gets there; `warning`: likely a slip, possibly meant */\n\tlevel: 'error' | 'warning'\n\t/** Where in the rules: `units.footman.trains`, `abilities.holy-light.effects[0].buff` */\n\twhere: string\n\t/** The id that is wrong, or the definition the warning is about */\n\tid: string\n\tmessage: string\n\t/**\n\t * The definition it is in and the field, as the editor's Data panel names them (`{ kind: 'abilities', id:\n\t * 'holy-light', path: 'effects.0.buff' }`), where it is in one\n\t */\n\tat?: { kind: DataKind; id: string; path: string }\n}\n\n/**\n * Checks a game's rules against themselves (`RulesProblem`): run by `defineGame` with the view's checks, and in a\n * game's tests (`expect(checkRules(rules).filter((p) => p.level === 'error')).toEqual([])`). Nothing is thrown\n *\n * @beta\n */\nexport function checkRules(rules: GameModule): RulesProblem[] {\n\tconst problems: RulesProblem[] = []\n\tconst ids = (list: readonly { id: string }[] | undefined) => new Set((list ?? []).map((def) => def.id))\n\tconst units = ids(rules.units)\n\tconst abilities = ids(rules.abilities)\n\tconst buffs = ids(rules.buffs)\n\tconst items = ids(rules.items)\n\tconst upgrades = ids(rules.upgrades)\n\tconst resources = ids(rules.resources)\n\t/** The types of effect something handles: the engine's own, and the game's (`GameModule.effects`) */\n\tconst handled = new Set<string>([...coreEffects, ...summonEffects, ...dispelEffects, ...(rules.effects ?? [])].map((kind) => kind.type))\n\tconst effectTypes = (type: string) => handled.has(type)\n\n\tconst known = (where: string, id: string | undefined, set: Set<string>, what: string) => {\n\t\tif (id === undefined || set.has(id)) return\n\t\tconst meant = nearestId(id, set)\n\t\tproblems.push({\n\t\t\tlevel: 'error',\n\t\t\twhere,\n\t\t\tid,\n\t\t\tmessage: `${where} names \"${id}\", which is no ${what} of the rules${meant ? `. Did you mean \"${meant}\"?` : ''}`\n\t\t})\n\t}\n\t/** A number that does not do what it is there for: said as a warning, the engine making do with it */\n\tconst odd = (where: string, id: string, message: string) => problems.push({ level: 'warning', where, id, message })\n\t/** Whether a number, or any of its levels (`Scaled`), is under a bound: at `least`, or above it where `above` */\n\tconst under = (value: Scaled | undefined, least: number, above = false) =>\n\t\tvalue !== undefined && (Array.isArray(value) ? value : [value]).some((each) => (above ? each <= least : each < least))\n\n\tconst all = (where: string, list: readonly string[] | undefined, set: Set<string>, what: string) =>\n\t\tlist?.forEach((id, index) => known(`${where}[${index}]`, id, set, what))\n\n\t/** What a requirement names: a unit type (a building to have) or an upgrade */\n\tconst requirable = new Set([...units, ...upgrades])\n\n\tfor (const unit of rules.units) {\n\t\tconst at = `units.${unit.id}`\n\t\tall(`${at}.trains`, unit.trains, units, 'unit type')\n\t\tall(`${at}.builds`, unit.builds, units, 'unit type')\n\t\tall(`${at}.hires`, unit.hires, units, 'unit type')\n\t\tall(`${at}.researches`, unit.researches, upgrades, 'upgrade')\n\t\tall(`${at}.requires`, unit.requires, requirable, 'unit type or upgrade')\n\t\tall(`${at}.sells`, unit.sells, items, 'item')\n\t\tall(`${at}.abilities`, unit.abilities, abilities, 'ability')\n\t\tif (typeof unit.upgradesTo === 'string') known(`${at}.upgradesTo`, unit.upgradesTo, units, 'unit type')\n\t\telse all(`${at}.upgradesTo`, unit.upgradesTo, units, 'unit type')\n\t\tif (Array.isArray(unit.drops)) unit.drops.forEach((drop, index) => known(`${at}.drops[${index}].item`, drop.item, items, 'item'))\n\t\tif (unit.hero) {\n\t\t\tall(`${at}.hero.learns`, unit.hero.learns, abilities, 'ability')\n\t\t\tall(`${at}.hero.spells`, unit.hero.spells, abilities, 'ability')\n\t\t\tknown(`${at}.hero.meter`, unit.hero.meter, buffs, 'buff')\n\t\t}\n\t}\n\n\tconst effects = (where: string, list: readonly EffectDef[] | undefined) => {\n\t\tlist?.map(anyEffect).forEach((effect, index) => {\n\t\t\tconst at = `${where}[${index}]`\n\t\t\tif (!effectTypes(effect.type)) {\n\t\t\t\tproblems.push({\n\t\t\t\t\tlevel: 'error',\n\t\t\t\t\twhere: `${at}.type`,\n\t\t\t\t\tid: effect.type,\n\t\t\t\t\tmessage: `${at} is of the type \"${effect.type}\", which nothing handles (GameModule.effects)`\n\t\t\t\t})\n\t\t\t}\n\t\t\tknown(`${at}.buff`, effect.buff, buffs, 'buff')\n\t\t\tknown(`${at}.ifBuff`, effect.ifBuff, buffs, 'buff')\n\t\t\tknown(`${at}.whileBuff`, effect.whileBuff, buffs, 'buff')\n\t\t\tknown(`${at}.unit`, effect.unit, units, 'unit type')\n\t\t\tknown(`${at}.ability`, effect.ability, abilities, 'ability')\n\t\t\tknown(`${at}.sell`, effect.sell, resources, 'resource')\n\t\t\tknown(`${at}.buy`, effect.buy, resources, 'resource')\n\t\t\t// what a missile is thrown and springs by (GP5): of a missile alone, and of numbers that do something\n\t\t\tfor (const field of ['arc', 'bounce'] as const)\n\t\t\t\tif (effect[field] && effect.type !== 'missile')\n\t\t\t\t\todd(`${at}.${field}`, effect.type, `${at}.${field} is read of a missile alone, not of ${effect.type}`)\n\t\t\tif (effect.arc && !(effect.arc.height > 0)) odd(`${at}.arc.height`, effect.type, `${at}.arc.height is not above 0: it is thrown flat`)\n\t\t\tif (effect.arc?.time !== undefined && !(effect.arc.time > 0))\n\t\t\t\todd(`${at}.arc.time`, effect.type, `${at}.arc.time is not above 0: it flies at its speed`)\n\t\t\tif (effect.bounce && under(effect.bounce.count, 1))\n\t\t\t\todd(`${at}.bounce.count`, effect.type, `${at}.bounce.count is under 1 at a level: it does not spring on there`)\n\t\t\tif (effect.bounce && !(effect.bounce.range > 0))\n\t\t\t\todd(`${at}.bounce.range`, effect.type, `${at}.bounce.range is not above 0: it finds nothing to spring to`)\n\t\t\teffects(`${at}.effects`, effect.effects)\n\t\t\teffects(`${at}.onEnd`, effect.onEnd)\n\t\t\teffects(`${at}.otherwise`, effect.otherwise)\n\t\t})\n\t}\n\tfor (const ability of rules.abilities ?? []) {\n\t\tconst at = `abilities.${ability.id}`\n\t\tknown(`${at}.charge`, ability.charge, buffs, 'buff')\n\t\t// the uses it holds (GP5): at least one, and one that comes back after a time\n\t\tif (ability.charges && under(ability.charges.count, 1))\n\t\t\todd(`${at}.charges.count`, ability.id, `${at}.charges.count is under 1 at a level: it holds 1 there`)\n\t\tif (ability.charges && under(ability.charges.refill, 0, true))\n\t\t\todd(`${at}.charges.refill`, ability.id, `${at}.charges.refill is not above 0 at a level: a use comes back at once there`)\n\t\teffects(`${at}.effects`, ability.effects)\n\t\teffects(`${at}.passive`, ability.passive)\n\t}\n\tfor (const buff of rules.buffs ?? []) {\n\t\tconst at = `buffs.${buff.id}`\n\t\tif (Array.isArray(buff.onApply)) effects(`${at}.onApply`, buff.onApply)\n\t\teffects(`${at}.onTick.effects`, buff.onTick?.effects)\n\t}\n\tfor (const race of rules.races ?? []) {\n\t\tconst start = race.start\n\t\tif (!start || 'spawn' in start) continue\n\t\tconst at = `races.${race.id}.start`\n\t\tknown(`${at}.hall`, start.hall, units, 'unit type')\n\t\tknown(`${at}.workers.type`, start.workers?.type, units, 'unit type')\n\t\tknown(`${at}.onMine`, start.onMine, units, 'unit type')\n\t\tstart.units?.forEach((each, index) => known(`${at}.units[${index}].type`, each.type, units, 'unit type'))\n\t}\n\tfor (const item of rules.items ?? []) {\n\t\tconst at = `items.${item.id}`\n\t\tknown(`${at}.ability`, item.ability, abilities, 'ability')\n\t\tknown(`${at}.passive`, item.passive, abilities, 'ability')\n\t\tall(`${at}.from`, item.from, items, 'item')\n\t}\n\tfor (const upgrade of rules.upgrades ?? []) {\n\t\tconst at = `upgrades.${upgrade.id}`\n\t\tupgrade.requires?.forEach((level, index) => all(`${at}.requires[${index}]`, level, requirable, 'unit type or upgrade'))\n\t\tupgrade.effects.forEach((effect, index) => {\n\t\t\tif (Array.isArray(effect.units)) all(`${at}.effects[${index}].units`, effect.units, units, 'unit type')\n\t\t})\n\t}\n\n\t// requirements that wait on each other: none of them can ever be had\n\tconst needs = new Map<string, string[]>()\n\tfor (const unit of rules.units) if (unit.requires?.length) needs.set(unit.id, unit.requires)\n\tfor (const upgrade of rules.upgrades ?? []) if (upgrade.requires?.[0]?.length) needs.set(upgrade.id, upgrade.requires[0])\n\tconst reported = new Set<string>()\n\tfor (const start of needs.keys()) {\n\t\tconst loop = cycleFrom(start, needs)\n\t\tif (!loop) continue\n\t\tconst key = [...loop].sort().join(',')\n\t\tif (reported.has(key)) continue\n\t\treported.add(key)\n\t\tproblems.push({\n\t\t\tlevel: 'error',\n\t\t\twhere: `requires`,\n\t\t\tid: start,\n\t\t\tmessage: `What is required waits on itself: ${[...loop, loop[0]].join(' → ')}. None of them can be had`\n\t\t})\n\t}\n\n\t// what has a cost and nothing makes: likely a slip (a unit forgotten in a building's trains)\n\tconst made = new Set<string>()\n\tfor (const unit of rules.units) {\n\t\tfor (const id of [...(unit.trains ?? []), ...(unit.builds ?? []), ...(unit.hires ?? []), ...(unit.researches ?? [])]) made.add(id)\n\t\tfor (const id of upgradesOf(unit)) made.add(id)\n\t}\n\tfor (const unit of rules.units) {\n\t\tif (!unit.cost || made.has(unit.id)) continue\n\t\tproblems.push({\n\t\t\tlevel: 'warning',\n\t\t\twhere: `units.${unit.id}`,\n\t\t\tid: unit.id,\n\t\t\tmessage: `units.${unit.id} has a cost, and nothing trains, builds or hires it`\n\t\t})\n\t}\n\tfor (const upgrade of rules.upgrades ?? []) {\n\t\tif (made.has(upgrade.id)) continue\n\t\tproblems.push({\n\t\t\tlevel: 'warning',\n\t\t\twhere: `upgrades.${upgrade.id}`,\n\t\t\tid: upgrade.id,\n\t\t\tmessage: `upgrades.${upgrade.id} is researched nowhere (UnitTypeDef.researches)`\n\t\t})\n\t}\n\n\t// abilities nothing has: no unit, hero, item or other ability names them\n\tconst had = new Set<string>()\n\tfor (const unit of rules.units)\n\t\tfor (const id of [...(unit.abilities ?? []), ...(unit.hero?.learns ?? []), ...(unit.hero?.spells ?? [])]) had.add(id)\n\tfor (const item of rules.items ?? []) for (const id of [item.ability, item.passive]) if (id) had.add(id)\n\tconst named = (ability: AbilityDef) => {\n\t\tconst walk = (list: readonly EffectDef[] | undefined) =>\n\t\t\tlist?.map(anyEffect).forEach((effect) => (effect.ability && had.add(effect.ability), walk(effect.otherwise)))\n\t\twalk(ability.effects)\n\t\twalk(ability.passive)\n\t}\n\tfor (const ability of rules.abilities ?? []) named(ability)\n\tfor (const ability of rules.abilities ?? []) {\n\t\tif (had.has(ability.id)) continue\n\t\tproblems.push({\n\t\t\tlevel: 'warning',\n\t\t\twhere: `abilities.${ability.id}`,\n\t\t\tid: ability.id,\n\t\t\tmessage: `abilities.${ability.id} is on no unit, hero or item`\n\t\t})\n\t}\n\treturn problems.map((problem) => {\n\t\tconst at = locate(rules, problem.where)\n\t\treturn at ? { ...problem, at } : problem\n\t})\n}\n\n/**\n * The definition and field a place in the rules is (`abilities.holy-light.effects[0].buff`): the kind, the longest id\n * of it the place begins with (an id may have dots), and the rest as a path of the Data panel's (`effects.0.buff`)\n */\nfunction locate(rules: GameModule, where: string): RulesProblem['at'] {\n\tconst dot = where.indexOf('.')\n\tconst kind = where.slice(0, dot) as DataKind\n\tif (dot < 0 || !DATA_KINDS.includes(kind)) return undefined\n\tconst rest = where.slice(dot + 1)\n\tconst ids = ((rules[kind] ?? []) as readonly { id: string }[]).map((def) => def.id)\n\tconst id = ids.filter((each) => rest === each || rest.startsWith(`${each}.`)).sort((a, b) => b.length - a.length)[0]\n\tif (id === undefined) return undefined\n\treturn { kind, id, path: rest.slice(id.length + 1).replace(/\\[(\\d+)\\]/g, '.$1') }\n}\n\n/** A loop of requirements through `start`, in order, or none */\nfunction cycleFrom(start: string, needs: Map<string, string[]>): string[] | undefined {\n\tconst path: string[] = []\n\tconst seen = new Set<string>()\n\tconst visit = (id: string): string[] | undefined => {\n\t\tif (id === start && path.length) return [...path]\n\t\tif (seen.has(id)) return undefined\n\t\tseen.add(id)\n\t\tpath.push(id)\n\t\tfor (const next of needs.get(id) ?? []) {\n\t\t\tconst found = visit(next)\n\t\t\tif (found) return found\n\t\t}\n\t\tpath.pop()\n\t\treturn undefined\n\t}\n\treturn visit(start)\n}\n\nexport { editDistance } from './nearest'\n","import type { StatChange, StatDef } from './defs'\nimport type { Entity } from './entity'\nimport { heroOf } from './hero'\nimport type { GamePack } from './packs/pack'\nimport { defineHook } from './hooks'\nimport { refreshVitals, type StatPart, statsOf } from './stats'\nimport type { World } from './world'\n\n/*\n * Hero attributes, an opt-in pack (review RV95): strength, agility and intelligence as stats, and what each point of\n * them makes of the rest (health, armor, attack speed, mana), as classic RTS games have them. A unit type says what it starts\n * with in its `stats` (`{ strength: 22 }`) and a hero what a level adds in `hero.growth` (`{ strength: 2.7 }`); items,\n * buffs and research add to them as to any stat\n */\n\n/**\n * The attributes pack's id\n *\n * @beta\n */\nexport const ATTRIBUTES = 'core.attributes'\n\n/**\n * One of the three attributes, each a stat of its own id\n *\n * @beta\n */\nexport type Attribute = 'strength' | 'agility' | 'intelligence'\n\n/**\n * The three attributes, in the order a hero's panel shows them\n *\n * @beta\n */\nexport const ATTRIBUTE_KEYS: readonly Attribute[] = ['strength', 'agility', 'intelligence']\n\n/**\n * What a point of each attribute gives, as classic RTS games have it: strength 25 health and 0.05 health a second, agility 0.3\n * armor and 2% attack speed, intelligence 15 mana and 0.05 mana a second\n *\n * @beta\n */\nexport const CLASSIC_ATTRIBUTES: Readonly<Record<Attribute, StatChange>> = {\n\tstrength: { stats: { health: 25, healthRegen: 0.05 } },\n\tagility: { stats: { armor: 0.3 }, percent: { attackSpeed: 0.02 } },\n\tintelligence: { stats: { mana: 15, manaRegen: 0.05 } }\n}\n\n/**\n * What the attributes pack is made with (`withAttributes`)\n *\n * @beta\n */\nexport interface AttributesOptions {\n\t/** What a point of each attribute gives: the classic ones (`CLASSIC_ATTRIBUTES`) for those left out */\n\tperPoint?: Partial<Record<Attribute, StatChange>>\n\t/** What a point of a unit's primary attribute gives besides: 1 attack damage when left out */\n\tprimary?: StatChange\n\t/** A unit's primary attribute, in code: its type's `hero.primary` when left out, none for a unit that has none */\n\tprimaryOf?: (world: World, entity: Entity) => Attribute | undefined\n}\n\nconst attributeStats: StatDef[] = [\n\t{ id: 'strength', name: 'Strength', description: 'Each point adds to health and its regeneration', min: 0 },\n\t{ id: 'agility', name: 'Agility', description: 'Each point adds to armor and attack speed', min: 0 },\n\t{ id: 'intelligence', name: 'Intelligence', description: 'Each point adds to mana and its regeneration', min: 0 }\n]\n\n/** Whether a unit's type starts with any attribute */\nfunction startsWithAttributes(entity: Entity): boolean {\n\tconst stats = entity.def.stats\n\treturn !!stats && !!(stats.strength || stats.agility || stats.intelligence)\n}\n\n/**\n * What a unit has of each attribute, everything counted (its type, its level, items, buffs, research): its stats'\n * `strength`, `agility` and `intelligence`\n *\n * @beta\n */\nexport function attributesOf(world: World, entity: Entity): Record<Attribute, number> {\n\tconst stats = statsOf(world, entity)\n\treturn { strength: stats.strength ?? 0, agility: stats.agility ?? 0, intelligence: stats.intelligence ?? 0 }\n}\n\n/**\n * A unit's primary attribute, as the attributes pack of its game says it (`AttributesOptions.primaryOf`, else its type's\n * `hero.primary`); none in a game without the pack\n *\n * @beta\n */\nexport function primaryAttribute(world: World, entity: Entity): Attribute | undefined {\n\tconst pack = world.registry.assembly?.game.packs?.find((each) => each.id === ATTRIBUTES)\n\tif (!pack) return undefined\n\tconst options = pack.options as AttributesOptions\n\treturn options.primaryOf ? options.primaryOf(world, entity) : entity.def.hero?.primary\n}\n\n/**\n * Hero attributes, as in classic RTS games: strength, agility and intelligence are stats (`ATTRIBUTE_KEYS`), and every point\n * of them adds to the others (`AttributesOptions.perPoint`, `CLASSIC_ATTRIBUTES` when left out), the primary one's\n * to the attack too (`hero.primary`, `primaryOf`). What a unit has of them is what it has of any stat: its type's\n * `stats`, its hero's `growth` by level, items' `bonus`, buffs, research and the `stats` hook, all of it added up\n * before the points are turned into the rest. A game without it has no attributes\n *\n * @beta\n */\nexport function withAttributes(options: AttributesOptions = {}): GamePack {\n\tconst perPoint: Record<Attribute, StatChange> = { ...CLASSIC_ATTRIBUTES, ...options.perPoint }\n\tconst primaryBonus = options.primary ?? { stats: { attackDamage: 1 } }\n\tconst primaryOf = options.primaryOf ?? ((_world: World, entity: Entity) => entity.def.hero?.primary)\n\tconst points: StatPart = {\n\t\tid: 'attributes',\n\t\t// a unit that starts with attributes is worked out again as its level changes; one that is given them by an item\n\t\t// or a buff is worked out again for that\n\t\tstamp: (entity) => (startsWithAttributes(entity) ? (heroOf(entity)?.level ?? 1) : 0),\n\t\tadd() {},\n\t\tderive(world, entity, sum) {\n\t\t\t// all three read before any is turned into the rest\n\t\t\tconst strength = sum.get('strength')\n\t\t\tconst agility = sum.get('agility')\n\t\t\tconst intelligence = sum.get('intelligence')\n\t\t\tif (strength) sum.add(perPoint.strength, strength)\n\t\t\tif (agility) sum.add(perPoint.agility, agility)\n\t\t\tif (intelligence) sum.add(perPoint.intelligence, intelligence)\n\t\t\tconst primary = primaryOf(world, entity)\n\t\t\tconst of = primary === 'strength' ? strength : primary === 'agility' ? agility : primary === 'intelligence' ? intelligence : 0\n\t\t\tif (of) sum.add(primaryBonus, of)\n\t\t}\n\t}\n\t// a unit is made with its type's health and mana: one with attributes has what they add as well, from the start\n\tconst made = defineHook({\n\t\thook: 'made',\n\t\tid: 'attributes',\n\t\trun(world, entity) {\n\t\t\tif (startsWithAttributes(entity)) refreshVitals(world, entity)\n\t\t}\n\t})\n\treturn { id: ATTRIBUTES, options, stats: attributeStats, statParts: [points], hooks: [made] }\n}\n","import { defineEffect, effectTargets } from './abilities/effects'\nimport { scaled } from './abilities/scaled'\nimport { at, type DamageType } from './defs'\nimport { manaChanged } from './engineEvents'\nimport type { Entity } from './entity'\nimport type { GamePack } from './packs/pack'\nimport type { World } from './world'\n\n/*\n * Mana burn, an opt-in pack (review RV95): the `manaBurn` effect takes a unit's mana and hurts it by as much, as the\n * demon hunter's spell does, and on every hit with `onHit` (Feedback)\n */\n\n/**\n * The mana burn pack's id\n *\n * @beta\n */\nexport const MANA_BURN = 'core.manaBurn'\n\n/**\n * How mana is burnt (`burnMana`)\n *\n * @beta\n */\nexport interface BurnOptions {\n\t/** Damage for each point of mana burnt: 1 when left out */\n\tratio?: number\n\t/** Magic when left out */\n\tdamageType?: DamageType\n\t/** The ability that burnt it, by id: for the damage and the mana told */\n\tability?: string\n}\n\n/**\n * Takes up to `amount` of a unit's mana and hurts it by as much as it took (times `ratio`), from `source`: what the\n * `manaBurn` effect does, for a game's own rules. Gives back the mana it took: none of a unit that has none, and no\n * damage then\n *\n * @beta\n */\nexport function burnMana(world: World, target: Entity, amount: number, source?: Entity, options: BurnOptions = {}): number {\n\tconst burnt = Math.min(Math.max(amount, 0), target.mana)\n\tif (burnt <= 0) return 0\n\ttarget.mana -= burnt\n\tworld.events.emit(manaChanged, { entity: target, amount: -burnt, ability: options.ability, source })\n\tconst damage = burnt * (options.ratio ?? 1)\n\tif (damage > 0) world.damage(target, damage, source, { damageType: options.damageType ?? 'magic', ability: options.ability })\n\treturn burnt\n}\n\nconst manaBurnEffect = defineEffect(\n\t'manaBurn',\n\t(context, effect) => {\n\t\tconst { world, caster, level } = context\n\t\tconst amount = scaled(world, caster, at(effect.amount, level), effect.scaling, level)\n\t\tfor (const entity of effectTargets(context, effect, 'enemies'))\n\t\t\tburnMana(world, entity, amount, caster, { ratio: effect.ratio, damageType: effect.damageType, ability: context.ability.id })\n\t},\n\t{\n\t\tfields: ['amount', 'scaling', 'damageType', { path: 'ratio', kind: 'number', min: 0, hint: 'Times the mana taken it hurts by: 1 when left out' }]\n\t}\n)\n\n/**\n * Mana burn, as in classic RTS games: the `manaBurn` effect (`EffectTypes.manaBurn`) takes `amount` of what it reaches of its\n * mana and hurts it by as much (times `ratio`). The demon hunter's spell is an ability with it; Feedback is a passive\n * whose `onHit` has it. `burnMana` does it in code\n *\n * @beta\n */\nexport function withManaBurn(): GamePack {\n\treturn { id: MANA_BURN, effects: [manaBurnEffect] }\n}\n","import type { Entity } from './entity'\nimport { defineHook } from './hooks'\nimport type { GamePack } from './packs/pack'\nimport { attackReaches } from './systems/combat'\nimport type { World } from './world'\n\n/*\n * Destructibles, an opt-in pack (review RV95): rocks, barricades and gates to break down, beyond the trees that are\n * felled. A thing of the map that stands in the way as a building does, and that a unit attacks when it is told to\n */\n\n/**\n * The destructibles pack's id\n *\n * @beta\n */\nexport const DESTRUCTIBLES = 'core.destructibles'\n\n/**\n * What the destructibles pack is made with (`withDestructibles`)\n *\n * @beta\n */\nexport interface DestructiblesOptions {\n\t/** Whether something is brought down by being attacked when told to, in code: its type's `destructible` when left out */\n\tdestructible?: (world: World, entity: Entity) => boolean\n}\n\n/**\n * Destructibles, as in classic RTS games: what is `destructible` (`UnitTypeDef.destructible`, a building of the neutral player\n * placed on the map: rocks, a barricade, a gate to break down) stands in the way until it is brought down, and any unit\n * whose attack reaches it attacks it when told to (the attack command), never of its own accord, as trees are felled\n * by what fells them. A gate that opens and shuts is the map's (`setGate`); one that is broken down is a destructible\n *\n * @beta\n */\nexport function withDestructibles(options: DestructiblesOptions = {}): GamePack {\n\tconst destructible = options.destructible ?? ((_world: World, entity: Entity) => !!entity.def.destructible)\n\tconst attacked = defineHook({\n\t\thook: 'canAttack',\n\t\tid: 'destructibles',\n\t\trun(world, event) {\n\t\t\tif (event.allowed || !event.ordered) return\n\t\t\tif (destructible(world, event.target) && attackReaches(world, event.attacker, event.target)) event.allowed = true\n\t\t}\n\t})\n\treturn { id: DESTRUCTIBLES, options, hooks: [attacked] }\n}\n","import { defineEffect } from './abilities/effects'\nimport { at } from './defs'\nimport { defineComponent } from './components'\nimport { defineEvent } from './events'\nimport { distanceToEdge, type Entity, moving } from './entity'\nimport { homeOf } from './home'\nimport { defineHook } from './hooks'\nimport { distSq, type Vec2 } from './math'\nimport { createOrder, giveOrder } from './orders/queue'\nimport type { GamePack } from './packs/pack'\nimport type { OrderBehavior, OrderParams } from './registry'\nimport { halt, moveToEntity } from './systems/movement'\nimport type { World } from './world'\n\n/*\n * Portals, an opt-in pack (review RV95): waygates, buildings a unit walks into to be elsewhere at once (`waygate`), and\n * the town portal, which takes a hero and its army to their side's home (`townPortal`)\n */\n\n/**\n * The portals pack's id\n *\n * @beta\n */\nexport const PORTALS = 'core.portals'\n\n/**\n * Where a waygate leads: a point of the map by its name (as the editor's field keeps it), or a place. A waygate without\n * it, or with `null`, is shut\n *\n * @beta\n */\nexport const waygate = defineComponent<string | Vec2 | null>('core.waygate', {\n\tfield: { name: 'Leads to', hint: 'The point of the map a unit that walks in comes out at', kind: 'point', for: (def) => !!def.waygate }\n})\n\n/**\n * A unit went through a waygate, or a town portal: told to everyone who sees either end, for a sound and a flash\n *\n * @beta\n */\nexport const portalUsed = defineEvent<{ entity: number; from: Vec2; to: Vec2; gate?: number }>('core.portalUsed', { replicate: 'everyone' })\n\n/** How near a waygate's edge a unit is in it */\nconst REACH = 0.6\n\n/**\n * Where a waygate leads, or nothing for one that is shut or leads to a point the map does not have\n *\n * @beta\n */\nexport function waygateTarget(world: World, gate: Entity): Vec2 | undefined {\n\tconst to = gate.get(waygate)\n\tif (!to || !gate.alive) return undefined\n\tif (typeof to !== 'string') return to\n\treturn world.map.points.some((point) => point.name === to) ? world.map.point(to) : undefined\n}\n\n/**\n * Says where a waygate leads (a point of the map by its name, or a place), or shuts it (`null`): what the editor's\n * \"Leads to\" field says of a placed one, in code. Any building can be made a waygate so\n *\n * @beta\n */\nexport function setWaygate(gate: Entity, to: string | Vec2 | null): void {\n\tgate.set(waygate, typeof to === 'object' && to ? { x: to.x, z: to.z } : to)\n}\n\n/**\n * Puts a unit somewhere at once, on the nearest ground it can stand on: what a waygate and a town portal do, for a game's\n * own rules. Told to everyone (`portalUsed`)\n *\n * @beta\n */\nexport function portal(world: World, entity: Entity, to: Vec2, gate?: Entity): void {\n\tconst from = { x: entity.pos.x, z: entity.pos.z }\n\tconst spot = (entity.flying ? world.air : world.nav).closestPoint(to, 6) ?? to\n\thalt(world, entity)\n\tworld.place(entity, spot)\n\tentity.prevPos.x = spot.x\n\tentity.prevPos.z = spot.z\n\tworld.events.emit(portalUsed, { entity: entity.id, from, to: { x: spot.x, z: spot.z }, gate: gate?.id })\n}\n\n/** Going through a waygate: walking into it, then out where it leads. Failed when it is shut, or there is no way to it */\nconst enterOrder: OrderBehavior<{ tried?: number }, Pick<OrderParams, 'target'>> = {\n\ttype: 'enterWaygate',\n\taccepts(world, entity, init) {\n\t\tconst gate = world.get(init.target)\n\t\treturn !!entity.get(moving) && !!gate && !!waygateTarget(world, gate)\n\t},\n\tupdate(world, entity, order) {\n\t\tconst gate = world.get(order.init.target)\n\t\tconst to = gate && waygateTarget(world, gate)\n\t\tif (!gate || !to) return 'failed'\n\t\tif (distanceToEdge(entity.pos, gate) - entity.def.radius <= REACH) {\n\t\t\tportal(world, entity, to, gate)\n\t\t\treturn 'done'\n\t\t}\n\t\tconst m = entity.get(moving)!\n\t\tif (m.status === 'moving') return 'running'\n\t\tif (m.status === 'failed' && order.state.tried === world.tick - 1) return 'failed'\n\t\torder.state.tried = world.tick\n\t\tmoveToEntity(world, entity, gate, REACH * 0.5)\n\t\treturn 'running'\n\t}\n}\n\n/** Offsets around a spot, nearest first: where those a town portal brings stand */\nconst AROUND: readonly Vec2[] = (() => {\n\tconst all: Vec2[] = []\n\tfor (let dz = -3; dz <= 3; dz++) for (let dx = -3; dx <= 3; dx++) all.push({ x: dx * 1.2, z: dz * 1.2 })\n\treturn all.sort((a, b) => a.x * a.x + a.z * a.z - (b.x * b.x + b.z * b.z))\n})()\n\n/**\n * Takes a unit and as many as `count` of its owner's units within `radius` of it, nearest first, to its side's home\n * nearest `near` (`homeOf`), spread around it: what the `townPortal` effect does, in code. Gives back who went, none\n * when the side has no home\n *\n * @beta\n */\nexport function townPortal(world: World, caster: Entity, near: Vec2, radius = 7, count = 12): Entity[] {\n\tconst home = homeOf(world, caster.owner, near)\n\tif (!home) return []\n\tconst others = world.spatial\n\t\t.query(caster.pos.x, caster.pos.z, radius)\n\t\t.filter(\n\t\t\t(entity) =>\n\t\t\t\tentity !== caster &&\n\t\t\t\tentity.alive &&\n\t\t\t\t!entity.hidden &&\n\t\t\t\tentity.owner === caster.owner &&\n\t\t\t\t!!entity.get(moving) &&\n\t\t\t\tdistanceToEdge(caster.pos, entity) <= radius\n\t\t)\n\t\t.map((entity) => ({ entity, d: distSq(entity.pos, caster.pos) }))\n\t\t.sort((a, b) => a.d - b.d || a.entity.id - b.entity.id)\n\t\t.slice(0, Math.max(0, count))\n\t\t.map(({ entity }) => entity)\n\tconst going = [caster, ...others]\n\tgoing.forEach((entity, i) => {\n\t\tconst offset = AROUND[i % AROUND.length]\n\t\tportal(world, entity, { x: home.x + offset.x, z: home.z + offset.z })\n\t})\n\treturn going\n}\n\nconst townPortalEffect = defineEffect(\n\t'townPortal',\n\t(context, effect) => {\n\t\tconst { world, caster, point, level } = context\n\t\ttownPortal(world, caster, point, at(effect.radius, level, 7), Math.round(at(effect.count, level, 12)))\n\t},\n\t{ fields: ['count'] }\n)\n\n/**\n * Portals, as in classic RTS games: waygates (`UnitTypeDef.waygate`), which a unit told to (a right-click, as any building is\n * walked up to) walks into and comes out of where the gate leads (the \"Leads to\" field of a placed one, a point of the\n * map; `setWaygate` in code), and the `townPortal` effect (`EffectTypes.townPortal`), which takes the caster and its\n * units around it to its side's home nearest where it was aimed (`homeOf`: the map's `home.<team>` point, or the\n * nearest of its buildings). `portal` and `townPortal` do them in code\n *\n * @beta\n */\nexport function withPortals(): GamePack {\n\t// told to walk up to a waygate that leads somewhere: through it\n\tconst intoGate = defineHook({\n\t\thook: 'beforeOrder',\n\t\tid: 'portals',\n\t\trun(world, event) {\n\t\t\tconst { order, entity } = event\n\t\t\tif (order.type !== 'move' || order.init.target === undefined) return\n\t\t\tconst gate = world.get(order.init.target)\n\t\t\tif (!gate?.def.waygate || !waygateTarget(world, gate) || !entity.get(moving)) return\n\t\t\tevent.rejected = true\n\t\t\tgiveOrder(world, entity, createOrder(world, { type: 'enterWaygate', target: gate.id }, order.groupId), event.queued)\n\t\t}\n\t})\n\treturn {\n\t\tid: PORTALS,\n\t\torders: [enterOrder],\n\t\tcomponents: [waygate],\n\t\tevents: [portalUsed],\n\t\teffects: [townPortalEffect],\n\t\thooks: [intoGate]\n\t}\n}\n","import type { ItemDef } from './defs'\nimport { itemPicked } from './engineEvents'\nimport type { Entity } from './entity'\nimport { defineHook } from './hooks'\nimport { createItem, type GroundItem, REACH } from './items'\nimport { distanceToEdge } from './entity'\nimport { fire } from './orders/cast'\nimport type { GamePack } from './packs/pack'\nimport type { System } from './registry'\nimport type { World } from './world'\n\n/*\n * Runes, an opt-in pack (review RV95): items used as they are picked up, by walking over them as by the order, and\n * never carried (`ItemDef.powerUp`): a rune of healing, a tome\n */\n\n/**\n * The runes pack's id\n *\n * @beta\n */\nexport const RUNES = 'core.runes'\n\n/**\n * What the runes pack is made with (`withRunes`)\n *\n * @beta\n */\nexport interface RunesOptions {\n\t/** Whether an item is used as it is picked up, in code: its `powerUp` when left out */\n\tpowerUp?: (item: ItemDef) => boolean\n\t/** Who picks one up by walking over it: any unit of a player's, not hidden, when left out */\n\ttakes?: (world: World, entity: Entity, item: GroundItem) => boolean\n\t/** How many ticks apart the ground is looked over for who walked onto a rune: 3 when left out */\n\tevery?: number\n}\n\n/**\n * Uses an item on the ground as a rune is used: whoever picked it casts its ability (where it stands, no mana), and it\n * is gone from the ground, told as an item picked (`itemPicked`). What the runes pack does as a unit walks over one;\n * false for an item not on the ground\n *\n * @beta\n */\nexport function usePowerUp(world: World, entity: Entity, groundId: number): boolean {\n\tconst index = world.items.findIndex((item) => item.id === groundId)\n\tif (index < 0) return false\n\tconst [item] = world.items.splice(index, 1)\n\tconst instance = createItem(world, item.item, item.charges)\n\tinstance.id = item.id\n\tworld.events.emit(itemPicked, { entity, item: instance })\n\tconst ability = world.registry.item(item.item).ability\n\tif (ability) fire(world, entity, world.registry.ability(ability), undefined, instance)\n\treturn true\n}\n\n/**\n * Runes, as in classic RTS games: an item that is a power-up (`ItemDef.powerUp`, `RunesOptions.powerUp` in code) is used as\n * it is picked up, by a unit that walks over it (`RunesOptions.takes`) or is told to pick it up, and never carried:\n * whoever picked it casts its ability where it stands. A rune of healing is an item whose ability heals around; a tome\n * one whose ability has the tomes pack's `tome` effect. `usePowerUp` does it in code\n *\n * @beta\n */\nexport function withRunes(options: RunesOptions = {}): GamePack {\n\tconst powerUp = options.powerUp ?? ((item: ItemDef) => !!item.powerUp)\n\tconst takes =\n\t\toptions.takes ??\n\t\t((world: World, entity: Entity) => entity.isUnit && !entity.hidden && !world.player(entity.owner).neutral && !entity.def.invulnerable)\n\tconst walkedOver: System = {\n\t\tname: 'runes',\n\t\tphase: 'cleanup',\n\t\tevery: Math.max(1, Math.round(options.every ?? 3)),\n\t\tupdate(world) {\n\t\t\tif (!world.items.length) return\n\t\t\t// a copy: a rune used takes itself off the ground\n\t\t\tfor (const item of [...world.items]) {\n\t\t\t\tif (!powerUp(world.registry.item(item.item))) continue\n\t\t\t\tfor (const entity of world.spatial.query(item.x, item.z, REACH)) {\n\t\t\t\t\tif (!entity.alive || distanceToEdge(item, entity) > REACH || !takes(world, entity, item)) continue\n\t\t\t\t\tusePowerUp(world, entity, item.id)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// told to pick one up: used at once, not carried\n\tconst ordered = defineHook({\n\t\thook: 'beforePickUp',\n\t\tid: 'runes',\n\t\trun(world, event) {\n\t\t\tif (!powerUp(world.registry.item(event.item))) return\n\t\t\tevent.cancelled = true\n\t\t\tusePowerUp(world, event.entity, event.ground)\n\t\t}\n\t})\n\treturn { id: RUNES, options, systems: [walkedOver], hooks: [ordered] }\n}\n","import { defineEffect, effectTargets } from './abilities/effects'\nimport { defineComponent } from './components'\nimport type { StatChange } from './defs'\nimport type { Entity } from './entity'\nimport { grantXp, heroOf, maxLevelOf } from './hero'\nimport type { GamePack } from './packs/pack'\nimport { invalidateStats, refreshVitals, type StatPart } from './stats'\nimport type { World } from './world'\n\n/*\n * Tomes, an opt-in pack (review RV95): what a unit gains for good, a point of strength a book, kept with it and in a\n * save, and the `tome` effect that gives it (an item's ability, used from the inventory or as it is picked up with the\n * runes pack). A hero's experience and levels from a book are the heroes' own (`grantXp`)\n */\n\n/**\n * The tomes pack's id\n *\n * @beta\n */\nexport const TOMES = 'core.tomes'\n\n/**\n * What a unit gained for good (`gainStats`): the stats added and the parts, everything it gained added up, and how many\n * times it gained\n *\n * @beta\n */\nexport interface GainedStats {\n\t/** What was added to each stat */\n\tstats: Record<string, number>\n\t/** The parts each stat was made bigger or smaller by */\n\tpercent: Record<string, number>\n\t/** How many times it gained: what tells the stats to be added up again */\n\ttimes: number\n}\n\n/**\n * What a unit gained for good from tomes or the game's own rules (`gainStats`): saved with it\n *\n * @beta\n */\nexport const gainedStats = defineComponent<GainedStats>('core.gainedStats')\n\n/**\n * Gives a unit stats for good, as a tome does: added to what it gained before, kept with it in a save, its health and\n * mana raised with them. For the tomes pack's `tome` effect and a game's own rules (a shrine that makes a unit\n * stronger); it works in a game with the tomes pack (`withTomes`), which adds what was gained to the stats\n *\n * @beta\n */\nexport function gainStats(world: World, entity: Entity, change: StatChange): void {\n\tconst had = entity.get(gainedStats)\n\tconst next: GainedStats = { stats: { ...had?.stats }, percent: { ...had?.percent }, times: (had?.times ?? 0) + 1 }\n\tfor (const key in change.stats) next.stats[key] = (next.stats[key] ?? 0) + change.stats[key]!\n\tfor (const key in change.percent) next.percent[key] = (next.percent[key] ?? 0) + change.percent[key]!\n\tentity.set(gainedStats, next)\n\tinvalidateStats(world, entity)\n\trefreshVitals(world, entity)\n}\n\n/** A tome read: what it gives for good, the experience and the levels it gives a hero */\nconst tomeEffect = defineEffect(\n\t'tome',\n\t(context, effect) => {\n\t\tconst { world } = context\n\t\tfor (const entity of effectTargets(context, effect, 'allies')) {\n\t\t\tif (effect.gain) gainStats(world, entity, effect.gain)\n\t\t\tif (effect.xp) grantXp(world, entity, effect.xp)\n\t\t\tfor (let i = 0; i < (effect.levels ?? 0); i++) {\n\t\t\t\tconst hero = heroOf(entity)\n\t\t\t\tif (!hero || hero.level >= maxLevelOf(world, entity)) break\n\t\t\t\tgrantXp(world, entity, world.rules.heroes.xpForLevel(hero.level + 1) - hero.xp)\n\t\t\t}\n\t\t}\n\t},\n\t{\n\t\tfields: [\n\t\t\t{ path: 'xp', kind: 'integer', min: 0, hint: 'Experience a hero gains' },\n\t\t\t{ path: 'levels', kind: 'integer', min: 0, hint: 'Levels a hero gains' }\n\t\t]\n\t}\n)\n\n/** What was gained, added to the stats: worked out again each time something is gained */\nconst gained: StatPart = {\n\tid: 'tomes',\n\tstamp: (entity) => entity.get(gainedStats)?.times ?? 0,\n\tadd(_world, entity, sum) {\n\t\tconst had = entity.get(gainedStats)\n\t\tif (had) sum.add(had)\n\t}\n}\n\n/**\n * Tomes, as in classic RTS games: the `tome` effect (`EffectTypes.tome`) gives what it reaches stats for good (`gain`: a\n * point of strength with the attributes pack), a hero experience (`xp`) and levels (`levels`). A tome is an item whose\n * ability has the effect, with a charge, used from the inventory, or as it is picked up with the runes pack\n * (`withRunes`). What a unit gained is kept with it and in a save (`gainedStats`), and a game gives it from its own\n * rules with `gainStats`\n *\n * @beta\n */\nexport function withTomes(): GamePack {\n\treturn { id: TOMES, components: [gainedStats], effects: [tomeEffect], statParts: [gained] }\n}\n","import type { Rect, Vec2 } from './math'\nimport type { GamePack } from './packs/pack'\nimport type { Entity } from './entity'\nimport { defineEvent } from './events'\nimport { bool, id, ids, optional, point, string } from './fields'\nimport { defineCommand } from './commands'\nimport { defineComponent } from './components'\nimport { defineHook } from './hooks'\nimport { constructionSite } from './systems/construction'\nimport { createOrder, giveOrder } from './orders/queue'\nimport type { World } from './world'\n\n/*\n * Walls (master plan OH9): pieces of a wall type (a building of one cell, `UnitTypeDef.wall: { family }`) join with the\n * pieces of their family next to them. Each piece's shape (`single`, `end`, `straight`, `corner`, `tee`, `cross`) and\n * which way it faces follow from its neighbours as pieces come and go, as its `look` (the model its type draws it with,\n * `UnitLook.looks`), and `wallJoined` says so. A line of them is laid along a drag (`wallLine`): by the editor's wall\n * tool on a map, by a builder's orders in a game (`buildLineCommand`)\n */\n\n/**\n * What a piece of wall is, among its family's: its shape, by the pieces of its family beside it\n *\n * @beta\n */\nexport type WallShape = 'single' | 'end' | 'straight' | 'corner' | 'tee' | 'cross'\n\n/**\n * A piece of wall took another shape, or turned: a piece came or went beside it\n *\n * @beta\n */\nexport const wallJoined = defineEvent<{ entity: number; shape: WallShape; facing: number }>('core.wallJoined', { replicate: 'everyone' })\n\n/** The four sides, as the cell beside and the facing toward it */\nconst SIDES = [\n\t{ dx: 1, dz: 0, facing: 0 },\n\t{ dx: 0, dz: 1, facing: Math.PI / 2 },\n\t{ dx: -1, dz: 0, facing: Math.PI },\n\t{ dx: 0, dz: -1, facing: -Math.PI / 2 }\n] as const\n\nconst near: Entity[] = []\n\n/** The live piece of a family standing on the cell of this point: by its footprint, a gate wider than a cell too */\nfunction pieceAt(world: World, family: string, x: number, z: number): Entity | undefined {\n\tconst cx = Math.floor(x) + 0.5\n\tconst cz = Math.floor(z) + 0.5\n\tfor (const other of world.spatial.query(cx, cz, 2, near)) {\n\t\tif (!other.alive || other.def.wall?.family !== family) continue\n\t\tconst rect = other.rect\n\t\tif (Math.abs(cx - rect.x) < rect.hw && Math.abs(cz - rect.z) < rect.hd) return other\n\t}\n\treturn undefined\n}\n\n/** The cell just past a piece's side: the next cell for a piece of one, past its footprint for a wider one (a gate) */\nconst besideOf = (rect: Rect, dx: number, dz: number): Vec2 => ({ x: rect.x + dx * (rect.hw + 0.5), z: rect.z + dz * (rect.hd + 0.5) })\n\n/**\n * The shape of a piece by the sides it has a piece of its family on (east, north, west, south), and which way it faces:\n * an end toward its one neighbour, a straight piece along its line, a corner toward the first of its two sides, a tee\n * toward the side it has none on\n *\n * @internal\n */\nexport function wallShapeOf(sides: readonly [boolean, boolean, boolean, boolean]): { shape: WallShape; facing: number } {\n\tconst count = sides.filter(Boolean).length\n\tif (count === 0) return { shape: 'single', facing: 0 }\n\tif (count === 4) return { shape: 'cross', facing: 0 }\n\tif (count === 1) return { shape: 'end', facing: SIDES[sides.indexOf(true)].facing }\n\tif (count === 3) return { shape: 'tee', facing: SIDES[(sides.indexOf(false) + 2) % 4].facing }\n\t// two: across from each other, or a corner\n\tif (sides[0] === sides[2]) return { shape: 'straight', facing: sides[0] ? 0 : Math.PI / 2 }\n\tconst first = sides[0] && sides[1] ? 0 : sides[1] && sides[2] ? 1 : sides[2] && sides[3] ? 2 : 3\n\treturn { shape: 'corner', facing: SIDES[first].facing }\n}\n\n/** Works out a piece's shape from its neighbours again, and says so where it changed */\nfunction reshape(world: World, piece: Entity): void {\n\tconst family = piece.def.wall?.family\n\tif (!family || !piece.alive) return\n\tconst rect = piece.rect\n\tconst sides = SIDES.map(({ dx, dz }) => {\n\t\tconst beside = besideOf(rect, dx, dz)\n\t\treturn !!pieceAt(world, family, beside.x, beside.z)\n\t}) as unknown as [\n\t\tboolean,\n\t\tboolean,\n\t\tboolean,\n\t\tboolean\n\t]\n\tconst { shape, facing } = wallShapeOf(sides)\n\t// a gate turns along its line, and keeps its look: open or shut\n\tconst look = piece.def.wall?.gate ? piece.look : shape\n\tif (piece.look === look && piece.facing === facing) return\n\tpiece.look = look\n\tpiece.facing = facing\n\tworld.events.emit(wallJoined, { entity: piece.id, shape, facing })\n}\n\n/** A piece and the pieces of its family beside it, shaped again: one came, or went */\nfunction reshapeAround(world: World, rect: Rect, family: string, self?: Entity): void {\n\tif (self) reshape(world, self)\n\tfor (const { dx, dz } of SIDES) {\n\t\tconst beside = besideOf(rect, dx, dz)\n\t\tconst other = pieceAt(world, family, beside.x, beside.z)\n\t\tif (other && other !== self) reshape(world, other)\n\t}\n}\n\n/**\n * The cells of a wall along a drag, as the genre lays one: along the longer of its two directions first, then the\n * other, a cell's middle each (`x + 0.5`), from where it started to where it ended, each once\n *\n * @beta\n */\nexport function wallLine(from: Vec2, to: Vec2): Vec2[] {\n\tconst x0 = Math.floor(from.x)\n\tconst z0 = Math.floor(from.z)\n\tconst x1 = Math.floor(to.x)\n\tconst z1 = Math.floor(to.z)\n\tconst cells: Vec2[] = []\n\tconst stepX = Math.sign(x1 - x0)\n\tconst stepZ = Math.sign(z1 - z0)\n\tconst alongX = Math.abs(x1 - x0) >= Math.abs(z1 - z0)\n\tlet x = x0\n\tlet z = z0\n\tcells.push({ x: x + 0.5, z: z + 0.5 })\n\tconst walk = (axis: 'x' | 'z') => {\n\t\tif (axis === 'x')\n\t\t\twhile (x !== x1) {\n\t\t\t\tx += stepX\n\t\t\t\tcells.push({ x: x + 0.5, z: z + 0.5 })\n\t\t\t}\n\t\telse\n\t\t\twhile (z !== z1) {\n\t\t\t\tz += stepZ\n\t\t\t\tcells.push({ x: x + 0.5, z: z + 0.5 })\n\t\t\t}\n\t}\n\twalk(alongX ? 'x' : 'z')\n\twalk(alongX ? 'z' : 'x')\n\treturn cells\n}\n\n/**\n * Lays a wall along a drag with the player's builders: a build order for each cell of the line (`wallLine`), queued\n * after one another (after what they were doing, with `queue`), for the first builder of theirs among the ids that can\n * build the type. What cannot be built where it is (a unit, a tree in the way) is refused there as one built by hand is\n *\n * @beta\n */\nexport const buildLineCommand = defineCommand(\n\t'buildLine',\n\t{ entities: ids, unitType: string, from: point, to: point, queue: optional(bool) },\n\t(world, player, command) => {\n\t\tif (!world.registry.units.has(command.unitType)) return\n\t\tconst builder = command.entities\n\t\t\t.map((id) => world.get(id))\n\t\t\t.find((entity) => entity?.alive && entity.owner === player && entity.def.builds?.includes(command.unitType))\n\t\tif (!builder) return\n\t\twallLine(command.from, command.to).forEach((cell, index) => {\n\t\t\tgiveOrder(world, builder, createOrder(world, { type: 'build', unitType: command.unitType, point: cell }), index > 0 || !!command.queue)\n\t\t})\n\t}\n)\n\n/**\n * A gate of a wall (`UnitTypeDef.wall.gate`): whether it stands open, every screen told. Open, it is in nobody's way,\n * whoever walks; shut, it is a piece of the wall. Its owner opens and shuts it (`wallGateCommand`, `setWallGate`)\n *\n * @beta\n */\nexport const wallGate = defineComponent<{ open: boolean }>('walls.gate', {\n\treplicate: 'everyone',\n\t// put up shut\n\tonSpawn(entity) {\n\t\tif (!entity.def.wall?.gate) return\n\t\tentity.set(wallGate, { open: false })\n\t\tentity.look = 'shut'\n\t},\n\tpassable: (gate) => gate.open\n})\n\n/**\n * A gate of a wall opened or shut (`setWallGate`)\n *\n * @beta\n */\nexport const wallGateChanged = defineEvent<{ entity: number; open: boolean }>('core.wallGateChanged', { replicate: 'everyone' })\n\n/**\n * Opens or shuts a gate of a wall, for everyone: open, what walks goes through its cell, whoever's; shut, around it.\n * Its look is `open` or `shut`. False for what is no gate, or one still going up\n *\n * @beta\n */\nexport function setWallGate(world: World, gate: Entity, open: boolean): boolean {\n\tconst now = gate.get(wallGate)\n\tif (!now || !gate.alive || gate.has(constructionSite)) return false\n\tif (now.open === open) return true\n\tgate.set(wallGate, { open })\n\tgate.look = open ? 'open' : 'shut'\n\tif (open) world.nav.removeObstacle(gate.id)\n\telse if (!world.nav.addObstacle(gate.id, gate.rect))\n\t\tworld.log.warn('navigation', `There is no room for another obstacle: the gate ${gate.id} does not block the way`, { entity: gate.id })\n\tworld.events.emit(wallGateChanged, { entity: gate.id, open })\n\treturn true\n}\n\n/**\n * Its owner opens or shuts a gate of a wall (`setWallGate`), for everyone\n *\n * @beta\n */\nexport const wallGateCommand = defineCommand('wallGate', { entity: id, open: bool }, (world, player, command) => {\n\tconst gate = world.get(command.entity)\n\tif (gate?.owner === player) setWallGate(world, gate, command.open)\n})\n\n/**\n * Walls for a game: its pieces (types with `wall: { family }`) join with their neighbours as they are put down and\n * taken away, and a builder lays a line of them (`buildLineCommand`). A game's pieces draw by their shape with\n * `UnitLook.looks` (`single`, `end`, `straight`, `corner`, `tee`, `cross`); its gates (`wall.gate`) by `open` and `shut`,\n * opened and shut by their owner (`wallGateCommand`)\n *\n * @beta\n */\nexport function withWalls(): GamePack {\n\tconst spawnHook = defineHook({\n\t\thook: 'spawn',\n\t\tid: 'core.walls.spawn',\n\t\trun(world, entity) {\n\t\t\tconst family = entity.def.wall?.family\n\t\t\tif (family) reshapeAround(world, entity.rect, family, entity)\n\t\t}\n\t})\n\tconst removeHook = defineHook({\n\t\thook: 'remove',\n\t\tid: 'core.walls.remove',\n\t\trun(world, entity) {\n\t\t\tconst family = entity.def.wall?.family\n\t\t\tif (family) reshapeAround(world, entity.rect, family)\n\t\t}\n\t})\n\treturn {\n\t\tid: 'walls',\n\t\tcommands: [buildLineCommand, wallGateCommand],\n\t\tcomponents: [wallGate],\n\t\tevents: [wallJoined, wallGateChanged],\n\t\thooks: [spawnHook, removeHook]\n\t}\n}\n","import { footprintOf } from './defs'\nimport type { PlayerId } from './entity'\nimport { BuildGrid, footprintCell } from './grid'\nimport { type GameMap, mapTerrain } from './map'\nimport { mapCells } from './mapCheck'\nimport type { Vec2 } from './math'\nimport type { Registry } from './registry'\nimport { hypot } from './exactMath'\n\n/**\n * A way on foot over a map: its length, and the points it goes through\n *\n * @beta\n */\nexport interface Walk {\n\tlength: number\n\tpoints: Vec2[]\n}\n\n/** How the cells of a map are walked: which are open, and between which a step is no cliff */\ninterface Walking {\n\twidth: number\n\tdepth: number\n\topen: Uint8Array\n\tpassable(a: number, b: number): boolean\n\t/** The open cell nearest a point, for what stands on cells nothing walks on, or -1 */\n\tcellAt(point: Vec2): number\n}\n\nfunction walking(map: GameMap, registry: Registry): Walking {\n\tconst { width, depth, levels, ramps } = map\n\tconst { open } = mapCells(map, registry, mapTerrain(map), true)\n\tconst cellAt = (point: Vec2) => {\n\t\tconst cx = Math.floor(point.x)\n\t\tconst cz = Math.floor(point.z)\n\t\tfor (let r = 0; r <= 6; r++) {\n\t\t\tfor (let z = cz - r; z <= cz + r; z++) {\n\t\t\t\tfor (let x = cx - r; x <= cx + r; x++) {\n\t\t\t\t\tif (x < 0 || z < 0 || x >= width || z >= depth || Math.max(Math.abs(x - cx), Math.abs(z - cz)) !== r) continue\n\t\t\t\t\tif (open[z * width + x]) return z * width + x\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn -1\n\t}\n\treturn { width, depth, open, passable: (a, b) => levels[a] === levels[b] || ramps[a] > 0 || ramps[b] > 0, cellAt }\n}\n\n/** The way on foot between two cells: A* over the cells, eight ways, corners not cut. Nothing when there is none */\nfunction walk(walking: Walking, from: number, to: number): Walk | undefined {\n\tconst { width, depth, open, passable } = walking\n\tif (from < 0 || to < 0) return undefined\n\tconst cells = width * depth\n\tconst cost = new Float32Array(cells).fill(Infinity)\n\tconst came = new Int32Array(cells).fill(-1)\n\tconst closed = new Uint8Array(cells)\n\tconst tx = to % width\n\tconst tz = Math.floor(to / width)\n\tconst guess = (c: number) => {\n\t\tconst dx = Math.abs((c % width) - tx)\n\t\tconst dz = Math.abs(Math.floor(c / width) - tz)\n\t\treturn Math.max(dx, dz) + (Math.SQRT2 - 1) * Math.min(dx, dz)\n\t}\n\t// a binary heap of cells by cost and guess\n\tconst heap: number[] = []\n\tconst score = new Float32Array(cells)\n\tconst push = (c: number) => {\n\t\theap.push(c)\n\t\tlet i = heap.length - 1\n\t\twhile (i > 0) {\n\t\t\tconst parent = (i - 1) >> 1\n\t\t\tif (score[heap[parent]] <= score[heap[i]]) break\n\t\t\t;[heap[parent], heap[i]] = [heap[i], heap[parent]]\n\t\t\ti = parent\n\t\t}\n\t}\n\tconst pop = () => {\n\t\tconst top = heap[0]\n\t\tconst last = heap.pop()!\n\t\tif (heap.length) {\n\t\t\theap[0] = last\n\t\t\tlet i = 0\n\t\t\tfor (;;) {\n\t\t\t\tconst left = i * 2 + 1\n\t\t\t\tconst right = left + 1\n\t\t\t\tlet least = i\n\t\t\t\tif (left < heap.length && score[heap[left]] < score[heap[least]]) least = left\n\t\t\t\tif (right < heap.length && score[heap[right]] < score[heap[least]]) least = right\n\t\t\t\tif (least === i) break\n\t\t\t\t;[heap[least], heap[i]] = [heap[i], heap[least]]\n\t\t\t\ti = least\n\t\t\t}\n\t\t}\n\t\treturn top\n\t}\n\tcost[from] = 0\n\tscore[from] = guess(from)\n\tpush(from)\n\twhile (heap.length) {\n\t\tconst c = pop()\n\t\tif (closed[c]) continue\n\t\tif (c === to) break\n\t\tclosed[c] = 1\n\t\tconst x = c % width\n\t\tconst z = (c - x) / width\n\t\tfor (let dz = -1; dz <= 1; dz++) {\n\t\t\tfor (let dx = -1; dx <= 1; dx++) {\n\t\t\t\tif (!dx && !dz) continue\n\t\t\t\tconst nx = x + dx\n\t\t\t\tconst nz = z + dz\n\t\t\t\tif (nx < 0 || nz < 0 || nx >= width || nz >= depth) continue\n\t\t\t\tconst n = nz * width + nx\n\t\t\t\tif (!open[n] || closed[n] || !passable(c, n)) continue\n\t\t\t\t// a diagonal step only past two open cells: no cutting the corner of a cliff\n\t\t\t\tif (dx && dz) {\n\t\t\t\t\tconst side1 = z * width + nx\n\t\t\t\t\tconst side2 = nz * width + x\n\t\t\t\t\tif (!open[side1] || !open[side2] || !passable(c, side1) || !passable(c, side2)) continue\n\t\t\t\t}\n\t\t\t\tconst next = cost[c] + (dx && dz ? Math.SQRT2 : 1)\n\t\t\t\tif (next >= cost[n]) continue\n\t\t\t\tcost[n] = next\n\t\t\t\tcame[n] = c\n\t\t\t\tscore[n] = next + guess(n)\n\t\t\t\tpush(n)\n\t\t\t}\n\t\t}\n\t}\n\tif (!Number.isFinite(cost[to])) return undefined\n\tconst points: Vec2[] = []\n\tfor (let c = to; c >= 0; c = came[c]) points.push({ x: (c % width) + 0.5, z: Math.floor(c / width) + 0.5 })\n\treturn { length: cost[to], points: points.reverse() }\n}\n\n/**\n * The way on foot between two points of a map, with what the checks count as in the way. Nothing when there is none\n *\n * @beta\n */\nexport function walkBetween(map: GameMap, registry: Registry, from: Vec2, to: Vec2): Walk | undefined {\n\tconst cells = walking(map, registry)\n\treturn walk(cells, cells.cellAt(from), cells.cellAt(to))\n}\n\n/**\n * How many cells each open cell is from what is not: half the width of the way there. A passage two cells wide has\n * cells 1 from its sides in its middle\n */\nfunction clearance(walking: Walking): Float32Array {\n\tconst { width, depth, open } = walking\n\tconst far = new Float32Array(width * depth)\n\tfor (let c = 0; c < far.length; c++) far[c] = open[c] ? Infinity : 0\n\t// two passes of a chamfer distance, eight ways\n\tconst step = (c: number, x: number, z: number, dx: number, dz: number, weight: number) => {\n\t\tconst nx = x + dx\n\t\tconst nz = z + dz\n\t\tconst next = nx < 0 || nz < 0 || nx >= width || nz >= depth ? 0 : far[nz * width + nx]\n\t\tif (next + weight < far[c]) far[c] = next + weight\n\t}\n\tfor (let z = 0; z < depth; z++) {\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tconst c = z * width + x\n\t\t\tif (!far[c]) continue\n\t\t\tstep(c, x, z, -1, 0, 1)\n\t\t\tstep(c, x, z, 0, -1, 1)\n\t\t\tstep(c, x, z, -1, -1, Math.SQRT2)\n\t\t\tstep(c, x, z, 1, -1, Math.SQRT2)\n\t\t}\n\t}\n\tfor (let z = depth - 1; z >= 0; z--) {\n\t\tfor (let x = width - 1; x >= 0; x--) {\n\t\t\tconst c = z * width + x\n\t\t\tif (!far[c]) continue\n\t\t\tstep(c, x, z, 1, 0, 1)\n\t\t\tstep(c, x, z, 0, 1, 1)\n\t\t\tstep(c, x, z, 1, 1, Math.SQRT2)\n\t\t\tstep(c, x, z, -1, 1, Math.SQRT2)\n\t\t}\n\t}\n\treturn far\n}\n\n/**\n * What one player's start has around it\n *\n * @beta\n */\nexport interface StartMeasure {\n\tplayer: PlayerId\n\tname: string\n\t/** The way on foot to the nearest mine, and how much it holds. Nothing without a mine they can walk to */\n\tmine?: { distance: number; amount: number; at: Vec2 }\n\t/** How many cells within `BUILD_REACH` of the start can be built on */\n\tbuildable: number\n\t/** Trees within `BUILD_REACH` of the start */\n\ttrees: number\n}\n\n/**\n * A number of a map a game measures of its own (`MapEditorDef.measure`): the length of the road, for a tower defense\n *\n * @beta\n */\nexport interface GameMeasure {\n\tname: string\n\tvalue: number | string\n}\n\n/**\n * What a map is like to play on, measured (see `measureMap`)\n *\n * @beta\n */\nexport interface MapReport {\n\t/** The way on foot between every two starts: how far a rush goes. Nothing for starts cut off from each other */\n\trushes: { from: PlayerId; to: PlayerId; length?: number; points?: Vec2[] }[]\n\t/** The narrowest place on the ways between the starts, and how wide it is */\n\tnarrowest?: { width: number; at: Vec2 }\n\tstarts: StartMeasure[]\n\t/** What each start has that another has more than `FAIR_MARGIN` more of: what is not fair */\n\tunfair: string[]\n\tgame: GameMeasure[]\n}\n\n/**\n * How far around a start counts as its ground, for building and trees\n *\n * @beta\n */\nexport const BUILD_REACH = 16\n/**\n * How much more one start can have of something than another before it is not fair, as a part\n *\n * @internal\n */\nexport const FAIR_MARGIN = 0.15\n/** The ends of a way, in cells, where the bases stand: the narrowest place is looked for between them */\nconst BASE_ROOM = 8\n\n/**\n * What a map is like to play on: the way on foot between every two starts, the narrowest place on those ways, and for\n * each start the nearest mine and how much it holds, the ground around it that can be built on, and its trees; side\n * by side, with what one start has much more of than another said. Then what the game measures of its own\n *\n * @beta\n */\nexport function measureMap(map: GameMap, registry: Registry): MapReport {\n\tconst cells = walking(map, registry)\n\tconst terrain = mapTerrain(map)\n\tconst grid = new BuildGrid(terrain)\n\tconst { built } = mapCells(map, registry, terrain)\n\tconst starts = map.players.filter((player) => player.start)\n\tconst rushes: MapReport['rushes'] = []\n\tfor (let i = 0; i < starts.length; i++) {\n\t\tfor (let j = i + 1; j < starts.length; j++) {\n\t\t\tconst way = walk(cells, cells.cellAt(starts[i].start!), cells.cellAt(starts[j].start!))\n\t\t\trushes.push({ from: starts[i].id, to: starts[j].id, ...(way && { length: Math.round(way.length * 10) / 10, points: way.points }) })\n\t\t}\n\t}\n\t// the narrowest place on the ways between the bases, not in the bases\n\tconst far = clearance(cells)\n\tlet narrowest: MapReport['narrowest']\n\tfor (const rush of rushes) {\n\t\tconst points = rush.points ?? []\n\t\tfor (let i = BASE_ROOM; i < points.length - BASE_ROOM; i++) {\n\t\t\tconst c = Math.floor(points[i].z) * cells.width + Math.floor(points[i].x)\n\t\t\tconst width = Math.round((far[c] * 2 - 1) * 10) / 10\n\t\t\tif (!narrowest || width < narrowest.width) narrowest = { width, at: points[i] }\n\t\t}\n\t}\n\tconst mines = map.objects.filter((object) => {\n\t\tif (!registry.units.has(object.type)) return false\n\t\tconst def = registry.unit(object.type)\n\t\treturn def.kind === 'resource' && footprintOf(def).w >= 2\n\t})\n\tconst measures: StartMeasure[] = starts.map((player) => {\n\t\tconst start = player.start!\n\t\tconst from = cells.cellAt(start)\n\t\tlet mine: StartMeasure['mine']\n\t\tfor (const object of mines) {\n\t\t\tconst way = walk(cells, from, cells.cellAt(object))\n\t\t\tif (!way || (mine && way.length >= mine.distance)) continue\n\t\t\tconst def = registry.unit(object.type)\n\t\t\tmine = { distance: Math.round(way.length * 10) / 10, amount: object.amount ?? def.resource?.amount ?? 0, at: { x: object.x, z: object.z } }\n\t\t}\n\t\tlet buildable = 0\n\t\tfor (let z = Math.floor(start.z - BUILD_REACH); z <= Math.ceil(start.z + BUILD_REACH); z++) {\n\t\t\tfor (let x = Math.floor(start.x - BUILD_REACH); x <= Math.ceil(start.x + BUILD_REACH); x++) {\n\t\t\t\tif (hypot(x + 0.5 - start.x, z + 0.5 - start.z) > BUILD_REACH) continue\n\t\t\t\tif (grid.isBuildable(x, z) && !built[z * map.width + x]) buildable++\n\t\t\t}\n\t\t}\n\t\tconst trees = map.objects.filter((object) => {\n\t\t\tif (!registry.units.has(object.type) || hypot(object.x - start.x, object.z - start.z) > BUILD_REACH) return false\n\t\t\tconst def = registry.unit(object.type)\n\t\t\treturn def.kind === 'resource' && footprintOf(def).w < 2\n\t\t}).length\n\t\treturn { player: player.id, name: player.name, ...(mine && { mine }), buildable, trees }\n\t})\n\t// what is not fair: one start with much more of something than another\n\tconst unfair: string[] = []\n\tconst compare = (what: string, value: (start: StartMeasure) => number | undefined, more = 'more') => {\n\t\tconst values = measures.map((start) => ({ start, value: value(start) }))\n\t\tconst known = values.filter((entry) => entry.value !== undefined) as { start: StartMeasure; value: number }[]\n\t\tif (known.length < 2) return\n\t\tconst most = known.reduce((a, b) => (b.value > a.value ? b : a))\n\t\tconst least = known.reduce((a, b) => (b.value < a.value ? b : a))\n\t\tif (most.value > least.value * (1 + FAIR_MARGIN) && most.value - least.value > 1) {\n\t\t\tunfair.push(`${most.start.name} has ${more} ${what} than ${least.start.name}: ${most.value} against ${least.value}`)\n\t\t}\n\t}\n\tcompare('way to their nearest mine', (start) => start.mine?.distance, 'a longer')\n\tcompare('gold in their nearest mine', (start) => start.mine?.amount)\n\tcompare('ground to build on', (start) => start.buildable)\n\tcompare('trees near their start', (start) => start.trees)\n\treturn {\n\t\trushes: rushes.map(({ points: _, ...rush }) => rush),\n\t\t...(narrowest && { narrowest }),\n\t\tstarts: measures,\n\t\tunfair,\n\t\tgame: registry.module?.editor?.measure?.(map, registry) ?? []\n\t}\n}\n\n/**\n * Seconds a unit type takes over a way on foot, at the speed it starts with\n *\n * @beta\n */\nexport const walkingTime = (registry: Registry, type: string, length: number): number | undefined => {\n\tif (!registry.units.has(type)) return undefined\n\tconst speed = registry.unit(type).stats.moveSpeed ?? 0\n\treturn speed > 0 ? Math.round((length / speed) * 10) / 10 : undefined\n}\n\n/** The cell of a footprint, for drawing where a mine stands */\nexport const footprintAt = (registry: Registry, type: string, at: Vec2) => {\n\tconst { w, d } = footprintOf(registry.unit(type))\n\treturn footprintCell(at.x, at.z, w, d)\n}\n","import { createWorldFromMap, type GameModule, loadWorld } from './game'\nimport { type GameMap, type MapFile, parseMap, serializeMap } from './map'\nimport { decodeSave, encodeSave, saveWorld, type WorldSave } from './save'\nimport type { Registry } from './registry'\nimport type { World } from './world'\n\n/**\n * A situation for a test to start from, set up in the editor: a map made for it, or a world saved at the moment that\n * matters (in the editor's play mode). Kept in the tests' scenarios (`<scenarios>/<game>/<name>.scenario.json`: `tests/scenarios` unless the project says otherwise), or in a game's folder,\n * and loaded with what was named in the editor found by name. It says which format it was saved with, and is brought\n * up to date like a map (`readScenario`): one that no longer loads fails its test with what is wrong\n *\n * @beta\n */\nexport type ScenarioFile = {\n\tformat: number\n\tname: string\n\t/** The game it is of, by the id of its module */\n\tgame: string\n\t/** What it is for, to read in a list */\n\tdescription?: string\n} & ({ kind: 'map'; map: MapFile } | { kind: 'save'; save: string })\n\n/**\n * The format scenarios are written in now\n *\n * @beta\n */\nexport const SCENARIO_FORMAT = 1\n\n/**\n * A scenario file as it is now, checked. Throws on what is wrong with it\n *\n * @beta\n */\nexport function readScenario(data: unknown): ScenarioFile {\n\tif (typeof data !== 'object' || data === null || Array.isArray(data)) throw new Error('A scenario is an object')\n\tconst file = data as Partial<ScenarioFile> & Record<string, unknown>\n\tif (typeof file.format !== 'number' || file.format > SCENARIO_FORMAT)\n\t\tthrow new Error(`A scenario of format ${file.format}, which this engine does not know`)\n\tif (typeof file.name !== 'string' || !file.name) throw new Error('A scenario has a name')\n\tif (typeof file.game !== 'string' || !file.game) throw new Error(`The scenario ${file.name} does not say which game it is of`)\n\tif (file.kind === 'map') {\n\t\t// what a map file is is the map's to say: read now, so that a broken one says what is wrong at once\n\t\tparseMap(file.map)\n\t} else if (file.kind === 'save') {\n\t\tif (typeof file.save !== 'string') throw new Error(`The scenario ${file.name} has no save in it`)\n\t} else throw new Error(`The scenario ${file.name} is neither a map nor a save`)\n\treturn { ...(file as ScenarioFile), format: SCENARIO_FORMAT }\n}\n\n/**\n * A map made for a test, as a scenario\n *\n * @beta\n */\nexport function scenarioOfMap(map: GameMap, name: string, game: string, description?: string): ScenarioFile {\n\treturn { format: SCENARIO_FORMAT, name, game, ...(description && { description }), kind: 'map', map: serializeMap(map) }\n}\n\n/**\n * A world at the moment that matters, as a scenario\n *\n * @beta\n */\nexport function scenarioOfWorld(world: World, name: string, description?: string): ScenarioFile {\n\treturn {\n\t\tformat: SCENARIO_FORMAT,\n\t\tname,\n\t\tgame: world.registry.game,\n\t\t...(description && { description }),\n\t\tkind: 'save',\n\t\tsave: encodeSave(portableSave(world.registry, saveWorld(world)))\n\t}\n}\n\n/** Only what is the game's: what an app keeps of its own in the world (`Component.portable` false) left out */\nfunction portableSave(registry: Registry, save: WorldSave): WorldSave {\n\tconst keep = (values: Record<string, unknown> | undefined) =>\n\t\tvalues && Object.fromEntries(Object.entries(values).filter(([id]) => registry.component(id)?.portable !== false))\n\treturn {\n\t\t...save,\n\t\tstate: keep(save.state)!,\n\t\tplayers: save.players.map((player) => ({ ...player, state: keep(player.state)! })),\n\t\tentities: save.entities.map((entity) =>\n\t\t\tentity.components ? { ...entity, components: keep(entity.components as Record<string, unknown>) } : entity\n\t\t),\n\t\tdetached: save.detached.map((entity) =>\n\t\t\tentity.components ? { ...entity, components: keep(entity.components as Record<string, unknown>) } : entity\n\t\t)\n\t}\n}\n\n/**\n * The world of a scenario, with the game's module: a map made into a world as a game would make it (with the seed 1,\n * so that it is the same every time), or a saved world loaded as it was\n *\n * @beta\n */\nexport async function scenarioWorld(scenario: ScenarioFile, game: GameModule): Promise<World> {\n\tif (scenario.game !== game.id) throw new Error(`The scenario ${scenario.name} is of the game \"${scenario.game}\", not \"${game.id}\"`)\n\tif (scenario.kind === 'map') return createWorldFromMap({ map: parseMap(scenario.map), game, seed: 1 })\n\treturn loadWorld(decodeSave(scenario.save), { game })\n}\n","import { inventoryChanged } from '#engine/engineEvents'\nimport type { Entity, PlayerId } from '#engine/entity'\nimport { createItem } from '#engine/items'\nimport { slotsOf } from '#engine/inventory'\nimport { heroOf, maxLevelOf } from '#engine/hero'\nimport { refreshVitals } from '#engine/stats'\nimport { readyAgain } from '#engine/abilities/charges'\nimport type { Vec2 } from '#engine/math'\nimport type { SpawnOptions, World } from '#engine/world'\n\n/**\n * An item a hero carries, as it is carried over: what it is, its uses left, the game's own state of it\n *\n * @beta\n */\nexport interface HeroItem {\n\titem: string\n\tcharges: number\n\tdata?: Record<string, unknown>\n}\n\n/**\n * A hero as plain data, to take from one world into another: a campaign's hero going on to the next mission with all\n * it has earned. Its level and experience, the points it has not spent, the abilities it learned and how far, and its\n * items slot by slot. Not where it is or how hurt: the next mission puts it where it starts, whole\n *\n * @beta\n */\nexport interface HeroRecord {\n\t/** Its unit type */\n\ttype: string\n\t/** The name it was known by in the rules (`world.named`), when it had one */\n\tname?: string\n\tlevel: number\n\txp: number\n\tpoints: number\n\t/** Learned abilities and their level. Ones not learned are left out */\n\tabilities: Record<string, number>\n\t/** Its inventory slot by slot: null for an empty slot */\n\titems: (HeroItem | null)[]\n}\n\n/**\n * A hero of a world as a record, to carry into another (see `applyHeroRecord`). Throws for what is no hero\n *\n * @beta\n */\nexport function heroRecord(world: World, hero: Entity): HeroRecord {\n\tconst state = heroOf(hero)\n\tif (!state) throw new Error(`${hero.def.id} is no hero to carry over`)\n\tconst name = world.nameOf(hero)\n\treturn {\n\t\ttype: hero.def.id,\n\t\t...(name !== undefined && { name }),\n\t\tlevel: state.level,\n\t\txp: state.xp,\n\t\tpoints: state.points,\n\t\tabilities: Object.fromEntries(hero.abilities.filter((ability) => ability.level > 0).map((ability) => [ability.id, ability.level])),\n\t\titems: (slotsOf(hero) ?? []).map((slot) =>\n\t\t\tslot ? { item: slot.item, charges: slot.charges, ...(slot.data && { data: structuredClone(slot.data) }) } : null\n\t\t)\n\t}\n}\n\n/**\n * Makes a hero of a world what a record says it was: its level, experience and points, its abilities as far as they\n * were learned, and its items in their slots. In place of what it had. What the game no longer has, an ability or an\n * item, is left out. Whole: health and mana full, nothing cooling down\n *\n * @beta\n */\nexport function applyHeroRecord(world: World, hero: Entity, record: HeroRecord): void {\n\tconst state = heroOf(hero)\n\tif (!state) throw new Error(`${hero.def.id} is no hero to carry a hero into`)\n\tstate.level = Math.max(1, Math.min(Math.floor(record.level), maxLevelOf(world, hero)))\n\tstate.xp = Math.max(record.xp, world.rules.heroes.xpForLevel(state.level))\n\tstate.points = Math.max(Math.floor(record.points), 0)\n\tfor (const ability of hero.abilities) {\n\t\tconst level = record.abilities[ability.id] ?? 0\n\t\tconst max = world.registry.abilities.has(ability.id) ? (world.registry.ability(ability.id).maxLevel ?? 3) : 0\n\t\tability.level = Math.min(level, max)\n\t\treadyAgain(ability)\n\t\tability.autocast = ability.level > 0 && (world.registry.ability(ability.id).autocast ?? false)\n\t}\n\tconst slots = slotsOf(hero)\n\tif (slots) {\n\t\tslots.fill(null)\n\t\trecord.items.forEach((carried, slot) => {\n\t\t\tif (!carried || slot >= slots.length || !world.registry.items.has(carried.item)) return\n\t\t\tconst instance = createItem(world, carried.item, carried.charges)\n\t\t\tif (carried.data) instance.data = structuredClone(carried.data)\n\t\t\tslots[slot] = instance\n\t\t})\n\t\tworld.events.emit(inventoryChanged, { entity: hero })\n\t}\n\trefreshVitals(world, hero)\n\thero.hp = hero.maxHp\n\thero.mana = hero.maxMana\n}\n\n/**\n * A hero made from a record (see `heroRecord`) for a player at a point, under the name it had unless told another\n *\n * @beta\n */\nexport function heroFromRecord(world: World, record: HeroRecord, owner: PlayerId, at: Vec2, options: SpawnOptions = {}): Entity {\n\tconst name = options.name ?? record.name\n\tconst hero = world.spawn(record.type, owner, at, { ...options, ...(name !== undefined && { name }) })\n\tapplyHeroRecord(world, hero, record)\n\treturn hero\n}\n\n/**\n * A record read back from what was kept (a campaign's progress, a file), checked. Throws on what is wrong\n *\n * @beta\n */\nexport function readHeroRecord(data: unknown): HeroRecord {\n\tconst record = data as Partial<HeroRecord> | null\n\tif (typeof record !== 'object' || record === null) throw new Error('A hero record is an object')\n\tif (typeof record.type !== 'string' || !record.type) throw new Error('A hero record says what type of unit it is')\n\tconst number = (value: unknown, what: string) => {\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) throw new Error(`A hero record's ${what} is a number`)\n\t\treturn value\n\t}\n\tconst abilities = record.abilities ?? {}\n\tif (typeof abilities !== 'object' || Array.isArray(abilities)) throw new Error(\"A hero record's abilities are levels by id\")\n\treturn {\n\t\ttype: record.type,\n\t\t...(typeof record.name === 'string' && { name: record.name }),\n\t\tlevel: number(record.level, 'level'),\n\t\txp: number(record.xp ?? 0, 'experience'),\n\t\tpoints: number(record.points ?? 0, 'points'),\n\t\tabilities: Object.fromEntries(Object.entries(abilities).map(([id, level]) => [id, number(level, `level of ${id}`)])),\n\t\titems: (Array.isArray(record.items) ? record.items : []).map((slot) =>\n\t\t\tslot && typeof slot === 'object' && typeof (slot as HeroItem).item === 'string'\n\t\t\t\t? {\n\t\t\t\t\t\titem: (slot as HeroItem).item,\n\t\t\t\t\t\tcharges: number((slot as HeroItem).charges ?? 0, 'charges'),\n\t\t\t\t\t\t...((slot as HeroItem).data && { data: (slot as HeroItem).data })\n\t\t\t\t\t}\n\t\t\t\t: null\n\t\t)\n\t}\n}\n","import { applyHeroRecord, heroFromRecord, type HeroItem, type HeroRecord, heroRecord, readHeroRecord } from './carry'\nimport { inventoryChanged } from '#engine/engineEvents'\nimport type { Entity, PlayerId } from '#engine/entity'\nimport { heroOf, heroesOf } from '#engine/hero'\nimport { slotsOf } from '#engine/inventory'\nimport { createItem } from '#engine/items'\nimport { cos, sin } from '#engine/exactMath'\nimport type { Vec2 } from '#engine/math'\nimport type { Purse } from '#engine/player'\nimport { refreshVitals } from '#engine/stats'\nimport { veterancy, type VeterancyState } from '#engine/veterancy'\nimport type { World } from '#engine/world'\n\n/**\n * How a mission of a campaign went, the last time it was won\n *\n * @beta\n */\nexport interface MissionResult {\n\t/** How long it took, in seconds of the game */\n\tseconds: number\n\t/** The shortest it ever took */\n\tbest: number\n\t/** When it was won, in milliseconds since 1970 */\n\tfinished: number\n}\n\n/**\n * How far a campaign has got, as plain data to keep between games: the mission it is at, the missions won and how\n * long each took, the heroes carried out of the last one won, and the game's own state of it (`data`, of the type\n * `D` the campaign says: choices made, gold saved up, the units that go on; what each mission won carries, merged in).\n * It says which format it is in, so that what was kept is read again when the format changes\n *\n * @beta\n */\nexport interface CampaignProgress<D extends object = Record<string, unknown>> {\n\tformat: number\n\t/** The campaign it is of, by id */\n\tcampaign: string\n\t/** The mission to play next */\n\tat: string\n\t/** The difficulty chosen for it (`CampaignDef.difficulties`), by name: its missions' computers play on it */\n\tdifficulty?: string\n\t/** Missions won, by id */\n\tdone: Record<string, MissionResult>\n\t/** The heroes carried into the next mission */\n\theroes: HeroRecord[]\n\t/** The game's own, plain data: what the missions won carried (`MissionDef.carry`), each mission's keys over the ones before */\n\tdata: Partial<D>\n}\n\n/**\n * The format campaign progress is written in now\n *\n * @internal\n */\nexport const CAMPAIGN_FORMAT = 1\n\n/**\n * A campaign as it is before anything is played: at its first mission, with nothing carried\n *\n * @beta\n */\nexport function newCampaignProgress<D extends object = Record<string, unknown>>(campaign: string, first: string): CampaignProgress<D> {\n\treturn { format: CAMPAIGN_FORMAT, campaign, at: first, done: {}, heroes: [], data: {} }\n}\n\n/**\n * Progress as it was kept, checked and brought up to date. Throws on what is wrong\n *\n * @beta\n */\nexport function readCampaignProgress(data: unknown): CampaignProgress {\n\tconst kept = data as Partial<CampaignProgress> | null\n\tif (typeof kept !== 'object' || kept === null) throw new Error(\"A campaign's progress is an object\")\n\tif (typeof kept.format !== 'number' || kept.format > CAMPAIGN_FORMAT)\n\t\tthrow new Error(`Campaign progress of format ${kept.format}, which this engine does not know`)\n\tif (typeof kept.campaign !== 'string' || typeof kept.at !== 'string')\n\t\tthrow new Error(\"A campaign's progress says which campaign it is and where it is at\")\n\tconst done: Record<string, MissionResult> = {}\n\tfor (const [mission, result] of Object.entries(kept.done ?? {})) {\n\t\tconst { seconds, best, finished } = (result ?? {}) as Partial<MissionResult>\n\t\tif (typeof seconds !== 'number' || !Number.isFinite(seconds)) throw new Error(`How long ${mission} took is a number`)\n\t\tdone[mission] = { seconds, best: typeof best === 'number' ? best : seconds, finished: typeof finished === 'number' ? finished : 0 }\n\t}\n\treturn {\n\t\tformat: CAMPAIGN_FORMAT,\n\t\tcampaign: kept.campaign,\n\t\tat: kept.at,\n\t\t...(typeof kept.difficulty === 'string' && { difficulty: kept.difficulty }),\n\t\tdone,\n\t\theroes: (kept.heroes ?? []).map(readHeroRecord),\n\t\tdata: typeof kept.data === 'object' && kept.data !== null ? kept.data : {}\n\t}\n}\n\n/**\n * A mission won: how long it took, the best time kept, the heroes it ends with to carry on, the campaign at the\n * mission after it (`next`), or still at this one when it was the last, and what it carries of the game's own\n * (`data`: its keys over the ones kept, the rest kept as they were). A new progress: the one given is left as it was\n *\n * @beta\n */\nexport function missionWon<D extends object = Record<string, unknown>>(\n\tprogress: CampaignProgress<D>,\n\tmission: string,\n\tseconds: number,\n\theroes: HeroRecord[],\n\tnext?: string,\n\tdata?: Partial<D>\n): CampaignProgress<D> {\n\tconst before = progress.done[mission]\n\treturn {\n\t\t...progress,\n\t\tat: next ?? progress.at,\n\t\tdone: { ...progress.done, [mission]: { seconds, best: before ? Math.min(before.best, seconds) : seconds, finished: Date.now() } },\n\t\theroes: structuredClone(heroes),\n\t\tdata: data ? { ...progress.data, ...structuredClone(data) } : progress.data\n\t}\n}\n\n/**\n * A unit as plain data, to take from one mission into the next (`carryUnits`, `placeUnits`): what it is, the name the\n * rules knew it by, how much of its health it has (a share, 0 to 1), its veterancy (`withVeterancy`) and its items\n * slot by slot. Not where it is: the next mission says where they come in. Heroes are carried as heroes (`carryOut`)\n *\n * @beta\n */\nexport interface UnitRecord {\n\t/** Its unit type */\n\ttype: string\n\t/** The name it was known by in the rules (`world.named`), when it had one */\n\tname?: string\n\t/** Its health, a share of the most it has: 1 for whole */\n\thealth: number\n\t/** Its experience and rank, where it has earned some (`withVeterancy`) */\n\tveterancy?: VeterancyState\n\t/** Its inventory slot by slot, where it has one: null for an empty slot */\n\titems?: (HeroItem | null)[]\n}\n\n/**\n * A player's units as records to carry on (`UnitRecord`): those alive, not structures, not heroes (`carryOut` carries\n * those), and of them what `filter` keeps (the footmen, the three nearest the gate). In the order of their ids\n *\n * @beta\n */\nexport function carryUnits(world: World, player: PlayerId, filter: (unit: Entity) => boolean = () => true): UnitRecord[] {\n\tconst units = [...world.index.ownedBy(player)]\n\t\t.filter((unit) => unit.alive && unit.isUnit && !heroOf(unit) && filter(unit))\n\t\t.sort((a, b) => a.id - b.id)\n\treturn units.map((unit) => {\n\t\tconst name = world.nameOf(unit)\n\t\tconst rank = unit.get(veterancy)\n\t\tconst slots = slotsOf(unit)\n\t\treturn {\n\t\t\ttype: unit.def.id,\n\t\t\t...(name !== undefined && { name }),\n\t\t\thealth: unit.maxHp > 0 ? Math.min(Math.max(unit.hp / unit.maxHp, 0), 1) : 1,\n\t\t\t...(rank && { veterancy: { ...rank } }),\n\t\t\t...(slots && {\n\t\t\t\titems: slots.map((slot) => (slot ? { item: slot.item, charges: slot.charges, ...(slot.data && { data: structuredClone(slot.data) }) } : null))\n\t\t\t})\n\t\t}\n\t})\n}\n\n/**\n * Brings carried units into a mission for a player, round a point (`spread` apart, in rings: 1.5 when left out), each\n * with its name, its share of health, its veterancy and its items. What the game no longer has, a type or an item, is\n * left out. The units made, in the order of the records\n *\n * @beta\n */\nexport function placeUnits(world: World, player: PlayerId, records: readonly UnitRecord[], at: Vec2, spread = 1.5): Entity[] {\n\tconst made: Entity[] = []\n\tconst kept = records.filter((record) => world.registry.units.has(record.type))\n\tkept.forEach((record, i) => {\n\t\tconst point = ringPoint(at, i, spread)\n\t\tconst unit = world.spawn(record.type, player, point, record.name !== undefined ? { name: record.name } : {})\n\t\tif (record.veterancy) {\n\t\t\tunit.set(veterancy, { ...record.veterancy })\n\t\t\trefreshVitals(world, unit)\n\t\t}\n\t\tconst slots = slotsOf(unit)\n\t\tif (slots && record.items) {\n\t\t\tslots.fill(null)\n\t\t\trecord.items.forEach((carried, slot) => {\n\t\t\t\tif (!carried || slot >= slots.length || !world.registry.items.has(carried.item)) return\n\t\t\t\tconst instance = createItem(world, carried.item, carried.charges)\n\t\t\t\tif (carried.data) instance.data = structuredClone(carried.data)\n\t\t\t\tslots[slot] = instance\n\t\t\t})\n\t\t\tworld.events.emit(inventoryChanged, { entity: unit })\n\t\t}\n\t\tunit.hp = Math.max(1, Math.round(unit.maxHp * Math.min(Math.max(record.health, 0), 1)))\n\t\tmade.push(unit)\n\t})\n\treturn made\n}\n\n/** The `index`-th place round a point: the point first, then rings of six, twelve, … `spread` apart */\nfunction ringPoint(at: Vec2, index: number, spread: number): Vec2 {\n\tif (index === 0) return { x: at.x, z: at.z }\n\tlet ring = 1\n\tlet first = 1\n\twhile (index >= first + ring * 6) {\n\t\tfirst += ring * 6\n\t\tring++\n\t}\n\tconst angle = ((index - first) / (ring * 6)) * Math.PI * 2\n\treturn { x: at.x + sin(angle) * ring * spread, z: at.z + cos(angle) * ring * spread }\n}\n\n/**\n * What a player has researched, to carry on (`giveResearch`): each upgrade's level, by its id\n *\n * @beta\n */\nexport function carryResearch(world: World, player: PlayerId): Record<string, number> {\n\treturn Object.fromEntries([...world.player(player).upgrades].filter(([, level]) => level > 0))\n}\n\n/**\n * Gives a player research carried in (`carryResearch`): each upgrade up to its level, never down, no further than it\n * goes, and what it does besides stats (`UpgradeDef.apply`) to the units the player has, as research finishing does.\n * What the game no longer has is left out\n *\n * @beta\n */\nexport function giveResearch(world: World, player: PlayerId, research: Readonly<Record<string, number>>): void {\n\tconst who = world.player(player)\n\tfor (const [upgrade, carried] of Object.entries(research)) {\n\t\tif (!world.registry.upgrades.has(upgrade)) continue\n\t\tconst def = world.registry.upgrade(upgrade)\n\t\tconst to = Math.min(Math.max(Math.floor(carried), 0), def.maxLevel ?? 1)\n\t\tfor (let level = (who.upgrades.get(upgrade) ?? 0) + 1; level <= to; level++) {\n\t\t\twho.setUpgrade(upgrade, level)\n\t\t\tif (def.apply) for (const entity of [...world.index.ownedBy(player)]) if (entity.alive) def.apply(world, entity, level)\n\t\t}\n\t\twho.researching.delete(upgrade)\n\t}\n}\n\n/**\n * What a player has of each resource, to carry on (`giveResources`): a copy, all of it, or of the kinds named\n *\n * @beta\n */\nexport function carryResources(world: World, player: PlayerId, kinds?: readonly string[]): Purse {\n\tconst resources = world.player(player).resources\n\treturn Object.fromEntries(Object.entries(resources).filter(([kind]) => !kinds || kinds.includes(kind)))\n}\n\n/**\n * Gives a player resources carried in (`carryResources`), on top of what the mission starts it with. What the game no\n * longer has is left out\n *\n * @beta\n */\nexport function giveResources(world: World, player: PlayerId, resources: Readonly<Purse>): void {\n\tconst purse = world.player(player).resources\n\tconst known = new Set(world.registry.resources.map((resource) => resource.id))\n\tfor (const [kind, amount] of Object.entries(resources)) if (known.has(kind) && Number.isFinite(amount)) purse[kind] = (purse[kind] ?? 0) + amount\n}\n\n/**\n * The heroes of a player as records to carry on (see `heroRecord`): fallen ones too, as a campaign brings them back\n *\n * @beta\n */\nexport function carryOut(world: World, player: PlayerId): HeroRecord[] {\n\treturn heroesOf(world, player).map((hero) => heroRecord(world, hero))\n}\n\n/**\n * Brings carried heroes into a mission for a player. Each takes the place of the hero the map has for it: the one of\n * that player under the same name, else one of that player of the same type; a hero the map has none for is made at\n * `at`. The heroes, in the order of the records\n *\n * @beta\n */\nexport function carryIn(world: World, heroes: readonly HeroRecord[], player: PlayerId, at: Vec2): Entity[] {\n\tconst taken = new Set<Entity>()\n\treturn heroes.map((record) => {\n\t\tconst named = record.name !== undefined ? world.named(record.name) : undefined\n\t\tconst placed =\n\t\t\tnamed && named.owner === player && heroOf(named) && !taken.has(named)\n\t\t\t\t? named\n\t\t\t\t: heroesOf(world, player).find((hero) => hero.def.id === record.type && !taken.has(hero))\n\t\tconst hero = placed ?? heroFromRecord(world, record, player, at)\n\t\tif (placed) applyHeroRecord(world, placed, record)\n\t\ttaken.add(hero)\n\t\treturn hero\n\t})\n}\n","/**\n * Replays of commands (determinism D4): a game kept as where it started and what its players told it, tick by tick,\n * and played back by running it again. A world comes out the same from the same start and the same commands (D1–D3),\n * so this is the whole game, from every side, in a few kilobytes where the frames a watcher was sent are megabytes.\n * Its hash every few seconds is kept with it: played back, a hash that differs says the game came apart there (rules\n * changed since, or a system a save does not bring back), and from then it is the game the rules make now\n */\nimport { decodeSave, encodeSave, saveWorld } from '#engine/save'\nimport { type Apart, saveDifference, worldFingerprint } from '#engine/determinism'\nimport { type GameModule, loadWorld } from '#engine/game'\nimport type { Component } from '#engine/components'\nimport type { IssuedCommand } from '#engine/commands'\nimport type { PlayerId } from '#engine/entity'\nimport type { World } from '#engine/world'\nimport { connect, type RemoteSession, SessionHost, type Transport } from './remote'\n\n/**\n * A game recorded as its start and its commands (`recordGame`'s `kind: 'commands'`), to run again (`playReplay`)\n *\n * @beta\n */\nexport interface CommandReplay {\n\tformat: 2\n\tkind: 'commands'\n\t/** The game it is of, by id: a page plays back what it has */\n\tgame: string\n\t/** The rules it was played with exactly (`registry.hash`): other rules may play it otherwise */\n\trules: string\n\t/** Whose side it is seen from when played back; any side can be, as all of the game is in it */\n\tplayer: PlayerId\n\ttickRate: number\n\t/** The tick it started and ended at */\n\tfrom: number\n\tto: number\n\t/** The world as it was at `from`, as a save (`encodeSave`) */\n\tstart: string\n\t/** What its players told it, each at the tick it was given at, before that tick ran */\n\tcommands: [tick: number, command: IssuedCommand][]\n\t/** The ticks it was saved at: a save puts the crowd back as a load does (D2), so playing back does it there too */\n\tsaves: number[]\n\t/** The world's fingerprint (`worldFingerprint`) every `every` ticks, to tell where a game played back came apart */\n\thashes: [tick: number, hash: string][]\n\t/**\n\t * The world as it was every so many ticks (`recordCommands`' `checkpoints`), as saves: a replay played from a moment\n\t * starts from the last one before it, not from its start. None in a replay made before there were any @beta\n\t */\n\tcheckpoints?: [tick: number, save: string][]\n\t/**\n\t * The players who could use the debug commands as it was recorded (`World.debugPlayers`, which no save keeps): played\n\t * back, they may again, so a game whose cheats were used (the editor's Play here, its map edits pushed) comes to the\n\t * same. None when left out\n\t */\n\tdebug?: PlayerId[]\n}\n\n/**\n * A game being recorded as its commands\n *\n * @beta\n */\nexport interface CommandRecorder {\n\treadonly ticks: number\n\tstop(): CommandReplay\n}\n\n/**\n * Records a world from now as its start and the commands given to it from outside a tick (the players', by a\n * session or a server; a computer player's are its system's, which runs again), with its hash every `every` ticks\n * (300, ten seconds at 30 a second, when left out). Starting takes a save of the world, as saving does (it puts the\n * crowd back as a load does)\n *\n * @beta\n */\nexport function recordCommands(world: World, options: { player: PlayerId; every?: number; checkpoints?: number }): CommandRecorder {\n\tconst every = options.every ?? 300\n\t// a save of the world every so many ticks, to play from a moment without running all before it: none when not asked\n\t// (a save of a full melee is a megabyte, where the whole replay without is a few hundred kilobytes)\n\tconst checkpointEvery = options.checkpoints ?? 0\n\tconst checkpoints: [tick: number, save: string][] = []\n\tconst from = world.tick\n\t// a save to start from: it puts the crowd back as loading it does, so the two go on the same from here\n\tconst start = encodeSave(saveWorld(world))\n\tconst commands: CommandReplay['commands'] = []\n\tconst saves: number[] = []\n\tconst hashes: CommandReplay['hashes'] = []\n\tconst unwatch = world.watch({\n\t\tcommand: (command) => void commands.push([world.tick, structuredClone(command)]),\n\t\tsaved: () => void saves.push(world.tick),\n\t\tstepped: () => {\n\t\t\tif ((world.tick - from) % every === 0) hashes.push([world.tick, worldFingerprint(world)])\n\t\t\t// taken as a save is: played back, a save is taken at that tick too, so the game goes on the same\n\t\t\tif (checkpointEvery > 0 && (world.tick - from) % checkpointEvery === 0) checkpoints.push([world.tick, encodeSave(saveWorld(world))])\n\t\t}\n\t})\n\tlet replay: CommandReplay | undefined\n\treturn {\n\t\tget ticks() {\n\t\t\treturn world.tick - from\n\t\t},\n\t\tstop() {\n\t\t\tif (replay) return replay\n\t\t\tunwatch()\n\t\t\treplay = {\n\t\t\t\tformat: 2,\n\t\t\t\tkind: 'commands',\n\t\t\t\tgame: world.registry.game,\n\t\t\t\trules: world.registry.hash,\n\t\t\t\tplayer: options.player,\n\t\t\t\ttickRate: world.tickRate,\n\t\t\t\tfrom,\n\t\t\t\tto: world.tick,\n\t\t\t\tstart,\n\t\t\t\tcommands,\n\t\t\t\tsaves,\n\t\t\t\thashes,\n\t\t\t\t...(checkpoints.length && { checkpoints }),\n\t\t\t\t...(world.debugPlayers.size > 0 && { debug: [...world.debugPlayers] })\n\t\t\t}\n\t\t\treturn replay\n\t\t}\n\t}\n}\n\n/**\n * A replay of commands run again, to its end or a tick, with no screen: the world as it is then, the first tick whose\n * hash differs from the one kept (none when all were the same), and what differed first at the first checkpoint\n * (`recordCommands`' `checkpoints`) where the world was not the one recorded: the entity and its field\n * (`entities[id 11].pos.x`), and what each held. A replay with no checkpoints says the tick alone. What a test of a\n * replay, and a server checking one, use\n *\n * @beta\n */\nexport async function runReplay(\n\treplay: CommandReplay,\n\toptions: { game: GameModule; to?: number; from?: number; components?: readonly Component<unknown, unknown>[] }\n): Promise<{ world: World; apart: number | null; difference: Apart | null }> {\n\tconst run = await replayRun(replay, options.game, options.from, options.components)\n\trun.stepTo(options.to ?? replay.to)\n\treturn { world: run.world, apart: run.apart, difference: run.difference }\n}\n\n/** A replay of commands being run: its world, stepped on to a tick with what the replay says given at each */\ninterface ReplayRun {\n\treadonly world: World\n\t/** The first tick whose hash differed from the replay's, or whose checkpoint did, or null */\n\treadonly apart: number | null\n\t/** What differed first at the first checkpoint the world was not the one recorded at, or null */\n\treadonly difference: Apart | null\n\t/** Runs the world on to a tick, or until `deadline` (`performance.now()`'s) is past: whether it got there */\n\tstepTo(tick: number, deadline?: number): boolean\n}\n\n/**\n * `components`: those the app kept in the world recorded beside the game's (`CreateWorldOptions.components`: where the\n * screen was played from), without which its saves do not load\n */\nasync function replayRun(\n\treplay: CommandReplay,\n\tgame: GameModule,\n\tat = replay.from,\n\tcomponents?: readonly Component<unknown, unknown>[]\n): Promise<ReplayRun> {\n\t// from the last checkpoint at or before the moment asked for, else from the start\n\tlet checkpoint: [number, string] = [replay.from, replay.start]\n\tfor (const kept of replay.checkpoints ?? []) if (kept[0] <= at && kept[0] > checkpoint[0]) checkpoint = kept\n\tconst [startTick, save0] = checkpoint\n\tconst world = await loadWorld(decodeSave(save0), { game, anyVersion: true, components })\n\t// who could use the debug tools as it was recorded may again: what they did is done the same\n\tfor (const player of replay.debug ?? []) world.debugPlayers.add(player)\n\t// what came before it is in it: the commands given at its tick are still to come (it was taken after the step to it)\n\tlet command = replay.commands.findIndex(([tick]) => tick >= startTick)\n\tif (command < 0) command = replay.commands.length\n\tlet save = replay.saves.findIndex((tick) => tick > startTick)\n\tif (save < 0) save = replay.saves.length\n\tlet hash = replay.hashes.findIndex(([tick]) => tick > startTick)\n\tif (hash < 0) hash = replay.hashes.length\n\t// the checkpoints after the one started from, to compare the whole world with: the hash says when, these say what\n\tconst ahead = (replay.checkpoints ?? []).filter(([tick]) => tick > startTick)\n\tlet next = 0\n\tlet apart: number | null = null\n\tlet difference: Apart | null = null\n\tconst cameApart = (tick: number, what?: string) => {\n\t\tif (apart === null) apart = tick\n\t\tworld.log.warn('replay', `The replay comes apart at tick ${tick}${what ?? ''}: the game is played on as these rules play it`, { tick })\n\t}\n\treturn {\n\t\tworld,\n\t\tget apart() {\n\t\t\treturn apart\n\t\t},\n\t\tget difference() {\n\t\t\treturn difference\n\t\t},\n\t\tstepTo(target, deadline = Infinity) {\n\t\t\tlet steps = 0\n\t\t\twhile (world.tick < Math.min(target, replay.to) && !world.failure) {\n\t\t\t\t// the clock looked at every few steps: a step is a fraction of a millisecond, a look is not free\n\t\t\t\tif (++steps % 8 === 0 && performance.now() > deadline) return false\n\t\t\t\t// what was given before this tick ran, and a save taken then, as they were\n\t\t\t\twhile (command < replay.commands.length && replay.commands[command][0] <= world.tick)\n\t\t\t\t\tworld.issue(structuredClone(replay.commands[command++][1]))\n\t\t\t\twhile (save < replay.saves.length && replay.saves[save] <= world.tick) {\n\t\t\t\t\tsaveWorld(world)\n\t\t\t\t\tsave++\n\t\t\t\t}\n\t\t\t\tworld.step()\n\t\t\t\twhile (hash < replay.hashes.length && replay.hashes[hash][0] < world.tick) hash++\n\t\t\t\tif (hash < replay.hashes.length && replay.hashes[hash][0] === world.tick) {\n\t\t\t\t\tif (apart === null && worldFingerprint(world) !== replay.hashes[hash][1]) cameApart(world.tick)\n\t\t\t\t\thash++\n\t\t\t\t}\n\t\t\t\twhile (next < ahead.length && ahead[next][0] < world.tick) next++\n\t\t\t\tif (difference === null && next < ahead.length && ahead[next][0] === world.tick) {\n\t\t\t\t\t// the world as a file keeps it, beside the one recorded: the first thing they differ in, by entity and field\n\t\t\t\t\tconst now = decodeSave(encodeSave(saveWorld(world, { reseat: false })))\n\t\t\t\t\tconst found = saveDifference(decodeSave(ahead[next][1]), now, world.registry)\n\t\t\t\t\tif (found) {\n\t\t\t\t\t\tdifference = { tick: world.tick, ...found }\n\t\t\t\t\t\tcameApart(world.tick, `, first at ${found.path} (${JSON.stringify(found.a)} recorded, ${JSON.stringify(found.b)} now)`)\n\t\t\t\t\t}\n\t\t\t\t\tnext++\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t}\n}\n\n/**\n * Two ends of a connection in the page, each message given to the other end once what runs now is done (a microtask):\n * in order, with no clock, and never inside the call that sent it\n */\nfunction pair(): [Transport, Transport] {\n\tconst end = () => {\n\t\tlet handler: (message: string) => void = () => {}\n\t\tlet open = true\n\t\tconst transport: Transport & { deliver(message: string): void } = {\n\t\t\tsend: (message) => {\n\t\t\t\tif (open) queueMicrotask(() => other(transport).deliver(message))\n\t\t\t},\n\t\t\tonMessage: (on) => void (handler = on),\n\t\t\tonClose: () => {},\n\t\t\tclose: () => void (open = false),\n\t\t\tdeliver: (message) => {\n\t\t\t\tif (open) handler(message)\n\t\t\t}\n\t\t}\n\t\treturn transport\n\t}\n\tconst a = end()\n\tconst b = end()\n\tconst other = (one: typeof a) => (one === a ? b : a)\n\treturn [a, b]\n}\n\n/** How often a replay being played looks whether its game is due a tick, a second */\nconst LOOKS = 30\n\n/**\n * Milliseconds of a look a replay being played spends running its game on, at most: what a seek has to catch up on\n * (minute 15 is 27,000 ticks from the start) is run a slice a look, the page drawn between them\n *\n * @beta\n */\nexport const REPLAY_SLICE = 12\n\n/**\n * Plays a replay of commands as a watcher's session: its world run again, `speed` times as fast, and served to the\n * session as a host serves one who watches (`SessionHost`), from `player`'s side, or `options.player`'s. A moment\n * asked for (`at`, `skipTo`) is run to a slice a look (`REPLAY_SLICE`), from the last checkpoint before it\n * (`recordCommands`' `checkpoints`) where it is behind: going back starts the world again from there, and the session\n * takes it up where it is (`RemoteSession.resume`). `behind` is how many ticks are still to run to it. `apart` is the\n * tick it came apart from the game recorded at, if it did, and `difference` what differed first at the first\n * checkpoint the world was not the one recorded (`runReplay`)\n *\n * @internal\n */\nexport function playCommands(\n\treplay: CommandReplay,\n\toptions: { game: GameModule; at?: number; player?: PlayerId; components?: readonly Component<unknown, unknown>[] }\n): {\n\tsession: Promise<RemoteSession>\n\treadonly tick: number\n\tspeed: number\n\tskipTo(tick: number): void\n\treadonly behind: number\n\treadonly ended: boolean\n\treadonly apart: number | null\n\treadonly difference: Apart | null\n\tstop(): void\n} {\n\tlet run: ReplayRun | undefined\n\tlet host: SessionHost | undefined\n\tlet timer: ReturnType<typeof setInterval> | undefined\n\tlet stopped = false\n\tconst within = (tick: number) => Math.min(Math.max(tick, replay.from), replay.to)\n\tlet due = within(options.at ?? replay.from)\n\t/** The world made again for a moment behind it, while it is made */\n\tlet going: Promise<void> | undefined\n\tconst watcher = options.player ?? replay.player\n\t/** A host for a world, with the watcher's end of a connection to it: the welcome goes out at once */\n\tconst serve = (world: World) => {\n\t\tconst [served, watching] = pair()\n\t\tconst serving = new SessionHost(world, { sendRate: 10 })\n\t\tserving.connect(watcher, served, { readOnly: true, observer: true })\n\t\treturn { serving, watching }\n\t}\n\tconst made = replayRun(replay, options.game, due, options.components).then((first) => {\n\t\trun = first\n\t\tconst { serving, watching } = serve(first.world)\n\t\thost = serving\n\t\treturn connect(watching, { game: options.game })\n\t})\n\t/** Back to a moment before the world: made again from the last checkpoint before it, and the session taken there */\n\tconst rewind = (session: RemoteSession, to: number) => {\n\t\tgoing = replayRun(replay, options.game, to, options.components)\n\t\t\t.then((again) => {\n\t\t\t\tif (stopped) return again.world.dispose()\n\t\t\t\tconst { serving, watching } = serve(again.world)\n\t\t\t\t// the welcome is on its way: the session hears it as it takes the new end up\n\t\t\t\tconst resumed = session.resume(watching)\n\t\t\t\thost?.dispose()\n\t\t\t\trun?.world.dispose()\n\t\t\t\trun = again\n\t\t\t\thost = serving\n\t\t\t\treturn resumed\n\t\t\t})\n\t\t\t.catch((error: unknown) => run?.world.log.warn('replay', 'The replay could not go back', { error: String(error) }))\n\t\t\t.finally(() => (going = undefined))\n\t}\n\tconst player = {\n\t\tsession: made.then((session) => {\n\t\t\tif (stopped) return session\n\t\t\tlet last = performance.now()\n\t\t\ttimer = setInterval(() => {\n\t\t\t\tconst now = performance.now()\n\t\t\t\tconst seconds = (now - last) / 1000\n\t\t\t\tlast = now\n\t\t\t\tif (going || !run) return\n\t\t\t\t// a moment behind the world: it is made again for it\n\t\t\t\tif (Math.floor(due) < run.world.tick) return rewind(session, Math.floor(due))\n\t\t\t\t// played on from where it is once it is where it was asked to be; what is still to run, a slice a look\n\t\t\t\tif (run.world.tick >= Math.floor(due)) due = Math.min(due + seconds * replay.tickRate * player.speed, replay.to)\n\t\t\t\trun.stepTo(Math.floor(due), now + REPLAY_SLICE)\n\t\t\t\thost!.publish(seconds)\n\t\t\t}, 1000 / LOOKS)\n\t\t\treturn session\n\t\t}),\n\t\tget tick() {\n\t\t\treturn run?.world.tick ?? replay.from\n\t\t},\n\t\tspeed: 1,\n\t\tskipTo(tick: number) {\n\t\t\tdue = within(tick)\n\t\t},\n\t\tget behind() {\n\t\t\tif (going) return Math.max(Math.floor(due) - replay.from, 1)\n\t\t\treturn Math.max(Math.floor(due) - (run?.world.tick ?? replay.from), 0)\n\t\t},\n\t\tget ended() {\n\t\t\treturn (run?.world.tick ?? replay.from) >= replay.to\n\t\t},\n\t\tget apart() {\n\t\t\treturn run?.apart ?? null\n\t\t},\n\t\tget difference() {\n\t\t\treturn run?.difference ?? null\n\t\t},\n\t\tstop() {\n\t\t\tstopped = true\n\t\t\tclearInterval(timer)\n\t\t\thost?.dispose()\n\t\t\trun?.world.dispose()\n\t\t}\n\t}\n\treturn player\n}\n","import { type CommandReplay, playCommands, recordCommands, REPLAY_SLICE } from './commandReplay'\nimport type { PlayerId } from '#engine/entity'\nimport type { GameModule } from '#engine/game'\nimport type { Component } from '#engine/components'\nimport type { World } from '#engine/world'\nimport { connect, type RemoteSession, SessionHost, type Transport } from './remote'\n\n/*\n * Replays: a game as an observer saw it, recorded, and played back. What is recorded is what a host sends someone who\n * watches (the welcome, and what changed after it), with the tick each went out at: played back through the same\n * remote session a watcher has, it shows the game as it was, at any speed. Not the commands run again: the engine does\n * not come back exactly from a save (ground paths, `PLAN.md`), and a run again would drift\n */\n\n/**\n * A game recorded (`recordGame`), to play back (`playReplay`): its commands, run again (`CommandReplay`), or the frames\n * a watcher of it was sent (`FramesReplay`)\n *\n * @beta\n */\nexport type Replay = FramesReplay | CommandReplay\n\n/**\n * A game recorded as the frames a watcher of it was sent: only what `player` saw, and what it was sent of it\n *\n * @beta\n */\nexport interface FramesReplay {\n\tformat: 1\n\t/** The game it is of, by id: a page plays back what it has */\n\tgame: string\n\t/** Whose side it was seen from: their lines and cinematics, everything in sight besides */\n\tplayer: PlayerId\n\ttickRate: number\n\t/** The tick it started and ended at */\n\tfrom: number\n\tto: number\n\t/** What the host sent, as it sent it, with the tick of the world then */\n\tframes: [tick: number, message: string][]\n}\n\n/**\n * A game being recorded\n *\n * @beta\n */\nexport interface ReplayRecorder {\n\t/** Ticks recorded so far */\n\treadonly ticks: number\n\t/** Stops, and gives what was recorded */\n\tstop(): Replay\n}\n\n/**\n * How a game is recorded (`recordGame`): whose side it is seen from when played back, and which kind of replay.\n * `commands` (the default) keeps the start and what the players told it, and plays it back by running it again: a few\n * kilobytes, every side of it, and the same to the last bit while the rules are (determinism D4). `frames` keeps what a\n * watcher from `player`'s side was sent, `sendRate` times a second: for a game whose rules cannot be run again\n *\n * @beta\n */\nexport interface RecordOptions {\n\tplayer: PlayerId\n\tkind?: 'commands' | 'frames'\n\t/** Frames a second, of a `frames` replay: 10 when left out */\n\tsendRate?: number\n\t/** Ticks between the hashes a `commands` replay keeps: 300 when left out */\n\tevery?: number\n\t/**\n\t * Ticks between the checkpoints a `commands` replay keeps (the world as a save, to be played from a moment without\n\t * running all before it: going back, opening it halfway). None when left out: each is as big as a save @beta\n\t */\n\tcheckpoints?: number\n}\n\n/** How often the recorder looks whether the world went on, a second: it keeps what changed at its own rate */\nconst LOOKS = 30\n\n/**\n * The tick a message says it brings, to answer that it got there: of a delta, from the head of its text where it comes\n * first; of the welcome, of the first frame it carries\n */\nconst tickOf = (message: string): number | undefined => {\n\tconst found =\n\t\t/^\\{\"type\":\"delta\",\"tick\":(\\d+)/.exec(message) ?? (message.startsWith('{\"type\":\"welcome\"') ? /\"first\":\\{\"tick\":(\\d+)/.exec(message) : null)\n\treturn found ? Number(found[1]) : undefined\n}\n\n/**\n * Records a game played in the page (`RecordOptions`): as its start and its players' commands (`kind: 'commands'`,\n * the default: `recordCommands`), or as an observer from `player`'s side sees it, what changed `sendRate` times a\n * second (`kind: 'frames'`). Frames are answered at once, as by a watcher who missed nothing, so what is kept is what\n * changed and not the whole world again\n *\n * @beta\n */\nexport function recordGame(world: World, options: RecordOptions): ReplayRecorder {\n\tif ((options.kind ?? 'commands') === 'commands') return recordCommands(world, options)\n\tconst host = new SessionHost(world, { sendRate: options.sendRate ?? 10 })\n\tconst frames: FramesReplay['frames'] = []\n\tconst from = world.tick\n\tlet answer: (text: string) => void = () => {}\n\tconst transport: Transport = {\n\t\tsend(message) {\n\t\t\tframes.push([world.tick, message])\n\t\t\tconst tick = tickOf(message)\n\t\t\tif (tick !== undefined) answer(JSON.stringify({ type: 'ack', tick }))\n\t\t},\n\t\tonMessage: (handler) => (answer = handler),\n\t\tonClose: () => {},\n\t\tclose: () => {}\n\t}\n\thost.connect(options.player, transport, { readOnly: true, observer: true })\n\tlet last = performance.now()\n\tconst timer = setInterval(() => {\n\t\tconst now = performance.now()\n\t\thost.publish((now - last) / 1000)\n\t\tlast = now\n\t}, 1000 / LOOKS)\n\tlet replay: FramesReplay | undefined\n\treturn {\n\t\tget ticks() {\n\t\t\treturn world.tick - from\n\t\t},\n\t\tstop() {\n\t\t\tif (replay) return replay\n\t\t\tclearInterval(timer)\n\t\t\thost.dispose()\n\t\t\treplay = { format: 1, game: world.registry.game, player: options.player, tickRate: world.tickRate, from, to: world.tick, frames }\n\t\t\treturn replay\n\t\t}\n\t}\n}\n\n/**\n * A replay playing (`playReplay`): its session, and its clock\n *\n * @beta\n */\nexport interface ReplayPlayer {\n\t/** The game as it was, once the welcome is in */\n\tsession: Promise<RemoteSession>\n\t/** The tick of the game it is at */\n\treadonly tick: number\n\t/** How fast it plays: 1 as it was played, 0 holds it */\n\tspeed: number\n\t/**\n\t * Goes to a tick, ahead or back, run (or handed over) a slice a look (`REPLAY_SLICE`) so that the page goes on\n\t * meanwhile: `behind` says how much is left. Back starts again in the same session (`RemoteSession.resume`): a\n\t * replay of commands from the last checkpoint before the tick, one of frames from its start\n\t */\n\tskipTo(tick: number): void\n\t/** Ticks still to run (or hand over) to come to the moment asked, by a seek or a fast speed: 0 while it keeps up */\n\treadonly behind: number\n\t/** Whether all of it has played */\n\treadonly ended: boolean\n\t/**\n\t * Of a replay of commands, the tick it came apart from the game recorded at (its hash differed: the rules changed\n\t * since), or null while it has not. Never for a replay of frames\n\t */\n\treadonly apart?: number | null\n\tstop(): void\n}\n\n/**\n * Plays a replay back, as a watcher's session (`connect`): a replay of commands run again (`playCommands`), or what the\n * host sent coming in as it came, by the replay's ticks; `speed` times as fast. `game` is the game module it is of, or\n * the modules the page has, by id\n *\n * @beta\n */\nexport function playReplay(\n\treplay: Replay,\n\toptions: {\n\t\tgame: GameModule | Record<string, GameModule>\n\t\tat?: number\n\t\t/** What the app kept in the world beside the game's (`CreateWorldOptions.components`): a replay of commands loads its saves with them */\n\t\tcomponents?: readonly Component<unknown, unknown>[]\n\t}\n): ReplayPlayer {\n\tif (replay.format === 2) {\n\t\tconst games = options.game\n\t\tconst game = 'units' in games && typeof games.id === 'string' ? (games as GameModule) : (games as Record<string, GameModule>)[replay.game]\n\t\tif (!game) throw new Error(`This page does not have the game the replay is of (${replay.game})`)\n\t\treturn playCommands(replay, { game, at: options.at, components: options.components })\n\t}\n\tlet deliver: (text: string) => void = () => {}\n\t// what a watcher says back (that it got a tick, a ping) goes nowhere: nothing is playing at the other end\n\tconst watching = (): Transport => ({ send: () => {}, onMessage: (handler) => void (deliver = handler), onClose: () => {}, close: () => {} })\n\tconst within = (tick: number) => Math.min(Math.max(tick, replay.from), replay.to)\n\tlet next = 0\n\t/** The moment it is asked to be at: the clock, or where a seek goes */\n\tlet due = within(options.at ?? replay.from)\n\tlet last = performance.now()\n\t/** The tick of the last frame handed to the session */\n\tconst shown = () => (next > 0 ? replay.frames[next - 1][0] : replay.from)\n\t/** Whether frames are still to be handed over to come to the moment asked */\n\tconst pending = () => next < replay.frames.length && replay.frames[next][0] <= due\n\tlet session: RemoteSession | undefined\n\tconst player: ReplayPlayer = {\n\t\tsession: connect(watching(), { game: options.game }),\n\t\tget tick() {\n\t\t\treturn pending() ? shown() : due\n\t\t},\n\t\tspeed: 1,\n\t\tskipTo(target) {\n\t\t\tdue = within(target)\n\t\t\t// back: what changed is told against what came before it, so the session takes it all again from the welcome\n\t\t\tif (session && due < shown()) {\n\t\t\t\tnext = 0\n\t\t\t\tvoid session.resume(watching()).catch(() => undefined)\n\t\t\t\tdeliver(replay.frames[next++]?.[1] ?? '')\n\t\t\t}\n\t\t},\n\t\tget behind() {\n\t\t\treturn pending() ? Math.max(Math.floor(due) - shown(), 1) : 0\n\t\t},\n\t\tget ended() {\n\t\t\treturn next >= replay.frames.length\n\t\t},\n\t\tstop() {\n\t\t\tstopped = true\n\t\t\tclearInterval(timer)\n\t\t}\n\t}\n\t/** Hands the session the frames up to the moment asked, until `deadline` is past */\n\tconst flush = (deadline: number) => {\n\t\tlet handed = 0\n\t\twhile (pending()) {\n\t\t\tdeliver(replay.frames[next++][1])\n\t\t\tif (++handed % 16 === 0 && performance.now() > deadline) return\n\t\t}\n\t}\n\t// the welcome at once; the rest once the session has made its map of it, from where it is to start, a slice a look\n\tlet timer: ReturnType<typeof setInterval> | undefined\n\tlet stopped = false\n\tdeliver(replay.frames[next++]?.[1] ?? '')\n\tplayer.session.then(\n\t\t(made) => {\n\t\t\tif (stopped) return\n\t\t\tsession = made\n\t\t\tlast = performance.now()\n\t\t\ttimer = setInterval(() => {\n\t\t\t\tconst now = performance.now()\n\t\t\t\tif (!pending()) due = Math.min(due + ((now - last) / 1000) * replay.tickRate * player.speed, replay.to)\n\t\t\t\tlast = now\n\t\t\t\tflush(now + REPLAY_SLICE)\n\t\t\t}, 1000 / LOOKS)\n\t\t},\n\t\t() => undefined\n\t)\n\treturn player\n}\n"],"mappings":"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"}