@v12-engine/engine 0.0.0-stage → 0.1.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 (341) hide show
  1. package/LICENSE +21 -0
  2. package/dist/abilities/buffs.d.ts +83 -0
  3. package/dist/abilities/castTold.d.ts +12 -0
  4. package/dist/abilities/charges.d.ts +28 -0
  5. package/dist/abilities/dispel.d.ts +9 -0
  6. package/dist/abilities/effectFields.d.ts +10 -0
  7. package/dist/abilities/effects/buff.d.ts +8 -0
  8. package/dist/abilities/effects/core.d.ts +1 -0
  9. package/dist/abilities/effects/damage.d.ts +1 -0
  10. package/dist/abilities/effects/heal.d.ts +2 -0
  11. package/dist/abilities/effects/missile.d.ts +1 -0
  12. package/dist/abilities/effects/moves.d.ts +11 -0
  13. package/dist/abilities/effects/passives.d.ts +15 -0
  14. package/dist/abilities/effects/sight.d.ts +4 -0
  15. package/dist/abilities/effects/spawn.d.ts +2 -0
  16. package/dist/abilities/effects/timed.d.ts +4 -0
  17. package/dist/abilities/effects/trade.d.ts +1 -0
  18. package/dist/abilities/effects.d.ts +122 -0
  19. package/dist/abilities/land.d.ts +21 -0
  20. package/dist/abilities/scaled.d.ts +21 -0
  21. package/dist/abilities/text.d.ts +113 -0
  22. package/dist/ai/area.d.ts +53 -0
  23. package/dist/ai/brain.d.ts +528 -0
  24. package/dist/ai/budget.d.ts +67 -0
  25. package/dist/ai/checks.d.ts +115 -0
  26. package/dist/ai/computer.d.ts +166 -0
  27. package/dist/ai/defence.d.ts +108 -0
  28. package/dist/ai/define.d.ts +21 -0
  29. package/dist/ai/economy.d.ts +129 -0
  30. package/dist/ai/geometry.d.ts +35 -0
  31. package/dist/ai/goals.d.ts +360 -0
  32. package/dist/ai/index.d.ts +38 -0
  33. package/dist/ai/knowledge.d.ts +418 -0
  34. package/dist/ai/lanes.d.ts +232 -0
  35. package/dist/ai/melee/build.d.ts +61 -0
  36. package/dist/ai/melee/goals.d.ts +299 -0
  37. package/dist/ai/melee/heroes.d.ts +27 -0
  38. package/dist/ai/melee/index.d.ts +14 -0
  39. package/dist/ai/melee/production.d.ts +8 -0
  40. package/dist/ai/melee/surrender.d.ts +24 -0
  41. package/dist/ai/micro.d.ts +278 -0
  42. package/dist/ai/mission.d.ts +195 -0
  43. package/dist/ai/missionRules.d.ts +18 -0
  44. package/dist/ai/module.d.ts +116 -0
  45. package/dist/ai/options.d.ts +61 -0
  46. package/dist/ai/plans/build.d.ts +280 -0
  47. package/dist/ai/plans/placement.d.ts +82 -0
  48. package/dist/ai/plans/plans.d.ts +105 -0
  49. package/dist/ai/plans/production.d.ts +210 -0
  50. package/dist/ai/plans/purse.d.ts +73 -0
  51. package/dist/ai/plans/tech.d.ts +37 -0
  52. package/dist/ai/profiles.d.ts +204 -0
  53. package/dist/ai/reach.d.ts +4 -0
  54. package/dist/ai/report.d.ts +203 -0
  55. package/dist/ai/roles.d.ts +133 -0
  56. package/dist/ai/rules.d.ts +288 -0
  57. package/dist/ai/scouting.d.ts +98 -0
  58. package/dist/ai/settings.d.ts +73 -0
  59. package/dist/ai/squads.d.ts +429 -0
  60. package/dist/ai/strength.d.ts +167 -0
  61. package/dist/ai/task.d.ts +118 -0
  62. package/dist/ai/tasks/attack.d.ts +7 -0
  63. package/dist/ai/tasks/capture.d.ts +21 -0
  64. package/dist/ai/tasks/creep.d.ts +16 -0
  65. package/dist/ai/tasks/defend.d.ts +29 -0
  66. package/dist/ai/tasks/drop.d.ts +34 -0
  67. package/dist/ai/tasks/escort.d.ts +16 -0
  68. package/dist/ai/tasks/gather.d.ts +23 -0
  69. package/dist/ai/tasks/harass.d.ts +7 -0
  70. package/dist/ai/tasks/hold.d.ts +20 -0
  71. package/dist/ai/tasks/index.d.ts +32 -0
  72. package/dist/ai/tasks/move.d.ts +19 -0
  73. package/dist/ai/tasks/patrol.d.ts +8 -0
  74. package/dist/ai/tasks/retreat.d.ts +20 -0
  75. package/dist/ai/tasks/scout.d.ts +29 -0
  76. package/dist/ai/tasks/shared.d.ts +74 -0
  77. package/dist/ai/team.d.ts +155 -0
  78. package/dist/ai/threat.d.ts +91 -0
  79. package/dist/ai/view.d.ts +366 -0
  80. package/dist/ai/waves.d.ts +126 -0
  81. package/dist/ai.js +6239 -0
  82. package/dist/ai.js.map +1 -0
  83. package/dist/aiTesting.d.ts +179 -0
  84. package/dist/areas.d.ts +149 -0
  85. package/dist/attacks.d.ts +66 -0
  86. package/dist/attributes.d.ts +66 -0
  87. package/dist/brain-BvVdUhX8.js +7659 -0
  88. package/dist/brain-BvVdUhX8.js.map +1 -0
  89. package/dist/builds-C6LfgvEU.js +460 -0
  90. package/dist/builds-C6LfgvEU.js.map +1 -0
  91. package/dist/bytes.d.ts +6 -0
  92. package/dist/camps.d.ts +95 -0
  93. package/dist/capture.d.ts +131 -0
  94. package/dist/cellLayers.d.ts +75 -0
  95. package/dist/cinematics.d.ts +194 -0
  96. package/dist/clock.d.ts +32 -0
  97. package/dist/commands.d.ts +235 -0
  98. package/dist/components.d.ts +184 -0
  99. package/dist/computers.d.ts +108 -0
  100. package/dist/concealment.d.ts +61 -0
  101. package/dist/coreComponents-syuh2fPG.js +5149 -0
  102. package/dist/coreComponents-syuh2fPG.js.map +1 -0
  103. package/dist/coreComponents.d.ts +1 -0
  104. package/dist/dashing.d.ts +8 -0
  105. package/dist/debug.d.ts +36 -0
  106. package/dist/debug.js +3 -0
  107. package/dist/debugCommands-CzjrSm66.js +14739 -0
  108. package/dist/debugCommands-CzjrSm66.js.map +1 -0
  109. package/dist/debugCommands.d.ts +213 -0
  110. package/dist/debugging.d.ts +10 -0
  111. package/dist/definitions.d.ts +43 -0
  112. package/dist/defs.d.ts +1162 -0
  113. package/dist/denying.d.ts +81 -0
  114. package/dist/destructibles.d.ts +27 -0
  115. package/dist/determinism-BCymQwiE.js +518 -0
  116. package/dist/determinism-BCymQwiE.js.map +1 -0
  117. package/dist/determinism.d.ts +121 -0
  118. package/dist/dialog.d.ts +94 -0
  119. package/dist/effectRefs.d.ts +16 -0
  120. package/dist/effects.d.ts +80 -0
  121. package/dist/endings.d.ts +22 -0
  122. package/dist/engagement.d.ts +108 -0
  123. package/dist/engineEvents.d.ts +710 -0
  124. package/dist/entity.d.ts +409 -0
  125. package/dist/entityIndex.d.ts +50 -0
  126. package/dist/errors.d.ts +85 -0
  127. package/dist/events.d.ts +97 -0
  128. package/dist/exactMath.d.ts +63 -0
  129. package/dist/features.d.ts +10 -0
  130. package/dist/fields.d.ts +114 -0
  131. package/dist/fixture.d.ts +17 -0
  132. package/dist/fog.d.ts +110 -0
  133. package/dist/formation.d.ts +111 -0
  134. package/dist/friendlyFire.d.ts +26 -0
  135. package/dist/game-DiJEN-Ks.js +5800 -0
  136. package/dist/game-DiJEN-Ks.js.map +1 -0
  137. package/dist/game.d.ts +501 -0
  138. package/dist/gameData.d.ts +325 -0
  139. package/dist/gameFiles.d.ts +26 -0
  140. package/dist/gates.d.ts +28 -0
  141. package/dist/generate.d.ts +403 -0
  142. package/dist/generateWorker.d.ts +39 -0
  143. package/dist/grid.d.ts +53 -0
  144. package/dist/ground.d.ts +127 -0
  145. package/dist/groundSpeed.d.ts +22 -0
  146. package/dist/hero.d.ts +177 -0
  147. package/dist/home.d.ts +14 -0
  148. package/dist/hooks.d.ts +780 -0
  149. package/dist/hotReload.d.ts +76 -0
  150. package/dist/ids.d.ts +26 -0
  151. package/dist/index.d.ts +227 -0
  152. package/dist/index.js +4701 -0
  153. package/dist/index.js.map +1 -0
  154. package/dist/inspect-D9dWHmZ0.js +491 -0
  155. package/dist/inspect-D9dWHmZ0.js.map +1 -0
  156. package/dist/inspect.d.ts +176 -0
  157. package/dist/inventory.d.ts +18 -0
  158. package/dist/items.d.ts +91 -0
  159. package/dist/lanes.d.ts +213 -0
  160. package/dist/life.d.ts +53 -0
  161. package/dist/local-Dkovq42k.js +1379 -0
  162. package/dist/local-Dkovq42k.js.map +1 -0
  163. package/dist/log.d.ts +140 -0
  164. package/dist/manaBurn.d.ts +39 -0
  165. package/dist/map/file.d.ts +114 -0
  166. package/dist/map/images.d.ts +18 -0
  167. package/dist/map/look.d.ts +47 -0
  168. package/dist/map/pathProfile.d.ts +13 -0
  169. package/dist/map/resize.d.ts +54 -0
  170. package/dist/map/schema.d.ts +10 -0
  171. package/dist/map/terrain.d.ts +32 -0
  172. package/dist/map/types.d.ts +613 -0
  173. package/dist/map.d.ts +7 -0
  174. package/dist/mapCheck/cells.d.ts +19 -0
  175. package/dist/mapCheck/rule.d.ts +30 -0
  176. package/dist/mapCheck/rules/names.d.ts +3 -0
  177. package/dist/mapCheck/rules/objects.d.ts +3 -0
  178. package/dist/mapCheck/rules/paths.d.ts +3 -0
  179. package/dist/mapCheck/rules/players.d.ts +3 -0
  180. package/dist/mapCheck/rules/races.d.ts +3 -0
  181. package/dist/mapCheck/rules/random.d.ts +3 -0
  182. package/dist/mapCheck/rules/regions.d.ts +3 -0
  183. package/dist/mapCheck/rules/targets.d.ts +3 -0
  184. package/dist/mapCheck/rules/walking.d.ts +3 -0
  185. package/dist/mapCheck.d.ts +23 -0
  186. package/dist/mapFields.d.ts +364 -0
  187. package/dist/mapFile.d.ts +23 -0
  188. package/dist/mapMeasure.d.ts +95 -0
  189. package/dist/mapMerge.d.ts +19 -0
  190. package/dist/mapObjectives.d.ts +82 -0
  191. package/dist/mapObjects.d.ts +1 -0
  192. package/dist/math.d.ts +44 -0
  193. package/dist/messages.d.ts +150 -0
  194. package/dist/missionRules-C-bGxm0Q.js +523 -0
  195. package/dist/missionRules-C-bGxm0Q.js.map +1 -0
  196. package/dist/missionRules.d.ts +179 -0
  197. package/dist/mods.d.ts +146 -0
  198. package/dist/names.d.ts +93 -0
  199. package/dist/navigation/agentParams.d.ts +4 -0
  200. package/dist/navigation/air.d.ts +89 -0
  201. package/dist/navigation/builds.d.ts +140 -0
  202. package/dist/navigation/groundAreas.d.ts +23 -0
  203. package/dist/navigation/navigation.d.ts +127 -0
  204. package/dist/navigation/recast.d.ts +214 -0
  205. package/dist/navigation/sidePaths.d.ts +69 -0
  206. package/dist/navigation/sized.d.ts +1 -0
  207. package/dist/navigation-worker.js +11 -0
  208. package/dist/navigation-worker.js.map +1 -0
  209. package/dist/nearest.d.ts +8 -0
  210. package/dist/noise.d.ts +12 -0
  211. package/dist/objectives.d.ts +93 -0
  212. package/dist/orders/basic.d.ts +96 -0
  213. package/dist/orders/build.d.ts +91 -0
  214. package/dist/orders/cast.d.ts +105 -0
  215. package/dist/orders/facts.d.ts +14 -0
  216. package/dist/orders/harvest.d.ts +94 -0
  217. package/dist/orders/idle.d.ts +7 -0
  218. package/dist/orders/items.d.ts +14 -0
  219. package/dist/orders/queue.d.ts +24 -0
  220. package/dist/pack.schema.json +6621 -0
  221. package/dist/packs/director/index.d.ts +81 -0
  222. package/dist/packs/heroes/campaign.d.ts +137 -0
  223. package/dist/packs/heroes/carry.d.ts +59 -0
  224. package/dist/packs/heroes/commands.d.ts +6 -0
  225. package/dist/packs/heroes/hire.d.ts +9 -0
  226. package/dist/packs/heroes/index.d.ts +12 -0
  227. package/dist/packs/heroes/making.d.ts +16 -0
  228. package/dist/packs/heroes/respawn.d.ts +42 -0
  229. package/dist/packs/moba/index.d.ts +34 -0
  230. package/dist/packs/pack.d.ts +84 -0
  231. package/dist/packs-g5thvmGn.js +3199 -0
  232. package/dist/packs-g5thvmGn.js.map +1 -0
  233. package/dist/packs.d.ts +84 -0
  234. package/dist/paths.d.ts +51 -0
  235. package/dist/plain.d.ts +17 -0
  236. package/dist/player.d.ts +117 -0
  237. package/dist/portals.d.ts +66 -0
  238. package/dist/prefabs.d.ts +139 -0
  239. package/dist/presetBuildings.d.ts +52 -0
  240. package/dist/presetGround.d.ts +22 -0
  241. package/dist/profiles-B3NS9jwk.js +335 -0
  242. package/dist/profiles-B3NS9jwk.js.map +1 -0
  243. package/dist/races.d.ts +136 -0
  244. package/dist/randomGroups.d.ts +2 -0
  245. package/dist/registry.d.ts +464 -0
  246. package/dist/remains.d.ts +119 -0
  247. package/dist/replication.d.ts +103 -0
  248. package/dist/rng.d.ts +17 -0
  249. package/dist/rules.d.ts +395 -0
  250. package/dist/rulesCheck.d.ts +37 -0
  251. package/dist/runes.d.ts +41 -0
  252. package/dist/save.d.ts +277 -0
  253. package/dist/scenario.d.ts +56 -0
  254. package/dist/scheduler.d.ts +67 -0
  255. package/dist/score.d.ts +306 -0
  256. package/dist/sequences.d.ts +132 -0
  257. package/dist/server/doorman.d.ts +21 -0
  258. package/dist/server/gameServer.d.ts +346 -0
  259. package/dist/server/index.d.ts +24 -0
  260. package/dist/server/lobby.d.ts +1 -0
  261. package/dist/server/log.d.ts +13 -0
  262. package/dist/server/match.d.ts +24 -0
  263. package/dist/server/mode.d.ts +168 -0
  264. package/dist/server/navigation-worker.d.ts +1 -0
  265. package/dist/server/navigation.d.ts +11 -0
  266. package/dist/server/ops.d.ts +78 -0
  267. package/dist/server/packs.d.ts +15 -0
  268. package/dist/server/ratings.d.ts +62 -0
  269. package/dist/server/relay.d.ts +34 -0
  270. package/dist/server/rooms.d.ts +162 -0
  271. package/dist/server/seat.d.ts +2 -0
  272. package/dist/server/seatSettings.d.ts +15 -0
  273. package/dist/server/secret.d.ts +5 -0
  274. package/dist/server/start.d.ts +54 -0
  275. package/dist/server/websocket.d.ts +74 -0
  276. package/dist/server.js +2861 -0
  277. package/dist/server.js.map +1 -0
  278. package/dist/session/can.d.ts +20 -0
  279. package/dist/session/commandReplay.d.ts +92 -0
  280. package/dist/session/debug.d.ts +65 -0
  281. package/dist/session/delay.d.ts +15 -0
  282. package/dist/session/delta.d.ts +98 -0
  283. package/dist/session/entityState.d.ts +1 -0
  284. package/dist/session/local.d.ts +214 -0
  285. package/dist/session/memory.d.ts +27 -0
  286. package/dist/session/protocol.d.ts +1155 -0
  287. package/dist/session/remote.d.ts +530 -0
  288. package/dist/session/replay.d.ts +114 -0
  289. package/dist/session/seed.d.ts +7 -0
  290. package/dist/session/share.d.ts +78 -0
  291. package/dist/session/socket.d.ts +8 -0
  292. package/dist/session/wire.d.ts +153 -0
  293. package/dist/session/worker.d.ts +227 -0
  294. package/dist/shared.d.ts +171 -0
  295. package/dist/sides.d.ts +75 -0
  296. package/dist/sight.d.ts +27 -0
  297. package/dist/simulate-oXBiw1Ff.js +167 -0
  298. package/dist/simulate-oXBiw1Ff.js.map +1 -0
  299. package/dist/simulate-worker.d.ts +1 -0
  300. package/dist/simulate-worker.js +28 -0
  301. package/dist/simulate-worker.js.map +1 -0
  302. package/dist/simulate.d.ts +154 -0
  303. package/dist/smart.d.ts +9 -0
  304. package/dist/spatial.d.ts +62 -0
  305. package/dist/spawning.d.ts +33 -0
  306. package/dist/stances.d.ts +76 -0
  307. package/dist/start.d.ts +71 -0
  308. package/dist/stats.d.ts +122 -0
  309. package/dist/summons.d.ts +63 -0
  310. package/dist/systems/abilities.d.ts +3 -0
  311. package/dist/systems/combat.d.ts +71 -0
  312. package/dist/systems/combatTold.d.ts +14 -0
  313. package/dist/systems/construction.d.ts +34 -0
  314. package/dist/systems/economy.d.ts +21 -0
  315. package/dist/systems/fog.d.ts +19 -0
  316. package/dist/systems/life.d.ts +3 -0
  317. package/dist/systems/movement.d.ts +105 -0
  318. package/dist/systems/orders.d.ts +7 -0
  319. package/dist/systems/production.d.ts +49 -0
  320. package/dist/systems/productionQueue.d.ts +40 -0
  321. package/dist/systems/victory.d.ts +14 -0
  322. package/dist/talk.d.ts +65 -0
  323. package/dist/tech.d.ts +62 -0
  324. package/dist/techTree.d.ts +38 -0
  325. package/dist/terrain.d.ts +173 -0
  326. package/dist/terrainSave.d.ts +29 -0
  327. package/dist/testing.d.ts +58 -0
  328. package/dist/testing.js +822 -0
  329. package/dist/testing.js.map +1 -0
  330. package/dist/tiles.d.ts +34 -0
  331. package/dist/timers.d.ts +146 -0
  332. package/dist/tomes.d.ts +48 -0
  333. package/dist/trade.d.ts +28 -0
  334. package/dist/transport.d.ts +76 -0
  335. package/dist/tunables.d.ts +45 -0
  336. package/dist/upkeep.d.ts +16 -0
  337. package/dist/veterancy.d.ts +80 -0
  338. package/dist/walls.d.ts +86 -0
  339. package/dist/world.d.ts +1118 -0
  340. package/package.json +80 -5
  341. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../src/fixture.ts","../src/aiTesting.ts","../src/testing.ts"],"sourcesContent":["/**\n * The fixture game: the smallest game the engine's kit has a part for each of its roles in (a hall and its workers,\n * supply, a barracks of a fighter and an archer, a tower, an altar and a hero, a gold mine and trees, a creep, an\n * upgrade, abilities and items), for the engine's own tests and a game's. Its numbers are round (health 100 or 200,\n * damage 10, speed 4) so that what a test expects reads as what it means: a soldier hits an archer ten times\n */\nimport type { AbilityDef, BuffDef, ItemDef, UnitTypeDef, UpgradeDef } from './defs'\nimport type { GameModule } from './game'\nimport { createMap, type GameMap } from './map'\nimport { dist, type Vec2 } from './math'\nimport { withHeroes } from './packs/heroes'\nimport type { PlayerId } from './entity'\nimport type { World } from './world'\n\nconst worker: UnitTypeDef = {\n\tid: 'worker',\n\tname: 'Worker',\n\tkind: 'unit',\n\tradius: 0.4,\n\tstats: { health: 100, attackDamage: 5, attackSpeed: 1, attackRange: 0.5, moveSpeed: 4 },\n\tsight: 8,\n\tattacks: [{ damagePoint: 0.3, acquisitionRange: 0, targets: ['unit', 'building'] }],\n\tcost: { gold: 50 },\n\tsupply: 1,\n\tbuildTime: 10,\n\tharvester: { capacity: 10, gatherTime: 1 },\n\tbuilds: ['hall', 'supply', 'barracks', 'tower', 'altar']\n}\n\nconst soldier: UnitTypeDef = {\n\tid: 'soldier',\n\tname: 'Soldier',\n\tkind: 'unit',\n\tradius: 0.45,\n\tstats: { health: 200, attackDamage: 10, attackSpeed: 1, attackRange: 0.5, armor: 10, moveSpeed: 4 },\n\tsight: 10,\n\tattacks: [{ damagePoint: 0.3, acquisitionRange: 8 }],\n\tcost: { gold: 100 },\n\tsupply: 2,\n\tbuildTime: 10,\n\tabilities: ['guard']\n}\n\nconst archer: UnitTypeDef = {\n\tid: 'archer',\n\tname: 'Archer',\n\tkind: 'unit',\n\tradius: 0.45,\n\tstats: { health: 100, attackDamage: 10, attackSpeed: 1, attackRange: 6, moveSpeed: 4 },\n\tsight: 10,\n\tattacks: [{ damagePoint: 0.3, acquisitionRange: 8, projectileSpeed: 20, targets: ['ground', 'air'] }],\n\tcost: { gold: 100, lumber: 20 },\n\tsupply: 2,\n\tbuildTime: 10\n}\n\nconst hero: UnitTypeDef = {\n\tid: 'hero',\n\tname: 'Hero',\n\tkind: 'unit',\n\tradius: 0.5,\n\tstats: { health: 300, mana: 100, manaRegen: 1, attackDamage: 20, attackSpeed: 1, attackRange: 0.5, armor: 10, moveSpeed: 4 },\n\tsight: 12,\n\tattacks: [{ damagePoint: 0.3, acquisitionRange: 8 }],\n\thero: { growth: { stats: { health: 20, mana: 10, attackDamage: 2 } }, learns: ['heal', 'guard'] },\n\tinventory: 6,\n\tcost: { gold: 400, lumber: 100 },\n\tsupply: 5,\n\tbuildTime: 40\n}\n\nconst creep: UnitTypeDef = {\n\tid: 'creep',\n\tname: 'Creep',\n\tkind: 'unit',\n\tradius: 0.45,\n\tstats: { health: 200, attackDamage: 10, attackSpeed: 1, attackRange: 0.5, moveSpeed: 3 },\n\tsight: 8,\n\tattacks: [{ damagePoint: 0.3, acquisitionRange: 5 }],\n\tlevel: 1,\n\tbounty: [10, 10],\n\txp: 20\n}\n\nconst hall: UnitTypeDef = {\n\tid: 'hall',\n\tname: 'Hall',\n\tkind: 'building',\n\tradius: 2,\n\tfootprint: { w: 4, d: 4 },\n\tstats: { health: 1500, armor: 10 },\n\tsight: 12,\n\tcost: { gold: 400, lumber: 200 },\n\tbuildTime: 40,\n\tsupplyProvided: 10,\n\ttrains: ['worker'],\n\tdropOff: true,\n\tupgradesTo: 'keep'\n}\n\nconst keep: UnitTypeDef = {\n\t...hall,\n\tid: 'keep',\n\tname: 'Keep',\n\tstats: { health: 2000, armor: 10 },\n\tcost: { gold: 300, lumber: 200 },\n\tprovides: ['hall'],\n\tupgradesTo: undefined\n}\n\nconst supply: UnitTypeDef = {\n\tid: 'supply',\n\tname: 'Supply',\n\tkind: 'building',\n\tradius: 1,\n\tfootprint: { w: 2, d: 2 },\n\tstats: { health: 500, armor: 10 },\n\tsight: 6,\n\tcost: { gold: 50 },\n\tbuildTime: 10,\n\tsupplyProvided: 10\n}\n\nconst barracks: UnitTypeDef = {\n\tid: 'barracks',\n\tname: 'Barracks',\n\tkind: 'building',\n\tradius: 1.5,\n\tfootprint: { w: 3, d: 3 },\n\tstats: { health: 1000, armor: 10 },\n\tsight: 9,\n\tcost: { gold: 150, lumber: 50 },\n\tbuildTime: 20,\n\ttrains: ['soldier', 'archer'],\n\tresearches: ['armour']\n}\n\nconst tower: UnitTypeDef = {\n\tid: 'tower',\n\tname: 'Tower',\n\tkind: 'building',\n\tradius: 1,\n\tfootprint: { w: 2, d: 2 },\n\tstats: { health: 500, attackDamage: 20, attackSpeed: 1, attackRange: 8, armor: 10 },\n\tsight: 12,\n\tattacks: [{ damagePoint: 0.3, acquisitionRange: 8, projectileSpeed: 20, targets: ['ground', 'air'] }],\n\tcost: { gold: 100, lumber: 50 },\n\tbuildTime: 20,\n\trequires: ['barracks']\n}\n\nconst altar: UnitTypeDef = {\n\tid: 'altar',\n\tname: 'Altar',\n\tkind: 'building',\n\tradius: 1.5,\n\tfootprint: { w: 3, d: 3 },\n\tstats: { health: 1000, armor: 10 },\n\tsight: 9,\n\tcost: { gold: 200, lumber: 50 },\n\tbuildTime: 30,\n\ttrains: ['hero'],\n\trevives: true\n}\n\nconst mine: UnitTypeDef = {\n\tid: 'mine',\n\tname: 'Mine',\n\tkind: 'resource',\n\tradius: 2,\n\tfootprint: { w: 4, d: 4 },\n\tstats: { health: 1 },\n\tsight: 0,\n\tinvulnerable: true,\n\tresource: { kind: 'gold', amount: 10000, slots: 1, entered: true }\n}\n\nconst tree: UnitTypeDef = {\n\tid: 'tree',\n\tname: 'Tree',\n\tkind: 'resource',\n\tradius: 0.5,\n\tfootprint: { w: 1, d: 1 },\n\tstats: { health: 1 },\n\tsight: 0,\n\tinvulnerable: true,\n\tfellable: true,\n\tresource: { kind: 'lumber', amount: 50, slots: 1, gatherTime: 5 }\n}\n\nconst armour: UpgradeDef = {\n\tid: 'armour',\n\tname: 'Armour',\n\tdescription: '+10 armor for soldiers and archers',\n\tcost: { gold: 100, lumber: 50 },\n\tresearchTime: 20,\n\tmaxLevel: 2,\n\teffects: [{ units: ['soldier', 'archer'], stats: { armor: 10 } }]\n}\n\nconst guarded: BuffDef = { id: 'guarded', name: 'Guarded', description: '+20 armor', duration: 10, stats: { armor: 20 } }\n\nconst abilities: AbilityDef[] = [\n\t{\n\t\tid: 'heal',\n\t\tname: 'Heal',\n\t\tdescription: 'Heals a friendly unit for 100 or 200',\n\t\ttarget: 'unit',\n\t\ttargets: { allies: true, self: false },\n\t\tmanaCost: 10,\n\t\tcooldown: 5,\n\t\trange: 6,\n\t\teffects: [{ type: 'heal', amount: [100, 200] }]\n\t},\n\t{\n\t\tid: 'guard',\n\t\tname: 'Guard',\n\t\tdescription: '+20 armor for 10 seconds',\n\t\ttarget: 'none',\n\t\tcooldown: 10,\n\t\teffects: [{ type: 'buff', buff: 'guarded', on: 'caster' }]\n\t},\n\t{ id: 'drink', name: 'Drink', description: 'Heals 100', target: 'none', cooldown: 10, effects: [{ type: 'heal', amount: 100, on: 'caster' }] }\n]\n\nconst items: ItemDef[] = [\n\t{ id: 'sword', name: 'Sword', description: '+10 attack damage', tier: 'basic', cost: { gold: 100 }, bonus: { stats: { attackDamage: 10 } } },\n\t{ id: 'potion', name: 'Potion', description: 'Heals 100 when drunk', tier: 'consumable', cost: { gold: 50 }, charges: 1, ability: 'drink' }\n]\n\n/** A hall where a player starts, and five workers on the side of the closest mine */\nfunction startingBase(world: World, player: PlayerId, at: Vec2): void {\n\tconst base = world.spawn('hall', player, at)\n\tlet closest: Vec2 | undefined\n\tfor (const entity of world.entities.values()) {\n\t\tif (entity.def.resource?.kind !== 'gold' || dist(entity.pos, base.pos) > 20) continue\n\t\tif (!closest || dist(entity.pos, base.pos) < dist(closest, base.pos)) closest = entity.pos\n\t}\n\tconst towards = closest ? { x: Math.sign(closest.x - at.x), z: Math.sign(closest.z - at.z) } : { x: 1, z: 0 }\n\tfor (let i = 0; i < 5; i++)\n\t\tworld.spawn('worker', player, { x: at.x + towards.x * 4 + (i - 2) * towards.z, z: at.z + towards.z * 4 + (i - 2) * towards.x })\n}\n\n/**\n * The fixture game (see the top of this file): every role of the kit, with round numbers. Gold and lumber, 1000 of each\n * to start with; a hall and five workers at each start; heroes on (`withHeroes`); no fog explored at the start. A new\n * one each time, for a test to change\n *\n * @beta\n */\nexport function fixtureGame(): GameModule {\n\treturn {\n\t\tid: 'fixture',\n\t\tname: 'Fixture',\n\t\tversion: '1.0.0',\n\t\tunits: [worker, soldier, archer, hero, creep, hall, keep, supply, barracks, tower, altar, mine, tree].map((def) => structuredClone(def)),\n\t\tupgrades: [structuredClone(armour)],\n\t\tabilities: structuredClone(abilities),\n\t\tbuffs: [structuredClone(guarded)],\n\t\titems: structuredClone(items),\n\t\tresources: [\n\t\t\t{ id: 'gold', name: 'Gold', start: 1000 },\n\t\t\t{ id: 'lumber', name: 'Lumber', start: 1000 }\n\t\t],\n\t\tcurrency: 'gold',\n\t\tpacks: [withHeroes()],\n\t\tstart: { spawn: startingBase }\n\t}\n}\n\n/**\n * A map of the fixture game, 64 cells a side: two players, starting at opposite corners (12, 12 and 52, 52), a gold\n * mine and a row of trees by each start, and a camp of three creeps in the middle\n *\n * @beta\n */\nexport function fixtureMap(): GameMap {\n\tconst map = createMap({ name: 'Fixture', width: 64, depth: 64, game: 'fixture' })\n\tmap.players[0].start = { x: 12, z: 12 }\n\tmap.players[1].start = { x: 52, z: 52 }\n\tlet id = 1\n\tconst object = (type: string, x: number, z: number) => map.objects.push({ id: id++, type, owner: 0, x, z, facing: 0, scale: 1 })\n\tobject('mine', 12, 22)\n\tobject('mine', 52, 42)\n\tfor (let i = 0; i < 6; i++) {\n\t\tobject('tree', 22.5 + i, 4.5)\n\t\tobject('tree', 36.5 + i, 59.5)\n\t}\n\tmap.camps.push({ id: id++, x: 32, z: 32, units: ['creep', 'creep', 'creep'] })\n\treturn map\n}\n","/**\n * Testing a computer player (AI plan, E3): what a game's tests of its brains are written with, in\n * `@v12-engine/engine/testing` beside `testWorld` and `run`. A brain is tested as it plays, through the world it sits in:\n *\n * const world = await testWorld(myGame)\n * world.computers.seat(ENEMY, { enemyBases: [home], brain: myBrain })\n * const watch = watchComputer(world, ENEMY) // its invariants, every think\n * run(world, 120)\n * expectDecision(thinkOnce(world, ENEMY), 'ai.attack')\n * watch.assert() // no rule broken\n *\n * `thinkOnce` has a seated brain think now and gives its report; `expectDecision` says a goal runs, or why not in\n * words; `watchComputer` checks the invariants of `ai/checks.ts` after every think (a unit in one squad, gold spent\n * once, finite numbers, commands about what it sees, no churn, nothing stuck) and keeps what it decided; `fairPlay` is\n * the one about seeing; `recordDecisions` keeps every computer's decisions for a replay's side file; `checkComputerSave`\n * is the seventh invariant: a game saved and loaded decides the same from then on. These take the world, which a test\n * may: the brains under test never do.\n */\nimport { type AiCheckOptions, type AiViolation, checkBrain } from './ai/checks'\nimport { Brain } from './ai/brain'\nimport type { GoalReport } from './ai/goals'\nimport { type AiDecision, type AiReport, explainGoal } from './ai/report'\nimport type { PlayerId } from './entity'\nimport { type GameModule, loadWorld } from './game'\nimport { decodeSave, encodeSave, saveWorld } from './save'\nimport { LocalSession } from './session/local'\nimport type { PlayerCommand, Snapshot } from './session/protocol'\nimport type { World } from './world'\n\n/**\n * The brain that plays a player, where one is seated (`world.computers.seat`): none where nobody is, or where what is\n * seated is not a brain (`defineComputer`)\n *\n * @beta\n */\nexport function brainOf(world: World, player: PlayerId): Brain | undefined {\n\tconst computer = world.computers.get(player)?.computer\n\treturn computer instanceof Brain ? computer : undefined\n}\n\n/** The brain at a player, or an error that says what is seated there instead */\nfunction seated(world: World, player: PlayerId): Brain {\n\tconst brain = brainOf(world, player)\n\tif (brain) return brain\n\tconst system = world.computers.get(player)\n\tthrow new Error(\n\t\tsystem ? `The computer player at ${player} is not a brain (defineBrain): it has no report` : `No computer player is seated at ${player}`\n\t)\n}\n\n/**\n * Has the brain at a player think now, all of it (a think its budget slices over ticks is run to its end), over a new\n * picture of the game, and gives its report: what a test reads after setting a scene. Its commands land at the next\n * tick, as a think's do. A think the seat would have had is not skipped: this one is beside them\n *\n * @beta\n */\nexport function thinkOnce(world: World, player: PlayerId): AiReport {\n\tconst brain = seated(world, player)\n\tdo brain.think()\n\twhile (brain.busy)\n\treturn brain.report()\n}\n\n/**\n * Says that a goal runs, as of a report (`thinkOnce`, `Brain.report`): it is picked and holds what it claimed. Throws\n * where it does not, with its row in words (`Brain.explain`): what each consideration answered and what kept it out.\n * Gives the goal's row. With `picked: false`, says it does not run\n *\n * expectDecision(thinkOnce(world, ENEMY), 'ai.defend')\n *\n * @beta\n */\nexport function expectDecision(report: AiReport, goal: string, options: { picked?: boolean } = {}): GoalReport {\n\tconst wanted = options.picked ?? true\n\tconst row = report.goals.find((each) => each.id === goal)\n\tif (!row)\n\t\tthrow new Error(`The brain ${report.brain} has no goal \"${goal}\": its goals are ${report.goals.map((each) => each.id).join(', ') || 'none'}`)\n\tif (row.picked === wanted) return row\n\tconst seconds = (tick: number) => tick / report.tickRate\n\tthrow new Error(\n\t\t`Expected ${goal} ${wanted ? 'to run' : 'not to run'} at ${report.time.toFixed(1)} s, and it ${wanted ? 'does not' : 'does'}. ${explainGoal(row, seconds, report.time)}${\n\t\t\treport.goal && report.goal !== goal ? ` The best goal is ${report.goal}.` : ''\n\t\t}`\n\t)\n}\n\n/**\n * A computer player followed over a run (`watchComputer`): the rules it broke, what it decided and sent, and, where\n * asked, what an observer saw at each of its thinks\n *\n * @beta\n */\nexport interface ComputerWatch {\n\t/** The brain watched */\n\treadonly brain: Brain\n\t/** Every invariant it broke, in the order found (`ai/checks.ts`) */\n\treadonly violations: readonly AiViolation[]\n\t/** What it decided while watched, oldest first: every line, not only the last fifty its log keeps */\n\treadonly decisions: readonly AiDecision[]\n\t/** Its thinks while watched */\n\treadonly thinks: number\n\t/** Commands it sent while watched */\n\treadonly commands: number\n\t/** Throws, listing them, where it broke any rule */\n\tassert(): void\n\t/** Stops watching */\n\tstop(): void\n}\n\n/**\n * How a computer player is watched (`watchComputer`): which invariants and how long things may go on (`AiCheckOptions`),\n * and what to be shown at each think\n *\n * @beta\n */\nexport interface WatchOptions extends AiCheckOptions {\n\t/**\n\t * Shown, at the end of each of its thinks, the game as an observer sees it (everything, no fog) and the brain: for a\n\t * look at what it does (a test that writes frames, a page that draws them). An observer's seat is made only when given\n\t */\n\tobserve?: (snapshot: Snapshot, brain: Brain) => void\n\t/** Each command as it sends it */\n\tsent?: (command: PlayerCommand, brain: Brain) => void\n}\n\n/**\n * Follows the brain at a player from now on: after every think, the invariants of `ai/checks.ts` (a unit in one squad\n * and one hold, gold spent once, finite numbers, commands about what it sees, no order sent again to a unit still at\n * it, builders, tasks, holds and wants that end), with what it decided and sent. A broken rule is kept, not thrown,\n * unless `onViolation` throws: `assert` at the end says them all\n *\n * @beta\n */\nexport function watchComputer(world: World, player: PlayerId, options: WatchOptions = {}): ComputerWatch {\n\tconst brain = seated(world, player)\n\tconst violations: AiViolation[] = []\n\tconst decisions: AiDecision[] = []\n\tlet thinks = 0\n\tlet commands = 0\n\tconst { stop: unchecked } = checkBrain(brain, {\n\t\t...options,\n\t\tonViolation: (violation) => {\n\t\t\tviolations.push(violation)\n\t\t\toptions.onViolation?.(violation)\n\t\t}\n\t})\n\tconst observer = options.observe ? new LocalSession(world, player, { observer: true }) : undefined\n\tconst unwatched = brain.watch({\n\t\tsent: (command) => {\n\t\t\tcommands++\n\t\t\toptions.sent?.(command, brain)\n\t\t},\n\t\tdecided: (decision) => void decisions.push(decision),\n\t\tthought: () => {\n\t\t\tthinks++\n\t\t\tif (observer) options.observe!(observer.snapshot(), brain)\n\t\t}\n\t})\n\treturn {\n\t\tbrain,\n\t\tviolations,\n\t\tdecisions,\n\t\tget thinks() {\n\t\t\treturn thinks\n\t\t},\n\t\tget commands() {\n\t\t\treturn commands\n\t\t},\n\t\tassert() {\n\t\t\tif (!violations.length) return\n\t\t\tconst lines = violations.slice(0, 20).map((each) => ` ${each.invariant} at tick ${each.tick}: ${each.message}`)\n\t\t\tconst more = violations.length > 20 ? `\\n and ${violations.length - 20} more` : ''\n\t\t\tthrow new Error(\n\t\t\t\t`The computer player at ${player} broke ${violations.length} rule${violations.length === 1 ? '' : 's'}:\\n${lines.join('\\n')}${more}`\n\t\t\t)\n\t\t},\n\t\tstop() {\n\t\t\tunchecked()\n\t\t\tunwatched()\n\t\t\tobserver?.dispose()\n\t\t}\n\t}\n}\n\n/**\n * Whether a computer player played fair over a run (`fairPlay`): every command it sent named what its own snapshot\n * had, and how many the game refused\n *\n * @beta\n */\nexport interface FairPlay {\n\t/** Commands that named an entity it did not see, or a place off the map */\n\treadonly unfair: readonly AiViolation[]\n\t/** Commands the game refused while watched (a unit that could not do it, a place it could not build at) */\n\treadonly refused: number\n\t/** Throws where it sent any command about what it did not see */\n\tassert(): void\n\tstop(): void\n}\n\n/**\n * Follows the brain at a player from now on for fair play: that it never sends a command about an entity its snapshot\n * did not have (a fog leak: its seat's session would drop the command, so a game shows nothing; this says it), and\n * counts what the game refused\n *\n * @beta\n */\nexport function fairPlay(world: World, player: PlayerId): FairPlay {\n\tconst watch = watchComputer(world, player, { invariants: ['commands'] })\n\tconst brain = watch.brain\n\tconst refusedBefore = brain.stats.refused\n\treturn {\n\t\tget unfair() {\n\t\t\treturn watch.violations\n\t\t},\n\t\tget refused() {\n\t\t\treturn brain.stats.refused - refusedBefore\n\t\t},\n\t\tassert: () => watch.assert(),\n\t\tstop: () => watch.stop()\n\t}\n}\n\n/**\n * One thing a computer player decided, with whose: a line of a replay's side file (`recordDecisions`)\n *\n * @beta\n */\nexport interface RecordedDecision extends AiDecision {\n\tplayer: PlayerId\n\t/** The brain's id */\n\tbrain: string\n}\n\n/**\n * The decisions of every computer of a world, as they are made (`recordDecisions`): plain data, for a side file beside a\n * replay of commands, read back by whoever wonders why the computer did what the replay shows\n *\n * @beta\n */\nexport interface DecisionRecorder {\n\t/** Every decision so far, in the order made */\n\treadonly decisions: readonly RecordedDecision[]\n\tstop(): void\n}\n\n/** How many recorders were made: each one's system a name of its own */\nlet recorders = 0\n\n/**\n * Keeps the decisions of every brain seated at a world, from now on, those seated later included (looked for at each\n * tick, by a system of its own that keeps nothing in a save)\n *\n * @beta\n */\nexport function recordDecisions(world: World): DecisionRecorder {\n\tconst decisions: RecordedDecision[] = []\n\tconst watched = new Map<Brain, () => void>()\n\tconst look = () => {\n\t\tfor (const player of world.computers.list()) {\n\t\t\tconst brain = brainOf(world, player)\n\t\t\tif (!brain || watched.has(brain)) continue\n\t\t\twatched.set(brain, brain.watch({ decided: (decision) => void decisions.push({ ...decision, player: brain.playerId, brain: brain.def.id }) }))\n\t\t}\n\t}\n\tlook()\n\tconst name = `core.ai.recordDecisions.${++recorders}`\n\tworld.addSystem({ name, update: look })\n\treturn {\n\t\tdecisions,\n\t\tstop() {\n\t\t\tworld.removeSystem(name)\n\t\t\tfor (const unwatch of watched.values()) unwatch()\n\t\t\twatched.clear()\n\t\t}\n\t}\n}\n\n/**\n * Where a game saved and loaded first decided otherwise than the game it was saved from (`checkComputerSave`): the\n * decision each made at that place in their logs. `null` where they decided alike to the end\n *\n * @beta\n */\nexport interface DecisionsApart {\n\t/** How many decisions since the save they shared before this one */\n\tindex: number\n\t/** The game that went on from the save */\n\tsaved?: RecordedDecision\n\t/** The game loaded from it */\n\tloaded?: RecordedDecision\n}\n\n/**\n * The seventh invariant of a computer player: a game saved at tick `from` and loaded makes the same decisions from then\n * on as the game it was saved from, under the same commands. Makes the world with `make` (its computers seated, as a\n * game seats them), runs it to `from`, saves it as a file would keep it and loads that with `game`, then runs both to\n * `ticks` and compares what every computer decided. What lost rng, tasks or memory in a restore shows as\n *\n * expect(await checkComputerSave(() => duel(), { from: 600, ticks: 2400, game: melee })).toBeNull()\n *\n * @beta\n */\nexport async function checkComputerSave(\n\tmake: () => World | Promise<World>,\n\toptions: { from: number; ticks: number; game: GameModule }\n): Promise<DecisionsApart | null> {\n\tconst saved = await make()\n\tlet loaded: World | undefined\n\ttry {\n\t\twhile (saved.tick < options.from) saved.step()\n\t\tloaded = await loadWorld(decodeSave(encodeSave(saveWorld(saved))), { game: options.game })\n\t\tconst before = recordDecisions(saved)\n\t\tconst after = recordDecisions(loaded)\n\t\twhile (saved.tick < options.ticks) {\n\t\t\tsaved.step()\n\t\t\tloaded.step()\n\t\t}\n\t\tbefore.stop()\n\t\tafter.stop()\n\t\tconst a = before.decisions\n\t\tconst b = after.decisions\n\t\tfor (let i = 0; i < Math.max(a.length, b.length); i++)\n\t\t\tif (JSON.stringify(a[i]) !== JSON.stringify(b[i])) return { index: i, ...(a[i] && { saved: a[i] }), ...(b[i] && { loaded: b[i] }) }\n\t\treturn null\n\t} finally {\n\t\tsaved.dispose()\n\t\tloaded?.dispose()\n\t}\n}\n","/**\n * `@v12-engine/engine/testing`: what a game's tests are written with. A world runs in a test as it does in a page, with no\n * screen: these make one, step it and give its units orders, so that a test says what happens in the game and little\n * else.\n *\n * const world = await testWorld(myGame.rules)\n * const knight = world.spawn('knight', 1, { x: 10, z: 10 })\n * order(world, [knight], { type: 'move', point: { x: 30, z: 10 } })\n * run(world, 5, () => knight.pos.x > 29)\n */\nimport type { Entity } from './entity'\nimport { createWorld, type GameModule } from './game'\nimport type { PlayerInit } from './player'\nimport type { Logger } from './log'\nimport type { OrderInit } from './registry'\nimport { Terrain } from './terrain'\nimport type { World } from './world'\n\n/**\n * Flat ground, `size` cells a side: 48 when left out\n *\n * @beta\n */\nexport const flatTerrain = (size = 48): Terrain => new Terrain(size, size, new Float32Array((size + 1) * (size + 1)))\n\n/**\n * The players of a test world, when a test says none: a neutral one, and two who are enemies\n *\n * @beta\n */\nexport const TEST_PLAYERS: PlayerInit[] = [\n\t{ id: 0, name: 'Neutral', team: 0, color: [1, 1, 0], neutral: true },\n\t{ id: 1, name: 'Player', team: 1, color: [0, 0, 1] },\n\t{ id: 2, name: 'Enemy', team: 2, color: [1, 0, 0] }\n]\n\n/**\n * A small world of a game for a test: flat ground, a neutral player and two enemies (`TEST_PLAYERS`), the same every\n * time (seed 7). Each of them is the test's to say otherwise\n *\n * @beta\n */\nexport function testWorld(\n\tgame: GameModule,\n\toptions: { terrain?: Terrain; size?: number; players?: PlayerInit[]; seed?: number; log?: Logger } = {}\n): Promise<World> {\n\treturn createWorld({\n\t\tterrain: options.terrain ?? flatTerrain(options.size),\n\t\tgame,\n\t\tseed: options.seed ?? 7,\n\t\tplayers: options.players ?? TEST_PLAYERS.map((player) => ({ ...player })),\n\t\tlog: options.log\n\t})\n}\n\n/**\n * Steps the world for up to `seconds`, stopping early once `until` holds. Returns the time that went by in it\n *\n * @beta\n */\nexport function run(world: World, seconds: number, until?: () => boolean): number {\n\tconst ticks = Math.ceil(seconds * world.tickRate)\n\tfor (let i = 0; i < ticks; i++) {\n\t\tworld.step()\n\t\tif (until?.()) return (i + 1) / world.tickRate\n\t}\n\treturn seconds\n}\n\n/**\n * Gives units an order, as their owner would: taken up at the next tick. `queue` adds it after what they are doing\n *\n * @beta\n */\nexport const order = (world: World, entities: Entity[], init: OrderInit, queue = false): void =>\n\tworld.issue({ type: 'order', player: entities[0].owner, entities: entities.map((entity) => entity.id), order: init, queue })\n\n// the fixture game, every role of the kit with round numbers: see `fixture.ts`\nexport { fixtureGame, fixtureMap } from './fixture'\n// many games at once, for balance: see `simulate.ts`\nexport {\n\ttype BrainResults,\n\ttype ComputerMeasures,\n\tdefineSimulation,\n\tplayGame,\n\ttype Counted,\n\ttype SimulatedGame,\n\ttype SimulateOptions,\n\tsimulate,\n\ttype Simulation,\n\twinRates\n} from './simulate'\n// a computer player under test: see `aiTesting.ts`\nexport {\n\tbrainOf,\n\tcheckComputerSave,\n\ttype ComputerWatch,\n\ttype DecisionRecorder,\n\ttype DecisionsApart,\n\texpectDecision,\n\ttype FairPlay,\n\tfairPlay,\n\ttype RecordedDecision,\n\trecordDecisions,\n\tthinkOnce,\n\twatchComputer,\n\ttype WatchOptions\n} from './aiTesting'\n\nexport {\n\ttype Apart,\n\tcheckDeterminism,\n\ttype DeterminismOptions,\n\ttype DeterminismReport,\n\ttype Difference,\n\tfirstDifference,\n\tworldFingerprint,\n\tworldHash,\n\tworldState\n} from './determinism'\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * What the ground of a map can be painted with, named by the game: grass, road, sand. A cell holds the index of its
