@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,179 @@
1
+ /**
2
+ * Testing a computer player (AI plan, E3): what a game's tests of its brains are written with, in
3
+ * `@v12-engine/engine/testing` beside `testWorld` and `run`. A brain is tested as it plays, through the world it sits in:
4
+ *
5
+ * const world = await testWorld(myGame)
6
+ * world.computers.seat(ENEMY, { enemyBases: [home], brain: myBrain })
7
+ * const watch = watchComputer(world, ENEMY) // its invariants, every think
8
+ * run(world, 120)
9
+ * expectDecision(thinkOnce(world, ENEMY), 'ai.attack')
10
+ * watch.assert() // no rule broken
11
+ *
12
+ * `thinkOnce` has a seated brain think now and gives its report; `expectDecision` says a goal runs, or why not in
13
+ * words; `watchComputer` checks the invariants of `ai/checks.ts` after every think (a unit in one squad, gold spent
14
+ * once, finite numbers, commands about what it sees, no churn, nothing stuck) and keeps what it decided; `fairPlay` is
15
+ * the one about seeing; `recordDecisions` keeps every computer's decisions for a replay's side file; `checkComputerSave`
16
+ * is the seventh invariant: a game saved and loaded decides the same from then on. These take the world, which a test
17
+ * may: the brains under test never do.
18
+ */
19
+ import { type AiCheckOptions, type AiViolation } from './ai/checks';
20
+ import { Brain } from './ai/brain';
21
+ import type { GoalReport } from './ai/goals';
22
+ import { type AiDecision, type AiReport } from './ai/report';
23
+ import type { PlayerId } from './entity';
24
+ import { type GameModule } from './game';
25
+ import type { PlayerCommand, Snapshot } from './session/protocol';
26
+ import type { World } from './world';
27
+ /**
28
+ * The brain that plays a player, where one is seated (`world.computers.seat`): none where nobody is, or where what is
29
+ * seated is not a brain (`defineComputer`)
30
+ *
31
+ * @beta
32
+ */
33
+ export declare function brainOf(world: World, player: PlayerId): Brain | undefined;
34
+ /**
35
+ * 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
36
+ * picture of the game, and gives its report: what a test reads after setting a scene. Its commands land at the next
37
+ * tick, as a think's do. A think the seat would have had is not skipped: this one is beside them
38
+ *
39
+ * @beta
40
+ */
41
+ export declare function thinkOnce(world: World, player: PlayerId): AiReport;
42
+ /**
43
+ * Says that a goal runs, as of a report (`thinkOnce`, `Brain.report`): it is picked and holds what it claimed. Throws
44
+ * where it does not, with its row in words (`Brain.explain`): what each consideration answered and what kept it out.
45
+ * Gives the goal's row. With `picked: false`, says it does not run
46
+ *
47
+ * expectDecision(thinkOnce(world, ENEMY), 'ai.defend')
48
+ *
49
+ * @beta
50
+ */
51
+ export declare function expectDecision(report: AiReport, goal: string, options?: {
52
+ picked?: boolean;
53
+ }): GoalReport;
54
+ /**
55
+ * A computer player followed over a run (`watchComputer`): the rules it broke, what it decided and sent, and, where
56
+ * asked, what an observer saw at each of its thinks
57
+ *
58
+ * @beta
59
+ */
60
+ export interface ComputerWatch {
61
+ /** The brain watched */
62
+ readonly brain: Brain;
63
+ /** Every invariant it broke, in the order found (`ai/checks.ts`) */
64
+ readonly violations: readonly AiViolation[];
65
+ /** What it decided while watched, oldest first: every line, not only the last fifty its log keeps */
66
+ readonly decisions: readonly AiDecision[];
67
+ /** Its thinks while watched */
68
+ readonly thinks: number;
69
+ /** Commands it sent while watched */
70
+ readonly commands: number;
71
+ /** Throws, listing them, where it broke any rule */
72
+ assert(): void;
73
+ /** Stops watching */
74
+ stop(): void;
75
+ }
76
+ /**
77
+ * How a computer player is watched (`watchComputer`): which invariants and how long things may go on (`AiCheckOptions`),
78
+ * and what to be shown at each think
79
+ *
80
+ * @beta
81
+ */
82
+ export interface WatchOptions extends AiCheckOptions {
83
+ /**
84
+ * Shown, at the end of each of its thinks, the game as an observer sees it (everything, no fog) and the brain: for a
85
+ * look at what it does (a test that writes frames, a page that draws them). An observer's seat is made only when given
86
+ */
87
+ observe?: (snapshot: Snapshot, brain: Brain) => void;
88
+ /** Each command as it sends it */
89
+ sent?: (command: PlayerCommand, brain: Brain) => void;
90
+ }
91
+ /**
92
+ * Follows the brain at a player from now on: after every think, the invariants of `ai/checks.ts` (a unit in one squad
93
+ * and one hold, gold spent once, finite numbers, commands about what it sees, no order sent again to a unit still at
94
+ * it, builders, tasks, holds and wants that end), with what it decided and sent. A broken rule is kept, not thrown,
95
+ * unless `onViolation` throws: `assert` at the end says them all
96
+ *
97
+ * @beta
98
+ */
99
+ export declare function watchComputer(world: World, player: PlayerId, options?: WatchOptions): ComputerWatch;
100
+ /**
101
+ * Whether a computer player played fair over a run (`fairPlay`): every command it sent named what its own snapshot
102
+ * had, and how many the game refused
103
+ *
104
+ * @beta
105
+ */
106
+ export interface FairPlay {
107
+ /** Commands that named an entity it did not see, or a place off the map */
108
+ readonly unfair: readonly AiViolation[];
109
+ /** Commands the game refused while watched (a unit that could not do it, a place it could not build at) */
110
+ readonly refused: number;
111
+ /** Throws where it sent any command about what it did not see */
112
+ assert(): void;
113
+ stop(): void;
114
+ }
115
+ /**
116
+ * Follows the brain at a player from now on for fair play: that it never sends a command about an entity its snapshot
117
+ * did not have (a fog leak: its seat's session would drop the command, so a game shows nothing; this says it), and
118
+ * counts what the game refused
119
+ *
120
+ * @beta
121
+ */
122
+ export declare function fairPlay(world: World, player: PlayerId): FairPlay;
123
+ /**
124
+ * One thing a computer player decided, with whose: a line of a replay's side file (`recordDecisions`)
125
+ *
126
+ * @beta
127
+ */
128
+ export interface RecordedDecision extends AiDecision {
129
+ player: PlayerId;
130
+ /** The brain's id */
131
+ brain: string;
132
+ }
133
+ /**
134
+ * The decisions of every computer of a world, as they are made (`recordDecisions`): plain data, for a side file beside a
135
+ * replay of commands, read back by whoever wonders why the computer did what the replay shows
136
+ *
137
+ * @beta
138
+ */
139
+ export interface DecisionRecorder {
140
+ /** Every decision so far, in the order made */
141
+ readonly decisions: readonly RecordedDecision[];
142
+ stop(): void;
143
+ }
144
+ /**
145
+ * Keeps the decisions of every brain seated at a world, from now on, those seated later included (looked for at each
146
+ * tick, by a system of its own that keeps nothing in a save)
147
+ *
148
+ * @beta
149
+ */
150
+ export declare function recordDecisions(world: World): DecisionRecorder;
151
+ /**
152
+ * Where a game saved and loaded first decided otherwise than the game it was saved from (`checkComputerSave`): the
153
+ * decision each made at that place in their logs. `null` where they decided alike to the end
154
+ *
155
+ * @beta
156
+ */
157
+ export interface DecisionsApart {
158
+ /** How many decisions since the save they shared before this one */
159
+ index: number;
160
+ /** The game that went on from the save */
161
+ saved?: RecordedDecision;
162
+ /** The game loaded from it */
163
+ loaded?: RecordedDecision;
164
+ }
165
+ /**
166
+ * The seventh invariant of a computer player: a game saved at tick `from` and loaded makes the same decisions from then
167
+ * on as the game it was saved from, under the same commands. Makes the world with `make` (its computers seated, as a
168
+ * game seats them), runs it to `from`, saves it as a file would keep it and loads that with `game`, then runs both to
169
+ * `ticks` and compares what every computer decided. What lost rng, tasks or memory in a restore shows as
170
+ *
171
+ * expect(await checkComputerSave(() => duel(), { from: 600, ticks: 2400, game: melee })).toBeNull()
172
+ *
173
+ * @beta
174
+ */
175
+ export declare function checkComputerSave(make: () => World | Promise<World>, options: {
176
+ from: number;
177
+ ticks: number;
178
+ game: GameModule;
179
+ }): Promise<DecisionsApart | null>;
@@ -0,0 +1,149 @@
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
+ import type { MapRegion } from './map';
6
+ /**
7
+ * Where an area is on the map: a circle, a rectangle by its middle and size, or a polygon by its corners round a middle
8
+ * of its own (`points`, each from `x` and `z`, three or more, in order round it: moving the middle moves it whole)
9
+ *
10
+ * @beta
11
+ */
12
+ export type AreaShape = {
13
+ kind: 'circle';
14
+ x: number;
15
+ z: number;
16
+ radius: number;
17
+ } | {
18
+ kind: 'rect';
19
+ x: number;
20
+ z: number;
21
+ width: number;
22
+ depth: number;
23
+ } | {
24
+ kind: 'polygon';
25
+ x: number;
26
+ z: number;
27
+ points: Vec2[];
28
+ };
29
+ /**
30
+ * The box round a shape: its least and greatest x and z on the map
31
+ *
32
+ * @beta
33
+ */
34
+ export declare function shapeBounds(shape: AreaShape): {
35
+ x0: number;
36
+ z0: number;
37
+ x1: number;
38
+ z1: number;
39
+ };
40
+ /**
41
+ * How much ground a shape covers, in cells
42
+ *
43
+ * @beta
44
+ */
45
+ export declare function shapeArea(shape: AreaShape): number;
46
+ /**
47
+ * A shape as a circle or a rectangle: a polygon as the rectangle round it. For what draws only those (mist, clouds and
48
+ * weather in a region of the map)
49
+ *
50
+ * @beta
51
+ */
52
+ export declare function shapeAsBox(shape: AreaShape): Exclude<AreaShape, {
53
+ kind: 'polygon';
54
+ }>;
55
+ /**
56
+ * A shape moved to stand at a point and sized `scale` times: a prefab's area where the prefab is put
57
+ *
58
+ * @beta
59
+ */
60
+ export declare function shapeAt(shape: AreaShape, at: Vec2, scale?: number): AreaShape;
61
+ /**
62
+ * Where something of the map is, by a shape of its own or by a region of the map, named: mist, clouds and weather in
63
+ * places (`MapMistArea.shape`). By the region, it is where the region is, moved with it, and is the rules' too
64
+ *
65
+ * @beta
66
+ */
67
+ export type AreaRef = AreaShape | {
68
+ region: string;
69
+ };
70
+ /**
71
+ * The shape an `AreaRef` stands for: its own, or the named region's among the map's. Nothing for a region that is
72
+ * not there
73
+ *
74
+ * @beta
75
+ */
76
+ export declare function areaShapeOf(ref: AreaRef, regions: readonly MapRegion[]): AreaShape | undefined;
77
+ /**
78
+ * A named part of the map that the rules watch: who walks into it and out of it (`enteredArea`, `leftArea` events),
79
+ * and who is in it now (`world.areas`). Units count, by where their middle is; buildings, scenery and units inside
80
+ * something do not. Given in `GameModule.areas`
81
+ *
82
+ * @beta
83
+ */
84
+ export interface AreaDef {
85
+ /** Shared by every game, like other ids: give it a prefix of the game's (`'td.gate'`) */
86
+ id: string;
87
+ shape: AreaShape;
88
+ }
89
+ /**
90
+ * Typed help for writing an area
91
+ *
92
+ * @beta
93
+ */
94
+ export declare const defineArea: (def: AreaDef) => AreaDef;
95
+ /**
96
+ * Whether a point is in a shape
97
+ *
98
+ * @beta
99
+ */
100
+ export declare function inShape(shape: AreaShape, point: Vec2): boolean;
101
+ /**
102
+ * The radius of a circle round the whole shape from its middle (`x`, `z`): what the spatial index is asked for
103
+ *
104
+ * @beta
105
+ */
106
+ export declare function shapeReach(shape: AreaShape): number;
107
+ /** Who is in each area, by id: kept in the world, so that a save knows, and nobody walks in twice after loading */
108
+ export declare const inside: import("./components").Component<Record<string, number[]>, Record<string, number[]>>;
109
+ /** Areas added while the game runs (`areas.add`): kept in the world, so that a save has them */
110
+ export declare const added: import("./components").Component<AreaDef[], AreaDef[]>;
111
+ /**
112
+ * The areas of a world, and who is in them
113
+ *
114
+ * @beta
115
+ */
116
+ export declare class Areas {
117
+ private readonly world;
118
+ private readonly byId;
119
+ /** Kept between ticks, not made anew */
120
+ private readonly found;
121
+ private readonly now;
122
+ constructor(world: World, defs: readonly AreaDef[]);
123
+ /** The areas of the game, then those added while it runs */
124
+ get all(): Iterable<AreaDef>;
125
+ get size(): number;
126
+ get(id: string): AreaDef;
127
+ /** Whether there is an area of that id */
128
+ has(id: string): boolean;
129
+ private find;
130
+ private added;
131
+ /**
132
+ * Adds an area while the game runs: a zone a spell leaves, a ring that closes in, a part of the map a quest opens.
133
+ * Who is in it is found at the end of the tick, and walks in then. One of the same id, added before, is replaced
134
+ */
135
+ add(def: AreaDef): void;
136
+ /** Takes away an area added while the game runs. Who was in it leaves it (`leftArea`). False when there was none */
137
+ remove(id: string): boolean;
138
+ /** Whether the entity was in the area when the areas were last looked at: the end of the last tick's movement */
139
+ contains(id: string, entity: Entity): boolean;
140
+ /** Who is in the area, as of the last look */
141
+ inside(id: string): Entity[];
142
+ private idsIn;
143
+ /** Looks who is in each area now, and tells who walked in and who walked out. What died in one is just gone */
144
+ update(): void;
145
+ /** Who is in one area now, against who was */
146
+ private look;
147
+ }
148
+ /** Watches the areas, after everyone has moved. Does nothing in a game without any */
149
+ export declare const areaSystem: System;
@@ -0,0 +1,66 @@
1
+ import type { AttackDef, AttackStats, Layer, Stats, UnitTypeDef } from '#engine/defs';
2
+ import { type Entity } from '#engine/entity';
3
+ import type { World } from '#engine/world';
4
+ /**
5
+ * Whether an attack that is for these targets is for this one
6
+ *
7
+ * @beta
8
+ */
9
+ export declare function reaches(targets: AttackDef['targets'], target: {
10
+ def: UnitTypeDef;
11
+ }, layer?: Layer): boolean;
12
+ /**
13
+ * How hard, how fast or how far an attack hits, from the attacker's stats: the stat the attack names
14
+ * (`AttackDef.stats`), or the unit's own (`attackDamage`, `attackSpeed`, `attackRange`). The unit's own for no attack
15
+ *
16
+ * @beta
17
+ */
18
+ export declare function attackStat(stats: Readonly<Stats>, attack: AttackDef | undefined, which: keyof AttackStats): number;
19
+ /**
20
+ * The first of an attacker's attacks that reaches the target where it is (its `targets`), by place, or -1 for none:
21
+ * the engine's `GameRules.combat.pickAttack`
22
+ *
23
+ * @beta
24
+ */
25
+ export declare function defaultPickAttack(world: World, attacker: Entity, target: Entity): number;
26
+ /**
27
+ * Whether a target is too near for one of an attacker's attacks (`AttackDef.minRange`), by place in its attacks: within
28
+ * its dead zone, edge to edge
29
+ *
30
+ * @beta
31
+ */
32
+ export declare function tooNear(attacker: Entity, target: Entity, weapon: number): boolean;
33
+ /**
34
+ * Which of an attacker's attacks it uses against a target, by place in `UnitTypeDef.attacks`, as the game's rules pick
35
+ * it (`GameRules.combat.pickAttack`): -1 for none, its attacks reach not where the target is
36
+ *
37
+ * @beta
38
+ */
39
+ export declare function pickAttack(world: World, attacker: Entity, target: Entity): number;
40
+ /**
41
+ * The farthest any attack of a type looks for enemies by itself (`AttackDef.acquisitionRange`): the engine's
42
+ * `GameRules.combat.acquisitionRange`. 0 for what does not attack
43
+ *
44
+ * @beta
45
+ */
46
+ export declare function farthestAcquisition(def: UnitTypeDef): number;
47
+ /**
48
+ * How far the farthest of a unit's attacks reaches, by its stats (its `attackRange`, or a stat an attack names): what
49
+ * it may hit anything from. 0 for what does not attack
50
+ *
51
+ * @beta
52
+ */
53
+ export declare function farthestReach(def: UnitTypeDef, stats: Readonly<Stats>): number;
54
+ /**
55
+ * How far an attacker's attack reaches a target: the range of the one it uses against it (`pickAttack`), the first's
56
+ * when none does
57
+ *
58
+ * @beta
59
+ */
60
+ export declare function rangeAgainst(world: World, attacker: Entity, target: Entity): number;
61
+ /**
62
+ * The first of a type's attacks that can be told to attack the ground (`AttackDef.ground`), by place, or -1 for none
63
+ *
64
+ * @beta
65
+ */
66
+ export declare function groundAttack(def: UnitTypeDef): number;
@@ -0,0 +1,66 @@
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 attributes pack's id
7
+ *
8
+ * @beta
9
+ */
10
+ export declare const ATTRIBUTES = "core.attributes";
11
+ /**
12
+ * One of the three attributes, each a stat of its own id
13
+ *
14
+ * @beta
15
+ */
16
+ export type Attribute = 'strength' | 'agility' | 'intelligence';
17
+ /**
18
+ * The three attributes, in the order a hero's panel shows them
19
+ *
20
+ * @beta
21
+ */
22
+ export declare const ATTRIBUTE_KEYS: readonly Attribute[];
23
+ /**
24
+ * 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
25
+ * armor and 2% attack speed, intelligence 15 mana and 0.05 mana a second
26
+ *
27
+ * @beta
28
+ */
29
+ export declare const CLASSIC_ATTRIBUTES: Readonly<Record<Attribute, StatChange>>;
30
+ /**
31
+ * What the attributes pack is made with (`withAttributes`)
32
+ *
33
+ * @beta
34
+ */
35
+ export interface AttributesOptions {
36
+ /** What a point of each attribute gives: the classic ones (`CLASSIC_ATTRIBUTES`) for those left out */
37
+ perPoint?: Partial<Record<Attribute, StatChange>>;
38
+ /** What a point of a unit's primary attribute gives besides: 1 attack damage when left out */
39
+ primary?: StatChange;
40
+ /** A unit's primary attribute, in code: its type's `hero.primary` when left out, none for a unit that has none */
41
+ primaryOf?: (world: World, entity: Entity) => Attribute | undefined;
42
+ }
43
+ /**
44
+ * What a unit has of each attribute, everything counted (its type, its level, items, buffs, research): its stats'
45
+ * `strength`, `agility` and `intelligence`
46
+ *
47
+ * @beta
48
+ */
49
+ export declare function attributesOf(world: World, entity: Entity): Record<Attribute, number>;
50
+ /**
51
+ * A unit's primary attribute, as the attributes pack of its game says it (`AttributesOptions.primaryOf`, else its type's
52
+ * `hero.primary`); none in a game without the pack
53
+ *
54
+ * @beta
55
+ */
56
+ export declare function primaryAttribute(world: World, entity: Entity): Attribute | undefined;
57
+ /**
58
+ * Hero attributes, as in classic RTS games: strength, agility and intelligence are stats (`ATTRIBUTE_KEYS`), and every point
59
+ * of them adds to the others (`AttributesOptions.perPoint`, `CLASSIC_ATTRIBUTES` when left out), the primary one's
60
+ * to the attack too (`hero.primary`, `primaryOf`). What a unit has of them is what it has of any stat: its type's
61
+ * `stats`, its hero's `growth` by level, items' `bonus`, buffs, research and the `stats` hook, all of it added up
62
+ * before the points are turned into the rest. A game without it has no attributes
63
+ *
64
+ * @beta
65
+ */
66
+ export declare function withAttributes(options?: AttributesOptions): GamePack;