@pkmn/engine 0.1.0-dev.028ab165

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 (62) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +343 -0
  3. package/build/pkg/addon.d.ts +7 -0
  4. package/build/pkg/addon.js +112 -0
  5. package/build/pkg/addon.js.map +1 -0
  6. package/build/pkg/data/ids.json +240 -0
  7. package/build/pkg/data/layout.json +108 -0
  8. package/build/pkg/data/protocol.json +230 -0
  9. package/build/pkg/data.d.ts +91 -0
  10. package/build/pkg/data.js +150 -0
  11. package/build/pkg/data.js.map +1 -0
  12. package/build/pkg/gen1.d.ts +110 -0
  13. package/build/pkg/gen1.js +684 -0
  14. package/build/pkg/gen1.js.map +1 -0
  15. package/build/pkg/index.d.ts +386 -0
  16. package/build/pkg/index.js +122 -0
  17. package/build/pkg/index.js.map +1 -0
  18. package/build/pkg/protocol.d.ts +73 -0
  19. package/build/pkg/protocol.js +473 -0
  20. package/build/pkg/protocol.js.map +1 -0
  21. package/build/test/display.js +400 -0
  22. package/build/test/display.js.map +1 -0
  23. package/build/tools/debug.js +135 -0
  24. package/build/tools/debug.js.map +1 -0
  25. package/build.zig +371 -0
  26. package/package.json +224 -0
  27. package/src/bin/install-pkmn-engine +396 -0
  28. package/src/bin/pkmn-debug +62 -0
  29. package/src/lib/binding/node.zig +134 -0
  30. package/src/lib/binding/wasm.zig +12 -0
  31. package/src/lib/common/battle.zig +17 -0
  32. package/src/lib/common/data.zig +117 -0
  33. package/src/lib/common/debug.zig +74 -0
  34. package/src/lib/common/js.zig +118 -0
  35. package/src/lib/common/optional.zig +67 -0
  36. package/src/lib/common/options.zig +49 -0
  37. package/src/lib/common/protocol.zig +1841 -0
  38. package/src/lib/common/rational.zig +353 -0
  39. package/src/lib/common/rng.zig +243 -0
  40. package/src/lib/common/util.zig +12 -0
  41. package/src/lib/gen1/README.md +894 -0
  42. package/src/lib/gen1/calc.zig +426 -0
  43. package/src/lib/gen1/chance.zig +1060 -0
  44. package/src/lib/gen1/data/moves.zig +1866 -0
  45. package/src/lib/gen1/data/species.zig +1105 -0
  46. package/src/lib/gen1/data/types.zig +131 -0
  47. package/src/lib/gen1/data.zig +634 -0
  48. package/src/lib/gen1/helpers.zig +779 -0
  49. package/src/lib/gen1/mechanics.zig +3128 -0
  50. package/src/lib/gen2/README.md +329 -0
  51. package/src/lib/gen2/calc.zig +143 -0
  52. package/src/lib/gen2/chance.zig +1314 -0
  53. package/src/lib/gen2/data/items.zig +230 -0
  54. package/src/lib/gen2/data/moves.zig +2878 -0
  55. package/src/lib/gen2/data/species.zig +1798 -0
  56. package/src/lib/gen2/data/types.zig +226 -0
  57. package/src/lib/gen2/data.zig +463 -0
  58. package/src/lib/gen2/generated.zig +808 -0
  59. package/src/lib/gen2/helpers.zig +219 -0
  60. package/src/lib/gen2/mechanics.zig +3551 -0
  61. package/src/lib/pkmn.zig +113 -0
  62. package/src/test/display/pkmn.html.tmpl +368 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021-2023 pkmn contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,343 @@