3
+ * paint: 0 for none, left to the slope and the height, and 1 and up for the game's tiles in the order it gives them
4
+ * (`GameModule.tiles`). The rules read and paint by name (`registry.tile('road')`); what each looks like is the
5
+ * view's (`GameView.ground.tiles`).
6
+ *
7
+ * A map file says the name of each index it was painted with (`GameMap.tileset`), so that a map keeps its paint when
8
+ * the game adds tiles or puts them in another order: it is brought in line with the game's list by name
9
+ *
10
+ * @beta
11
+ */
12
+ export interface TileDef {
13
+ /** Shared by every game, like other ids */
14
+ id: string;
15
+ /** What the editor's palette calls it */
16
+ name: string;
17
+ /**
18
+ * How fast one on foot goes over it, as a multiplier of its speed: mud at 0.5, a road at 1.2. 1 when left out. What
19
+ * flies or sails is not slowed; the game's own `moveSpeed` rule keeps the last word (`groundSpeedAt`)
20
+ */
21
+ speed?: number;
22
+ }
23
+ /**
24
+ * Typed help for writing a tile
25
+ *
26
+ * @beta
27
+ */
28
+ export declare const defineTile: (def: TileDef) => TileDef;
29
+ /**
30
+ * The most tiles a game can have: a cell holds its tile in a byte, and 0 is none
31
+ *
32
+ * @beta
33
+ */
34
+ export declare const MAX_TILES = 255;
@@ -0,0 +1,146 @@
1
+ import type { PlayerId } from './entity';
2
+ import { type Message, type MessageRef } from './messages';
3
+ import type { System } from './registry';
4
+ import type { World } from './world';
5
+ /**
6
+ * Something a game does after a while, or every so often: a wave coming, a spell wearing off, a line of dialog.
7
+ * Made with `defineTimer` and given in `GameModule.timers`, the way listeners are, so that a loaded save finds the
8
+ * code by id: what is waiting in the world is data, which timer and with what, never a function
9
+ *
10
+ * @beta
11
+ */
12
+ export interface TimerDef<T = any> {
13
+ /** Shared by every game, like other ids: give it a prefix of the game's (`'td.waveComes'`) */
14
+ readonly id: string;
15
+ run(world: World, data: T, timer: TimerInfo): void;
16
+ }
17
+ /**
18
+ * Typed help: `defineTimer<{ wave: number }>('td.waveComes', (world, { wave }) => ...)`
19
+ *
20
+ * @beta
21
+ */
22
+ export declare function defineTimer<T = undefined>(id: string, run: (world: World, data: T, timer: TimerInfo) => void): TimerDef<T>;
23
+ /** A timer as it waits in the world. Plain data: it goes into a save */
24
+ interface Waiting {
25
+ /** Unique in the world, for `cancel` and `left` */
26
+ id: number;
27
+ timer: string;
28
+ data: unknown;
29
+ /** The tick it goes off at */
30
+ at: number;
31
+ /** Ticks between two times, for one that repeats */
32
+ every?: number;
33
+ /** How many times it still goes off, for one that repeats a number of times. Forever when left out */
34
+ times?: number;
35
+ }
36
+ /**
37
+ * A timer as the debug tools show it: seconds until it goes off, and between two times
38
+ *
39
+ * @beta
40
+ */
41
+ export interface WaitingTimer {
42
+ id: number;
43
+ timer: string;
44
+ data: unknown;
45
+ left: number;
46
+ every?: number;
47
+ times?: number;
48
+ }
49
+ /**
50
+ * How a timer repeats, and what it is given, for one whose handler takes something
51
+ *
52
+ * @beta
53
+ */
54
+ export type EveryOptions<T> = {
55
+ times?: number;
56
+ first?: number;
57
+ } & (T extends undefined ? {
58
+ data?: undefined;
59
+ } : {
60
+ data: T;
61
+ });
62
+ /**
63
+ * What a timer's handler is told about the time it went off
64
+ *
65
+ * @beta
66
+ */
67
+ export interface TimerInfo {
68
+ id: number;
69
+ /** How many more times it goes off after this one: 0 for the last, undefined for one that repeats forever */
70
+ left?: number;
71
+ }
72
+ /**
73
+ * A timer the rules show a player (`world.timers.show`): its words, and the tick it goes off at, for the screen to count
74
+ * down to
75
+ *
76
+ * @beta
77
+ */
78
+ export interface ShownTimer {
79
+ id: number;
80
+ label: Message;
81
+ at: number;
82
+ }
83
+ /** The timers each player is shown, by the id of each and its words: kept in the world, so that a save has them */
84
+ export declare const shownTimers: import("./components").Component<Record<number, {
85
+ id: number;
86
+ label: Message;
87
+ }[]>, Record<number, {
88
+ id: number;
89
+ label: Message;
90
+ }[]>>;
91
+ /** The timers waiting in a world, kept in it so that a save has them */
92
+ export declare const waiting: import("./components").Component<{
93
+ next: number;
94
+ list: Waiting[];
95
+ }, {
96
+ next: number;
97
+ list: Waiting[];
98
+ }>;
99
+ /** The timers waiting in the state of a save, by the id of their definition: what a game must still have to load it */
100
+ export declare const waitingTimers: (state: Record<string, unknown>) => string[];
101
+ /**
102
+ * The timers of a world. Time is counted in ticks, which every machine counts the same, never with the clock:
103
+ * a timer goes off at the start of the tick it is due, after the players' commands and before anything else, in the
104
+ * order they are due and then the order they were set
105
+ *
106
+ * @beta
107
+ */
108
+ export declare class Timers {
109
+ private readonly world;
110
+ private readonly defs;
111
+ constructor(world: World, defs: readonly TimerDef[]);
112
+ /** Goes off once, `seconds` from now. Returns its id, for `cancel` and `left` */
113
+ after<T>(seconds: number, timer: TimerDef<T>, ...data: T extends undefined ? [] : [T]): number;
114
+ /**
115
+ * Goes off every `seconds`: the first time `seconds` from now, or after `first` seconds; `times` times, or until
116
+ * cancelled. Returns its id
117
+ */
118
+ every<T>(seconds: number, timer: TimerDef<T>, options: EveryOptions<T>): number;
119
+ /** Stops a timer from going off again. Whether it was still waiting */
120
+ cancel(id: number): boolean;
121
+ /**
122
+ * Shows a player a timer (campaign plan CP5): its words and when it goes off, counted down on their screen (the HUD's
123
+ * timers) for as long as it waits. A timer that repeats is shown to each time it next goes off
124
+ */
125
+ show(player: PlayerId, id: number, options: {
126
+ label: MessageRef;
127
+ }): void;
128
+ /** Shows a player a timer no more */
129
+ hide(player: PlayerId, id: number): void;
130
+ /** The timers a player is shown that still wait, with the tick each goes off at next */
131
+ shownTo(player: PlayerId): ShownTimer[];
132
+ /** Seconds until the timer next goes off, or undefined when it is not waiting any more */
133
+ left(id: number): number | undefined;
134
+ /** Whether the timer is still waiting */
135
+ has(id: number): boolean;
136
+ /** What is waiting, in the order it was set: a copy, for the debug tools */
137
+ list(): WaitingTimer[];
138
+ /** Sets off what is due. The `timers` system calls it at the start of every tick */
139
+ update(): void;
140
+ private add;
141
+ private ticks;
142
+ private state;
143
+ }
144
+ /** Sets off the timers that are due, at the start of the tick, after the players' commands */
145
+ export declare const timerSystem: System;
146
+ export {};
@@ -0,0 +1,48 @@
1
+ import type { StatChange } from './defs';
2
+ import type { Entity } from './entity';
3
+ import type { GamePack } from './packs/pack';
4
+ import type { World } from './world';
5
+ /**
6
+ * The tomes pack's id
7
+ *
8
+ * @beta
9
+ */
10
+ export declare const TOMES = "core.tomes";
11
+ /**
12
+ * What a unit gained for good (`gainStats`): the stats added and the parts, everything it gained added up, and how many
13
+ * times it gained
14
+ *
15
+ * @beta
16
+ */
17
+ export interface GainedStats {
18
+ /** What was added to each stat */
19
+ stats: Record<string, number>;
20
+ /** The parts each stat was made bigger or smaller by */
21
+ percent: Record<string, number>;
22
+ /** How many times it gained: what tells the stats to be added up again */
23
+ times: number;
24
+ }
25
+ /**
26
+ * What a unit gained for good from tomes or the game's own rules (`gainStats`): saved with it
27
+ *
28
+ * @beta
29
+ */
30
+ export declare const gainedStats: import("./components").Component<GainedStats, GainedStats>;
31
+ /**
32
+ * 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
33
+ * mana raised with them. For the tomes pack's `tome` effect and a game's own rules (a shrine that makes a unit
34
+ * stronger); it works in a game with the tomes pack (`withTomes`), which adds what was gained to the stats
35
+ *
36
+ * @beta
37
+ */
38
+ export declare function gainStats(world: World, entity: Entity, change: StatChange): void;
39
+ /**
40
+ * Tomes, as in classic RTS games: the `tome` effect (`EffectTypes.tome`) gives what it reaches stats for good (`gain`: a
41
+ * point of strength with the attributes pack), a hero experience (`xp`) and levels (`levels`). A tome is an item whose
42
+ * ability has the effect, with a charge, used from the inventory, or as it is picked up with the runes pack
43
+ * (`withRunes`). What a unit gained is kept with it and in a save (`gainedStats`), and a game gives it from its own
44
+ * rules with `gainStats`
45
+ *
46
+ * @beta
47
+ */
48
+ export declare function withTomes(): GamePack;
@@ -0,0 +1,28 @@
1
+ import type { PlayerId } from './entity';
2
+ import type { World } from './world';
3
+ /**
4
+ * Gives `amount` of a resource from one player to an ally (`traded`), both told. Nothing to who is not an ally, more
5
+ * than the giver has, or a resource the game does not have; and as the `beforeTrade` hook says: how much arrives, or not
6
+ *
7
+ * @beta
8
+ */
9
+ export declare function give(world: World, from: PlayerId, to: PlayerId, resource: string, amount: number): void;
10
+ /**
11
+ * Shares with an ally, or no longer: control of the player's units (`shareControl`), and what the player's team sees
12
+ * (`shareVision`, when the ally is of another team: a team sees as one already). Nothing for who is not an ally
13
+ *
14
+ * @beta
15
+ */
16
+ export declare function shareWith(world: World, player: PlayerId, ally: PlayerId, what: {
17
+ vision?: boolean;
18
+ control?: boolean;
19
+ }): void;
20
+ /**
21
+ * Trades `amount` of one resource of a player's (`sold`) for another (`bought`) at a rate: `rate` of it for each one
22
+ * sold, rounded down (`exchanged`), the player told. What the `exchange` effect does (a marketplace's ability,
23
+ * `presetMarket`), for a game's own rules. Nothing of a resource the game does not have, of one for itself, or more
24
+ * than the player has. Gives back how much came
25
+ *
26
+ * @beta
27
+ */
28
+ export declare function exchange(world: World, player: PlayerId, sold: string, bought: string, amount: number, rate: number): number;
@@ -0,0 +1,76 @@
1
+ import { type Entity } from './entity';
2
+ import type { Vec2 } from './math';
3
+ import type { System } from './registry';
4
+ import type { World } from './world';
5
+ /**
6
+ * What a transport carries, and whether it is near enough the land to let them out: kept for its side to see, the
7
+ * card's unload button reads it (see `UnitTypeDef.transport`)
8
+ *
9
+ * @beta
10
+ */
11
+ export interface Cargo {
12
+ passengers: number[];
13
+ /** There is land within reach to let them out on */
14
+ ashore: boolean;
15
+ }
16
+ /** @beta */
17
+ export declare const cargo: import("./components").Component<Cargo, Cargo>;
18
+ /**
19
+ * How many more a transport has room for
20
+ *
21
+ * @beta
22
+ */
23
+ export declare function roomIn(transport: Entity): number;
24
+ /**
25
+ * Whether a unit can get into a transport: one of its side's that has room, and a unit that walks. What flies, what
26
+ * sails and what carries others do not get in
27
+ *
28
+ * @beta
29
+ */
30
+ export declare function canBoard(world: World, passenger: Entity, transport: Entity): boolean;
31
+ /**
32
+ * Puts a unit into a transport at once, wherever the two are. False when it cannot get in
33
+ *
34
+ * @beta
35
+ */
36
+ export declare function board(world: World, passenger: Entity, transport: Entity): boolean;
37
+ /**
38
+ * Lets out what a transport carries, on the land nearest it (or nearest `near`, within reach of the transport), spread
39
+ * around it. How many got out: none when there is no land in reach
40
+ *
41
+ * @beta
42
+ */
43
+ export declare function unload(world: World, transport: Entity, near?: Vec2): number;
44
+ /**
45
+ * What `board` keeps: the tick it last set out for its transport
46
+ *
47
+ * @beta
48
+ */
49
+ export interface BoardState {
50
+ /** The tick it last set out for its transport */
51
+ tried?: number;
52
+ }
53
+ /**
54
+ * What `unload` keeps: whether it set its passengers down already
55
+ *
56
+ * @beta
57
+ */
58
+ export interface UnloadState {
59
+ /** It set them down already */
60
+ sent?: boolean;
61
+ }
62
+ /**
63
+ * What `load` keeps: the tick it last set out for its passenger, and where it was then
64
+ *
65
+ * @beta
66
+ */
67
+ export interface LoadState {
68
+ /** The tick it last set out for its passenger */
69
+ tried?: number;
70
+ /** Where it was when it last set out */
71
+ from?: Vec2;
72
+ }
73
+ /** Keeps each transport's word of whether it is near the land, for its card. A few times a second */
74
+ export declare const transportSystem: System;
75
+ /** A transport that dies takes down what it carries with it: a boat. A building that falls lets them out */
76
+ export declare const transportSank: import("./events").ListenerDef;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * A number of a game's rules to be tuned while it plays: the seconds between waves, how much a kill pays. Read in the
3
+ * rules with `world.tunable(id)`, and changed while the game runs from the editor's play mode (`debug.tune`), in the
4
+ * world itself, so that a save and a screen over a wire have the same. Given in `GameModule.tunables`
5
+ *
6
+ * @beta
7
+ */
8
+ export interface TunableDef {
9
+ /** Shared by every game: give it a prefix of the game's */
10
+ id: string;
11
+ /** What the tuning panel calls it */
12
+ name?: string;
13
+ default: number;
14
+ min: number;
15
+ max: number;
16
+ /** What the slider steps by. A hundredth of the way from min to max when left out */
17
+ step?: number;
18
+ }
19
+ /** @beta */
20
+ export declare const defineTunable: (def: TunableDef) => TunableDef;
21
+ /**
22
+ * The tunables of a game with what a file says over their defaults: the values kept from the tuning panel, in the
23
+ * game's `tuning.json` (`{ "td.betweenWaves": 12 }`). Code can still set any of them as it likes
24
+ *
25
+ * @beta
26
+ */
27
+ export declare function withTuning(defs: readonly TunableDef[], file?: Readonly<Record<string, unknown>>): TunableDef[];
28
+ /**
29
+ * A tunable changed while the game runs: for what has to be worked out again from it
30
+ *
31
+ * @beta
32
+ */
33
+ export declare const tunableChanged: import("./events").EventKey<{
34
+ id: string;
35
+ value: number;
36
+ }>;
37
+ /**
38
+ * Sets a tunable while the game runs: for players allowed the debug tools
39
+ *
40
+ * @beta
41
+ */
42
+ export declare const tuneCommand: import("#engine/commands").DefinedCommand<"debug.tune", {
43
+ id: import("./fields").Check<string>;
44
+ value: import("./fields").Check<number>;
45
+ }>;
@@ -0,0 +1,16 @@
1
+ import type { PlayerId } from './entity';
2
+ import type { World } from './world';
3
+ /** @beta */
4
+ export interface Upkeep {
5
+ /** 0 without upkeep, then counting up with the tiers of the game */
6
+ tier: number;
7
+ name: string;
8
+ /** Part of the gold a worker brings in that reaches the player */
9
+ income: number;
10
+ }
11
+ /**
12
+ * What a player's army costs them, by how much supply they use
13
+ *
14
+ * @beta
15
+ */
16
+ export declare function upkeepOf(world: World, player: PlayerId): Upkeep;
@@ -0,0 +1,80 @@
1
+ import type { GamePack } from './packs/pack';
2
+ import type { StatChange } from './defs';
3
+ import type { Entity } from './entity';
4
+ import type { World } from './world';
5
+ /**
6
+ * A rank of veterancy: the experience it starts at, its name, and what it adds to a unit's stats (in place of the rank
7
+ * before's: each says all a unit of that rank has)
8
+ *
9
+ * @beta
10
+ */
11
+ export interface VeterancyRank {
12
+ name: string;
13
+ xp: number;
14
+ stats?: StatChange;
15
+ }
16
+ /**
17
+ * What a unit has of veterancy: its experience and the rank it reached (0 for none yet)
18
+ *
19
+ * @beta
20
+ */
21
+ export interface VeterancyState {
22
+ xp: number;
23
+ rank: number;
24
+ }
25
+ /**
26
+ * Ranks as many games have them: three, at 50, 150 and 300 experience, 10%, 20% and 30% more damage and health
27
+ *
28
+ * @beta
29
+ */
30
+ export declare const VETERANCY_RANKS: readonly VeterancyRank[];
31
+ /**
32
+ * What veterancy is made of (`withVeterancy`)
33
+ *
34
+ * @beta
35
+ */
36
+ export interface VeterancyOptions {
37
+ /** The ranks, from the lowest: `VETERANCY_RANKS` when left out */
38
+ ranks?: readonly VeterancyRank[];
39
+ /** Who earns it: units of a player's that are not heroes and not structures, when left out */
40
+ earns?: (world: World, entity: Entity) => boolean;
41
+ /** What a kill is worth to the killer: what it is worth to heroes (`xpWorth`), when left out. 0 for nothing */
42
+ worth?: (world: World, dead: Entity, killer: Entity) => number;
43
+ }
44
+ /**
45
+ * What a unit has of veterancy, told to everyone (a rank shows on its plate): none for one that has earned nothing
46
+ *
47
+ * @beta
48
+ */
49
+ export declare const veterancy: import("./components").Component<VeterancyState, VeterancyState>;
50
+ /**
51
+ * A unit reached a rank: told to everyone, for a sound or a word on the screen
52
+ *
53
+ * @beta
54
+ */
55
+ export declare const rankedUp: import("./events").EventKey<{
56
+ entity: number;
57
+ rank: number;
58
+ name: string;
59
+ }>;
60
+ /**
61
+ * The rank a unit has reached, as a definition, or none: of the game's ranks (`VeterancyOptions.ranks`)
62
+ *
63
+ * @beta
64
+ */
65
+ export declare function rankOf(entity: Entity, ranks?: readonly VeterancyRank[]): VeterancyRank | undefined;
66
+ /**
67
+ * Gives a unit experience, as a kill does: its rank goes up where it reaches the next ones' thresholds, its stats
68
+ * with it, and `rankedUp` is told for each. Gives back the rank it is at. For a game's own rules (a unit that trains
69
+ * at a camp), and what `withVeterancy` does on a kill
70
+ *
71
+ * @beta
72
+ */
73
+ export declare function grantVeterancy(world: World, entity: Entity, xp: number, ranks?: readonly VeterancyRank[]): number;
74
+ /**
75
+ * Veterancy for a game's units (`VeterancyOptions`): the killer of an enemy earns what it was worth, ranks come at
76
+ * their thresholds, each rank's stats are added (the `stats` hook). The game is the same otherwise
77
+ *
78
+ * @beta
79
+ */
80
+ export declare function withVeterancy(options?: VeterancyOptions): GamePack;
@@ -0,0 +1,86 @@
1
+ import type { Vec2 } from './math';
2
+ import type { GamePack } from './packs/pack';
3
+ import type { Entity } from './entity';
4
+ import type { World } from './world';
5
+ /**
6
+ * What a piece of wall is, among its family's: its shape, by the pieces of its family beside it
7
+ *
8
+ * @beta
9
+ */
10
+ export type WallShape = 'single' | 'end' | 'straight' | 'corner' | 'tee' | 'cross';
11
+ /**
12
+ * A piece of wall took another shape, or turned: a piece came or went beside it
13
+ *
14
+ * @beta
15
+ */
16
+ export declare const wallJoined: import("./events").EventKey<{
17
+ entity: number;
18
+ shape: WallShape;
19
+ facing: number;
20
+ }>;
21
+ /**
22
+ * The cells of a wall along a drag, as the genre lays one: along the longer of its two directions first, then the
23
+ * other, a cell's middle each (`x + 0.5`), from where it started to where it ended, each once
24
+ *
25
+ * @beta
26
+ */
27
+ export declare function wallLine(from: Vec2, to: Vec2): Vec2[];
28
+ /**
29
+ * Lays a wall along a drag with the player's builders: a build order for each cell of the line (`wallLine`), queued
30
+ * after one another (after what they were doing, with `queue`), for the first builder of theirs among the ids that can
31
+ * 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
32
+ *
33
+ * @beta
34
+ */
35
+ export declare const buildLineCommand: import("#engine/commands").DefinedCommand<"buildLine", {
36
+ entities: import("./fields").Check<number[]>;
37
+ unitType: import("./fields").Check<string>;
38
+ from: import("./fields").Check<Vec2>;
39
+ to: import("./fields").Check<Vec2>;
40
+ queue: import("./fields").Check<boolean | undefined>;
41
+ }>;
42
+ /**
43
+ * A gate of a wall (`UnitTypeDef.wall.gate`): whether it stands open, every screen told. Open, it is in nobody's way,
44
+ * whoever walks; shut, it is a piece of the wall. Its owner opens and shuts it (`wallGateCommand`, `setWallGate`)
45
+ *
46
+ * @beta
47
+ */
48
+ export declare const wallGate: import("./components").Component<{
49
+ open: boolean;
50
+ }, {
51
+ open: boolean;
52
+ }>;
53
+ /**
54
+ * A gate of a wall opened or shut (`setWallGate`)
55
+ *
56
+ * @beta
57
+ */
58
+ export declare const wallGateChanged: import("./events").EventKey<{
59
+ entity: number;
60
+ open: boolean;
61
+ }>;
62
+ /**
63
+ * Opens or shuts a gate of a wall, for everyone: open, what walks goes through its cell, whoever's; shut, around it.
64
+ * Its look is `open` or `shut`. False for what is no gate, or one still going up
65
+ *
66
+ * @beta
67
+ */
68
+ export declare function setWallGate(world: World, gate: Entity, open: boolean): boolean;
69
+ /**
70
+ * Its owner opens or shuts a gate of a wall (`setWallGate`), for everyone
71
+ *
72
+ * @beta
73
+ */
74
+ export declare const wallGateCommand: import("#engine/commands").DefinedCommand<"wallGate", {
75
+ entity: import("./fields").Check<number>;
76
+ open: import("./fields").Check<boolean>;
77
+ }>;
78
+ /**
79
+ * Walls for a game: its pieces (types with `wall: { family }`) join with their neighbours as they are put down and
80
+ * taken away, and a builder lays a line of them (`buildLineCommand`). A game's pieces draw by their shape with
81
+ * `UnitLook.looks` (`single`, `end`, `straight`, `corner`, `tee`, `cross`); its gates (`wall.gate`) by `open` and `shut`,
82
+ * opened and shut by their owner (`wallGateCommand`)
83
+ *
84
+ * @beta
85
+ */
86
+ export declare function withWalls(): GamePack;