@pikehub/warpass-bot 62.0.1 → 63.0.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.
- package/CHANGELOG.md +1 -1
- package/docs/api/act.md +1 -1
- package/docs/api/custom.md +24 -0
- package/docs/api/events.md +2 -0
- package/docs/api/game.md +2 -2
- package/docs/api/online.md +2 -0
- package/docs/errors.md +1 -1
- package/docs/llms-full.txt +33 -5
- package/docs/rules/index.md +1 -1
- package/docs/rules/orcs.md +1 -1
- package/docs/rules/templars.md +1 -1
- package/docs/rules/witches.md +1 -1
- package/docs/rules.json +1 -1
- package/index.js +12 -0
- package/llms-full.txt +33 -5
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/docs/api/act.md
CHANGED
|
@@ -14,7 +14,7 @@ Every order a bot can give, on `act` during a think (and on the builder passed t
|
|
|
14
14
|
| `target(who, target, { queued })` | `target(who, target, queued=False)` | the right-click order: attack an enemy, gather a resource, repair your building |
|
|
15
15
|
| `repair(who, target, { queued })` | `repair(who, target, queued=False)` | workers repair one of your buildings |
|
|
16
16
|
| `gather(who, tile, { queued })` | `gather(who, tile, queued=False)` | workers gather the resource on a tile (from `nearestResource`) |
|
|
17
|
-
| `build(who, building, at, { queued })` | `build(who, building, at, queued=False)` | workers place and build a building with its top-left at `at
|
|
17
|
+
| `build(who, building, at, { queued })` | `build(who, building, at, queued=False)` | workers place and build a building with its top-left at `at` (the footprint must be in view); pays on placement |
|
|
18
18
|
| `buildLine(who, building, from, to, { queued })` | `build_line(who, building, start, end, queued=False)` | a line of wall segments |
|
|
19
19
|
| `train(building, unit, count = 1)` | `train(building, unit, count=1)` | queue units (pays now) |
|
|
20
20
|
| `research(building, upgrade)` | `research(building, upgrade)` | queue an upgrade (pays now) |
|
package/docs/api/custom.md
CHANGED
|
@@ -51,7 +51,31 @@ Ops after the first step still apply but make the game unreplayable.
|
|
|
51
51
|
| `until(maxTicks, (observer, tick) => done)` | `until(max_ticks, lambda observer, tick: done)` | step until `done`; returns ticks taken or `-1` |
|
|
52
52
|
| `view(slot)` | `view(slot)` | the fogged [view](view.md) of a slot |
|
|
53
53
|
| `observer()` | `observer()` | the full view of everything, no fog |
|
|
54
|
+
| `events(slot)` | `events(slot)` | the [events](events.md) that slot got since the last call, fog-filtered exactly as in a match |
|
|
55
|
+
| `observerEvents()` | `observer_events()` | every event since the last call, unfiltered |
|
|
54
56
|
| `game(slot)` | `game(slot)` | [queries](game.md) as that slot |
|
|
55
57
|
| `map()` | `map()` | map size, starts, chokes, sites |
|
|
56
58
|
| `replay()` | `replay()` | a [Replay](replay.md) of setup and orders so far |
|
|
57
59
|
| `tick`, `winner` | `tick`, `winner` | current tick; winning slot once over |
|
|
60
|
+
|
|
61
|
+
The first `events` call for a slot (or `observerEvents`) starts recording for it and returns `[]`, so call it once before stepping. After that, each call returns what that player would have received in its `think` during a [local match](local.md):
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import { CustomGame, rules } from "@pikehub/warpass-bot";
|
|
65
|
+
|
|
66
|
+
const r = rules();
|
|
67
|
+
const [a, b] = r.races;
|
|
68
|
+
const g = new CustomGame({ seed: 5, races: [a, b] });
|
|
69
|
+
const [x0, y0] = g.flattenArea(24, 12);
|
|
70
|
+
const fighter = (race) => r.units.find((u) => u.race === race && !u.worker && u.attack);
|
|
71
|
+
const ours = [0, 1, 2].map((k) => g.spawn(0, fighter(a).id, (x0 + 4) * 256, (y0 + 3 + k) * 256));
|
|
72
|
+
[0, 1, 2].forEach((k) => g.spawn(1, fighter(b).id, (x0 + 10) * 256, (y0 + 3 + k) * 256));
|
|
73
|
+
g.events(0);
|
|
74
|
+
g.events(1);
|
|
75
|
+
g.order(0, (act) => act.attackMove(ours, (x0 + 12) * 256, (y0 + 4) * 256));
|
|
76
|
+
g.step(20 * 30);
|
|
77
|
+
const mine = g.events(0);
|
|
78
|
+
const theirs = g.events(1);
|
|
79
|
+
console.log(`slot 0: ${mine.filter((e) => e.t === "hit").length} hits, ${mine.filter((e) => e.t === "death").length} deaths`);
|
|
80
|
+
console.log(`slot 1: ${theirs.filter((e) => e.t === "hit").length} hits`);
|
|
81
|
+
```
|
package/docs/api/events.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
What happened to your player since the last think, in `events` (oldest first). Each event is an object with a type tag `t` and its own fields; ids are numbers that index the rules (unit, building and upgrade lists in `rules()` order).
|
|
4
4
|
|
|
5
|
+
In a [custom game](custom.md), `events(slot)` returns the same events for any slot.
|
|
6
|
+
|
|
5
7
|
| `t` | When |
|
|
6
8
|
|---|---|
|
|
7
9
|
| `trained` | one of your units finished training |
|
package/docs/api/game.md
CHANGED
|
@@ -12,7 +12,7 @@ Questions a bot can ask during a think (`game`, or `match.game` online). Queries
|
|
|
12
12
|
| `canResearch(building, upgrade)` | `can_research(building, upgrade)` | |
|
|
13
13
|
| `placeRefusal(building, at)` | `place_refusal(building, at)` | `null` if a building id fits with its top-left at tile `at`, else a reason |
|
|
14
14
|
| `canPlace(building, at)` | `can_place(building, at)` | |
|
|
15
|
-
| `findPlacement(building, near, radius = 16)` | `find_placement(building, near, radius=16)` | `[tx, ty]` where it fits closest to `near
|
|
15
|
+
| `findPlacement(building, near, radius = 16)` | `find_placement(building, near, radius=16)` | `[tx, ty]` where it fits closest to `near` and is in view now, or `null` |
|
|
16
16
|
| `nearestResource(from, resource, radius = 40)` | `nearest_resource(start, resource, radius=40)` | `[tx, ty]` of the nearest tile with `food`, `wood`, `stone` or `gold` left |
|
|
17
17
|
| `reachable(from, to)` | `reachable(start, end)` | `true` if your units can walk between the two tiles |
|
|
18
18
|
| `front(toward?)` | `front(toward=None)` | `[tx, ty]`: the tile where your army should gather to face tile `toward` (default: the map centre), usually a choke near your base |
|
|
@@ -23,4 +23,4 @@ Questions a bot can ask during a think (`game`, or `match.game` online). Queries
|
|
|
23
23
|
- `building` arguments take a view object or an eid; `unit`, `upgrade` and building ids are strings from the rules.
|
|
24
24
|
- Tile arguments take `[tx, ty]` or an object with `x`, `y` in tiles.
|
|
25
25
|
- Training and research refusals: `notEnough` (resources), `supplyLimit`, `needHousing`, `queueFull`, `requirementsNotMet`, `limitReached`, `invalid` (wrong building, not finished, not yours).
|
|
26
|
-
- Placement refusals: `outOfBounds`, `somethingInWay`, `cannotBuildThere`, `unevenGround`, `rampBlocked`, `buildOnSite` / `siteGround` (site buildings must stand on their site), `alreadyBuilt`, `limitReached`, `requirementsNotMet`, `unknownBuilding`.
|
|
26
|
+
- Placement refusals: `outOfBounds`, `notVisible` (every footprint tile must be in your current vision; send a unit to look first), `somethingInWay`, `cannotBuildThere`, `unevenGround`, `rampBlocked`, `buildOnSite` / `siteGround` (site buildings must stand on their site), `alreadyBuilt`, `limitReached`, `requirementsNotMet`, `unknownBuilding`.
|
package/docs/api/online.md
CHANGED
|
@@ -9,6 +9,7 @@ Connect a bot account, queue or join a lobby by code, play a match and read the
|
|
|
9
9
|
| `await offer.accept({ everyTicks? })` | `offer.accept(every_ticks=10)` | `OnlineMatch` once both accepted |
|
|
10
10
|
| `await wp.lobby({ code, race, everyTicks? })` | `wp.lobby(code, race, every_ticks=10)` | `OnlineMatch` once the host starts: joins a player's lobby by its code, marks ready (again after the host changes the map or race) and waits |
|
|
11
11
|
| `await offer.decline()` | `offer.decline()` | declines; the queue may give you a short penalty |
|
|
12
|
+
| `wp.close()` | `wp.close()` | leaves the queue or lobby and closes the socket; a pending `connect`, `queue`, `accept` or `lobby` fails with `closed` (`stopped`). Call it before exiting on Ctrl-C |
|
|
12
13
|
| `await Warpass.join({ token, matchId, url?, everyTicks? })` | `Warpass.join(match_id, token=, url=, every_ticks=10)` | `OnlineMatch`: rejoin a match you are in after a crash |
|
|
13
14
|
| `match.onThink(think, { everyTicks? })` | `match.on_think(think, every_ticks=None)` | registers your think; returns the match |
|
|
14
15
|
| `await match.ended()` | `match.ended()` | `{ reason }` when the match ends |
|
|
@@ -19,6 +20,7 @@ Connect a bot account, queue or join a lobby by code, play a match and read the
|
|
|
19
20
|
- `url` defaults to `DEFAULT_URL` (`https://warpass.pike.com.br`).
|
|
20
21
|
- `Offer.opponent` is `{ name, bot, rating, race }`.
|
|
21
22
|
- `lobby` fails with `refused` (`missing`, `full`, `started`) when the code is wrong or taken, and with `cancelled` (`closed`) when the host closes the lobby.
|
|
23
|
+
- In Python, Ctrl-C during `connect`, `queue`, `accept` or `lobby` closes the session and raises `KeyboardInterrupt`.
|
|
22
24
|
- In Python, `ended()` and `result()` run your think loop on the calling thread until the match ends; an `async def` think is awaited.
|
|
23
25
|
- In JS, the think loop runs in the background after `onThink`; `ended()` and `result()` wait for it.
|
|
24
26
|
|
package/docs/errors.md
CHANGED
|
@@ -8,7 +8,7 @@ Every SDK call that fails throws a `WarpassError` with a `kind` and the fields b
|
|
|
8
8
|
| `unauthenticated` | | the key is wrong, rotated, or the bot was deleted | create or rotate the key on the Developer page |
|
|
9
9
|
| `refused` | `about`, `reason`, `message` | the server refused a request | see reasons below |
|
|
10
10
|
| `cancelled` | `reason` | the offer fell through (`declined`, `timeout`, the rival left) or the host closed the lobby (`closed`) | queue again |
|
|
11
|
-
| `closed` | `reason` | the socket closed and could not reconnect | connect again; `Warpass.join` resumes a running match |
|
|
11
|
+
| `closed` | `reason` | the socket closed and could not reconnect, or you called `close()` (`stopped`) | connect again; `Warpass.join` resumes a running match |
|
|
12
12
|
| `timeout` | | no answer in time (`result` waits 120 s by default) | retry `result()`; the match may still be sealing |
|
|
13
13
|
| `network` | `message` | DNS, TLS or HTTP failure | check `url` and connectivity |
|
|
14
14
|
|
package/docs/llms-full.txt
CHANGED
|
@@ -285,6 +285,7 @@ Connect a bot account, queue or join a lobby by code, play a match and read the
|
|
|
285
285
|
| `await offer.accept({ everyTicks? })` | `offer.accept(every_ticks=10)` | `OnlineMatch` once both accepted |
|
|
286
286
|
| `await wp.lobby({ code, race, everyTicks? })` | `wp.lobby(code, race, every_ticks=10)` | `OnlineMatch` once the host starts: joins a player's lobby by its code, marks ready (again after the host changes the map or race) and waits |
|
|
287
287
|
| `await offer.decline()` | `offer.decline()` | declines; the queue may give you a short penalty |
|
|
288
|
+
| `wp.close()` | `wp.close()` | leaves the queue or lobby and closes the socket; a pending `connect`, `queue`, `accept` or `lobby` fails with `closed` (`stopped`). Call it before exiting on Ctrl-C |
|
|
288
289
|
| `await Warpass.join({ token, matchId, url?, everyTicks? })` | `Warpass.join(match_id, token=, url=, every_ticks=10)` | `OnlineMatch`: rejoin a match you are in after a crash |
|
|
289
290
|
| `match.onThink(think, { everyTicks? })` | `match.on_think(think, every_ticks=None)` | registers your think; returns the match |
|
|
290
291
|
| `await match.ended()` | `match.ended()` | `{ reason }` when the match ends |
|
|
@@ -295,6 +296,7 @@ Connect a bot account, queue or join a lobby by code, play a match and read the
|
|
|
295
296
|
- `url` defaults to `DEFAULT_URL` (`https://warpass.pike.com.br`).
|
|
296
297
|
- `Offer.opponent` is `{ name, bot, rating, race }`.
|
|
297
298
|
- `lobby` fails with `refused` (`missing`, `full`, `started`) when the code is wrong or taken, and with `cancelled` (`closed`) when the host closes the lobby.
|
|
299
|
+
- In Python, Ctrl-C during `connect`, `queue`, `accept` or `lobby` closes the session and raises `KeyboardInterrupt`.
|
|
298
300
|
- In Python, `ended()` and `result()` run your think loop on the calling thread until the match ends; an `async def` think is awaited.
|
|
299
301
|
- In JS, the think loop runs in the background after `onThink`; `ended()` and `result()` wait for it.
|
|
300
302
|
|
|
@@ -423,7 +425,7 @@ Questions a bot can ask during a think (`game`, or `match.game` online). Queries
|
|
|
423
425
|
| `canResearch(building, upgrade)` | `can_research(building, upgrade)` | |
|
|
424
426
|
| `placeRefusal(building, at)` | `place_refusal(building, at)` | `null` if a building id fits with its top-left at tile `at`, else a reason |
|
|
425
427
|
| `canPlace(building, at)` | `can_place(building, at)` | |
|
|
426
|
-
| `findPlacement(building, near, radius = 16)` | `find_placement(building, near, radius=16)` | `[tx, ty]` where it fits closest to `near
|
|
428
|
+
| `findPlacement(building, near, radius = 16)` | `find_placement(building, near, radius=16)` | `[tx, ty]` where it fits closest to `near` and is in view now, or `null` |
|
|
427
429
|
| `nearestResource(from, resource, radius = 40)` | `nearest_resource(start, resource, radius=40)` | `[tx, ty]` of the nearest tile with `food`, `wood`, `stone` or `gold` left |
|
|
428
430
|
| `reachable(from, to)` | `reachable(start, end)` | `true` if your units can walk between the two tiles |
|
|
429
431
|
| `front(toward?)` | `front(toward=None)` | `[tx, ty]`: the tile where your army should gather to face tile `toward` (default: the map centre), usually a choke near your base |
|
|
@@ -434,7 +436,7 @@ Questions a bot can ask during a think (`game`, or `match.game` online). Queries
|
|
|
434
436
|
- `building` arguments take a view object or an eid; `unit`, `upgrade` and building ids are strings from the rules.
|
|
435
437
|
- Tile arguments take `[tx, ty]` or an object with `x`, `y` in tiles.
|
|
436
438
|
- Training and research refusals: `notEnough` (resources), `supplyLimit`, `needHousing`, `queueFull`, `requirementsNotMet`, `limitReached`, `invalid` (wrong building, not finished, not yours).
|
|
437
|
-
- Placement refusals: `outOfBounds`, `somethingInWay`, `cannotBuildThere`, `unevenGround`, `rampBlocked`, `buildOnSite` / `siteGround` (site buildings must stand on their site), `alreadyBuilt`, `limitReached`, `requirementsNotMet`, `unknownBuilding`.
|
|
439
|
+
- Placement refusals: `outOfBounds`, `notVisible` (every footprint tile must be in your current vision; send a unit to look first), `somethingInWay`, `cannotBuildThere`, `unevenGround`, `rampBlocked`, `buildOnSite` / `siteGround` (site buildings must stand on their site), `alreadyBuilt`, `limitReached`, `requirementsNotMet`, `unknownBuilding`.
|
|
438
440
|
|
|
439
441
|
<!-- api/act.md -->
|
|
440
442
|
|
|
@@ -454,7 +456,7 @@ Every order a bot can give, on `act` during a think (and on the builder passed t
|
|
|
454
456
|
| `target(who, target, { queued })` | `target(who, target, queued=False)` | the right-click order: attack an enemy, gather a resource, repair your building |
|
|
455
457
|
| `repair(who, target, { queued })` | `repair(who, target, queued=False)` | workers repair one of your buildings |
|
|
456
458
|
| `gather(who, tile, { queued })` | `gather(who, tile, queued=False)` | workers gather the resource on a tile (from `nearestResource`) |
|
|
457
|
-
| `build(who, building, at, { queued })` | `build(who, building, at, queued=False)` | workers place and build a building with its top-left at `at
|
|
459
|
+
| `build(who, building, at, { queued })` | `build(who, building, at, queued=False)` | workers place and build a building with its top-left at `at` (the footprint must be in view); pays on placement |
|
|
458
460
|
| `buildLine(who, building, from, to, { queued })` | `build_line(who, building, start, end, queued=False)` | a line of wall segments |
|
|
459
461
|
| `train(building, unit, count = 1)` | `train(building, unit, count=1)` | queue units (pays now) |
|
|
460
462
|
| `research(building, upgrade)` | `research(building, upgrade)` | queue an upgrade (pays now) |
|
|
@@ -475,6 +477,8 @@ Every order a bot can give, on `act` during a think (and on the builder passed t
|
|
|
475
477
|
|
|
476
478
|
What happened to your player since the last think, in `events` (oldest first). Each event is an object with a type tag `t` and its own fields; ids are numbers that index the rules (unit, building and upgrade lists in `rules()` order).
|
|
477
479
|
|
|
480
|
+
In a [custom game](custom.md), `events(slot)` returns the same events for any slot.
|
|
481
|
+
|
|
478
482
|
| `t` | When |
|
|
479
483
|
|---|---|
|
|
480
484
|
| `trained` | one of your units finished training |
|
|
@@ -560,11 +564,35 @@ Ops after the first step still apply but make the game unreplayable.
|
|
|
560
564
|
| `until(maxTicks, (observer, tick) => done)` | `until(max_ticks, lambda observer, tick: done)` | step until `done`; returns ticks taken or `-1` |
|
|
561
565
|
| `view(slot)` | `view(slot)` | the fogged [view](view.md) of a slot |
|
|
562
566
|
| `observer()` | `observer()` | the full view of everything, no fog |
|
|
567
|
+
| `events(slot)` | `events(slot)` | the [events](events.md) that slot got since the last call, fog-filtered exactly as in a match |
|
|
568
|
+
| `observerEvents()` | `observer_events()` | every event since the last call, unfiltered |
|
|
563
569
|
| `game(slot)` | `game(slot)` | [queries](game.md) as that slot |
|
|
564
570
|
| `map()` | `map()` | map size, starts, chokes, sites |
|
|
565
571
|
| `replay()` | `replay()` | a [Replay](replay.md) of setup and orders so far |
|
|
566
572
|
| `tick`, `winner` | `tick`, `winner` | current tick; winning slot once over |
|
|
567
573
|
|
|
574
|
+
The first `events` call for a slot (or `observerEvents`) starts recording for it and returns `[]`, so call it once before stepping. After that, each call returns what that player would have received in its `think` during a [local match](local.md):
|
|
575
|
+
|
|
576
|
+
```js
|
|
577
|
+
import { CustomGame, rules } from "@pikehub/warpass-bot";
|
|
578
|
+
|
|
579
|
+
const r = rules();
|
|
580
|
+
const [a, b] = r.races;
|
|
581
|
+
const g = new CustomGame({ seed: 5, races: [a, b] });
|
|
582
|
+
const [x0, y0] = g.flattenArea(24, 12);
|
|
583
|
+
const fighter = (race) => r.units.find((u) => u.race === race && !u.worker && u.attack);
|
|
584
|
+
const ours = [0, 1, 2].map((k) => g.spawn(0, fighter(a).id, (x0 + 4) * 256, (y0 + 3 + k) * 256));
|
|
585
|
+
[0, 1, 2].forEach((k) => g.spawn(1, fighter(b).id, (x0 + 10) * 256, (y0 + 3 + k) * 256));
|
|
586
|
+
g.events(0);
|
|
587
|
+
g.events(1);
|
|
588
|
+
g.order(0, (act) => act.attackMove(ours, (x0 + 12) * 256, (y0 + 4) * 256));
|
|
589
|
+
g.step(20 * 30);
|
|
590
|
+
const mine = g.events(0);
|
|
591
|
+
const theirs = g.events(1);
|
|
592
|
+
console.log(`slot 0: ${mine.filter((e) => e.t === "hit").length} hits, ${mine.filter((e) => e.t === "death").length} deaths`);
|
|
593
|
+
console.log(`slot 1: ${theirs.filter((e) => e.t === "hit").length} hits`);
|
|
594
|
+
```
|
|
595
|
+
|
|
568
596
|
<!-- api/replay.md -->
|
|
569
597
|
|
|
570
598
|
# Replays
|
|
@@ -773,7 +801,7 @@ Every SDK call that fails throws a `WarpassError` with a `kind` and the fields b
|
|
|
773
801
|
| `unauthenticated` | | the key is wrong, rotated, or the bot was deleted | create or rotate the key on the Developer page |
|
|
774
802
|
| `refused` | `about`, `reason`, `message` | the server refused a request | see reasons below |
|
|
775
803
|
| `cancelled` | `reason` | the offer fell through (`declined`, `timeout`, the rival left) or the host closed the lobby (`closed`) | queue again |
|
|
776
|
-
| `closed` | `reason` | the socket closed and could not reconnect | connect again; `Warpass.join` resumes a running match |
|
|
804
|
+
| `closed` | `reason` | the socket closed and could not reconnect, or you called `close()` (`stopped`) | connect again; `Warpass.join` resumes a running match |
|
|
777
805
|
| `timeout` | | no answer in time (`result` waits 120 s by default) | retry `result()`; the match may still be sealing |
|
|
778
806
|
| `network` | `message` | DNS, TLS or HTTP failure | check `url` and connectivity |
|
|
779
807
|
|
|
@@ -794,7 +822,7 @@ Errors from local games and custom games (unknown ids, setup ops off the map) ar
|
|
|
794
822
|
|
|
795
823
|
<!-- rules/index.md -->
|
|
796
824
|
|
|
797
|
-
# Rules for engine
|
|
825
|
+
# Rules for engine 63
|
|
798
826
|
|
|
799
827
|
Generated from the engine this SDK bundles. Every id below is what the view, the queries and the orders use.
|
|
800
828
|
|
package/docs/rules/index.md
CHANGED
package/docs/rules/orcs.md
CHANGED
package/docs/rules/templars.md
CHANGED
package/docs/rules/witches.md
CHANGED
package/docs/rules.json
CHANGED
package/index.js
CHANGED
|
@@ -220,6 +220,10 @@ export class Warpass {
|
|
|
220
220
|
return new OnlineMatch(this.session, info);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
close() {
|
|
224
|
+
this.session.close();
|
|
225
|
+
}
|
|
226
|
+
|
|
223
227
|
static async join({ token, url = DEFAULT_URL, matchId, everyTicks = 10 } = {}) {
|
|
224
228
|
const session = new native.OnlineSession();
|
|
225
229
|
const info = parse(await guard(session.join(url, token, matchId, everyTicks)));
|
|
@@ -453,6 +457,14 @@ export class CustomGame {
|
|
|
453
457
|
return this.native.view(null);
|
|
454
458
|
}
|
|
455
459
|
|
|
460
|
+
events(slot) {
|
|
461
|
+
return this.native.events(slot);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
observerEvents() {
|
|
465
|
+
return this.native.events(null);
|
|
466
|
+
}
|
|
467
|
+
|
|
456
468
|
map() {
|
|
457
469
|
return this.native.query(0, "map", {});
|
|
458
470
|
}
|
package/llms-full.txt
CHANGED
|
@@ -285,6 +285,7 @@ Connect a bot account, queue or join a lobby by code, play a match and read the
|
|
|
285
285
|
| `await offer.accept({ everyTicks? })` | `offer.accept(every_ticks=10)` | `OnlineMatch` once both accepted |
|
|
286
286
|
| `await wp.lobby({ code, race, everyTicks? })` | `wp.lobby(code, race, every_ticks=10)` | `OnlineMatch` once the host starts: joins a player's lobby by its code, marks ready (again after the host changes the map or race) and waits |
|
|
287
287
|
| `await offer.decline()` | `offer.decline()` | declines; the queue may give you a short penalty |
|
|
288
|
+
| `wp.close()` | `wp.close()` | leaves the queue or lobby and closes the socket; a pending `connect`, `queue`, `accept` or `lobby` fails with `closed` (`stopped`). Call it before exiting on Ctrl-C |
|
|
288
289
|
| `await Warpass.join({ token, matchId, url?, everyTicks? })` | `Warpass.join(match_id, token=, url=, every_ticks=10)` | `OnlineMatch`: rejoin a match you are in after a crash |
|
|
289
290
|
| `match.onThink(think, { everyTicks? })` | `match.on_think(think, every_ticks=None)` | registers your think; returns the match |
|
|
290
291
|
| `await match.ended()` | `match.ended()` | `{ reason }` when the match ends |
|
|
@@ -295,6 +296,7 @@ Connect a bot account, queue or join a lobby by code, play a match and read the
|
|
|
295
296
|
- `url` defaults to `DEFAULT_URL` (`https://warpass.pike.com.br`).
|
|
296
297
|
- `Offer.opponent` is `{ name, bot, rating, race }`.
|
|
297
298
|
- `lobby` fails with `refused` (`missing`, `full`, `started`) when the code is wrong or taken, and with `cancelled` (`closed`) when the host closes the lobby.
|
|
299
|
+
- In Python, Ctrl-C during `connect`, `queue`, `accept` or `lobby` closes the session and raises `KeyboardInterrupt`.
|
|
298
300
|
- In Python, `ended()` and `result()` run your think loop on the calling thread until the match ends; an `async def` think is awaited.
|
|
299
301
|
- In JS, the think loop runs in the background after `onThink`; `ended()` and `result()` wait for it.
|
|
300
302
|
|
|
@@ -423,7 +425,7 @@ Questions a bot can ask during a think (`game`, or `match.game` online). Queries
|
|
|
423
425
|
| `canResearch(building, upgrade)` | `can_research(building, upgrade)` | |
|
|
424
426
|
| `placeRefusal(building, at)` | `place_refusal(building, at)` | `null` if a building id fits with its top-left at tile `at`, else a reason |
|
|
425
427
|
| `canPlace(building, at)` | `can_place(building, at)` | |
|
|
426
|
-
| `findPlacement(building, near, radius = 16)` | `find_placement(building, near, radius=16)` | `[tx, ty]` where it fits closest to `near
|
|
428
|
+
| `findPlacement(building, near, radius = 16)` | `find_placement(building, near, radius=16)` | `[tx, ty]` where it fits closest to `near` and is in view now, or `null` |
|
|
427
429
|
| `nearestResource(from, resource, radius = 40)` | `nearest_resource(start, resource, radius=40)` | `[tx, ty]` of the nearest tile with `food`, `wood`, `stone` or `gold` left |
|
|
428
430
|
| `reachable(from, to)` | `reachable(start, end)` | `true` if your units can walk between the two tiles |
|
|
429
431
|
| `front(toward?)` | `front(toward=None)` | `[tx, ty]`: the tile where your army should gather to face tile `toward` (default: the map centre), usually a choke near your base |
|
|
@@ -434,7 +436,7 @@ Questions a bot can ask during a think (`game`, or `match.game` online). Queries
|
|
|
434
436
|
- `building` arguments take a view object or an eid; `unit`, `upgrade` and building ids are strings from the rules.
|
|
435
437
|
- Tile arguments take `[tx, ty]` or an object with `x`, `y` in tiles.
|
|
436
438
|
- Training and research refusals: `notEnough` (resources), `supplyLimit`, `needHousing`, `queueFull`, `requirementsNotMet`, `limitReached`, `invalid` (wrong building, not finished, not yours).
|
|
437
|
-
- Placement refusals: `outOfBounds`, `somethingInWay`, `cannotBuildThere`, `unevenGround`, `rampBlocked`, `buildOnSite` / `siteGround` (site buildings must stand on their site), `alreadyBuilt`, `limitReached`, `requirementsNotMet`, `unknownBuilding`.
|
|
439
|
+
- Placement refusals: `outOfBounds`, `notVisible` (every footprint tile must be in your current vision; send a unit to look first), `somethingInWay`, `cannotBuildThere`, `unevenGround`, `rampBlocked`, `buildOnSite` / `siteGround` (site buildings must stand on their site), `alreadyBuilt`, `limitReached`, `requirementsNotMet`, `unknownBuilding`.
|
|
438
440
|
|
|
439
441
|
<!-- api/act.md -->
|
|
440
442
|
|
|
@@ -454,7 +456,7 @@ Every order a bot can give, on `act` during a think (and on the builder passed t
|
|
|
454
456
|
| `target(who, target, { queued })` | `target(who, target, queued=False)` | the right-click order: attack an enemy, gather a resource, repair your building |
|
|
455
457
|
| `repair(who, target, { queued })` | `repair(who, target, queued=False)` | workers repair one of your buildings |
|
|
456
458
|
| `gather(who, tile, { queued })` | `gather(who, tile, queued=False)` | workers gather the resource on a tile (from `nearestResource`) |
|
|
457
|
-
| `build(who, building, at, { queued })` | `build(who, building, at, queued=False)` | workers place and build a building with its top-left at `at
|
|
459
|
+
| `build(who, building, at, { queued })` | `build(who, building, at, queued=False)` | workers place and build a building with its top-left at `at` (the footprint must be in view); pays on placement |
|
|
458
460
|
| `buildLine(who, building, from, to, { queued })` | `build_line(who, building, start, end, queued=False)` | a line of wall segments |
|
|
459
461
|
| `train(building, unit, count = 1)` | `train(building, unit, count=1)` | queue units (pays now) |
|
|
460
462
|
| `research(building, upgrade)` | `research(building, upgrade)` | queue an upgrade (pays now) |
|
|
@@ -475,6 +477,8 @@ Every order a bot can give, on `act` during a think (and on the builder passed t
|
|
|
475
477
|
|
|
476
478
|
What happened to your player since the last think, in `events` (oldest first). Each event is an object with a type tag `t` and its own fields; ids are numbers that index the rules (unit, building and upgrade lists in `rules()` order).
|
|
477
479
|
|
|
480
|
+
In a [custom game](custom.md), `events(slot)` returns the same events for any slot.
|
|
481
|
+
|
|
478
482
|
| `t` | When |
|
|
479
483
|
|---|---|
|
|
480
484
|
| `trained` | one of your units finished training |
|
|
@@ -560,11 +564,35 @@ Ops after the first step still apply but make the game unreplayable.
|
|
|
560
564
|
| `until(maxTicks, (observer, tick) => done)` | `until(max_ticks, lambda observer, tick: done)` | step until `done`; returns ticks taken or `-1` |
|
|
561
565
|
| `view(slot)` | `view(slot)` | the fogged [view](view.md) of a slot |
|
|
562
566
|
| `observer()` | `observer()` | the full view of everything, no fog |
|
|
567
|
+
| `events(slot)` | `events(slot)` | the [events](events.md) that slot got since the last call, fog-filtered exactly as in a match |
|
|
568
|
+
| `observerEvents()` | `observer_events()` | every event since the last call, unfiltered |
|
|
563
569
|
| `game(slot)` | `game(slot)` | [queries](game.md) as that slot |
|
|
564
570
|
| `map()` | `map()` | map size, starts, chokes, sites |
|
|
565
571
|
| `replay()` | `replay()` | a [Replay](replay.md) of setup and orders so far |
|
|
566
572
|
| `tick`, `winner` | `tick`, `winner` | current tick; winning slot once over |
|
|
567
573
|
|
|
574
|
+
The first `events` call for a slot (or `observerEvents`) starts recording for it and returns `[]`, so call it once before stepping. After that, each call returns what that player would have received in its `think` during a [local match](local.md):
|
|
575
|
+
|
|
576
|
+
```js
|
|
577
|
+
import { CustomGame, rules } from "@pikehub/warpass-bot";
|
|
578
|
+
|
|
579
|
+
const r = rules();
|
|
580
|
+
const [a, b] = r.races;
|
|
581
|
+
const g = new CustomGame({ seed: 5, races: [a, b] });
|
|
582
|
+
const [x0, y0] = g.flattenArea(24, 12);
|
|
583
|
+
const fighter = (race) => r.units.find((u) => u.race === race && !u.worker && u.attack);
|
|
584
|
+
const ours = [0, 1, 2].map((k) => g.spawn(0, fighter(a).id, (x0 + 4) * 256, (y0 + 3 + k) * 256));
|
|
585
|
+
[0, 1, 2].forEach((k) => g.spawn(1, fighter(b).id, (x0 + 10) * 256, (y0 + 3 + k) * 256));
|
|
586
|
+
g.events(0);
|
|
587
|
+
g.events(1);
|
|
588
|
+
g.order(0, (act) => act.attackMove(ours, (x0 + 12) * 256, (y0 + 4) * 256));
|
|
589
|
+
g.step(20 * 30);
|
|
590
|
+
const mine = g.events(0);
|
|
591
|
+
const theirs = g.events(1);
|
|
592
|
+
console.log(`slot 0: ${mine.filter((e) => e.t === "hit").length} hits, ${mine.filter((e) => e.t === "death").length} deaths`);
|
|
593
|
+
console.log(`slot 1: ${theirs.filter((e) => e.t === "hit").length} hits`);
|
|
594
|
+
```
|
|
595
|
+
|
|
568
596
|
<!-- api/replay.md -->
|
|
569
597
|
|
|
570
598
|
# Replays
|
|
@@ -773,7 +801,7 @@ Every SDK call that fails throws a `WarpassError` with a `kind` and the fields b
|
|
|
773
801
|
| `unauthenticated` | | the key is wrong, rotated, or the bot was deleted | create or rotate the key on the Developer page |
|
|
774
802
|
| `refused` | `about`, `reason`, `message` | the server refused a request | see reasons below |
|
|
775
803
|
| `cancelled` | `reason` | the offer fell through (`declined`, `timeout`, the rival left) or the host closed the lobby (`closed`) | queue again |
|
|
776
|
-
| `closed` | `reason` | the socket closed and could not reconnect | connect again; `Warpass.join` resumes a running match |
|
|
804
|
+
| `closed` | `reason` | the socket closed and could not reconnect, or you called `close()` (`stopped`) | connect again; `Warpass.join` resumes a running match |
|
|
777
805
|
| `timeout` | | no answer in time (`result` waits 120 s by default) | retry `result()`; the match may still be sealing |
|
|
778
806
|
| `network` | `message` | DNS, TLS or HTTP failure | check `url` and connectivity |
|
|
779
807
|
|
|
@@ -794,7 +822,7 @@ Errors from local games and custom games (unknown ids, setup ops off the map) ar
|
|
|
794
822
|
|
|
795
823
|
<!-- rules/index.md -->
|
|
796
824
|
|
|
797
|
-
# Rules for engine
|
|
825
|
+
# Rules for engine 63
|
|
798
826
|
|
|
799
827
|
Generated from the engine this SDK bundles. Every id below is what the view, the queries and the orders use.
|
|
800
828
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikehub/warpass-bot",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "63.0.0",
|
|
4
4
|
"description": "Play Warpass from code: online matches, local games, custom games and replays",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"optionalDependencies": {
|
|
25
|
-
"@pikehub/warpass-bot-linux-x64-gnu": "
|
|
26
|
-
"@pikehub/warpass-bot-linux-arm64-gnu": "
|
|
25
|
+
"@pikehub/warpass-bot-linux-x64-gnu": "63.0.0",
|
|
26
|
+
"@pikehub/warpass-bot-linux-arm64-gnu": "63.0.0"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|