1
+ <p align="center">
2
+ <img alt="pkmn/engine" width="192" height="192" src="https://pkmn.cc/engine.svg" />
3
+ <br />
4
+ <br />
5
+ <a href="https://github.com/pkmn/engine/actions/workflows/test.yml">
6
+ <img alt="Test Status" src="https://github.com/pkmn/engine/workflows/Tests/badge.svg" />
7
+ </a>
8
+ <a href="#status">
9
+ <img alt="WIP" src="https://img.shields.io/badge/status-WIP-red.svg" />
10
+ </a>
11
+ <a href="https://github.com/pkmn/engine/blob/master/LICENSE">
12
+ <img alt="License" src="https://img.shields.io/badge/License-MIT-blue.svg" />
13
+ </a>
14
+ </p>
15
+
16
+ > [!WARNING]
17
+ > **This project is under heavy development** and currently the `main` branch contains numerous breaking
18
+ > changes which may not work and which are not fully documented. Please **wait for the forthcoming
19
+ > initial v0.1 release** before depending on this project (code from the
20
+ > [`old`](https://github.com/pkmn/engine/releases/tag/old) tag can also be used to experiment with a
21
+ > more stable version of the codebase).
22
+
23
+ <hr />
24
+
25
+ A minimal, complete, Pokémon battle simulation engine optimized for performance and
26
+ [designed](docs/DESIGN.md) for tooling, embedded systems, and [artificial
27
+ intelligence](https://github.com/pkmn/0-ERROR) use cases. This engine aims to be a frame-accurate and
28
+ [bug-for-bug compatible](http://www.catb.org/jargon/html/B/bug-for-bug-compatible.html)
29
+ implementation of both Pokémon battles as defined by the original game code and the [Pokémon
30
+ Showdown](https://pokemonshowdown.com/)[^1] simulator which represents Pokémon battling as practically
31
+ interpreted online.
32
+
33
+ The pkmn engine is [**more than 1000× faster**](docs/TESTING.md#results) than the
34
+ [patched](docs/TESTING.md#patches) [Pokémon Showdown simulator
35
+ code](https://github.com/smogon/pokemon-showdown) when playing out supported formats in
36
+ compatibility mode and is extensively [tested](docs/TESTING.md) and [documented](docs). Note,
37
+ however, that the engine is **not a fully featured simulator** but is instead a low-level library
38
+ which can be used as a building block for more advanced use cases.
39
+
40
+ ## Installation
41
+
42
+ This repository hosts both the engine code (written in [Zig](https://ziglang.org/)) and the
43
+ reference driver code (written in [TypeScript](https://www.typescriptlang.org/)).
44
+
45
+ ### `libpkmn`
46
+
47
+ Binaries of the engine code can be downloaded from the
48
+ [releases](https://github.com/pkmn/engine/releases) tab on GitHub, or you can [download the source
49
+ code](https://github.com/pkmn/engine/archive/refs/heads/main.zip) directly and build it with the
50
+ latest `zig` compiler, see `zig build --help` for build options:
51
+
52
+ ```sh
53
+ $ curl https://github.com/pkmn/engine/archive/refs/heads/main.zip -o engine.zip
54
+ $ unzip engine.zip
55
+ $ cd engine
56
+ $ zig build --prefix /usr/local -Doptimize=ReleaseFast
57
+ ```
58
+
59
+ The Zig website has [installation instructions](https://ziglang.org/learn/getting-started/) which
60
+ walk through how to install Zig on each platform - the engine code should work on Zig v0.11.0 or
61
+ greater, though tracks Zig's master branch so this may change in the future if breaking language
62
+ changes are introduced.
63
+
64
+ `libpkmn` can be built with `-Dshowdown` to instead produce the Pokémon Showdown compatible
65
+ `libpkmn-showdown` library. Furthermore, protocol message logging can be enabled through `-Dlog`.
66
+ The `libpkmn` and `libpkmn-showdown` objects available in the binary release are both compiled with
67
+ the `-Dlog` flag by default.
68
+
69
+ ### `@pkmn/engine`
70
+
71
+ The driver code can be installed from [npm](https://www.npmjs.com/package/@pkmn/engine):
72
+
73
+ ```sh
74
+ $ npm install @pkmn/engine
75
+ ```
76
+
77
+ The driver depends on being able to find compiled Node/WASM addons in
78
+ `node_modules/@pkmn/engine/build/lib` to be useful. When you install the package a [`postinstall`
79
+ lifecycle script](https://docs.npmjs.com/cli/v8/using-npm/scripts) runs
80
+ [`install-pkmn-engine`](src/bin/install-pkmn-engine) which checks for a compatible `zig` compiler
81
+ (see earlier regarding minimum version) and download one to `node_module/@pkmn/engine/build/bin` if
82
+ it can't find one, as well as looking for (and downloading, if necessary) the required Node headers
83
+ needed to successfully build the addons natively.
84
+
85
+ **If you have configured `npm` to `--ignore-scripts` you must either run `npx install-pkmn-engine`
86
+ directly or build the addons manually and place the artifacts in the expected paths.**
87
+
88
+ ### `pkmn`
89
+
90
+ Until the [Zig package manager](https://github.com/ziglang/zig/projects/4) is completed, the
91
+ recommended way of using the `pkmn` package in Zig is by either copying this repository into your
92
+ project or by using [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) and then
93
+ adding the following to your `build.zig`:
94
+
95
+ ```zig
96
+ const std = @import("std");
97
+ const pkmn = @import("lib/pkmn/build.zig");
98
+
99
+ pub fn build(b: *std.Build) void {
100
+ ...
101
+ exe.addModule("pkmn", pkmn.module(b, .{ .showdown = true, .log = true }));
102
+ ...
103
+ }
104
+ ```
105
+
106
+ The engine's `build.zig` exposes a `module` function that takes an options structure to allow for
107
+ configuring whether or not Pokémon Showdown compatibility mode or protocol message logging should be
108
+ enabled. Alternatively, you may set options via a `pkmn_options` [root source file
109
+ declaration](https://ziglang.org/documentation/master/#Root-Source-File). There are several
110
+ undocumented internal options that can be tweaked as well via build or root options, though these
111
+ options aren't officially supported, affect correctness, and may change meaning or behavior without
112
+ warning. Use at your own risk.
113
+
114
+ ```zig
115
+ pub const pkmn_options = .{ .showdown = true, .log = true };
116
+ ```
117
+
118
+ ## Usage
119
+
120
+ For each Pokémon generation, the engine provides a battle structure with two functions - a function
121
+ to `update` the battle's state based on both players' choices and a function that defines which
122
+ `choices` are valid at that decision point (at the beginning of a battle both player's must "pass"
123
+ as their first choice to switch in the first member of their party). If `-Dlog` protocol logging is
124
+ enabled each update produces logs which can be decoded into a buffer (`LOGS_SIZE` constants are
125
+ provided to make it easy to allocate a buffer of the correct size). Each `update` returns a result
126
+ to indicate either that the battle has terminated or which types of choices are available for each
127
+ player.
128
+
129
+ Unlike [Pokémon Showdown's
130
+ SIM-PROTOCOL](https://github.com/smogon/pokemon-showdown/blob/master/sim/SIM-PROTOCOL.md#choice-requests)
131
+ which provides a rich request object at each decision point, the pkmn engine computes the possible
132
+ choices on demand based on the result of the previous `update` and the battle state (`CHOICES_SIZE`
133
+ is a good size to initialize the buffer passed to `choices`). **Attempting to update the battle with
134
+ a choice not present in the options returned by `choices` is undefined behavior and may corrupt
135
+ state or cause the engine to crash.**
136
+
137
+ Battles may be played out from any point but to freshly initialize a battle which is yet to start
138
+ the turn count and active Pokémon should be zeroed out (driver code should handle this for you).
139
+ Most driver code should also provide helpers to make initializing battle convenient - check the
140
+ respective documentation and examples for the bindings being used. The engine's [protocol
141
+ documentation](docs/PROTOCOL.md) goes into greater detail on the specifics of updates and the
142
+ potential logs that may result.
143
+
144
+ *The snippets below are meant to merely illustrate in broad strokes how the pkmn engine can be used
145
+ \- the [`examples`](examples) directory contains fully commented and runnable code.*
146
+
147
+ ### C
148
+
149
+ [`pkmn.h`](src/include/pkmn.h) exports the C API for `libpkmn`. Symbols are all prefixed with
150
+ `pkmn_` to avoid name collisions. If `-Dlog` is enabled and logging throws an error then the error
151
+ is encoded in the `pkmn_result` and can be checked with `pkmn_error`.
152
+
153
+ ```c
154
+ #include <pkmn.h>
155
+
156
+ pkmn_battle_options options;
157
+ pkmn_gen1_battle_options_set(&options, ...);
158
+ pkmn_battle battle = ...;
159
+
160
+ pkmn_result result;
161
+ pkmn_choice c1 = 0, c2 = 0;
162
+ while (!pkmn_result_type(result = pkmn_battle_update(&battle, c1, c2, &options))) {
163
+ c1 = choose(PKMN_PLAYER_P1, pkmn_result_p1(result));
164
+ c2 = choose(PKMN_PLAYER_P2, pkmn_result_p2(result));
165
+ pkmn_gen1_battle_options_set(&options, ...);
166
+ }
167
+ if (pkmn_error(result)) exit(1);
168
+ ```
169
+
170
+ [(full code)](examples/c/example.c)
171
+
172
+ The C API doesn't export any helpers for creating or accessing the opaque battle objects - it's
173
+ instead intended to be used as the foundation for more ergonomic bindings in [other
174
+ languages](#other) (the lack of namespaces and bit fields having an implementation-defined layout in
175
+ C are the main contributing factors to the sparseness of what `libpkmn` chooses to expose).
176
+
177
+ ### JavaScript / TypeScript
178
+
179
+ `@pkmn/engine` depends on the [`@pkmn/data`](https://www.npmjs.com/package/@pkmn/data) package which
180
+ requires a `Dex` implementation to be provided as well. The `Battle.create` function can be used to
181
+ initialize a `Battle` from the beginning, or `Battle.restore` can be used to re-instantiate a battle
182
+ which is already in progress. If logging is enabled the output can be turned into Pokémon Showdown
183
+ protocol via `Log.parse`.
184
+
185
+ ```ts
186
+ import {Dex} from '@pkmn/dex';
187
+ import {Generations} from '@pkmn/data';
188
+ import {Battle} from '@pkmn/engine';
189
+
190
+ const gens = new Generations(Dex);
191
+ const battle = Battle.create(...);
192
+
193
+ const choose = (n: number) => Math.random() * n;
194
+
195
+ let result: Result;
196
+ let c1: Choice, c2: Choice;
197
+ while (!(result = battle.update(c1, c2)).type) {
198
+ c1 = battle.choose('p1', result, choose);
199
+ c2 = battle.choose('p2', result, choose);
200
+ }
201
+
202
+ console.log(result);
203
+ ```
204
+
205
+ [(full code)](examples/js/example.ts)
206
+
207
+ By default, the `@pkmn/engine` package compiles the engine with `-Dshowdown`, though by running
208
+ `install-pkmn-engine` directly and passing in `--options` you can override this default and build
209
+ different configurations of the extension for the driver to use. The driver can support
210
+ configurations both with and without Pokémon Showdown compatibility simultaneously if present. On
211
+ update, the post-install script attempts to rebuild whichever extensions it finds with the same
212
+ configuration parameters that were originally used meaning updating to the newest version of the
213
+ library should be seamless.
214
+
215
+ Despite relying on the native engine code, the `@pkmn/engine` code is designed to also work in
216
+ browsers which support [WebAssembly](https://webassembly.org/). Running `npm run start:web` from the
217
+ [`examples`](examples/js) directory starts a server that can be used to demonstrate the engine
218
+ running in the browser.
219
+
220
+ ### Zig
221
+
222
+ The `pkmn` Zig package exposes helper methods to simplify state instantiation and any `Writer` can
223
+ be used when logging is enabled to allow for easily printing e.g. to standard out or a buffer.
224
+
225
+ ```zig
226
+ const std = @import("std");
227
+ const pkmn = @import("pkmn");
228
+
229
+ var random = std.rand.DefaultPrng.init(seed).random();
230
+ var choices: [pkmn.CHOICES_SIZE]pkmn.Choice = undefined;
231
+
232
+ var battle = ...
233
+ var options = pkmn.battle.options(...);
234
+
235
+ var c1 = pkmn.Choice{};
236
+ var c2 = pkmn.Choice{};
237
+
238
+ var result = try battle.update(c1, c2, &options);
239
+ while (result.type == .None) : (result = try battle.update(c1, c2, &options)) {
240
+ c1 = choices[random.uintLessThan(u8, battle.choices(.P1, result.p1, &choices))];
241
+ c2 = choices[random.uintLessThan(u8, battle.choices(.P2, result.p2, &choices))];
242
+ }
243
+
244
+ std.debug.print("{}\n", .{result.type});
245
+ ```
246
+
247
+ [(full code)](examples/zig/example.zig)
248
+
249
+ The Zig package also supports some APIs which are difficult to expose elsewhere such as the
250
+ `FixedRNG` which allows you to fully specify the exact RNG frames (which can be useful for ensuring
251
+ certain outcomes/effects always occur) for a battle, though doing so changes the size of the
252
+ `Battle` object.
253
+
254
+ ### Other
255
+
256
+ Developers who wish to use the engine in other languages should find writing bindings against
257
+ [`libpkmn`](#libpkmn) relatively straightforward based on the existing documentation, though to
258
+ simplify the process even further [`src/data`](src/data) contains JSON dumps of all of the Pokémon
259
+ data, structure sizes and offsets, and protocol information used by the reference driver code. The
260
+ following is a list of known `libpkmn` bindings written by developers outside of the [pkmn
261
+ organization](https://github.com/pkmn) that may be helpful (though note that these projects may not
262
+ necessarily be up-to-date/complete/correct - inclusion in this list doesn't imply endorsement):
263
+
264
+ | Language | License | URL |
265
+ | ---------- | --------- | ------------------------------------ |
266
+ | **C++** | `BSL-1.0` | https://github.com/pasyg/wrapsire |
267
+ | **Python** | `MIT` | https://github.com/AnnikaCodes/PyKMN |
268
+
269
+
270
+ #### `pkmn-debug`
271
+
272
+ The [`@pkmn/engine`](#pkmnengine) package ships with a `pkmn-debug` tool which exists to decode the
273
+ binary data structures and protocols used by the engine and to output a [standalone
274
+ webpage](https://pkmn.cc/debug.html) that can be used for debugging. To use this tool in a folder
275
+ that has the `@pkmn/engine` package installed locally you can use `npx pkmn-debug`, though you may
276
+ also wish to install the package globally to be able to use this tool anywhere without
277
+ [`npx`](https://docs.npmjs.com/cli/v7/commands/npx):
278
+
279
+ ```sh
280
+ $ npm install --global @pkmn/engine
281
+ ```
282
+
283
+ By default, `pkmn-debug` expects to read [binary debug protocol](docs/PROTOCOL.md#debugging) from
284
+ [standard input](https://en.wikipedia.org/wiki/Standard_streams) and output HTML to standard output:
285
+
286
+ ```sh
287
+ $ <cmd> | pkmn-debug > index.html
288
+ ```
289
+
290
+ Alternatively, if a single filename argument is passed to the `pkmn-debug` it reads from that
291
+ instead:
292
+
293
+ ```sh
294
+ $ pkmn-debug <file> > index.html
295
+ ```
296
+
297
+ ## Status
298
+
299
+ The engine is currently expected to be developed over multiple stages:
300
+
301
+ | Stage | Deliverables |
302
+ | ------- | ----------------------------------------------- |
303
+ | **0** | documentation, integration, benchmark, protocol |
304
+ | **1** | RBY & GSC |
305
+ | **2** | ADV & DPP |
306
+ | ***3*** | *modern generations* |
307
+
308
+ Currently, most of the foundational work from stage 0 is done:
309
+
310
+ - [benchmark and integration testing](src/test) infrastructure
311
+ - [documentation](docs) about design, research, methodology, etc
312
+ - definition and implementation of the [protocol](docs/PROTOCOL.md) that's used by the engine
313
+
314
+ **Stage 1 is currently in progress** and involves the implementation of the actual Generation I & II
315
+ battle engines, followed by Generation III & IV in stage 2. The implementation of further Pokémon
316
+ generations is in scope for the project but shouldn't be considered part of the immediate roadmap
317
+ (i.e. exploring the options for broadening support for old generation APIs is given higher priority
318
+ than implementing more modern generations). Furthermore, implementation of modern generations is
319
+ soft-blocked on the [availability of high quality
320
+ decompilations](https://github.com/orgs/pret/repositories) of the original games in question.
321
+
322
+ Certain features will always be deemed **out of scope**:
323
+
324
+ - team/set validation or custom rule ("format") enforcement
325
+ - first-class support for "mods" to core Pokémon data and mechanics
326
+ - [battle variants](https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_battle#Battle_variants)
327
+ other than single (full) or double battles
328
+ - code for exposing the engine to users (input validation, game socket server, etc)
329
+
330
+ ## License
331
+
332
+ The pkmn engine is distributed under the terms of the [MIT License](LICENSE).
333
+
334
+ [^1]: In the case of Pokémon Showdown, only bugs which stem from a misimplementation of specific
335
+ effects are reproduced in the engine, bugs which are the result of a misunderstanding of the
336
+ fundamental mechanics of Pokémon or which simply arise due to specific Pokémon Showdown
337
+ implementation details that aren't replicable without making the same (incorrect) architectural
338
+ choices aren't. Furthermore, the "Pokémon Showdown" code referenced by this project includes
339
+ several [patches](docs/TESTING.md#patches) to improve accuracy and smooth over some of the more
340
+ egregious implementation issues. In practical terms, the vast majority of games played out in the
341
+ pkmn engine's compatibility mode and on this patched Pokémon Showdown simulator are the same,
342
+ it's only in a well defined and documented set of circumstances where the two implementations
343
+ diverge.
@@ -0,0 +1,7 @@
1
+ import { Choice, Player, Result } from '.';
2
+ export declare function check(showdown: boolean): void;
3
+ export declare function supports(showdown: boolean, log?: boolean): boolean;
4
+ export declare function update(index: number, showdown: boolean, battle: ArrayBuffer, c1?: Choice, c2?: Choice, log?: ArrayBuffer): Result;
5
+ export declare function choices(index: number, showdown: boolean, battle: ArrayBuffer, player: Player, choice: Choice['type'], buf: ArrayBuffer): Choice[];
6
+ export declare function choose(index: number, showdown: boolean, battle: ArrayBuffer, player: Player, choice: Choice['type'], buf: ArrayBuffer, fn: (n: number) => number): Choice;
7
+ export declare function size(index: number, type: 'choices' | 'log'): number;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.size = exports.choose = exports.choices = exports.update = exports.supports = exports.check = void 0;
27
+ const path = __importStar(require("path"));
28
+ const _1 = require(".");
29
+ const ROOT = path.join(__dirname, '..', '..');
30
+ let ADDON = undefined;
31
+ function load() {
32
+ if (ADDON)
33
+ return ADDON;
34
+ let pkmn = undefined;
35
+ let showdown = undefined;
36
+ try {
37
+ pkmn = require(path.join(ROOT, 'build', 'lib', 'pkmn.node')).engine;
38
+ }
39
+ catch { }
40
+ try {
41
+ showdown =
42
+ require(path.join(ROOT, 'build', 'lib', 'pkmn-showdown.node')).engine;
43
+ }
44
+ catch { }
45
+ if (!pkmn && !showdown) {
46
+ throw new Error('Could not find native addons - did you run `npx install-pkmn-engine`?');
47
+ }
48
+ return (ADDON = [pkmn, showdown]);
49
+ }
50
+ function check(showdown) {
51
+ if (!load()[+showdown]) {
52
+ const opts = ADDON[+!showdown].options.log ? ['-log'] : [];
53
+ if (showdown)
54
+ opts.push('-Dshowdown');
55
+ throw new Error(`@pkmn/engine has ${showdown ? 'not' : 'only'} been configured to support Pokémon Showdown.` +
56
+ `\n(running \`npx install-pkmn-engine --options='${opts.join(' ')}'\` can fix this issue).`);
57
+ }
58
+ }
59
+ exports.check = check;
60
+ function supports(showdown, log) {
61
+ if (!load()[+showdown])
62
+ return false;
63
+ if (log === undefined)
64
+ return true;
65
+ return ADDON[+showdown].options.log === log;
66
+ }
67
+ exports.supports = supports;
68
+ function update(index, showdown, battle, c1, c2, log) {
69
+ return _1.Result.decode(ADDON[+showdown].bindings[index]
70
+ .update(battle, _1.Choice.encode(c1), _1.Choice.encode(c2), log));
71
+ }
72
+ exports.update = update;
73
+ function choices(index, showdown, battle, player, choice, buf) {
74
+ const request = choice[0] === 'p' ? 0 : choice[0] === 'm' ? 1 : 2;
75
+ const n = ADDON[+showdown].bindings[index].choices(battle, +(player !== 'p1'), request, buf);
76
+ // The top-level API signature means our hands our tied with respect to
77
+ // writing really fast bindings here. The simplest approach would be to return
78
+ // the ArrayBuffer the bindings populate as well as its size and only decode a
79
+ // Choice after the selection. However, given that we need to return
80
+ // `Choices[]` we need to decode all of them even if they're not all being
81
+ // used which is wasteful. This shouldn't be *that* bad as its a very small
82
+ // list, but its still wasted work. Switching the top-level API to return an
83
+ // Iterable<Choice> doesn't help as we need both the length and the ability to
84
+ // randomly access it, so the best way to make the current API fast would be
85
+ // to have the Zig bindings create Choice objects directly, only that won't
86
+ // scale well as it would require us to basically rewrite the low-level
87
+ // choices function for each generation within node.zig. We could do something
88
+ // really galaxy-brained and return some sort of frankenstein subclass of
89
+ // Array backed by ArrayBuffer which would lazily decode the Choice on access,
90
+ // but thats ultimately not worth the effort. You can't have both a high-level
91
+ // idiomatic API and performance here, hence why the choose function below
92
+ // exists.
93
+ const options = new Array(n);
94
+ const data = new Uint8Array(buf);
95
+ for (let i = 0; i < n; i++)
96
+ options[i] = _1.Choice.decode(data[i]);
97
+ return options;
98
+ }
99
+ exports.choices = choices;
100
+ function choose(index, showdown, battle, player, choice, buf, fn) {
101
+ const request = choice[0] === 'p' ? 0 : choice[0] === 'm' ? 1 : 2;
102
+ const n = ADDON[+showdown].bindings[index].choices(battle, +(player !== 'p1'), request, buf);
103
+ const data = new Uint8Array(buf);
104
+ return _1.Choice.decode(data[fn(n)]);
105
+ }
106
+ exports.choose = choose;
107
+ function size(index, type) {
108
+ const bindings = (ADDON[1] ?? ADDON[0]).bindings[index];
109
+ return type[0] === 'c' ? bindings.CHOICES_SIZE : bindings.LOGS_SIZE;
110
+ }
111
+ exports.size = size;
112
+ //# sourceMappingURL=addon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addon.js","sourceRoot":"","sources":["../../src/pkg/addon.ts"],"names":[],"mappings":"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"}