├── .gitattributes
├── .github
└── workflows
│ ├── fuzz.yml
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── CITATION.cff
├── LICENSE
├── Makefile
├── README.md
├── build.zig
├── docs
├── CONTRIBUTING.md
├── DESIGN.md
├── NOTES.md
├── PROTOCOL.md
├── RESEARCH.md
└── TESTING.md
├── eslint.config.mjs
├── examples
├── c
│ ├── Makefile
│ └── example.c
├── js
│ ├── .parcelrc
│ ├── example.ts
│ ├── index.html
│ ├── package.json
│ ├── tsconfig.json
│ └── vite.config.mts
└── zig
│ ├── example.zig
│ ├── legacy
│ ├── build.zig
│ ├── example.zig
│ └── lib
│ │ └── pkmn
│ └── modern
│ ├── build.zig
│ ├── build.zig.zon
│ └── example.zig
├── package.json
├── src
├── bin
│ ├── install-pkmn-engine
│ └── pkmn-debug
├── data
│ ├── data.json
│ ├── layout.json
│ └── protocol.json
├── include
│ └── pkmn.h
├── lib
│ ├── bindings
│ │ ├── c.zig
│ │ ├── node.zig
│ │ └── wasm.zig
│ ├── c.zig
│ ├── common
│ │ ├── array.zig
│ │ ├── battle.zig
│ │ ├── data.zig
│ │ ├── data
│ │ │ ├── items.zig.tmpl
│ │ │ ├── moves.zig.tmpl
│ │ │ ├── species.zig.tmpl
│ │ │ └── types.zig.tmpl
│ │ ├── debug.zig
│ │ ├── js.zig
│ │ ├── napi.zig
│ │ ├── optional.zig
│ │ ├── options.zig
│ │ ├── protocol.zig
│ │ ├── rational.zig
│ │ ├── rng.zig
│ │ ├── test.zig
│ │ └── util.zig
│ ├── gen1
│ │ ├── README.md
│ │ ├── calc.zig
│ │ ├── chance.zig
│ │ ├── data.zig
│ │ ├── data
│ │ │ ├── moves.zig
│ │ │ ├── species.zig
│ │ │ └── types.zig
│ │ ├── helpers.zig
│ │ ├── mechanics.zig
│ │ └── test.zig
│ ├── gen2
│ │ ├── README.md
│ │ ├── calc.zig
│ │ ├── chance.zig
│ │ ├── data.zig
│ │ ├── data
│ │ │ ├── items.zig
│ │ │ ├── moves.zig
│ │ │ ├── species.zig
│ │ │ └── types.zig
│ │ ├── generated.zig
│ │ ├── helpers.zig
│ │ ├── mechanics.zig
│ │ └── test.zig
│ ├── node.zig
│ ├── pkmn.zig
│ ├── test.zig
│ └── wasm.zig
├── pkg
│ ├── addon.test.ts
│ ├── addon.ts
│ ├── addon
│ │ ├── browser.ts
│ │ ├── node.ts
│ │ └── wasm.ts
│ ├── common.test.ts
│ ├── common.ts
│ ├── data.test.ts
│ ├── data.ts
│ ├── data
│ │ ├── ids.json
│ │ ├── layout.json
│ │ ├── mapping.json
│ │ └── protocol.json
│ ├── fixtures
│ │ ├── p1.txt
│ │ └── p2.txt
│ ├── gen1.test.ts
│ ├── gen1.ts
│ ├── index.test.ts
│ ├── index.ts
│ ├── protocol.test.ts
│ └── protocol.ts
├── test
│ ├── README.md
│ ├── benchmark.test.ts
│ ├── benchmark.ts
│ ├── benchmark.zig
│ ├── fixtures
│ │ └── gen1
│ │ │ ├── 0x11C7F5D02584A5A4.input.log
│ │ │ ├── 0x130C2A0BF1934A4C.showdown.bin
│ │ │ ├── 0x138CA5166EFF6A9.input.log
│ │ │ ├── 0x166525E4E3DD0132.input.log
│ │ │ ├── 0x1A2182BB0BBD9E64.showdown.bin
│ │ │ ├── 0x1C6394FF9C3565F4.pkmn.bin
│ │ │ ├── 0x1EE16974B4257C8E.input.log
│ │ │ ├── 0x208E374CB1E2F97F.input.log
│ │ │ ├── 0x20C2659866E5ED21.input.log
│ │ │ ├── 0x219E8F9B8DFA3E50.pkmn.bin
│ │ │ ├── 0x2E41948934F9D949.input.log
│ │ │ ├── 0x2E5A75A49C4B8EA4.input.log
│ │ │ ├── 0x306C5E0779663612.input.log
│ │ │ ├── 0x30B477546C73D7BC.input.log
│ │ │ ├── 0x317C2C25C222F280.input.log
│ │ │ ├── 0x39CCE4D290A254CD.input.log
│ │ │ ├── 0x3AAFC8792686FE24.input.log
│ │ │ ├── 0x43952058CEDD7279.input.log
│ │ │ ├── 0x46C1FA4F5C3A1B4B.showdown.bin
│ │ │ ├── 0x479DCF7B406B5186.input.log
│ │ │ ├── 0x48ADAAC95C9CC04A.input.log
│ │ │ ├── 0x490175968B905049.input.log
│ │ │ ├── 0x4AE7643BF1626D6C.input.log
│ │ │ ├── 0x510BC88B7E670BB9.pkmn.bin
│ │ │ ├── 0x53821EB41ED3144A.input.log
│ │ │ ├── 0x582807711B0A22D.pkmn.bin
│ │ │ ├── 0x5BB7D44744B7DDB5.input.log
│ │ │ ├── 0x5C0BFA662F064934.input.log
│ │ │ ├── 0x5C0EF6E4C9278E03.input.log
│ │ │ ├── 0x5DB1BB2DED9461F2.input.log
│ │ │ ├── 0x5F4C27C3C400CCEF.input.log
│ │ │ ├── 0x62D8FB8ED11CDD7D.input.log
│ │ │ ├── 0x63F75EBC9E2B6DF8.input.log
│ │ │ ├── 0x6861A8111EF46045.input.log
│ │ │ ├── 0x6C979DFBC6743D5C.input.log
│ │ │ ├── 0x6EFF8B7677077FE6.input.log
│ │ │ ├── 0x762098D67285A45A.input.log
│ │ │ ├── 0x7DE5A2DD96BA07A5.input.log
│ │ │ ├── 0x842EFA1D879EC636.showdown.bin
│ │ │ ├── 0x87CB47D78C9E83DB.input.log
│ │ │ ├── 0x891A4DEC2DA0D04A.input.log
│ │ │ ├── 0x895A570B71E79B86.input.log
│ │ │ ├── 0x898990C029C4E108.input.log
│ │ │ ├── 0x89A935237DDA962E.showdown.bin
│ │ │ ├── 0x8C9747603D30586E.input.log
│ │ │ ├── 0x924FD037527C65A3.input.log
│ │ │ ├── 0x973C10A9C58D94FD.input.log
│ │ │ ├── 0x973EF0823E0530B9.input.log
│ │ │ ├── 0x9C329D229CD33ED7.input.log
│ │ │ ├── 0x9E2B535EAB26BB7E.input.log
│ │ │ ├── 0x9FFAFACA6FEECB03.input.log
│ │ │ ├── 0xA0406E4B3AA33F5E.input.log
│ │ │ ├── 0xA0F50070ADB32DED.input.log
│ │ │ ├── 0xA31F27EAF9BF4E3B.input.log
│ │ │ ├── 0xA99BCE90DBE18670.pkmn.bin
│ │ │ ├── 0xAF52B504F51A337C.pkmn.bin
│ │ │ ├── 0xB265471DCC2DDDC8.input.log
│ │ │ ├── 0xB5A6F7607C1F2AFD.input.log
│ │ │ ├── 0xB679D91D90ED0486.input.log
│ │ │ ├── 0xB758AB5F9D7AD36D.input.log
│ │ │ ├── 0xB9131B7324E482AD.input.log
│ │ │ ├── 0xB9A1A38FCBBF6648.input.log
│ │ │ ├── 0xBABA377EE1638987.input.log
│ │ │ ├── 0xBB26504CA21FA2C0.input.log
│ │ │ ├── 0xBB75F6633DBA4C08.input.log
│ │ │ ├── 0xBC0AF7D28AA6F25F.input.log
│ │ │ ├── 0xBC867937B5A262F8.input.log
│ │ │ ├── 0xBCC4F5F803A4C0C5.input.log
│ │ │ ├── 0xC1F3A1A3CBF66E2B.input.log
│ │ │ ├── 0xC2A02FC2F3D1EF24.input.log
│ │ │ ├── 0xC40D2C12D0F8185D.input.log
│ │ │ ├── 0xC468FF6E1CEE314D.pkmn.bin
│ │ │ ├── 0xC58F31E184357C16.input.log
│ │ │ ├── 0xC8524A847B4AF353.input.log
│ │ │ ├── 0xCA20018840CC123.pkmn.bin
│ │ │ ├── 0xCB56DFD6457B04BA.input.log
│ │ │ ├── 0xCC64741157FC11DB.pkmn.bin
│ │ │ ├── 0xCDD8EB1C112F2B02.input.log
│ │ │ ├── 0xCDE87ADE2DEA69C.input.log
│ │ │ ├── 0xCE3086F839722570.input.log
│ │ │ ├── 0xCE87A7774C1AAB24.input.log
│ │ │ ├── 0xCF83C12D71CE716D.pkmn.bin
│ │ │ ├── 0xD2B1817739AAF4B3.input.log
│ │ │ ├── 0xD463BA4C49D333F3.input.log
│ │ │ ├── 0xDAF1C0765173FF0F.input.log
│ │ │ ├── 0xDAFD0E44A75472CB.input.log
│ │ │ ├── 0xDC1E0DB334E0EAF2.input.log
│ │ │ ├── 0xDDE61D4454448DA8.input.log
│ │ │ ├── 0xE1C1F3089C963B91.input.log
│ │ │ ├── 0xE26C9A0D11C52B93.input.log
│ │ │ ├── 0xE2D929DD7D14C5F4.showdown.bin
│ │ │ ├── 0xE331C7BB28218AD3.input.log
│ │ │ ├── 0xE3FE59D3E25042F4.input.log
│ │ │ ├── 0xE47319978AD041B1.input.log
│ │ │ ├── 0xE6412ECA6071C6D4.pkmn.bin
│ │ │ ├── 0xE7E6B0F82286A08B.input.log
│ │ │ ├── 0xEBEC48B906A37945.pkmn.bin
│ │ │ ├── 0xEC4103CD675CDAA1.input.log
│ │ │ ├── 0xEC906D7B433288F0.pkmn.bin
│ │ │ ├── 0xED1F32123199F701.input.log
│ │ │ ├── 0xED964909377B7E8E.input.log
│ │ │ ├── 0xEFAA766A8ED2D5BF.showdown.bin
│ │ │ ├── 0xF091D4934DA9A368.input.log
│ │ │ ├── 0xF12F2AB7B055F0E7.input.log
│ │ │ ├── 0xF2D588816B2E321C.input.log
│ │ │ ├── 0xF783B7B8A7EC8BE6.input.log
│ │ │ ├── 0xF9035DA297392F5D.input.log
│ │ │ └── 0xFFD857F18AB7602.input.log
│ ├── fuzz.test.ts
│ ├── fuzz.ts
│ ├── fuzz.zig
│ ├── integration.test.ts
│ ├── integration.ts
│ ├── regression.test.ts
│ ├── showdown.html.tmpl
│ ├── showdown.ts
│ ├── showdown
│ │ ├── gen1.test.ts
│ │ └── gen2.test.ts
│ └── stats.ts
└── tools
│ ├── README.md
│ ├── analyze.zig
│ ├── debug.ts
│ ├── demo.ts
│ ├── demo.zig
│ ├── display
│ ├── autocomplete.old.css
│ ├── autocomplete.old.ts
│ ├── debug.css
│ ├── debug.tsx
│ ├── demo.tsx
│ ├── dom.ts
│ ├── index.ts
│ ├── select.css
│ ├── select.tsx
│ ├── ui.css
│ ├── ui.tsx
│ └── util.ts
│ ├── dump.zig
│ ├── generate.ts
│ ├── release.ts
│ ├── serde.ts
│ ├── serde.zig
│ ├── transitions.zig
│ ├── version.zig
│ └── vscode
│ ├── LICENSE
│ ├── README.md
│ ├── extension.ts
│ └── package.json
├── tsconfig.json
├── vite.config.mts
└── zig.patch
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Windows
2 | * text=auto
3 | *.zig text=auto eol=lf
4 | *.zon text=auto eol=lf
5 |
6 | # Binary
7 | *.bin binary
8 |
9 | # GitHub
10 | src/data/* linguist-generated=true
11 | src/lib/gen1/data/* linguist-generated=true
12 | src/lib/gen2/data/* linguist-generated=true
13 | src/lib/gen2/generated.zig linguist-generated=true
14 | src/pkg/data/* linguist-generated=true
15 | src/pkg/data/mapping.json linguist-generated=false
16 |
--------------------------------------------------------------------------------
/.github/workflows/fuzz.yml:
--------------------------------------------------------------------------------
1 | name: Fuzz
2 | on:
3 | schedule:
4 | - cron: '36 */6 * * *'
5 | push:
6 | branches: [ main ]
7 | pull_request:
8 | branches: [ main ]
9 | workflow_dispatch:
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
12 | cancel-in-progress: true
13 | jobs:
14 | fuzz:
15 | strategy:
16 | fail-fast: false
17 | matrix:
18 | gen: [1]
19 | options: ['', '-Dshowdown']
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v4
23 | - uses: scheibo/build-zig@main
24 | with:
25 | patch-file: zig.patch
26 | - run: npm install --ignore-scripts
27 | - run: zig build -Doptimize=ReleaseSafe -Dlog -Dchance -Dcalc ${{matrix.options}} fuzz -- ${{matrix.gen}} 15m | tee seed.txt
28 | shell: bash
29 | - run: |
30 | node src/bin/install-pkmn-engine
31 | npm run --silent fuzz -- ${{matrix.options == '' && 'pkmn' || 'showdown' }} ${{matrix.gen}} 1s $(cat seed.txt)
32 | if: failure()
33 | - run: |
34 | node src/bin/install-pkmn-engine --options="-Dshowdown -Dlog -Dchance -Dcalc"
35 | npm run integration -- --gen=${{matrix.gen}} --duration=15m --maxFailures=5 --debug=false
36 | if: ${{ matrix.options != '' }}
37 | - uses: actions/upload-artifact@v4
38 | if: failure()
39 | with:
40 | name: logs
41 | path: logs
42 | if-no-files-found: error
43 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | schedule:
4 | - cron: '0 2 * * *'
5 | workflow_dispatch:
6 | jobs:
7 | test:
8 | uses: ./.github/workflows/test.yml
9 | release:
10 | needs: test
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: actions/setup-node@v4
15 | with:
16 | node-version: 20
17 | registry-url: 'https://registry.npmjs.org'
18 | scope: '@pkmn'
19 | - uses: scheibo/build-zig@main
20 | with:
21 | patch-file: zig.patch
22 | - run: npm install --ignore-scripts
23 | - run: npm run release
24 | env:
25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26 | NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on:
3 | push:
4 | branches: [ main ]
5 | pull_request:
6 | branches: [ main ]
7 | workflow_dispatch:
8 | workflow_call:
9 | concurrency:
10 | group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
11 | cancel-in-progress: true
12 | jobs:
13 | test:
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | os: [ubuntu-latest, macos-latest, windows-latest]
18 | options: ['', '-Dlog -Dchance -Dcalc', '-Dshowdown', '-Dshowdown -Dlog -Dchance -Dcalc']
19 | zig: [local, 0.14.0, master] # local = 0.11.0
20 | exclude:
21 | - os: windows-latest
22 | zig: local
23 | runs-on: ${{matrix.os}}
24 | steps:
25 | - uses: actions/checkout@v4
26 | - run: git config core.symlinks true
27 | # NOTE: we rely on npm postinstall-ed zig for local zig
28 | - uses: goto-bus-stop/setup-zig@default
29 | if: ${{ matrix.zig != 'local' }}
30 | with:
31 | version: ${{matrix.zig}}
32 | - run: npm install
33 | - run: echo "${GITHUB_WORKSPACE}/build/bin/zig" >> $GITHUB_PATH
34 | if: ${{ matrix.zig == 'local' && matrix.os != 'windows-latest' }}
35 | - run: echo "${env:GITHUB_WORKSPACE}/build/bin/zig" >> $env:GITHUB_PATH
36 | if: ${{ matrix.zig == 'local' && matrix.os == 'windows-latest' }}
37 | - run: zig build test ${{matrix.options}}
38 | - run: zig build test ${{matrix.options}} -Doptimize=ReleaseFast
39 | - run: npm run compile
40 | - run: npm test
41 | - run: node src/bin/install-pkmn-engine --options="${{matrix.options}}"
42 | - run: npm run test:integration
43 | - run: zig build ${{matrix.options}} -p build
44 | - run: make example options="${{matrix.options}}"
45 | - uses: AnnikaCodes/install-ziglint@main
46 | with:
47 | token: ${{ secrets.GITHUB_TOKEN }}
48 | - run: make lint
49 | - run: make clean && node src/bin/install-pkmn-engine --zig
50 | - run: zig build ${{matrix.options}} -p build -Ddynamic
51 | - run: make c-example options="${{matrix.options}}" dynamic=true
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac
2 | .DS_Store
3 | Thumbs.db
4 | .vscode
5 |
6 | # Zig
7 | .zig-cache/
8 | zig-cache/
9 | zig-out/
10 | build/
11 | /docgen_tmp/
12 |
13 | # C
14 | *.o
15 |
16 | # JS
17 | coverage/
18 | node_modules/
19 | dist/
20 | *package-lock.json
21 | *npm-debug.log
22 | .eslintcache
23 | .tsbuildinfo
24 | .parcel-cache/
25 |
26 | # Project
27 | .cache
28 | examples/c/example
29 | examples/zig/zig-cache
30 | logs/
31 | release/
32 | !src/test/fixtures/*/*.log
33 | src/tools/vscode/extension.js
34 | *.vsix
35 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: 1.2.0
2 | title: libpkmn
3 | type: software
4 | authors:
5 | - given-names: Kirk
6 | family-names: Scheibelhut
7 | email: pre@pkmn.cc
8 | orcid: 'https://orcid.org/0009-0004-7829-4237'
9 | license: MIT
10 | url: 'https://pkmn.cc/engine'
11 | repository-code: 'https://github.com/pkmn/engine'
12 | repository-artifact: 'https://github.com/pkmn/engine/releases/'
13 | abstract: >-
14 | libpkmn is minimal, complete, Pokémon battle simulation engine optimized for
15 | performance and designed for tooling, embedded systems, and artificial
16 | intelligence use cases. This engine aims to be a frame-accurate and
17 | bug-for-bug compatible implementation of both Pokémon battles as defined by
18 | the original game code and the Pokémon Showdown simulator which represents
19 | Pokémon battling as practically interpreted online.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2021-2025 pkmn contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Please read through the [README](../README.md), [docs](../docs), and
4 | [pkmn.cc/@pkmn](https://pkmn.cc/@pkmn/) for general information about the pkmn engine and about
5 | development on `@pkmn` projects respectively. The pkmn engine Zig code loosely adheres to the [style
6 | guidelines outlined by
7 | TigerBeetle](https://github.com/tigerbeetledb/tigerbeetle/blob/main/docs/TIGER_STYLE.md), whereas
8 | the TypeScript code follows the usual [`@pkmn` style](https://pkmn.cc/@pkmn/#style). When opening
9 | issues or pull requests, please use one of the existing templates and fill them out to the best of
10 | your ability. Pull requests are unlikely to be merged without tests, but it's fine to open a pull
11 | request without tests for feedback or to ask for help with testing. :)
12 |
13 | The best way to help contribute to the pkmn engine is actually to contribute to the upstream
14 | projects that the engine depends on - fixing bugs/simplifying
15 | [smogon/pokemon-showdown](https://github.com/smogon/pokemon-showdown) or improving/clarifying the
16 | [pret](https://github.com/pret) decompilations are the highest impact ways to benefit not just the
17 | engine but the larger Pokémon development community.
18 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import pkmn from "@pkmn/eslint-config";
2 |
3 | export default [...pkmn, {
4 | files: ["src/bin/!(*.*)"],
5 | }, {
6 | ignores: ["dist/", "node_modules/", "examples/zig", "build/", "src/tools/vscode/extension.js"],
7 | }, {
8 | files: ["src/pkg/common.ts", "src/pkg/index.ts", "src/test/integration.ts"],
9 | rules: {
10 | "no-control-regex": "off",
11 | "@typescript-eslint/no-empty-interface": "off",
12 | "@typescript-eslint/no-shadow": "off",
13 | "@typescript-eslint/no-unsafe-declaration-merging": "off"
14 | }
15 | }, {
16 | files: ["src/pkg/addon/node.ts", "src/tools/debug.ts"],
17 | rules: {
18 | "@typescript-eslint/no-var-requires": "off",
19 | "@typescript-eslint/no-require-imports": "off",
20 | }
21 | },{
22 | files: ["src/test/benchmark*.ts"],
23 | rules: {
24 | "@typescript-eslint/no-unused-vars": "off",
25 | "@typescript-eslint/no-redundant-type-constituents": "off"
26 | }
27 | }, {
28 | files: ["src/pkg/protocol.test.ts"],
29 | rules: {"jest/no-standalone-expect": "off", "jest/no-conditional-expect": "off"}
30 | }, {
31 | files: ["src/test/*.test.ts"],
32 | rules: {"jest/no-standalone-expect": "off"}
33 | }, {
34 | files: ["src/test/showdown/**"],
35 | rules: {"jest/expect-expect": ["warn", {assertFunctionNames: ["expect", "expectLog", "verify"]}]}
36 | }, {
37 | files: ["src/test/fuzz.ts", "src/tools/serde.ts"],
38 | rules: {"@typescript-eslint/prefer-promise-reject-errors": "off"},
39 | }, {
40 | files: ["src/tools/generate.ts"],
41 | rules: {"@typescript-eslint/restrict-template-expressions": ["error", {"allowBoolean": true}]}
42 | }];
43 |
--------------------------------------------------------------------------------
/examples/js/.parcelrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@parcel/config-default"],
3 | "reporters": ["...", "parcel-reporter-static-files-copy"]
4 | }
--------------------------------------------------------------------------------
/examples/js/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @pkmn/engine
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@pkmn/data": "^0.9.31",
4 | "@pkmn/dex": "^0.9.31",
5 | "@pkmn/engine": "file:../..",
6 | "@pkmn/sets": "^5.1.2"
7 | },
8 | "devDependencies": {
9 | "parcel-reporter-static-files-copy": "^1.5.3",
10 | "parcel": "^2.13.3",
11 | "vite-plugin-commonjs": "^0.10.4",
12 | "vite": "^6.2.0",
13 | "typescript": "^5.8.2"
14 | },
15 | "scripts": {
16 | "prestart": "tsc -p .",
17 | "start": "node build/example.js",
18 | "start:web": "npm run start:vite",
19 | "start:parcel": "parcel --no-autoinstall index.html",
20 | "start:vite": "vite"
21 | },
22 | "alias": {
23 | "process": {
24 | "global": "process"
25 | }
26 | },
27 | "staticFiles": {
28 | "staticPath": "node_modules/@pkmn/engine/build/lib/pkmn-showdown.wasm"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/js/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "exclude": ["vite.config.mts"],
3 | "compilerOptions": {
4 | "downlevelIteration": true,
5 | "outDir": "build",
6 | "rootDir": ".",
7 | "sourceMap": true,
8 | "strict": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/js/vite.config.mts:
--------------------------------------------------------------------------------
1 | import commonjs from 'vite-plugin-commonjs';
2 |
3 | export default {
4 | publicDir: 'node_modules/@pkmn/engine/build/lib',
5 | plugins: [commonjs()]
6 | }
--------------------------------------------------------------------------------
/examples/zig/legacy/build.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const pkmn = @import("lib/pkmn/build.zig");
3 |
4 | pub fn build(b: *std.Build) void {
5 | const target = b.standardTargetOptions(.{});
6 | const optimize = b.standardOptimizeOption(.{});
7 |
8 | const showdown = b.option(bool, "showdown", "Enable Pokémon Showdown compatibility mode");
9 | const log = b.option(bool, "log", "Enable protocol message logging");
10 |
11 | const exe = b.addExecutable(.{
12 | .name = "example",
13 | .root_source_file = .{ .path = "example.zig" },
14 | .optimize = optimize,
15 | .target = target,
16 | });
17 | const module = pkmn.module(b, .{ .showdown = showdown, .log = log });
18 | if (@hasField(@TypeOf(exe.*), "root_module")) {
19 | exe.root_module.addImport("pkmn", module);
20 | } else {
21 | exe.addModule("pkmn", module);
22 | }
23 | b.installArtifact(exe);
24 |
25 | const run_cmd = b.addRunArtifact(exe);
26 | run_cmd.step.dependOn(b.getInstallStep());
27 | if (b.args) |args| run_cmd.addArgs(args);
28 |
29 | const run_step = b.step("run", "Run the app");
30 | run_step.dependOn(&run_cmd.step);
31 | }
32 |
--------------------------------------------------------------------------------
/examples/zig/legacy/example.zig:
--------------------------------------------------------------------------------
1 | ../example.zig
--------------------------------------------------------------------------------
/examples/zig/legacy/lib/pkmn:
--------------------------------------------------------------------------------
1 | ../../../..
--------------------------------------------------------------------------------
/examples/zig/modern/build.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 |
3 | pub fn build(b: *std.Build) void {
4 | const target = b.standardTargetOptions(.{});
5 | const optimize = b.standardOptimizeOption(.{});
6 |
7 | const showdown =
8 | b.option(bool, "showdown", "Enable Pokémon Showdown compatibility mode") orelse false;
9 | const log = b.option(bool, "log", "Enable protocol message logging") orelse false;
10 |
11 | const exe = b.addExecutable(.{
12 | .name = "example",
13 | .root_source_file = if (@hasField(std.Build.LazyPath, "path"))
14 | .{ .path = "example.zig" }
15 | else
16 | b.path("example.zig"),
17 | .optimize = optimize,
18 | .target = target,
19 | });
20 | const pkmn = b.dependency("pkmn", .{ .showdown = showdown, .log = log });
21 | exe.root_module.addImport("pkmn", pkmn.module("pkmn"));
22 | b.installArtifact(exe);
23 |
24 | const run_cmd = b.addRunArtifact(exe);
25 | run_cmd.step.dependOn(b.getInstallStep());
26 | if (b.args) |args| run_cmd.addArgs(args);
27 |
28 | const run_step = b.step("run", "Run the app");
29 | run_step.dependOn(&run_cmd.step);
30 | }
31 |
--------------------------------------------------------------------------------
/examples/zig/modern/build.zig.zon:
--------------------------------------------------------------------------------
1 | .{
2 | .name = .example,
3 | .version = "0.0.1",
4 | .fingerprint = 0x6eec9b9ff9b9cee6,
5 | .minimum_zig_version = "0.14.0",
6 | .paths = .{"."},
7 | .dependencies = .{
8 | .pkmn = .{ .path = "../../.." },
9 | },
10 | }
11 |
--------------------------------------------------------------------------------
/examples/zig/modern/example.zig:
--------------------------------------------------------------------------------
1 | ../example.zig
--------------------------------------------------------------------------------
/src/bin/pkmn-debug:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 |
4 | try {
5 | require('source-map-support').install();
6 | } catch (err) {
7 | if (err.code !== 'MODULE_NOT_FOUND') throw err;
8 | }
9 |
10 | const {execFileSync} = require('child_process');
11 | const {readFileSync} = require('fs');
12 | const {join, resolve} = require('path');
13 |
14 | const ROOT = resolve(__dirname, '..', '..');
15 | const packageJSON = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'));
16 |
17 | const missing = [];
18 | for (const dep of ['@pkmn/img', 'html-minifier', 'esbuild']) {
19 | try {
20 | require.resolve(dep);
21 | } catch (e) {
22 | if (e.code !== 'MODULE_NOT_FOUND') throw e;
23 | missing.push(`${dep}@${packageJSON.devDependencies[dep]}`);
24 | }
25 | }
26 |
27 | let Dex = undefined;
28 | try {
29 | Dex = require('@pkmn/sim').Dex;
30 | } catch (err) {
31 | if (err.code !== 'MODULE_NOT_FOUND') throw err;
32 | try {
33 | Dex = require('@pkmn/dex').Dex;
34 | } catch (e) {
35 | if (e.code !== 'MODULE_NOT_FOUND') throw e;
36 | missing.push(`@pkmn/dex@${packageJSON.dependencies['@pkmn/data']}`);
37 | }
38 | }
39 |
40 | if (missing.length) {
41 | if (+/^v(\d+)/.exec(process.version)[1] < 16) {
42 | console.error('pkmn-debug requires Node v16+');
43 | process.exit(1);
44 | }
45 |
46 | execFileSync('npm', ['install', ...missing, '--global'], {encoding: 'utf8'});
47 |
48 | const node_modules = execFileSync('npm', ['root', '--global'], {encoding: 'utf8'}).trim();
49 | if (!process.env.NODE_PATH || !process.env.NODE_PATH.includes(node_modules)) {
50 | console.error(`NODE_PATH must include npm's global node_modules directory: '${node_modules}'`);
51 | process.exit(1);
52 | }
53 | }
54 |
55 | const {Generations} = require('@pkmn/data');
56 |
57 | const {run} = require('../../build/tools/debug');
58 |
59 | run(new Generations(Dex)).catch(err => {
60 | console.error(err.message);
61 | process.exit(1);
62 | });
63 |
--------------------------------------------------------------------------------
/src/data/layout.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "sizes": {
4 | "Battle": 384,
5 | "Side": 184,
6 | "Pokemon": 24,
7 | "ActivePokemon": 32,
8 | "Actions": 16,
9 | "Durations": 8,
10 | "Summaries": 12
11 | },
12 | "offsets": {
13 | "Battle": {
14 | "sides": 0,
15 | "turn": 368,
16 | "last_damage": 370,
17 | "last_moves": 372,
18 | "rng": 374
19 | },
20 | "Side": {
21 | "pokemon": 0,
22 | "active": 144,
23 | "order": 176,
24 | "last_selected_move": 182,
25 | "last_used_move": 183
26 | },
27 | "Pokemon": {
28 | "stats": 0,
29 | "moves": 10,
30 | "hp": 18,
31 | "status": 20,
32 | "species": 21,
33 | "types": 22,
34 | "level": 23
35 | },
36 | "ActivePokemon": {
37 | "stats": 0,
38 | "species": 10,
39 | "types": 11,
40 | "boosts": 12,
41 | "volatiles": 16,
42 | "moves": 24
43 | },
44 | "Stats": {
45 | "hp": 0,
46 | "atk": 2,
47 | "def": 4,
48 | "spe": 6,
49 | "spc": 8
50 | },
51 | "Boosts": {
52 | "atk": 0,
53 | "def": 4,
54 | "spe": 8,
55 | "spc": 12,
56 | "accuracy": 16,
57 | "evasion": 20
58 | },
59 | "Volatiles": {
60 | "Bide": 0,
61 | "Thrashing": 1,
62 | "MultiHit": 2,
63 | "Flinch": 3,
64 | "Charging": 4,
65 | "Binding": 5,
66 | "Invulnerable": 6,
67 | "Confusion": 7,
68 | "Mist": 8,
69 | "FocusEnergy": 9,
70 | "Substitute": 10,
71 | "Recharging": 11,
72 | "Rage": 12,
73 | "LeechSeed": 13,
74 | "Toxic": 14,
75 | "LightScreen": 15,
76 | "Reflect": 16,
77 | "Transform": 17,
78 | "confusion": 18,
79 | "attacks": 21,
80 | "state": 24,
81 | "substitute": 40,
82 | "transform": 48,
83 | "disable_duration": 52,
84 | "disable_move": 56,
85 | "toxic": 59
86 | },
87 | "Action": {
88 | "damage": 0,
89 | "hit": 8,
90 | "critical_hit": 10,
91 | "secondary_chance": 12,
92 | "speed_tie": 14,
93 | "confused": 16,
94 | "paralyzed": 18,
95 | "duration": 20,
96 | "sleep": 24,
97 | "confusion": 26,
98 | "disable": 29,
99 | "attacking": 31,
100 | "binding": 33,
101 | "move_slot": 36,
102 | "pp": 40,
103 | "multi_hit": 44,
104 | "psywave": 48,
105 | "metronome": 56
106 | },
107 | "Duration": {
108 | "sleeps": 0,
109 | "confusion": 18,
110 | "disable": 21,
111 | "attacking": 25,
112 | "binding": 28
113 | },
114 | "Damage": {
115 | "base": 0,
116 | "final": 2,
117 | "capped": 4
118 | }
119 | }
120 | }
121 | ]
122 |
--------------------------------------------------------------------------------
/src/lib/bindings/wasm.zig:
--------------------------------------------------------------------------------
1 | const pkmn = @import("../pkmn.zig");
2 | const std = @import("std");
3 |
4 | const assert = std.debug.assert;
5 |
6 | const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
7 | const Strong = if (@hasField(std.builtin.GlobalLinkage, "strong")) .strong else .Strong;
8 |
9 | pub const options = pkmn.options;
10 |
11 | pub fn gen(comptime num: comptime_int) type {
12 | const g = @field(pkmn, "gen" ++ std.fmt.comptimePrint("{d}", .{num}));
13 | return struct {
14 | pub const CHOICES_SIZE = size(g.CHOICES_SIZE);
15 | pub const LOGS_SIZE = size(g.LOGS_SIZE);
16 |
17 | pub fn update(
18 | battle: *g.Battle(g.PRNG),
19 | c1: pkmn.Choice,
20 | c2: pkmn.Choice,
21 | options_: ?[*]u8,
22 | ) callconv(.C) pkmn.Result {
23 | return (if (options_) |o| result: {
24 | const buf = @as([*]u8, @ptrCast(o))[0..g.LOGS_SIZE];
25 | var stream: pkmn.protocol.ByteStream = .{ .buffer = buf };
26 | // TODO: extract out
27 | var opts = pkmn.battle.options(
28 | pkmn.protocol.FixedLog{ .writer = stream.writer() },
29 | g.chance.NULL,
30 | g.calc.NULL,
31 | );
32 | break :result battle.update(c1, c2, &opts);
33 | } else battle.update(c1, c2, &g.NULL)) catch unreachable;
34 | }
35 |
36 | pub fn choices(
37 | battle: *g.Battle(g.PRNG),
38 | player: u8,
39 | request: u8,
40 | buf: [*]u8,
41 | ) callconv(.C) u8 {
42 | assert(player <= @field(@typeInfo(pkmn.Player), @tagName(Enum)).fields.len);
43 | assert(request <= @field(@typeInfo(pkmn.Choice.Type), @tagName(Enum)).fields.len);
44 |
45 | const n = CHOICES_SIZE;
46 | return battle.choices(@enumFromInt(player), @enumFromInt(request), @ptrCast(buf[0..n]));
47 | }
48 | };
49 | }
50 |
51 | pub fn exports() type {
52 | @export(gen(1).update, .{ .name = "GEN1_update", .linkage = Strong });
53 | @export(gen(1).choices, .{ .name = "GEN1_choices", .linkage = Strong });
54 | return struct {};
55 | }
56 |
57 | fn size(n: usize) u32 {
58 | return std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(n))) catch unreachable;
59 | }
60 |
--------------------------------------------------------------------------------
/src/lib/c.zig:
--------------------------------------------------------------------------------
1 | const c = @import("bindings/c.zig");
2 | const std = @import("std");
3 |
4 | export const PKMN_OPTIONS = c.OPTIONS;
5 |
6 | export const PKMN_MAX_CHOICES = c.MAX_CHOICES;
7 | export const PKMN_CHOICES_SIZE = c.CHOICES_SIZE;
8 | export const PKMN_MAX_LOGS = c.MAX_LOGS;
9 | export const PKMN_LOGS_SIZE = c.LOGS_SIZE;
10 |
11 | export const PKMN_GEN1_MAX_CHOICES = c.gen(1).MAX_CHOICES;
12 | export const PKMN_GEN1_CHOICES_SIZE = c.gen(1).CHOICES_SIZE;
13 | export const PKMN_GEN1_MAX_LOGS = c.gen(1).MAX_LOGS;
14 | export const PKMN_GEN1_LOGS_SIZE = c.gen(1).LOGS_SIZE;
15 |
16 | const exportable = @hasDecl(std.zig, "Zir") and !@hasField(std.zig.Zir.Inst.Tag, "export_value");
17 |
18 | usingnamespace if (exportable) struct {
19 | export const pkmn_choice_init = c.choice_init;
20 | export const pkmn_choice_type = c.choice_type;
21 | export const pkmn_choice_data = c.choice_data;
22 |
23 | export const pkmn_result_type = c.result_type;
24 | export const pkmn_result_p1 = c.result_p1;
25 | export const pkmn_result_p2 = c.result_p2;
26 |
27 | export const pkmn_error = c.err;
28 |
29 | export const pkmn_psrng_init = c.psrng_init;
30 | export const pkmn_psrng_next = c.psrng_next;
31 |
32 | export const pkmn_rational_init = c.rational_init;
33 | export const pkmn_rational_reduce = c.rational_reduce;
34 | export const pkmn_rational_numerator = c.rational_numerator;
35 | export const pkmn_rational_denominator = c.rational_denominator;
36 |
37 | export const pkmn_gen1_battle_options_set =
38 | c.gen(1).battle_options_set;
39 | export const pkmn_gen1_battle_options_chance_probability =
40 | c.gen(1).battle_options_chance_probability;
41 | export const pkmn_gen1_battle_options_chance_actions =
42 | c.gen(1).battle_options_chance_actions;
43 | export const pkmn_gen1_battle_options_chance_durations =
44 | c.gen(1).battle_options_chance_durations;
45 | export const pkmn_gen1_battle_options_calc_summaries =
46 | c.gen(1).battle_options_calc_summaries;
47 |
48 | export const pkmn_gen1_battle_update = c.gen(1).battle_update;
49 | export const pkmn_gen1_battle_choices = c.gen(1).battle_choices;
50 | } else c.exports();
51 |
--------------------------------------------------------------------------------
/src/lib/common/array.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 |
3 | const expectEqual = std.testing.expectEqual;
4 | const assert = std.debug.assert;
5 |
6 | const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
7 | const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
8 |
9 | /// Helpers for working with bit-packed arrays of non-powers-of-2 types.
10 | /// NOTE: ziglang/zig#12547
11 | pub fn Array(comptime n: comptime_int, comptime U: type) type {
12 | return struct {
13 | const size = @bitSizeOf(U);
14 | const options: std.builtin.Type.Int = .{ .signedness = .unsigned, .bits = size * n };
15 | pub const T = @Type(if (@hasField(std.builtin.Type, "int"))
16 | .{ .int = options }
17 | else
18 | .{ .Int = options });
19 |
20 | /// Returns the value stored at index `i` in the array `a`.
21 | pub fn get(a: T, i: usize) U {
22 | assert(i < n);
23 | const shift = i * size;
24 | const mask: T = (1 << size) - 1;
25 | const result = (a >> @intCast(shift)) & mask;
26 | return switch (@typeInfo(U)) {
27 | Enum => @enumFromInt(result),
28 | Int => @intCast(result),
29 | else => unreachable,
30 | };
31 | }
32 |
33 | /// Sets the value at index `i` to `val` in the array `a`.
34 | pub fn set(a: T, i: usize, val: U) T {
35 | assert(i < n);
36 | const v: T = switch (@typeInfo(U)) {
37 | Enum => @intFromEnum(val),
38 | Int => @intCast(val),
39 | else => unreachable,
40 | };
41 | const shift = i * size;
42 | const mask: T = @as(T, @intCast((1 << size) - 1)) << @intCast(shift);
43 | const result: T = a & ~mask;
44 | return result | (v << @intCast(shift));
45 | }
46 | };
47 | }
48 |
49 | test Array {
50 | const A = Array(5, u8);
51 | var a: A.T = 0;
52 | try expectEqual(u40, @TypeOf(a));
53 |
54 | a = A.set(a, 4, 241);
55 | try expectEqual(@as(u8, 241), A.get(a, 4));
56 | a = A.set(a, 4, 1);
57 | try expectEqual(@as(u8, 1), A.get(a, 4));
58 |
59 | for (0..5) |i| a = A.set(a, i, @intCast(i));
60 | for (0..5) |i| try expectEqual(@as(u8, @intCast(i)), A.get(a, i));
61 |
62 | const Optional = @import("optional.zig").Optional;
63 |
64 | const B = Array(4, Optional(bool));
65 | var b: B.T = 0;
66 | try expectEqual(u8, @TypeOf(b));
67 |
68 | b = B.set(b, 2, .true);
69 | try expectEqual(Optional(bool).None, B.get(b, 1));
70 | try expectEqual(Optional(bool).true, B.get(b, 2));
71 | try expectEqual(@as(u8, 0b00100000), b);
72 | b = B.set(b, 2, .None);
73 | b = B.set(b, 0, .false);
74 | try expectEqual(Optional(bool).None, B.get(b, 2));
75 | try expectEqual(Optional(bool).false, B.get(b, 0));
76 | try expectEqual(@as(u8, 0b0000001), b);
77 | }
78 |
--------------------------------------------------------------------------------
/src/lib/common/battle.zig:
--------------------------------------------------------------------------------
1 | /// Stores state required by optional features to the engine that can be passed to a generation's
2 | /// `Battle.update` function. All generations generically support protocol logging (enabled via
3 | /// `-Dlog`), chance actions and probability tracking (enabled via `-Dchance`), and damage
4 | /// computation and chance overrides (`-Dcalc`), though the concrete types for these features are
5 | /// generation dependent.
6 | pub fn Options(comptime Log: type, comptime Chance: type, comptime Calc: type) type {
7 | return struct { log: Log, chance: Chance, calc: Calc };
8 | }
9 |
10 | /// Helper to create a battle `Options` object with the provided `log`, `chance`, and `calc`.
11 | pub fn options(
12 | log: anytype,
13 | chance: anytype,
14 | calc: anytype,
15 | ) Options(@TypeOf(log), @TypeOf(chance), @TypeOf(calc)) {
16 | return .{ .log = log, .chance = chance, .calc = calc };
17 | }
18 |
--------------------------------------------------------------------------------
/src/lib/common/data/items.zig.tmpl:
--------------------------------------------------------------------------------
1 | //! Code generated by `tools/generate` - manual edits will be overwritten.
2 |
3 | const data = @import("../../gen{{{ gen }}}/data.zig");
4 | const std = @import("std");
5 |
6 | const assert = std.debug.assert;
7 | const Type = data.Type;
8 |
9 | /// Representation of a held item in Generation {{{ roman }}} Pokémon.
10 | pub const Item = enum({{{ Item.type }}}) {
11 | None,
12 | {{{ Item.values }}}
13 |
14 | comptime {
15 | assert(@sizeOf(Item) == {{{ Item.size }}});
16 | }
17 |
18 | /// The number of held items in this generation.
19 | pub const size = {{{ Item.num }}};
20 |
21 | /// Returns a `Type` boosted by this item or `null` if the item is not a type-boosting item.
22 | pub fn boost(item: Item) ?Type {
23 | assert(item != .None);
24 | if (item == .PolkadotBow) return .Normal;
25 | return if (@intFromEnum(item) <= {{{ Item.boosts }}}) @enumFromInt(@intFromEnum(item) - 1) else null;
26 | }
27 |
28 | /// Whether or not this item is Mail.
29 | pub fn isMail(item: Item) bool {
30 | assert(item != .None);
31 | return @intFromEnum(item) > {{{ Item.present }}} and @intFromEnum(item) <= {{{ Item.mail }}};
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/src/lib/common/data/moves.zig.tmpl:
--------------------------------------------------------------------------------
1 | //! Code generated by `tools/generate` - manual edits will be overwritten.
2 |
3 | const gen{{{ gen }}} = @import("../../gen{{{ gen }}}/data.zig");
4 | {{{ import }}}
5 | const std = @import("std");
6 |
7 | const assert = std.debug.assert;{{{ percent }}}
8 | const Type = gen{{{ gen }}}.Type;
9 |
10 | /// Representation of a Generation {{{ roman }}} Pokémon move.
11 | pub const Move = enum({{{ Move.type }}}) {
12 | None,
13 | {{{ Move.values }}},
14 |
15 | {{{ Move.Data }}}
16 |
17 | const DATA = [_]Data{
18 | {{{ Move.data }}},
19 | };
20 | {{{ Move.Effect }}}
21 | const Target = enum({{{ Move.targetType }}}) {
22 | // none
23 | All,
24 | AllySide,
25 | Field,
26 | Self,
27 | // resolve
28 | AllOthers,
29 | Depends,
30 | Other,
31 | Any,
32 | Allies,
33 | Ally,
34 | AllyOrSelf,
35 | Foe,
36 | // resolve + run
37 | Foes,
38 | FoeSide,
39 | RandomFoe,
40 | };
41 |
42 | const PP = [_]u8{
43 | {{{ Move.ppData }}},
44 | };
45 |
46 | comptime {
47 | assert(@sizeOf(Move) == {{{ Move.size }}});
48 | assert(@sizeOf(@TypeOf(DATA)) == {{{ Move.dataSize }}});
49 | }
50 |
51 | /// The number of Pokémon moves in this generation.
52 | pub const size = {{{ Move.num }}};
53 |
54 | /// Pokémon moves that can be called by Metronome in this generation.
55 | pub const METRONOME = {{{ Move.metronome }}}
56 |
57 | /// Returns the `Data` corresponding to the move.
58 | pub fn get(id: Move) Data {
59 | {{{ Move.assert }}}
60 | return DATA[@intFromEnum(id) - 1];
61 | }
62 |
63 | /// Returns the base PP of the move.
64 | pub fn pp(id: Move) u8 {
65 | assert(id != .None);
66 | return PP[@intFromEnum(id) - 1];
67 | }
68 | };
69 |
--------------------------------------------------------------------------------
/src/lib/common/data/species.zig.tmpl:
--------------------------------------------------------------------------------
1 | //! Code generated by `tools/generate` - manual edits will be overwritten.
2 |
3 | const gen{{{ gen }}} = @import("../../gen{{{ gen }}}/data.zig");
4 | const std = @import("std");
5 |
6 | const assert = std.debug.assert;
7 | const Stats = gen{{{ gen }}}.Stats;
8 | const Types = gen{{{ gen }}}.Types;
9 |
10 | /// Representation of a Generation {{{ roman }}} Pokémon species.
11 | pub const Species = enum({{{ Species.type }}}) {
12 | None,
13 | {{{ Species.values }}},
14 |
15 | {{{ Species.chances }}}{{{ Species.Data }}}
16 |
17 | const DATA = [_]Data{
18 | {{{ Species.data }}},
19 | };
20 |
21 | comptime {
22 | assert(@sizeOf(Species) == {{{ Species.size }}});
23 | }
24 |
25 | /// The number of Pokémon species in this generation.
26 | pub const size = {{{ Species.num }}};{{{ Species.chanceFn }}}
27 |
28 | /// Returns the `Data` corresponding to the species.
29 | pub fn get(id: Species) Data {
30 | assert(id != .None);
31 | return DATA[@intFromEnum(id) - 1];
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/src/lib/common/data/types.zig.tmpl:
--------------------------------------------------------------------------------
1 | //! Code generated by `tools/generate` - manual edits will be overwritten.
2 |
3 | const gen1 = @import("../../gen1/data.zig");
4 | const std = @import("std");
5 |
6 | const assert = std.debug.assert;
7 | const Effectiveness = gen1.Effectiveness;
8 |
9 | const S = Effectiveness.Super;
10 | const N = Effectiveness.Neutral;
11 | const R = Effectiveness.Resisted;
12 | const I = Effectiveness.Immune;
13 |
14 | /// Representation of a Generation {{{ roman }}} type in Pokémon.
15 | pub const Type = enum({{{ Type.type }}}) {
16 | {{{ Type.values }}},
17 |
18 | const CHART: [{{{ Type.num }}}][{{{ Type.num }}}]Effectiveness = .{
19 | {{{ Type.chart }}}
20 | };
21 |
22 | {{{ Type.precedence }}}{{{ Type.extra }}}
23 |
24 | comptime {
25 | assert(@bitSizeOf(Type) == {{{ Type.bitSize }}});
26 | assert(@sizeOf(@TypeOf(CHART)) == {{{ Type.chartSize }}});
27 | assert(@sizeOf(@TypeOf(PRECEDENCE)) == {{{ Type.precedenceSize }}});{{{ Type.extraSizes }}}
28 | }
29 |
30 | /// The number of types in this generation.
31 | pub const size = {{{ Type.num }}};
32 |
33 | /// Whether or not this type is considered to be special as opposed to physical.
34 | pub fn special(self: Type) bool {
35 | return @intFromEnum(self) >= @intFromEnum(Type.Fire);
36 | }
37 |
38 | /// The `Effectiveness` of type `t2` vs. type `t1`.
39 | pub fn effectiveness(t1: Type, t2: Type) Effectiveness {
40 | return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
41 | }
42 |
43 | {{{ Type.precedenceFn }}}{{{ Type.extraFns }}}
44 | };
45 |
46 | /// Representation of a Pokémon's typing.
47 | pub const Types = {{{ Types.qualifier }}} struct {
48 | /// A Pokémon's primary type.
49 | type1: Type = .Normal,
50 | /// A Pokémon's secondary type (may be identical to its primary type).
51 | type2: Type = .Normal,
52 |
53 | comptime {
54 | assert(@sizeOf(Types) == {{{ Types.size }}});
55 | }
56 |
57 | /// Whether this typing is immune to type `t`.
58 | pub fn immune(self: Types, t: Type) bool {
59 | return t.effectiveness(self.type1) == I or t.effectiveness(self.type2) == I;
60 | }
61 |
62 | /// Whether this typing includes type `t`.
63 | pub fn includes(self: Types, t: Type) bool {
64 | return self.type1 == t or self.type2 == t;
65 | }{{{ Types.extraFns }}}
66 | };
67 |
--------------------------------------------------------------------------------
/src/lib/common/napi.zig:
--------------------------------------------------------------------------------
1 | pub usingnamespace @cImport({
2 | @cDefine("NAPI_VERSION", "8");
3 | @cInclude("node_api.h");
4 | });
5 |
--------------------------------------------------------------------------------
/src/lib/common/optional.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 |
3 | const expect = std.testing.expect;
4 | const assert = std.debug.assert;
5 |
6 | const Bool = if (@hasField(std.builtin.Type, "bool")) .bool else .Bool;
7 |
8 | // TODO: ziglang/zig#104
9 | pub fn Optional(comptime T: type) type {
10 | const fields = std.meta.fields(switch (@typeInfo(T)) {
11 | Bool => enum { false, true },
12 | else => T,
13 | });
14 |
15 | var enumFields: [fields.len + 1]std.builtin.Type.EnumField = undefined;
16 | var decls = [_]std.builtin.Type.Declaration{};
17 |
18 | enumFields[0] = .{ .name = "None", .value = 0 };
19 |
20 | inline for (fields, 1..) |field, i| {
21 | assert(!std.mem.eql(u8, field.name, "None"));
22 | enumFields[i] = .{
23 | .name = field.name,
24 | .value = i,
25 | };
26 | }
27 |
28 | const options: std.builtin.Type.Enum = .{
29 | .tag_type = std.math.IntFittingRange(0, fields.len),
30 | .fields = &enumFields,
31 | .decls = &decls,
32 | .is_exhaustive = true,
33 | };
34 | return @Type(if (@hasField(std.builtin.Type, "enum"))
35 | .{ .@"enum" = options }
36 | else
37 | .{ .Enum = options });
38 | }
39 |
40 | test Optional {
41 | try expect(@bitSizeOf(Optional(bool)) == 2);
42 |
43 | const a: Optional(bool) = .true;
44 | try expect(a != .None);
45 | try expect(a == .true);
46 | try expect(a != .false);
47 |
48 | const b: Optional(bool) = .None;
49 | try expect(b == .None);
50 | try expect(b != .true);
51 | try expect(b != .false);
52 |
53 | const Player = @import("data.zig").Player;
54 | try expect(@bitSizeOf(Optional(Player)) == 2);
55 |
56 | const p: Optional(Player) = .P2;
57 | try expect(p != .None);
58 | try expect(p != .P1);
59 | try expect(p == .P2);
60 |
61 | const q: Optional(Player) = .None;
62 | try expect(q == .None);
63 | try expect(q != .P1);
64 | try expect(q != .P2);
65 |
66 | const Three = enum(u2) { A, B, C };
67 | try expect(@bitSizeOf(Optional(Three)) == 2);
68 |
69 | const Four = enum(u2) { A, B, C, D };
70 | try expect(@bitSizeOf(Optional(Four)) == 3);
71 | }
72 |
--------------------------------------------------------------------------------
/src/lib/common/options.zig:
--------------------------------------------------------------------------------
1 | const build_options = @import("build_options");
2 | const root = @import("root");
3 |
4 | /// Configures the behavior of the pkmn package.
5 | pub const Options = struct {
6 | showdown: ?bool = null,
7 | log: ?bool = null,
8 | chance: ?bool = null,
9 | calc: ?bool = null,
10 | mod: ?bool = null,
11 | advance: ?bool = null,
12 | ebc: ?bool = null,
13 | key: ?bool = null,
14 | miss: ?bool = null,
15 | overwrite: ?bool = null,
16 | internal: ?bool = null,
17 | };
18 |
19 | /// Whether or not Pokémon Showdown compatibility mode is enabled.
20 | pub const showdown = get("showdown", false);
21 | /// Whether or not protocol message logging is enabled.
22 | pub const log = get("log", false);
23 | /// Whether or not update probability tracking is enabled.
24 | pub const chance = get("chance", false);
25 | /// Whether or not damage calculator support is enabled.
26 | pub const calc = get("calc", false);
27 |
28 | pub const mod = showdown or get("mod", false);
29 | pub const advance = get("advance", true);
30 | pub const ebc = get("ebc", true);
31 | pub const key = get("key", false);
32 | pub const miss = get("miss", true);
33 | pub const overwrite = get("overwrite", true);
34 | pub const internal = get("internal", false);
35 |
36 | fn get(comptime name: []const u8, default: bool) bool {
37 | var build_enable: ?bool = null;
38 | var root_enable: ?bool = null;
39 |
40 | if (@hasDecl(root, "pkmn_options")) {
41 | root_enable = @field(@as(Options, root.pkmn_options), name);
42 | }
43 | if (@hasDecl(build_options, name)) {
44 | build_enable = @as(?bool, @field(build_options, name));
45 | }
46 | if (build_enable != null and root_enable != null) {
47 | if (build_enable.? != root_enable.?) {
48 | const r = name ++ " (" ++ (if (root_enable.?) "false" else "true") ++ ")";
49 | const b = name ++ " (" ++ (if (build_enable.?) "false" else "true") ++ ")";
50 | @compileError("root decl pkmn_options." ++ r ++ " != build option " ++ b ++ ".");
51 | }
52 | }
53 |
54 | return root_enable orelse (build_enable orelse default);
55 | }
56 |
--------------------------------------------------------------------------------
/src/lib/common/test.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | _ = @import("array.zig");
3 | _ = @import("data.zig");
4 | _ = @import("optional.zig");
5 | _ = @import("protocol.zig");
6 | _ = @import("rational.zig");
7 | _ = @import("rng.zig");
8 | _ = @import("util.zig");
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/common/util.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 |
3 | const expect = std.testing.expect;
4 | const expectEqual = std.testing.expectEqual;
5 |
6 | const Pointer = if (@hasField(std.builtin.Type, "pointer")) .pointer else .Pointer;
7 | const One = if (@hasField(std.builtin.Type.Pointer.Size, "one")) .one else .One;
8 |
9 | pub fn PointerType(comptime P: type, comptime C: type) type {
10 | return if (@field(@typeInfo(P), @tagName(Pointer)).is_const) *const C else *C;
11 | }
12 |
13 | test PointerType {
14 | try expectEqual(*bool, PointerType(*u8, bool));
15 | try expectEqual(*const f64, PointerType(*const i32, f64));
16 | }
17 |
18 | pub fn isPointerTo(p: anytype, comptime P: type) bool {
19 | const info = @typeInfo(@TypeOf(p));
20 | return switch (info) {
21 | Pointer => @field(info, @tagName(Pointer)).child == P,
22 | else => false,
23 | };
24 | }
25 |
26 | test isPointerTo {
27 | const S = struct {};
28 | const s: S = .{};
29 | try expect(!isPointerTo(s, S));
30 | try expect(isPointerTo(&s, S));
31 | }
32 |
33 | // NOTE: std.mem.bytesAsValue backported from ziglang/zig#18061
34 | pub fn bytesAsValue(comptime T: type, bytes: anytype) BytesAsValueReturnType(T, @TypeOf(bytes)) {
35 | return @as(BytesAsValueReturnType(T, @TypeOf(bytes)), @ptrCast(bytes));
36 | }
37 |
38 | fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
39 | return CopyPtrAttrs(B, One, T);
40 | }
41 |
42 | fn CopyPtrAttrs(
43 | comptime source: type,
44 | comptime size: std.builtin.Type.Pointer.Size,
45 | comptime child: type,
46 | ) type {
47 | const info = @field(@typeInfo(source), @tagName(Pointer));
48 | const args: std.builtin.Type.Pointer = if (@hasField(std.builtin.Type.Pointer, "sentinel")) .{
49 | .size = size,
50 | .is_const = info.is_const,
51 | .is_volatile = info.is_volatile,
52 | .is_allowzero = info.is_allowzero,
53 | .alignment = info.alignment,
54 | .address_space = info.address_space,
55 | .child = child,
56 | .sentinel = null,
57 | } else .{
58 | .size = size,
59 | .is_const = info.is_const,
60 | .is_volatile = info.is_volatile,
61 | .is_allowzero = info.is_allowzero,
62 | .alignment = info.alignment,
63 | .address_space = info.address_space,
64 | .child = child,
65 | .sentinel_ptr = null,
66 | };
67 | return @Type(if (@hasField(std.builtin.Type, "pointer"))
68 | .{ .pointer = args }
69 | else
70 | .{ .Pointer = args });
71 | }
72 |
73 | // NOTE: std.meta.FieldType replaced by @FieldType in 0.14.0
74 | pub fn FieldType(comptime T: type, comptime field: std.meta.FieldEnum(T)) type {
75 | return std.meta.fieldInfo(T, field).type;
76 | }
77 |
--------------------------------------------------------------------------------
/src/lib/node.zig:
--------------------------------------------------------------------------------
1 | const c = @import("common/napi.zig");
2 | const js = @import("common/js.zig");
3 | const node = @import("bindings/node.zig");
4 | const std = @import("std");
5 |
6 | const assert = std.debug.assert;
7 |
8 | export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi_value {
9 | const properties = [_]c.napi_property_descriptor{
10 | js.Property.init("engine", .{ .value = node.register(env) }),
11 | };
12 | assert(c.napi_define_properties(env, exports, properties.len, &properties) == c.napi_ok);
13 | return exports;
14 | }
15 |
--------------------------------------------------------------------------------
/src/lib/test.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | _ = @import("common/test.zig");
3 | _ = @import("gen1/test.zig");
4 | _ = @import("gen2/test.zig");
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/wasm.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const wasm = @import("bindings/wasm.zig");
3 |
4 | export const SHOWDOWN = wasm.options.showdown;
5 | export const LOG = wasm.options.log;
6 | export const CHANCE = wasm.options.chance;
7 | export const CALC = wasm.options.calc;
8 |
9 | export const GEN1_CHOICES_SIZE = wasm.gen(1).CHOICES_SIZE;
10 | export const GEN1_LOGS_SIZE = wasm.gen(1).LOGS_SIZE;
11 |
12 | const exportable = @hasDecl(std.zig, "Zir") and !@hasField(std.zig.Zir.Inst.Tag, "export_value");
13 |
14 | usingnamespace if (exportable) struct {
15 | export const GEN1_update = wasm.gen(1).update;
16 | export const GEN1_choices = wasm.gen(1).choices;
17 | } else wasm.exports();
18 |
--------------------------------------------------------------------------------
/src/pkg/addon.test.ts:
--------------------------------------------------------------------------------
1 | import * as addon from './addon';
2 |
3 | describe('AddOn', () => {
4 | test('check', () => {
5 | expect(() => addon.check(true)).not.toThrow();
6 | expect(() => addon.check(false))
7 | .toThrow('@pkmn/engine has only been configured to support Pokémon Showdown');
8 | });
9 |
10 | test('supports', () => {
11 | const showdown = true;
12 | const log = true;
13 |
14 | expect(addon.supports(!showdown)).toBe(false);
15 | expect(addon.supports(!showdown, log)).toBe(false);
16 | expect(addon.supports(!showdown, !log)).toBe(false);
17 |
18 | expect(addon.supports(showdown)).toBe(true);
19 | expect(addon.supports(showdown, log)).toBe(false);
20 | expect(addon.supports(showdown, !log)).toBe(true);
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/src/pkg/addon/browser.ts:
--------------------------------------------------------------------------------
1 |
2 | import type {Argument} from '../addon';
3 |
4 | import {toBindings} from './wasm';
5 |
6 | export async function load(showdown: boolean, addon?: Argument) {
7 | if (typeof addon === 'string' && addon !== 'wasm') {
8 | throw new Error('Unable to load native addons in the browser!');
9 | }
10 |
11 | let wasm: WebAssembly.Instance;
12 | if (addon instanceof WebAssembly.Instance) {
13 | wasm = addon;
14 | } else if (addon instanceof WebAssembly.Module) {
15 | try {
16 | wasm = (await WebAssembly.instantiate(addon));
17 | } catch (err) {
18 | if (!(err instanceof Error)) throw err;
19 | throw new Error(`Could not instantiate WASM module!\n${err.message}`);
20 | }
21 | } else {
22 | const name = `pkmn${showdown ? '-showdown' : ''}.wasm`;
23 | try {
24 | const response = !addon || addon === 'wasm' ? fetch(name)
25 | : (addon as Promise | URL) instanceof URL ? fetch(addon) : addon;
26 | wasm = (await WebAssembly.instantiateStreaming(response)).instance;
27 | } catch (err) {
28 | if (!(err instanceof Error)) throw err;
29 | const message = !addon || addon === 'wasm'
30 | ? `Could not find ${name} - did you run \`npx install-pkmn-engine\`?`
31 | : (addon as Promise | URL) instanceof URL
32 | ? `Could not fetch WASM module from '${(addon as URL).href}'!`
33 | : 'Could not instantiate WASM module!';
34 | throw new Error(`${message}\n${err.message}`);
35 | }
36 | }
37 |
38 | return toBindings(wasm.exports);
39 | }
40 |
41 | export function loadSync() {
42 | throw new Error('You must `initialize` the WASM addon before using the engine!');
43 | }
44 |
--------------------------------------------------------------------------------
/src/pkg/addon/node.ts:
--------------------------------------------------------------------------------
1 |
2 | import * as fs from 'fs';
3 | import * as path from 'path';
4 |
5 | import type {Argument} from '../addon';
6 |
7 | import {toBindings} from './wasm';
8 |
9 | const ROOT = path.join(__dirname, '..', '..', '..');
10 | const LIB = path.join(ROOT, 'build', 'lib');
11 |
12 | const NODE = [path.join(LIB, 'pkmn.node'), path.join(LIB, 'pkmn-showdown.node')];
13 | const WASM = [path.join(LIB, 'pkmn.wasm'), path.join(LIB, 'pkmn-showdown.wasm')];
14 |
15 | export async function load(showdown: boolean, addon?: Argument) {
16 | if (addon === undefined || typeof addon === 'string' && addon !== 'wasm') {
17 | try {
18 | return require(!addon || addon === 'node' ? NODE[+showdown] : addon).engine;
19 | } catch (err) {
20 | if (!(err instanceof Error)) return err;
21 | if (addon && addon !== 'node') {
22 | throw new Error(`Unable to load native addon: '${addon}'\n${err.message}`);
23 | } else {
24 | throw error(NODE[+showdown], err);
25 | }
26 | }
27 | }
28 |
29 | let wasm: WebAssembly.Instance;
30 | if (addon === 'wasm') {
31 | try {
32 | wasm = (await WebAssembly.instantiate(fs.readFileSync(WASM[+showdown]))).instance;
33 | } catch (err) {
34 | throw error(WASM[+showdown], err);
35 | }
36 | } else if (addon instanceof WebAssembly.Instance) {
37 | wasm = addon;
38 | } else if (addon instanceof WebAssembly.Module) {
39 | try {
40 | wasm = (await WebAssembly.instantiate(addon));
41 | } catch (err) {
42 | if (!(err instanceof Error)) throw err;
43 | throw new Error(`Could not instantiate WASM module!\n${err.message}`);
44 | }
45 | } else {
46 | try {
47 | const response = (addon as Promise | URL) instanceof Promise ? addon : fetch(addon);
48 | wasm = (await WebAssembly.instantiateStreaming(response)).instance;
49 | } catch (err) {
50 | if (!(err instanceof Error)) throw err;
51 | throw new Error(`Could not instantiate WASM module!\n${err.message}`);
52 | }
53 | }
54 |
55 | return toBindings(wasm.exports);
56 | }
57 |
58 | export function loadSync(showdown: boolean) {
59 | try {
60 | return require(NODE[+showdown]).engine;
61 | } catch {
62 | return undefined;
63 | }
64 | }
65 |
66 | function error(file: string, err: unknown) {
67 | if (!(err instanceof Error)) return err;
68 | const message = `Could not find ${path.basename(file)} addon`;
69 | return new Error(`${message} - did you run \`npx install-pkmn-engine\`?\n${err.message}`);
70 | }
71 |
--------------------------------------------------------------------------------
/src/pkg/addon/wasm.ts:
--------------------------------------------------------------------------------
1 | import type {Binding, Bindings} from '../addon';
2 | import {LAYOUT} from '../data';
3 |
4 | export function toBindings(w: WebAssembly.Exports): Bindings {
5 | const memory = new Uint8Array((w.memory as WebAssembly.Memory).buffer);
6 | return {
7 | options: {
8 | showdown: !!memory[w.SHOWDOWN.valueOf()] as T,
9 | log: !!memory[w.LOG.valueOf()],
10 | chance: !!memory[w.CHANCE.valueOf()],
11 | calc: !!memory[w.CALC.valueOf()],
12 | },
13 | bindings: [toBinding(1, w)],
14 | };
15 | }
16 |
17 | function toBinding(gen: number, w: WebAssembly.Exports): Binding {
18 | const prefix = `GEN${gen}`;
19 | const buf = (w.memory as WebAssembly.Memory).buffer;
20 |
21 | const constants = new Uint32Array(buf);
22 | const CHOICES_SIZE = constants[w[`${prefix}_CHOICES_SIZE`].valueOf() / 4];
23 | const LOGS_SIZE = constants[w[`${prefix}_LOGS_SIZE`].valueOf() / 4];
24 |
25 | const size = LAYOUT[gen - 1].sizes.Battle;
26 | const update = w[`${prefix}_update`] as CallableFunction;
27 | const choices = w[`${prefix}_choices`] as CallableFunction;
28 | const memory = new Uint8Array(buf);
29 |
30 | return {
31 | CHOICES_SIZE,
32 | LOGS_SIZE,
33 | update(battle: ArrayBuffer, c1: number, c2: number, log: ArrayBuffer | undefined): number {
34 | const bytes = new Uint8Array(battle);
35 | memory.set(bytes, 0);
36 |
37 | let result: number;
38 | if (log) {
39 | result = update(0, c1, c2, size);
40 | new Uint8Array(log).set(memory.subarray(size, size + LOGS_SIZE));
41 | } else {
42 | result = update(0, c1, c2, 0);
43 | }
44 |
45 | bytes.set(memory.subarray(0, size));
46 | return result;
47 | },
48 | choices(battle: ArrayBuffer, player: number, request: number, options: ArrayBuffer): number {
49 | const opts = new Uint8Array(options);
50 | memory.set(new Uint8Array(battle));
51 | const n = choices(0, player, request, size);
52 | opts.set(memory.subarray(size, size + n));
53 | return n;
54 | },
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/src/pkg/common.test.ts:
--------------------------------------------------------------------------------
1 | import {Choice, Result} from './common';
2 |
3 | test('Choice.decode', () => {
4 | expect(Choice.decode(0b0001_0001)).toEqual(Choice.move(4));
5 | expect(Choice.decode(0b0001_0110)).toEqual(Choice.switch(5));
6 | });
7 |
8 | test('Choice.encode', () => {
9 | expect(Choice.encode()).toBe(Choice.encode(Choice.pass));
10 | expect(Choice.encode(Choice.move(4))).toBe(0b0001_0001);
11 | expect(Choice.encode(Choice.switch(5))).toBe(0b0001_0110);
12 | });
13 |
14 | test('Choice.parse', () => {
15 | expect(() => Choice.parse('foo')).toThrow('Invalid choice');
16 | expect(Choice.parse('pass')).toEqual(Choice.pass);
17 | expect(() => Choice.parse('pass 2')).toThrow('Invalid choice');
18 | expect(Choice.parse('move 2')).toEqual(Choice.move(2));
19 | expect(Choice.parse('move 0')).toEqual(Choice.move(0));
20 | expect(() => Choice.parse('move 5')).toThrow('Invalid choice');
21 | expect(Choice.parse('switch 4')).toEqual(Choice.switch(4));
22 | expect(() => Choice.parse('switch 1')).toThrow('Invalid choice');
23 | });
24 |
25 | test('Choice.format', () => {
26 | expect(Choice.format(Choice.pass)).toBe('pass');
27 | expect(Choice.format(Choice.move(2))).toBe('move 2');
28 | expect(Choice.format(Choice.switch(4))).toBe('switch 4');
29 | });
30 |
31 | test('Result.decode', () => {
32 | expect(Result.decode(0b0101_0000)).toEqual({type: undefined, p1: 'move', p2: 'move'});
33 | expect(Result.decode(0b1000_0000)).toEqual({type: undefined, p1: 'pass', p2: 'switch'});
34 | });
35 |
36 | test('Result.encode', () => {
37 | expect(Result.encode({type: undefined, p1: 'move', p2: 'move'})).toBe(0b0101_0000);
38 | expect(Result.encode({type: undefined, p1: 'pass', p2: 'switch'})).toBe(0b1000_0000);
39 | expect(Result.encode({type: 'win', p1: 'pass', p2: 'pass'})).toBe(0b0000_0001);
40 | });
41 |
--------------------------------------------------------------------------------
/src/pkg/data.test.ts:
--------------------------------------------------------------------------------
1 | import {Generations, ID} from '@pkmn/data';
2 | import {Dex} from '@pkmn/sim';
3 |
4 | import {Lookup} from './data';
5 |
6 | for (const gen of new Generations(Dex as any)) {
7 | if (gen.num > 2) break;
8 |
9 | const lookup = Lookup.get(gen);
10 | describe(`Gen ${gen.num}`, () => {
11 | test('Lookup.sizes', () => {
12 | const i = gen.num - 1;
13 | expect(lookup.sizes).toEqual({
14 | types: [15, 18][i],
15 | species: [151, 251][i],
16 | moves: [165, 251][i],
17 | items: [0, 195][i],
18 | });
19 | });
20 |
21 | test('Lookup.type', () => {
22 | expect(lookup.typeByName('Rock')).toBe(gen.num === 1 ? 5 : 1);
23 | expect(lookup.typeByNum(14)).toBe(gen.num === 1 ? 'Dragon' : 'Psychic');
24 | });
25 |
26 | test('Lookup.species', () => {
27 | expect(lookup.speciesByID('gengar' as ID)).toBe(94);
28 | expect(lookup.speciesByNum(151)).toBe('mew');
29 | });
30 |
31 | test('Lookup.move', () => {
32 | expect(lookup.moveByID('lowkick' as ID)).toBe(67);
33 | expect(lookup.moveByNum(133)).toBe('amnesia');
34 | });
35 |
36 | if (gen.num > 1) {
37 | test('Lookup.item', () => {
38 | expect(lookup.itemByID('leftovers' as ID)).toBe(27);
39 | expect(lookup.itemByNum(24)).toBe('thickclub');
40 | expect(lookup.itemByID('mail' as ID)).toBe(61);
41 | expect(lookup.itemByNum(61)).toBe('mail');
42 | });
43 | }
44 | });
45 | }
46 |
--------------------------------------------------------------------------------
/src/pkg/data/layout.json:
--------------------------------------------------------------------------------
1 | ../../data/layout.json
--------------------------------------------------------------------------------
/src/pkg/data/mapping.json:
--------------------------------------------------------------------------------
1 | {
2 | "base": {
3 | "Cant": [
4 | "slp",
5 | "frz",
6 | "par",
7 | "partiallytrapped",
8 | "flinch",
9 | "recharge",
10 | "nopp",
11 | "Attract"
12 | ],
13 | "Damage": [
14 | "",
15 | "psn",
16 | "brn",
17 | "confusion",
18 | "Leech Seed",
19 | "Recoil"
20 | ],
21 | "Boosts": [
22 | "atk",
23 | "atk",
24 | "def",
25 | "spe",
26 | "spa",
27 | "spd",
28 | "accuracy",
29 | "evasion"
30 | ],
31 | "Fail": [
32 | "",
33 | "slp",
34 | "psn",
35 | "brn",
36 | "frz",
37 | "par",
38 | "tox",
39 | "move: Substitute",
40 | "move: Substitute"
41 | ],
42 | "Activate": [
43 | "Bide",
44 | "confusion",
45 | "move: Haze",
46 | "move: Mist",
47 | "move: Struggle",
48 | "move: Substitute",
49 | "move: Splash"
50 | ],
51 | "Start": [
52 | "Bide",
53 | "confusion",
54 | "confusion",
55 | "move: Focus Energy",
56 | "move: Leech Seed",
57 | "Light Screen",
58 | "Mist",
59 | "Reflect",
60 | "Substitute",
61 | "typechange",
62 | "Disable",
63 | "Mimic"
64 | ],
65 | "End": [
66 | "Disable",
67 | "confusion",
68 | "Bide",
69 | "Substitute",
70 | "Disable",
71 | "confusion",
72 | "Mist",
73 | "move: Focus Energy",
74 | "move: Leech Seed",
75 | "Toxic counter",
76 | "Light Screen",
77 | "Reflect",
78 | "move: Bide"
79 | ],
80 | "Side": [
81 | "Safeguard",
82 | "Reflect",
83 | "move: Light Screen",
84 | "Spikes"
85 | ]
86 | },
87 | "diffs": [
88 | {
89 | "Activate": [
90 | [0, "move: Bide"]
91 | ],
92 | "Start": [
93 | [0, "move: Bide"]
94 | ],
95 | "End": [
96 | [0, "move: Disable"],
97 | [2, "move: Bide"]
98 | ]
99 | }
100 | ]
101 | }
--------------------------------------------------------------------------------
/src/pkg/data/protocol.json:
--------------------------------------------------------------------------------
1 | ../../data/protocol.json
--------------------------------------------------------------------------------
/src/pkg/fixtures/p1.txt:
--------------------------------------------------------------------------------
1 | Fushigidane (Bulbasaur)
2 | - Sleep Powder
3 | - Swords Dance
4 | - Razor Leaf
5 | - Body Slam
6 |
7 | Hitokage (Charmander)
8 | - Fire Blast
9 | - Fire Spin
10 | - Slash
11 | - Counter
12 |
13 | Zenigame (Squirtle)
14 | - Surf
15 | - Blizzard
16 | - Body Slam
17 | - Rest
18 |
19 | Pikachuu (Pikachu)
20 | - Thunderbolt
21 | - Thunder Wave
22 | - Surf
23 | - Seismic Toss
24 |
25 | Koratta (Rattata)
26 | - Super Fang
27 | - Body Slam
28 | - Blizzard
29 | - Thunderbolt
30 |
31 | Poppo (Pidgey)
32 | - Double-Edge
33 | - Quick Attack
34 | - Wing Attack
35 | - Mirror Move
36 |
--------------------------------------------------------------------------------
/src/pkg/fixtures/p2.txt:
--------------------------------------------------------------------------------
1 | Kentarosu (Tauros)
2 | - Body Slam
3 | - Hyper Beam
4 | - Blizzard
5 | - Earthquake
6 |
7 | Rakkii (Chansey)
8 | - Reflect
9 | - Seismic Toss
10 | - Soft-Boiled
11 | - Thunder Wave
12 |
13 | Kabigon (Snorlax)
14 | - Body Slam
15 | - Reflect
16 | - Rest
17 | - Ice Beam
18 |
19 | Nasshii (Exeggutor)
20 | - Sleep Powder
21 | - Psychic
22 | - Explosion
23 | - Double-Edge
24 |
25 | Sutaamii (Starmie)
26 | - Recover
27 | - Thunder Wave
28 | - Blizzard
29 | - Thunderbolt
30 |
31 | Fuudin (Alakazam)
32 | - Psychic
33 | - Seismic Toss
34 | - Thunder Wave
35 | - Recover
36 |
--------------------------------------------------------------------------------
/src/pkg/index.test.ts:
--------------------------------------------------------------------------------
1 | import {Generations} from '@pkmn/data';
2 | import {Dex, PRNG} from '@pkmn/sim';
3 |
4 | import {Options} from '../test/benchmark';
5 |
6 | import {Battle} from './index';
7 |
8 | for (const gen of new Generations(Dex as any)) {
9 | if (gen.num > 1) {
10 | describe(`Gen ${gen.num}`, () => {
11 | test('Battle.create/restore', () => {
12 | const options = {showdown: true} as any;
13 | expect(() => Battle.create(gen, options)).toThrow('Unsupported gen');
14 | expect(() => Battle.restore(gen, {} as any, options)).toThrow('Unsupported gen');
15 | });
16 | });
17 | continue;
18 | }
19 |
20 | describe(`Gen ${gen.num}`, () => {
21 | test('Battle.create/restore', () => {
22 | const options = Options.get(gen, PRNG.get('1,2,3,4'));
23 | const battle = Battle.create(gen, options);
24 | const restored = Battle.restore(gen, battle, options);
25 | expect(restored.toJSON()).toEqual(battle.toJSON());
26 | });
27 | });
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/README.md:
--------------------------------------------------------------------------------
1 | ../../docs/TESTING.md
--------------------------------------------------------------------------------
/src/test/benchmark.test.ts:
--------------------------------------------------------------------------------
1 | import {Generations} from '@pkmn/data';
2 | import {Dex} from '@pkmn/sim';
3 |
4 | import * as addon from '../pkg/addon';
5 |
6 | import {comparison, iterations} from './benchmark';
7 |
8 | // Simple smoke tests just to confirm things are wired up correctly and actually execute
9 | describe('benchmark', () => {
10 | const gens = new Generations(Dex as any);
11 |
12 | test('iterations', () => {
13 | expect(() => iterations(gens, 10, 10, [1, 2, 3, 4])).not.toThrow();
14 | });
15 |
16 | (addon.supports(true) ? test : test.skip)('comparison', () =>
17 | expect(comparison(gens, 10, [1, 2, 3, 4])).resolves.toBeDefined());
18 | });
19 |
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x130C2A0BF1934A4C.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x130C2A0BF1934A4C.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x138CA5166EFF6A9.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[312,51793,26351,63145]}
2 | >player p1 {"name":"Bot 1","team":"Jigglypuff|||None|leer,thundershock,conversion,quickattack||241,160,234,175,175,252|N|2,17,0,21,21,7||64|172]Persian|||None|peck,minimize,doubleedge,thunderpunch||209,84,55,156,156,225|N|1,25,1,27,27,17||71|37]Snorlax|||None|thunderbolt,flash,horndrill,poisongas||174,151,164,72,72,56|N|8,10,8,16,16,0||72|109]Wartortle|||None|acid,vinewhip,dreameater,smog||221,121,125,176,176,37|N|14,30,27,5,5,30||69|164]Venonat|||None|waterfall,meditate,supersonic,strength||96,65,222,97,97,129|N|13,22,2,,,1||72|40]Marowak|||None|blizzard,focusenergy,roar,thunderwave||94,151,18,197,197,95|N|2,24,17,0,0,19||94|11"}
3 | >player p2 {"name":"Bot 2","team":"Nidorino|||None|screech,toxic,thunder,pound||173,17,5,249,249,131|N|5,0,19,3,3,9||80|36]Poliwhirl|||None|substitute,rage,solarbeam,doublekick||16,236,232,231,231,182|N|11,7,25,26,26,14||80|45]Parasect|||None|bite,sludge,disable,whirlwind||2,93,3,149,149,134|N|8,15,13,8,8,20||54|236]Weedle|||None|jumpkick,fireblast,leer,meditate||49,36,196,30,30,228|N|6,21,11,16,16,15||67|210]Porygon|||None|doubleslap,megapunch,conversion,wingattack||19,237,57,244,244,239|N|9,10,1,11,11,16||99|107]Ninetales|||None|cometpunch,thrash,razorleaf,earthquake||242,63,168,72,72,205|N|10,23,16,0,0,14||78|31"}
4 | >p1 move leer
5 | >p2 switch 2
6 | >p1 move thundershock
7 | >p2 move substitute
8 | >p1 move conversion
9 | >p2 move rage
10 | >p1 move quickattack
11 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x166525E4E3DD0132.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[5733,9700,58333,306]}
2 | >player p1 {"name":"Bot 1","team":"Charizard|||None|scratch,supersonic,quickattack,cut||165,48,50,96,96,135|N|15,14,3,2,2,3||55|94]Poliwrath|||None|poisongas,agility,smog,splash||222,48,76,50,50,71|N|12,27,23,16,16,20||82|176]Zapdos|||None|stringshot,slash,confusion,hyperfang||184,199,171,84,84,102|N|13,22,6,26,26,8||50|65]Kabuto|||None|haze,spore,poisonpowder,lightscreen||250,32,10,152,152,29|N|1,16,25,15,15,8||71|185]Exeggutor|||None|psywave,withdraw,strength,thunderpunch||151,25,38,4,4,159|N|4,8,26,28,28,16||97|193]Dragonair|||None|petaldance,watergun,meditate,bonemerang||52,113,72,246,246,226|N|13,10,,7,7,12||87|44"}
3 | >player p2 {"name":"Bot 2","team":"Porygon|||None|conversion,harden,highjumpkick,fissure||65,124,3,125,125,93|N|11,6,8,3,3,7||94|153]Mewtwo|||None|recover,karatechop,icebeam,thunderwave||30,44,117,135,135,204|N|5,1,27,11,11,4||64|140]Kakuna|||None|barrage,screech,megakick,doubleteam||11,154,134,28,28,55|N|15,26,19,3,3,||81|10]Bellsprout|||None|vinewhip,payday,leechlife,hydropump||96,44,193,174,174,122|N|12,19,27,20,20,4||88|194]Venusaur|||None|acidarmor,sleeppowder,thrash,superfang||113,150,210,77,77,239|N|3,9,16,11,11,26||93|71]Mew|||None|lowkick,doubleslap,constrict,nightshade||5,240,100,15,15,117|N|14,18,7,21,21,26||70|251"}
4 | >p1 move scratch
5 | >p2 switch 2
6 | >p1 move supersonic
7 | >p2 move recover
8 | >p1 move quickattack
9 | >p2 move karatechop
10 | >p1 move cut
11 | >p2 move icebeam
12 | >p1 switch 2
13 | >p2 move thunderwave
14 | >p1 switch 2
15 | >p2 move thunderwave
16 | >p1 move scratch
17 | >p2 switch 2
18 | >p1 switch 3
19 | >p2 move conversion
20 | >p1 move stringshot
21 | >p2 move harden
22 | >p1 switch 4
23 | >p2 move highjumpkick
24 | >p1 move haze
25 | >p2 move fissure
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x1A2182BB0BBD9E64.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x1A2182BB0BBD9E64.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x1C6394FF9C3565F4.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x1C6394FF9C3565F4.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x1EE16974B4257C8E.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[7905,26996,46117,31886]}
2 | >player p1 {"name":"Bot 1","team":"Charmander|||None|stunspore,thundershock,ember,teleport||67,250,50,187,187,67|N|7,25,23,27,27,22||53|21]Mr. Mime|||None|explosion,hornattack,wingattack,payday||30,180,35,129,129,57|N|15,2,7,,,||75|53]Primeape|||None|tackle,spikecannon,hypnosis,barrage||200,109,35,135,135,176|N|12,19,2,1,1,8||53|230]Squirtle|||None|bodyslam,solarbeam,flamethrower,sonicboom||182,116,124,220,220,183|N|2,25,5,25,25,14||93|73]Graveler|||None|stomp,flash,defensecurl,glare||75,24,80,33,33,65|N|13,23,27,7,7,9||85|90]Jynx|||None|growl,blizzard,tailwhip,leechlife||144,22,118,154,154,239|N|4,20,19,5,5,13||96|224"}
3 | >player p2 {"name":"Bot 2","team":"Horsea|||None|scratch,acidarmor,swift,lovelykiss||153,13,83,83,83,1|N|14,7,7,4,4,14||78|240]Mankey|||None|substitute,rage,cut,horndrill||36,76,152,95,95,115|N|0,25,13,29,29,25||95|49]Oddish|||None|megapunch,karatechop,quickattack,visegrip||37,131,25,177,177,113|N|1,28,8,11,11,5||78|22]Ninetales|||None|razorwind,dizzypunch,spore,waterfall||176,159,222,104,104,162|N|2,5,24,1,1,11||56|103]Magnemite|||None|kinesis,recover,aurorabeam,slam||70,74,237,68,68,191|N|4,5,22,29,29,5||62|69]Nidorino|||None|earthquake,lightscreen,splash,petaldance||165,238,227,96,96,82|N|0,21,24,29,29,4||65|60"}
4 | >p1 move stunspore
5 | >p2 move scratch
6 | >p1 move thundershock
7 | >p2 move acidarmor
8 | >p1 move ember
9 | >p2 move swift
10 | >p1 move teleport
11 | >p2 move lovelykiss
12 | >p1 move thundershock
13 | >p2 switch 2
14 | >p1 move thundershock
15 | >p2 move substitute
16 | >p1 move teleport
17 | >p2 move rage
18 | >p1 switch 2
19 | >p1 move explosion
20 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x20C2659866E5ED21.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[8386,26008,26341,60705]}
2 | >player p1 {"name":"Bot 1","team":"Raichu|||None|stringshot,firepunch,strength,poisonsting||,229,73,106,106,49|N|14,26,10,1,1,27||60|23]Weepinbell|||None|hypnosis,psybeam,superfang,jumpkick||37,240,83,99,99,55|N|0,20,8,21,21,21||67|201]Beedrill|||None|reflect,doubleteam,roar,thunderwave||93,131,52,68,68,173|N|4,1,15,28,28,20||52|158]Mew|||None|twineedle,bubble,thunderbolt,toxic||184,141,159,25,25,67|N|2,21,12,4,4,22||56|237]Flareon|||None|dizzypunch,hyperbeam,teleport,whirlwind||18,121,181,38,38,221|N|1,1,20,30,30,17||52|245]Ponyta|||None|absorb,icepunch,megakick,slam||120,238,179,178,178,144|N|9,2,29,10,10,28||82|178"}
3 | >player p2 {"name":"Bot 2","team":"Weedle|||None|wingattack,flash,doubleedge,tackle||192,60,219,234,234,82|N|3,0,16,7,7,15||78|56]Electrode|||None|slash,psywave,recover,dragonrage||213,115,149,154,154,111|N|9,10,16,26,26,29||98|52]Slowbro|||None|rage,kinesis,sleeppowder,spikecannon||9,90,96,147,147,57|N|10,,21,28,28,3||77|213]Tangela|||None|drillpeck,skullbash,watergun,cometpunch||173,213,219,227,227,90|N|6,9,18,20,20,15||61|254]Rattata|||None|payday,lowkick,icebeam,leechlife||60,223,69,26,26,73|N|8,27,16,9,9,13||70|242]Electabuzz|||None|acidarmor,sludge,barrier,doublekick||179,215,188,14,14,176|N|7,24,6,11,11,14||50|121"}
4 | >p1 move stringshot
5 | >p2 move doubleedge
6 | >p1 move poisonsting
7 | >p2 switch 2
8 | >p1 switch 2
9 | >p2 switch 2
10 | >p1 move hypnosis
11 | >p2 move tackle
12 | >p1 move superfang
13 | >p2 move tackle
14 | >p1 move jumpkick
15 | >p2 switch 3
16 | >p1 switch 2
17 | >p2 move rage
18 | >p1 move strength
19 | >p2 move rage
20 | >p1 move firepunch
21 | >p2 move rage
22 | >p1 switch 3
23 | >p1 switch 4
24 | >p2 move rage
25 | >p1 switch 5
26 | >p2 move rage
27 | >p1 switch 6
28 | >p2 move rage
29 | >p1 switch 6
30 | >p2 move rage
31 | >p1 switch 2
32 | >p2 move rage
33 | >p1 move superfang
34 | >p2 move rage
35 | >p1 switch 2
36 | >p2 move rage
37 | >p1 move hyperbeam
38 | >p2 move rage
39 | >p1 switch 2
40 | >p1 move hypnosis
41 | >p2 move rage
42 | >p1 switch 6
43 | >p1 move megakick
44 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x219E8F9B8DFA3E50.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x219E8F9B8DFA3E50.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x2E41948934F9D949.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[11841,38025,13561,55625]}
2 | >player p1 {"name":"Bot 1","team":"Sandslash|||None|karatechop,crabhammer,jumpkick,payday||159,83,158,1,1,141|N|6,20,7,17,17,22||69|224]Clefairy|||None|thrash,gust,cometpunch,disable||36,142,165,112,112,65|N|1,9,20,10,10,5||66|26]Electrode|||None|pound,hornattack,leechseed,ember||228,218,176,198,198,121|N|4,0,11,0,0,24||55|221]Flareon|||None|thunderwave,glare,supersonic,spore||67,34,29,218,218,169|N|1,28,8,10,10,28||65|87]Sandshrew|||None|takedown,absorb,swordsdance,fly||171,74,,18,18,242|N|7,0,7,15,15,27||53|38]Marowak|||None|peck,sandattack,rollingkick,psybeam||39,236,252,135,135,163|N|11,23,13,26,26,||58|98"}
3 | >player p2 {"name":"Bot 2","team":"Venusaur|||None|icepunch,furyattack,dreameater,substitute||91,173,205,251,251,83|N|9,11,29,3,3,28||97|10]Nidoran-M|||None|leechlife,eggbomb,furyswipes,lovelykiss||58,182,10,127,127,|N|1,5,25,22,22,17||93|252]Krabby|||None|sonicboom,stomp,surf,amnesia||233,246,27,43,43,40|N|6,0,22,8,8,7||58|118]Charizard|||None|bonemerang,spikecannon,thunder,minimize||206,105,63,241,241,6|N|4,0,27,29,29,1||69|193]Moltres|||None|poisonpowder,stringshot,petaldance,bite||51,163,84,251,251,223|N|15,14,19,,,10||89|63]Nidoran-F|||None|conversion,explosion,thunderpunch,bubble||87,61,149,196,196,66|N|1,17,1,6,6,17||67|83"}
4 | >p1 switch 2
5 | >p2 move icepunch
6 | >p1 move thrash
7 | >p2 move furyattack
8 | >p1 move thrash
9 | >p2 switch 2
10 | >p1 move thrash
11 | >p2 move leechlife
12 | >p1 switch 2
13 | >p2 move eggbomb
14 | >p1 switch 3
15 | >p2 switch 2
16 | >p1 move pound
17 | >p2 switch 3
18 | >p1 move hornattack
19 | >p2 move sonicboom
20 | >p1 move leechseed
21 | >p2 move stomp
22 | >p1 move ember
23 | >p2 move surf
24 | >p1 move leechseed
25 | >p2 move amnesia
26 | >p1 move ember
27 | >p2 move amnesia
28 | >p1 switch 4
29 | >p2 move sonicboom
30 | >p2 switch 4
31 | >p1 move thunderwave
32 | >p2 move bonemerang
33 | >p1 switch 5
34 | >p1 switch 6
35 | >p2 move spikecannon
36 | >p1 switch 4
37 | >p2 switch 5
38 | >p1 move hornattack
39 | >p2 switch 6
40 | >p1 move leechseed
41 | >p2 move conversion
42 | >p1 switch 3
43 | >p2 switch 3
44 | >p1 move karatechop
45 | >p2 move dreameater
46 | >p1 switch 6
47 | >p2 move substitute
48 | >p1 move takedown
49 | >p2 move substitute
50 | >p1 move absorb
51 | >p2 move furyattack
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x30B477546C73D7BC.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[12468,30548,27763,55228]}
2 | >player p1 {"name":"Bot 1","team":"Jolteon|||None|sonicboom,hornattack,thunderbolt,jumpkick||22,164,109,207,207,169|N|5,8,7,18,18,12||95|95]Rattata|||None|eggbomb,growl,scratch,vinewhip||170,70,153,63,63,74|N|7,0,27,,,26||93|44]Vaporeon|||None|disable,whirlwind,rage,tailwhip||59,219,224,155,155,83|N|2,21,24,8,8,2||85|147]Cubone|||None|psywave,conversion,leechlife,headbutt||183,45,202,74,74,76|N|13,26,11,3,3,0||60|71]Mewtwo|||None|explosion,teleport,dragonrage,lightscreen||126,78,32,250,250,75|N|1,25,21,22,22,25||70|206]Nidorino|||None|sing,toxic,thunderwave,watergun||246,170,134,216,216,179|N|14,7,22,20,20,2||59|220"}
3 | >player p2 {"name":"Bot 2","team":"Nidoqueen|||None|psybeam,selfdestruct,constrict,growl||104,242,247,72,72,145|N|12,26,2,9,9,28||66|170]Flareon|||None|pound,roar,teleport,petaldance||32,101,14,156,156,238|N|10,27,9,29,29,14||69|235]Farfetch’d|||None|meditate,sleeppowder,gust,thrash||76,166,59,160,160,7|N|4,25,30,0,0,5||81|166]Voltorb|||None|icepunch,smokescreen,doubleslap,whirlwind||93,126,120,196,196,126|N|1,17,25,3,3,13||98|113]Pidgey|||None|thunder,crabhammer,agility,headbutt||216,178,4,126,126,24|N|2,28,24,12,12,2||83|218]Hypno|||None|razorleaf,toxic,lowkick,skyattack||80,12,85,154,154,130|N|6,16,2,8,8,19||76|136"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 switch 2
8 | >p1 move sonicboom
9 | >p2 move growl
10 | >p1 move hornattack
11 | >p2 switch 3
12 | >p1 move thunderbolt
13 | >p2 switch 4
14 | >p1 move jumpkick
15 | >p2 move whirlwind
16 | >p2 switch 5
17 | >p1 switch 3
18 | >p2 move headbutt
19 | >p1 switch 4
20 | >p2 switch 6
21 | >p1 move psywave
22 | >p2 move toxic
23 | >p1 switch 5
24 | >p2 move skyattack
25 | >p1 move explosion
26 | >p2 move skyattack
27 | >p1 switch 6
28 | >p2 switch 6
29 | >p1 move sing
30 | >p2 move agility
31 | >p1 move thunderwave
32 | >p2 switch 2
33 | >p1 move toxic
34 | >p2 switch 4
35 | >p1 move sing
36 | >p2 switch 4
37 | >p1 move thunderwave
38 | >p2 move teleport
39 | >p1 switch 3
40 | >p2 switch 3
41 | >p1 move thunderbolt
42 | >p2 move growl
43 | >p1 switch 2
44 | >p2 move constrict
45 | >p1 move eggbomb
46 | >p2 move growl
47 | >p1 move scratch
48 | >p2 switch 3
49 | >p1 move vinewhip
50 | >p2 move roar
51 | >p1 move vinewhip
52 | >p2 switch 3
53 | >p1 switch 2
54 | >p2 move selfdestruct
55 | >p1 switch 5
56 | >p2 switch 4
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x317C2C25C222F280.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[12668,11301,49698,62080]}
2 | >player p1 {"name":"Bot 1","team":"Omanyte|||None|growth,skyattack,razorwind,skullbash||168,99,243,115,115,75|N|2,0,29,20,20,18||81|88]Zapdos|||None|explosion,vinewhip,doubleteam,swordsdance||126,110,186,29,29,95|N|11,3,16,30,30,26||76|]Magnemite|||None|barrage,glare,icebeam,whirlwind||89,46,90,200,200,24|N|10,30,12,21,21,14||98|206]Cubone|||None|eggbomb,doubleedge,rockthrow,twineedle||125,50,172,207,207,179|N|2,20,29,1,1,7||98|143]Arcanine|||None|rage,boneclub,surf,hydropump||247,197,17,22,22,114|N|12,6,26,16,16,8||83|191]Koffing|||None|growl,thunderpunch,recover,watergun||154,54,93,52,52,77|N|15,19,,2,2,26||58|27"}
3 | >player p2 {"name":"Bot 2","team":"Magikarp|||None|bide,doublekick,bonemerang,kinesis||229,64,57,176,176,158|N|15,22,7,,,10||90|162]Raticate|||None|lovelykiss,poisonpowder,sharpen,strength||61,107,23,159,159,169|N|10,19,8,25,25,2||88|213]Weedle|||None|swift,bubblebeam,rollingkick,flamethrower||162,194,122,39,39,153|N|4,13,,9,9,5||51|231]Tentacool|||None|softboiled,withdraw,stomp,conversion||33,126,86,122,122,251|N|0,24,16,21,21,4||85|177]Gastly|||None|poisongas,guillotine,barrier,megadrain||71,33,84,158,158,157|N|2,4,5,24,24,||80|56]Sandslash|||None|stunspore,bite,drillpeck,hornattack||159,91,26,24,24,119|N|5,1,30,,,16||71|63"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 move explosion
7 | >p2 move lovelykiss
8 | >p1 move vinewhip
9 | >p2 move poisonpowder
10 | >p1 switch 2
11 | >p2 move sharpen
12 | >p1 switch 3
13 | >p2 move strength
14 | >p1 move barrage
15 | >p2 move lovelykiss
16 | >p1 switch 4
17 | >p2 switch 2
18 | >p1 switch 5
19 | >p2 move bide
20 | >p1 switch 6
21 | >p2 move bide
22 | >p1 move growl
23 | >p2 move bide
24 | >p1 switch 3
25 | >p2 switch 3
26 | >p1 move growth
27 | >p2 switch 4
28 | >p1 switch 3
29 | >p2 move softboiled
30 | >p1 move thunderpunch
31 | >p2 move withdraw
32 | >p1 move recover
33 | >p2 move stomp
34 | >p1 move watergun
35 | >p2 switch 5
36 | >p1 move growl
37 | >p2 move poisongas
38 | >p1 move thunderpunch
39 | >p2 move guillotine
40 | >p1 switch 2
41 | >p1 move doubleteam
42 | >p2 switch 6
43 | >p1 switch 6
44 | >p2 switch 5
45 | >p1 switch 6
46 | >p2 move conversion
47 | >p1 switch 4
48 | >p2 move softboiled
49 | >p1 move glare
50 | >p2 move conversion
51 | >p1 move icebeam
52 | >p2 move softboiled
53 | >p1 switch 4
54 | >p2 move stomp
55 | >p1 move swordsdance
56 | >p2 switch 6
57 | >p1 move doubleteam
58 | >p2 switch 3
59 | >p1 switch 6
60 | >p2 move doublekick
61 | >p1 move rage
62 | >p2 move bonemerang
63 | >p1 move rage
64 | >p2 move kinesis
65 | >p1 move rage
66 | >p2 move bide
67 | >p1 move rage
68 | >p2 move bide
69 | >p1 move rage
70 | >p2 move bide
71 | >p1 move rage
72 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x39CCE4D290A254CD.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[14796,58578,37026,21709]}
2 | >player p1 {"name":"Bot 1","team":"Victreebel|||None|furyattack,clamp,doublekick,rollingkick||143,57,235,30,30,240|N|14,10,3,1,1,22||99|61]Flareon|||None|counter,selfdestruct,waterfall,twineedle||22,197,176,171,171,217|N|13,7,30,14,14,13||86|107]Exeggcute|||None|metronome,crabhammer,takedown,kinesis||169,202,48,28,28,21|N|1,0,8,10,10,1||63|200]Pidgeot|||None|disable,confuseray,megapunch,megadrain||250,246,68,128,128,66|N|10,10,13,12,12,18||52|194]Pinsir|||None|whirlwind,hyperbeam,psychic,jumpkick||92,73,252,86,86,164|N|2,5,28,9,9,26||93|244]Nidoran-M|||None|fissure,explosion,scratch,sludge||149,213,33,145,145,148|N|0,4,28,29,29,5||79|117"}
3 | >player p2 {"name":"Bot 2","team":"Charizard|||None|solarbeam,eggbomb,surf,thunderpunch||59,209,244,241,241,106|N|1,4,28,18,18,28||78|239]Dratini|||None|thunderbolt,skullbash,karatechop,horndrill||119,131,30,81,81,31|N|12,,2,21,21,1||84|107]Graveler|||None|thunderwave,hornattack,fly,toxic||69,32,232,125,125,218|N|14,30,30,20,20,7||91|232]Poliwag|||None|boneclub,hydropump,bubblebeam,furyswipes||95,65,203,65,65,128|N|0,13,9,4,4,1||73|207]Hitmonchan|||None|splash,haze,peck,strength||132,199,91,114,114,136|N|10,11,24,16,16,18||66|78]Koffing|||None|leechlife,headbutt,bonemerang,dragonrage||19,244,146,93,93,4|N|0,12,12,12,12,25||66|85"}
4 | >p1 move furyattack
5 | >p2 move solarbeam
6 | >p1 move clamp
7 | >p2 move solarbeam
8 | >p1 move doublekick
9 | >p2 move eggbomb
10 | >p1 switch 2
11 | >p2 move surf
12 | >p1 move counter
13 | >p2 switch 2
14 | >p1 move selfdestruct
15 | >p2 move thunderbolt
16 | >p1 switch 2
17 | >p2 switch 2
18 | >p1 move rollingkick
19 | >p2 move thunderpunch
20 | >p1 move furyattack
21 | >p2 move surf
22 | >p1 move clamp
23 | >p2 switch 3
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x43952058CEDD7279.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[17301,8280,52957,29305]}
2 | >player p1 {"name":"Bot 1","team":"Vaporeon|||None|nightshade,confusion,constrict,icebeam||228,149,98,207,207,36|N|2,16,13,5,5,7||53|234]Charizard|||None|flamethrower,headbutt,megakick,boneclub||48,119,29,220,220,240|N|5,20,,18,18,4||81|143]Tentacool|||None|teleport,megapunch,acid,swordsdance||74,159,3,240,240,208|N|8,,20,0,0,9||75|122]Poliwhirl|||None|fly,doubleslap,roar,hornattack||165,83,43,206,206,189|N|0,21,5,8,8,12||73|194]Weepinbell|||None|lick,thrash,kinesis,agility||185,128,11,94,94,214|N|8,22,12,9,9,9||86|183]Wartortle|||None|icepunch,firepunch,pound,tailwhip||29,49,235,72,72,173|N|3,12,1,3,3,30||61|227"}
3 | >player p2 {"name":"Bot 2","team":"Clefairy|||None|eggbomb,earthquake,surf,amnesia||229,55,153,80,80,157|N|12,23,3,21,21,16||67|118]Tangela|||None|conversion,glare,rockthrow,stunspore||140,108,52,3,3,208|N|13,10,26,23,23,9||96|71]Zapdos|||None|karatechop,vinewhip,blizzard,guillotine||16,238,243,143,143,219|N|4,8,26,16,16,13||90|157]Koffing|||None|bubblebeam,jumpkick,bubble,sharpen||101,23,103,226,226,174|N|0,21,5,20,20,29||57|70]Ivysaur|||None|takedown,focusenergy,quickattack,stringshot||246,89,238,147,147,33|N|11,23,17,10,10,||81|229]Golem|||None|supersonic,disable,doublekick,ember||112,118,214,188,188,177|N|12,18,22,25,25,21||52|249"}
4 | >p1 move nightshade
5 | >p2 move eggbomb
6 | >p1 move confusion
7 | >p2 move earthquake
8 | >p1 move constrict
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p2 move conversion
12 | >p1 move flamethrower
13 | >p2 move glare
14 | >p1 move headbutt
15 | >p2 move rockthrow
16 | >p1 move megakick
17 | >p2 move stunspore
18 | >p1 switch 2
19 | >p2 move conversion
20 | >p1 switch 3
21 | >p2 move glare
22 | >p1 move teleport
23 | >p2 move stunspore
24 | >p1 switch 4
25 | >p2 move rockthrow
26 | >p1 move fly
27 | >p2 switch 2
28 | >p1 move fly
29 | >p2 move surf
30 | >p1 move doubleslap
31 | >p2 move amnesia
32 | >p1 move roar
33 | >p2 move surf
34 | >p1 switch 5
35 | >p2 move earthquake
36 | >p1 move lick
37 | >p2 move surf
38 | >p1 switch 6
39 | >p2 switch 3
40 | >p1 move icepunch
41 | >p2 move karatechop
42 | >p1 move firepunch
43 | >p2 move vinewhip
44 | >p1 switch 5
45 | >p1 move hornattack
46 | >p2 move blizzard
47 | >p1 switch 2
48 | >p1 move boneclub
49 | >p2 switch 4
50 | >p1 move megakick
51 | >p2 move bubblebeam
52 | >p2 switch 5
53 | >p1 move headbutt
54 | >p2 switch 6
55 | >p1 move flamethrower
56 | >p2 move supersonic
57 | >p1 move boneclub
58 | >p2 move disable
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x46C1FA4F5C3A1B4B.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x46C1FA4F5C3A1B4B.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x479DCF7B406B5186.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[18333,53115,16491,20870]}
2 | >player p1 {"name":"Bot 1","team":"Geodude|||None|sharpen,psywave,psychic,petaldance||105,173,109,69,69,137|N|10,7,13,4,4,23||67|68]Lickitung|||None|lowkick,wingattack,hornattack,leechlife||161,180,18,24,24,119|N|2,4,9,5,5,22||83|28]Growlithe|||None|bite,conversion,payday,headbutt||219,227,222,113,113,|N|0,16,8,29,29,17||73|17]Graveler|||None|poisonpowder,eggbomb,stomp,doubleteam||167,47,215,105,105,173|N|10,22,29,16,16,23||81|134]Hitmonchan|||None|razorwind,fireblast,surf,furyattack||231,3,174,183,183,143|N|15,10,,7,7,15||61|89]Gengar|||None|hypnosis,superfang,kinesis,blizzard||174,216,55,103,103,178|N|11,30,21,27,27,11||63|92"}
3 | >player p2 {"name":"Bot 2","team":"Cloyster|||None|bide,sing,hydropump,nightshade||60,217,136,221,221,18|N|0,29,9,12,12,12||97|70]Caterpie|||None|bonemerang,pound,minimize,icebeam||183,64,178,35,35,78|N|14,6,,5,5,27||99|196]Starmie|||None|lightscreen,bubble,splash,firepunch||27,30,235,251,251,158|N|15,,26,19,19,15||77|134]Pidgeotto|||None|smokescreen,thunderbolt,stringshot,highjumpkick||64,28,190,16,16,180|N|14,30,15,0,0,19||70|57]Omanyte|||None|screech,teleport,psywave,wingattack||99,178,196,201,201,63|N|2,5,28,4,4,23||79|68]Muk|||None|focusenergy,fissure,spore,quickattack||198,169,16,132,132,162|N|11,6,25,18,18,10||55|2"}
4 | >p1 move sharpen
5 | >p2 switch 2
6 | >p1 move psywave
7 | >p2 move pound
8 | >p1 move psychic
9 | >p2 move minimize
10 | >p1 switch 2
11 | >p2 move minimize
12 | >p1 switch 2
13 | >p2 move bonemerang
14 | >p1 move petaldance
15 | >p2 move minimize
16 | >p1 move petaldance
17 | >p2 move pound
18 | >p1 move petaldance
19 | >p2 move pound
20 | >p1 move psychic
21 | >p2 move bonemerang
22 | >p1 move petaldance
23 | >p2 switch 2
24 | >p1 move petaldance
25 | >p2 move nightshade
26 | >p1 move petaldance
27 | >p2 move bide
28 | >p1 move psychic
29 | >p2 move bide
30 | >p1 switch 3
31 | >p1 move payday
32 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x490175968B905049.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[18689,30102,35728,20553]}
2 | >player p1 {"name":"Bot 1","team":"Mankey|||None|minimize,fly,softboiled,poisongas||185,250,135,122,122,23|N|11,11,25,26,26,3||71|146]Rhyhorn|||None|superfang,bubble,bind,solarbeam||32,230,75,99,99,167|N|8,6,20,25,25,25||89|215]Zapdos|||None|mimic,smog,recover,rockslide||60,218,101,248,248,81|N|7,25,23,22,22,11||67|182]Poliwhirl|||None|megakick,barrier,skyattack,megapunch||228,158,97,78,78,133|N|4,13,,5,5,1||90|217]Omastar|||None|watergun,seismictoss,stomp,thunderwave||222,74,154,133,133,176|N|5,13,10,14,14,13||55|120]Kakuna|||None|lovelykiss,clamp,mist,sleeppowder||237,76,168,91,91,144|N|8,30,25,0,0,29||58|158"}
3 | >player p2 {"name":"Bot 2","team":"Arcanine|||None|growth,twineedle,withdraw,rage||78,61,172,229,229,13|N|1,17,1,14,14,16||76|11]Clefairy|||None|triattack,pinmissile,acidarmor,flamethrower||187,153,82,244,244,195|N|4,17,3,29,29,24||79|32]Jynx|||None|fissure,jumpkick,eggbomb,flash||216,108,11,17,17,202|N|6,24,14,5,5,7||74|28]Nidoran-M|||None|blizzard,roar,psychic,growl||111,69,81,63,63,249|N|8,3,5,5,5,12||64|49]Gastly|||None|icebeam,skullbash,cometpunch,rest||75,58,168,36,36,151|N|11,18,12,27,27,19||59|240]Cloyster|||None|hypnosis,confuseray,fireblast,razorwind||252,6,19,132,132,220|N|12,15,,25,25,16||65|29"}
4 | >p1 move minimize
5 | >p2 move growth
6 | >p1 switch 2
7 | >p2 move twineedle
8 | >p1 move superfang
9 | >p2 move withdraw
10 | >p1 move bubble
11 | >p2 move rage
12 | >p1 move bind
13 | >p2 move rage
14 | >p1 move bind
15 | >p2 move rage
16 | >p1 switch 2
17 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x4AE7643BF1626D6C.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[19175,25659,61794,28012]}
2 | >player p1 {"name":"Bot 1","team":"Tentacruel|||None|thunderbolt,psychic,toxic,nightshade||178,103,138,163,163,227|N|8,19,28,12,12,1||92|105]Exeggcute|||None|fissure,stringshot,fireblast,poisonsting||6,100,204,60,60,18|N|1,20,24,10,10,12||96|144]Ditto|||None|conversion,roar,disable,bite||97,155,80,85,85,89|N|15,11,14,23,23,23||86|194]Oddish|||None|jumpkick,superfang,tailwhip,teleport||162,222,197,226,226,185|N|11,3,28,10,10,3||53|139]Poliwhirl|||None|solarbeam,acidarmor,dragonrage,swordsdance||146,114,180,139,139,242|N|9,,21,30,30,24||72|81]Flareon|||None|glare,stunspore,slam,skullbash||133,173,116,51,51,108|N|2,29,29,28,28,14||77|37"}
3 | >player p2 {"name":"Bot 2","team":"Omanyte|||None|rockthrow,sludge,watergun,twineedle||42,155,60,160,160,219|N|9,11,4,3,3,12||90|166]Charmeleon|||None|thunderpunch,dreameater,rage,kinesis||203,247,213,124,124,193|N|15,6,6,19,19,14||88|47]Staryu|||None|lightscreen,drillpeck,stomp,poisonpowder||248,17,200,7,7,232|N|12,19,11,9,9,1||55|141]Graveler|||None|splash,skyattack,quickattack,sonicboom||238,44,54,162,162,238|N|12,7,18,9,9,4||50|190]Nidorino|||None|ember,leechlife,flamethrower,crabhammer||85,52,51,1,1,103|N|15,19,30,7,7,22||74|105]Voltorb|||None|eggbomb,hypnosis,doubleedge,spore||238,3,124,161,161,142|N|14,22,15,20,20,11||74|31"}
4 | >p1 switch 2
5 | >p2 move rockthrow
6 | >p1 move fissure
7 | >p2 move sludge
8 | >p1 move stringshot
9 | >p2 move watergun
10 | >p1 move fireblast
11 | >p2 move twineedle
12 | >p1 move poisonsting
13 | >p2 move sludge
14 | >p1 switch 2
15 | >p1 switch 3
16 | >p2 switch 2
17 | >p1 move conversion
18 | >p2 move thunderpunch
19 | >p1 move roar
20 | >p2 move dreameater
21 | >p1 move disable
22 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x510BC88B7E670BB9.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x510BC88B7E670BB9.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x582807711B0A22D.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x582807711B0A22D.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x5BB7D44744B7DDB5.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[23479,54343,17591,56757]}
2 | >player p1 {"name":"Bot 1","team":"Oddish|||None|confuseray,sludge,teleport,growl||241,111,160,169,169,95|N|13,11,6,15,15,12||66|250]Gyarados|||None|megapunch,furyattack,smokescreen,surf||134,59,70,44,44,192|N|11,7,0,11,11,26||72|172]Butterfree|||None|aurorabeam,gust,boneclub,thunderpunch||168,21,245,45,45,211|N|2,16,8,17,17,18||89|131]Hypno|||None|payday,fly,bubblebeam,vinewhip||115,246,30,246,246,74|N|8,14,9,16,16,0||79|209]Mankey|||None|triattack,rest,thunder,megadrain||139,90,234,160,160,97|N|4,21,6,25,25,5||92|252]Nidoran-F|||None|hydropump,smog,dizzypunch,strength||192,97,131,152,152,174|N|5,12,18,22,22,16||88|205"}
3 | >player p2 {"name":"Bot 2","team":"Primeape|||None|reflect,acid,recover,nightshade||232,84,195,7,7,52|N|5,28,27,,,13||57|56]Gengar|||None|hyperfang,earthquake,icebeam,bind||22,52,195,211,211,87|N|3,28,28,19,19,15||61|181]Voltorb|||None|mist,dreameater,sing,skullbash||190,14,46,88,88,172|N|0,25,25,28,28,5||81|102]Kadabra|||None|watergun,thunderwave,seismictoss,rockslide||182,56,91,29,29,181|N|11,14,25,2,2,||61|203]Hitmonchan|||None|wrap,substitute,sharpen,disable||165,10,247,133,133,153|N|6,25,30,29,29,10||77|126]Bulbasaur|||None|razorleaf,solarbeam,withdraw,psychic||161,87,189,17,17,73|N|10,19,16,5,5,14||62|47"}
4 | >p1 move confuseray
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 move hyperfang
8 | >p1 move furyattack
9 | >p2 move earthquake
10 | >p1 move smokescreen
11 | >p2 switch 2
12 | >p1 move smokescreen
13 | >p2 move reflect
14 | >p1 move smokescreen
15 | >p2 move reflect
16 | >p1 move smokescreen
17 | >p2 move recover
18 | >p1 switch 2
19 | >p2 move recover
20 | >p1 switch 3
21 | >p2 switch 3
22 | >p1 move boneclub
23 | >p2 move sing
24 | >p1 move boneclub
25 | >p2 switch 4
26 | >p1 move gust
27 | >p2 move thunderwave
28 | >p1 move gust
29 | >p2 move thunderwave
30 | >p1 move aurorabeam
31 | >p2 switch 5
32 | >p1 move boneclub
33 | >p2 move wrap
34 | >p1 move gust
35 | >p2 move wrap
36 | >p1 move thunderpunch
37 | >p2 move wrap
38 | >p1 switch 4
39 | >p2 move wrap
40 | >p1 move bubblebeam
41 | >p2 move wrap
42 | >p1 move payday
43 | >p2 move wrap
44 | >p1 move fly
45 | >p2 switch 6
46 | >p1 move vinewhip
47 | >p2 move razorleaf
48 | >p1 move vinewhip
49 | >p2 switch 2
50 | >p1 switch 5
51 | >p2 move earthquake
52 | >p1 move thunder
53 | >p2 switch 6
54 | >p1 move rest
55 | >p2 move substitute
56 | >p1 move megadrain
57 | >p2 move substitute
58 | >p1 move rest
59 | >p2 move sharpen
60 | >p1 move thunder
61 | >p2 move disable
62 | >p1 move rest
63 | >p2 move wrap
64 | >p1 move thunder
65 | >p2 move wrap
66 | >p1 move rest
67 | >p2 move wrap
68 | >p1 move rest
69 | >p2 move sharpen
70 | >p1 move rest
71 | >p2 switch 6
72 | >p1 move rest
73 | >p2 switch 5
74 | >p1 move rest
75 | >p2 switch 6
76 | >p1 move megadrain
77 | >p2 switch 4
78 | >p1 move megadrain
79 | >p2 switch 4
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x5F4C27C3C400CCEF.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[24396,10179,50176,52463]}
2 | >player p1 {"name":"Bot 1","team":"Squirtle|||None|mirrormove,rest,wingattack,doubleteam||153,38,144,96,96,129|N|6,5,7,1,1,14||71|59]Golduck|||None|counter,horndrill,leechseed,bodyslam||106,154,81,227,227,246|N|13,2,11,27,27,1||59|67]Charmander|||None|stomp,peck,leechlife,triattack||39,27,170,36,36,245|N|14,6,27,8,8,7||91|55]Jolteon|||None|lightscreen,rollingkick,smokescreen,aurorabeam||231,85,139,122,122,30|N|10,2,8,21,21,23||98|78]Dugtrio|||None|stunspore,sharpen,icepunch,thunder||213,81,93,150,150,25|N|11,22,16,22,22,30||61|156]Gyarados|||None|submission,bonemerang,confuseray,megapunch||31,4,115,36,36,149|N|0,16,25,16,16,0||90|90"}
3 | >player p2 {"name":"Bot 2","team":"Kangaskhan|||None|guillotine,psychic,harden,boneclub||252,35,4,84,84,3|N|13,10,11,14,14,13||87|17]Charmeleon|||None|quickattack,eggbomb,leer,thunderwave||149,234,208,156,156,92|N|1,8,9,14,14,9||69|29]Fearow|||None|toxic,constrict,furyattack,petaldance||106,155,116,197,197,45|N|13,,30,30,30,8||86|221]Zapdos|||None|solarbeam,furyswipes,rage,karatechop||214,129,241,78,78,112|N|0,24,17,1,1,1||67|139]Golem|||None|bite,razorleaf,whirlwind,poisongas||91,58,56,167,167,100|N|1,9,29,14,14,24||81|249]Arbok|||None|payday,flash,dig,agility||204,81,127,117,117,211|N|13,18,15,3,3,5||83|"}
4 | >p1 move mirrormove
5 | >p2 switch 2
6 | >p1 move rest
7 | >p2 move quickattack
8 | >p1 switch 2
9 | >p2 move eggbomb
10 | >p1 move counter
11 | >p2 move leer
12 | >p1 move horndrill
13 | >p2 switch 2
14 | >p1 move leechseed
15 | >p2 switch 3
16 | >p1 move bodyslam
17 | >p2 move toxic
18 | >p1 switch 2
19 | >p2 switch 4
20 | >p1 move wingattack
21 | >p2 move solarbeam
22 | >p1 move doubleteam
23 | >p2 move solarbeam
24 | >p1 switch 3
25 | >p1 move stomp
26 | >p2 move furyswipes
27 | >p1 move peck
28 | >p2 move rage
29 | >p1 move leechlife
30 | >p2 move rage
31 | >p1 move triattack
32 | >p2 move rage
33 | >p1 switch 4
34 | >p2 move rage
35 | >p1 move lightscreen
36 | >p2 move rage
37 | >p1 switch 5
38 | >p2 move rage
39 | >p1 move stunspore
40 | >p2 move rage
41 | >p1 move sharpen
42 | >p2 move rage
43 | >p1 move icepunch
44 | >p2 move rage
45 | >p1 switch 6
46 | >p1 switch 5
47 | >p2 move rage
48 | >p1 switch 2
49 | >p2 move rage
50 | >p1 move counter
51 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x63F75EBC9E2B6DF8.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[25591,24252,40491,28152]}
2 | >player p1 {"name":"Bot 1","team":"Ekans|||None|sharpen,poisonsting,earthquake,furyswipes||14,87,176,225,225,43|N|5,1,7,2,2,12||71|104]Exeggcute|||None|horndrill,rollingkick,explosion,nightshade||118,75,27,38,38,147|N|5,4,14,6,6,4||72|75]Eevee|||None|roar,spore,pinmissile,wingattack||123,169,146,15,15,120|N|1,25,1,10,10,20||99|131]Nidoking|||None|furyattack,thunderbolt,dreameater,thunderpunch||216,178,70,247,247,59|N|1,9,1,6,6,17||92|59]Gastly|||None|screech,growth,poisonpowder,lightscreen||159,171,223,137,137,31|N|14,22,11,4,4,11||60|144]Persian|||None|hyperbeam,sleeppowder,substitute,karatechop||126,162,8,44,44,4|N|1,21,9,14,14,29||89|118"}
3 | >player p2 {"name":"Bot 2","team":"Nidoqueen|||None|guillotine,thunder,hornattack,poisongas||247,201,64,221,221,131|N|12,30,27,24,24,29||95|199]Clefable|||None|bide,defensecurl,stunspore,watergun||98,238,141,94,94,95|N|3,16,16,7,7,7||78|59]Growlithe|||None|megapunch,swordsdance,flash,razorwind||184,150,10,88,88,226|N|1,13,8,10,10,8||52|143]Starmie|||None|strength,sandattack,confusion,bodyslam||125,193,190,135,135,86|N|3,13,29,3,3,18||69|244]Venusaur|||None|sonicboom,seismictoss,acidarmor,growl||67,4,180,161,161,148|N|4,21,11,12,12,12||89|151]Omanyte|||None|mist,focusenergy,stomp,acid||61,219,155,158,158,221|N|11,11,5,23,23,19||75|96"}
4 | >p1 switch 2
5 | >p2 move guillotine
6 | >p1 move horndrill
7 | >p2 move thunder
8 | >p1 move rollingkick
9 | >p2 move hornattack
10 | >p1 switch 2
11 | >p2 move poisongas
12 | >p1 move sharpen
13 | >p2 switch 2
14 | >p1 move poisonsting
15 | >p2 move bide
16 | >p1 switch 3
17 | >p2 move bide
18 | >p1 move roar
19 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x6EFF8B7677077FE6.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[28415,35702,30471,32742]}
2 | >player p1 {"name":"Bot 1","team":"Magmar|||None|superfang,stomp,rollingkick,leechseed||160,139,191,165,165,159|N|9,30,16,27,27,8||90|105]Golem|||None|vinewhip,psywave,minimize,screech||73,87,202,103,103,18|N|13,2,23,14,14,24||61|141]Tentacool|||None|highjumpkick,bubble,headbutt,reflect||147,181,165,239,239,21|N|1,21,25,2,2,24||95|196]Gyarados|||None|spikecannon,meditate,lowkick,poisonpowder||44,215,201,186,186,166|N|4,4,3,9,9,17||98|158]Nidoran-M|||None|conversion,crabhammer,lovelykiss,doublekick||84,84,196,180,180,228|N|14,11,22,24,24,2||62|41]Lickitung|||None|dreameater,leer,eggbomb,takedown||18,173,153,80,80,18|N|1,9,4,14,14,16||74|135"}
3 | >player p2 {"name":"Bot 2","team":"Scyther|||None|amnesia,supersonic,barrage,bide||26,165,22,71,71,93|N|0,4,5,17,17,17||81|201]Rapidash|||None|twineedle,bodyslam,leechlife,razorwind||32,2,48,158,158,99|N|15,27,2,30,30,7||93|96]Slowpoke|||None|bonemerang,petaldance,surf,scratch||164,114,172,163,163,247|N|6,0,27,20,20,15||80|205]Ivysaur|||None|submission,icepunch,earthquake,hydropump||59,126,234,16,16,247|N|14,14,14,8,8,3||75|30]Parasect|||None|selfdestruct,smog,aurorabeam,thunderbolt||38,180,59,188,188,96|N|5,16,3,15,15,5||57|136]Arcanine|||None|harden,furyswipes,thrash,furyattack||52,157,191,179,179,190|N|1,21,16,2,2,0||90|197"}
4 | >p1 switch 2
5 | >p2 move amnesia
6 | >p1 move vinewhip
7 | >p2 switch 2
8 | >p1 move psywave
9 | >p2 move twineedle
10 | >p1 switch 2
11 | >p2 move bodyslam
12 | >p1 switch 3
13 | >p2 switch 2
14 | >p1 move highjumpkick
15 | >p2 move supersonic
16 | >p1 switch 4
17 | >p2 switch 3
18 | >p1 switch 5
19 | >p2 move bonemerang
20 | >p1 switch 6
21 | >p1 switch 3
22 | >p2 move petaldance
23 | >p1 move superfang
24 | >p2 move petaldance
25 | >p1 move stomp
26 | >p2 move petaldance
27 | >p1 switch 4
28 | >p2 move petaldance
29 | >p1 move bubble
30 | >p2 move surf
31 | >p1 move headbutt
32 | >p2 move scratch
33 | >p2 switch 4
34 | >p1 switch 2
35 | >p2 move submission
36 | >p1 switch 3
37 | >p2 move icepunch
38 | >p1 move dreameater
39 | >p2 move earthquake
40 | >p1 move leer
41 | >p2 move hydropump
42 | >p1 move eggbomb
43 | >p2 move submission
44 | >p1 switch 3
45 | >p2 move submission
46 | >p1 move minimize
47 | >p2 switch 5
48 | >p1 switch 2
49 | >p2 move selfdestruct
50 | >p2 switch 6
51 | >p1 move reflect
52 | >p2 move harden
53 | >p1 move reflect
54 | >p2 move furyswipes
55 | >p1 switch 4
56 | >p2 switch 5
57 | >p1 move rollingkick
58 | >p2 switch 2
59 | >p1 switch 4
60 | >p2 switch 2
61 | >p1 move bubble
62 | >p2 switch 3
63 | >p1 move bubble
64 | >p2 move barrage
65 | >p1 switch 3
66 | >p1 switch 4
67 | >p2 move bide
68 | >p1 move leechseed
69 | >p2 move bide
70 | >p1 switch 4
71 | >p2 move bide
72 | >p1 move takedown
73 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x7DE5A2DD96BA07A5.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[32229,41693,38586,1957]}
2 | >player p1 {"name":"Bot 1","team":"Jynx|||None|dizzypunch,mist,confuseray,gust||135,197,88,76,76,27|N|1,20,24,2,2,12||98|246]Doduo|||None|boneclub,highjumpkick,seismictoss,visegrip||191,97,133,131,131,231|N|10,,0,4,4,23||58|21]Slowpoke|||None|submission,thunderpunch,mist,icepunch||133,168,228,109,109,185|N|1,12,4,26,26,25||67|136]Snorlax|||None|bonemerang,lightscreen,superfang,sludge||250,28,171,222,222,113|N|7,8,23,6,6,6||91|70]Rattata|||None|triattack,psybeam,thundershock,barrier||171,171,125,160,160,57|N|3,1,8,15,15,22||98|117]Ninetales|||None|slash,smog,bubble,hydropump||70,203,206,80,80,133|N|2,29,17,0,0,15||73|163"}
3 | >player p2 {"name":"Bot 2","team":"Voltorb|||None|slam,skyattack,guillotine,doubleteam||165,35,97,4,4,58|N|3,12,1,23,23,18||78|177]Magmar|||None|smokescreen,flamethrower,surf,dig||79,90,38,224,224,26|N|13,15,26,10,10,9||92|195]Bellsprout|||None|flash,firepunch,fly,dragonrage||4,92,204,202,202,103|N|4,1,26,8,8,28||74|16]Machamp|||None|amnesia,eggbomb,sandattack,tailwhip||77,24,202,85,85,223|N|6,21,19,17,17,14||77|173]Gyarados|||None|rockthrow,poisonpowder,harden,substitute||60,166,123,151,151,216|N|2,13,1,29,29,2||71|110]Kakuna|||None|furyattack,bubblebeam,cometpunch,doubleedge||176,69,161,61,61,169|N|10,26,28,17,17,15||59|209"}
4 | >p1 switch 2
5 | >p2 move doubleteam
6 | >p1 switch 2
7 | >p2 switch 2
8 | >p1 move dizzypunch
9 | >p2 move smokescreen
10 | >p1 move mist
11 | >p2 move surf
12 | >p1 switch 3
13 | >p2 move smokescreen
14 | >p1 move icepunch
15 | >p2 move smokescreen
16 | >p1 move thunderpunch
17 | >p2 switch 2
18 | >p1 switch 4
19 | >p2 move slam
20 | >p1 move bonemerang
21 | >p2 switch 3
22 | >p1 move lightscreen
23 | >p2 move fly
24 | >p1 move sludge
25 | >p2 move fly
26 | >p2 switch 4
27 | >p1 move lightscreen
28 | >p2 move amnesia
29 | >p1 switch 5
30 | >p2 switch 5
31 | >p1 move triattack
32 | >p2 move substitute
33 | >p1 move psybeam
34 | >p2 move harden
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x842EFA1D879EC636.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x842EFA1D879EC636.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x87CB47D78C9E83DB.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[34763,18391,35998,33755]}
2 | >player p1 {"name":"Bot 1","team":"Charmeleon|||None|seismictoss,sing,poisongas,strength||59,114,126,59,59,163|N|11,11,25,11,11,11||76|217]Eevee|||None|sandattack,thrash,razorleaf,bite||37,98,229,190,190,143|N|10,7,13,0,0,3||77|213]Rattata|||None|highjumpkick,acid,tailwhip,blizzard||78,125,76,132,132,187|N|13,,14,7,7,13||90|65]Meowth|||None|swordsdance,dreameater,explosion,slash||99,232,221,87,87,119|N|1,1,8,14,14,28||69|41]Hitmonlee|||None|growth,growl,thunderpunch,furyswipes||149,180,106,49,49,119|N|11,2,4,23,23,2||88|45]Doduo|||None|eggbomb,horndrill,softboiled,cometpunch||238,249,88,121,121,169|N|12,10,11,21,21,20||70|150"}
3 | >player p2 {"name":"Bot 2","team":"Venonat|||None|rest,minimize,poisonpowder,peck||182,136,200,137,137,179|N|10,30,8,1,1,14||77|223]Rapidash|||None|fireblast,constrict,roar,superfang||30,10,132,53,53,216|N|5,13,6,11,11,9||65|58]Metapod|||None|skyattack,icepunch,megadrain,flamethrower||76,23,252,140,140,76|N|8,30,8,12,12,21||62|249]Weedle|||None|sonicboom,karatechop,lightscreen,vinewhip||246,25,114,215,215,78|N|3,8,4,3,3,7||91|196]Beedrill|||None|doublekick,hyperbeam,payday,sleeppowder||86,224,88,117,117,99|N|14,30,11,12,12,||98|75]Venusaur|||None|skullbash,smog,furyattack,visegrip||213,188,210,146,146,78|N|5,21,11,2,2,28||64|162"}
4 | >p1 move seismictoss
5 | >p2 move rest
6 | >p1 move sing
7 | >p2 move minimize
8 | >p1 switch 2
9 | >p2 move poisonpowder
10 | >p1 switch 2
11 | >p2 move peck
12 | >p1 move poisongas
13 | >p2 switch 2
14 | >p1 switch 3
15 | >p2 switch 2
16 | >p1 switch 4
17 | >p2 move minimize
18 | >p1 move swordsdance
19 | >p2 switch 3
20 | >p1 switch 5
21 | >p2 switch 4
22 | >p1 move growth
23 | >p2 move sonicboom
24 | >p1 move growl
25 | >p2 move karatechop
26 | >p1 switch 6
27 | >p2 switch 5
28 | >p1 move eggbomb
29 | >p2 move doublekick
30 | >p1 move horndrill
31 | >p2 move hyperbeam
32 | >p1 switch 4
33 | >p1 switch 5
34 | >p2 move payday
35 | >p1 move dreameater
36 | >p2 move sleeppowder
37 | >p1 move explosion
38 | >p2 move doublekick
39 | >p1 switch 5
40 | >p1 switch 6
41 | >p2 move payday
42 | >p1 move thunderpunch
43 | >p2 switch 6
44 | >p1 move furyswipes
45 | >p2 move skullbash
46 | >p1 move furyswipes
47 | >p2 move skullbash
48 | >p1 move growth
49 | >p2 move smog
50 | >p1 switch 3
51 | >p2 move furyattack
52 | >p1 switch 3
53 | >p2 move visegrip
54 | >p1 switch 3
55 | >p1 move strength
56 | >p2 move furyattack
57 | >p1 move poisongas
58 | >p2 switch 4
59 | >p1 move sing
60 | >p2 move skyattack
61 | >p1 switch 6
62 | >p2 move skyattack
63 | >p1 move highjumpkick
64 | >p2 switch 4
65 | >p1 move acid
66 | >p2 move smog
67 | >p2 switch 4
68 | >p1 move tailwhip
69 | >p2 switch 5
70 | >p1 switch 2
71 | >p2 move lightscreen
72 | >p1 move sandattack
73 | >p2 move vinewhip
74 | >p1 move thrash
75 | >p2 move vinewhip
76 | >p1 move thrash
77 | >p2 move karatechop
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x891A4DEC2DA0D04A.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[35098,19948,11680,53322]}
2 | >player p1 {"name":"Bot 1","team":"Horsea|||None|razorleaf,absorb,lovelykiss,doublekick||222,37,81,97,97,11|N|5,29,2,3,3,29||90|136]Hitmonlee|||None|horndrill,aurorabeam,jumpkick,thunderwave||94,129,66,89,89,241|N|5,21,3,,,28||62|67]Ditto|||None|vinewhip,slash,dreameater,ember||3,176,142,43,43,98|N|12,27,27,0,0,4||50|196]Dodrio|||None|leechlife,leechseed,psywave,supersonic||92,199,122,202,202,113|N|3,4,28,26,26,10||92|2]Gyarados|||None|crabhammer,whirlwind,substitute,bite||222,124,93,45,45,200|N|9,18,24,15,15,17||74|118]Farfetch’d|||None|dragonrage,seismictoss,sludge,strength||50,172,199,,,215|N|2,1,5,9,9,22||93|37"}
3 | >player p2 {"name":"Bot 2","team":"Vulpix|||None|solarbeam,swift,razorwind,splash||231,60,106,81,81,96|N|15,15,15,18,18,15||86|130]Charmander|||None|explosion,toxic,rollingkick,quickattack||187,199,107,73,73,247|N|5,5,30,22,22,21||72|117]Jigglypuff|||None|growth,karatechop,superfang,wingattack||2,95,182,64,64,181|N|1,0,13,7,7,20||88|56]Metapod|||None|megadrain,doubleedge,sonicboom,confusion||8,13,208,126,126,246|N|14,,18,24,24,30||97|253]Tentacruel|||None|leer,furyattack,rest,focusenergy||43,100,98,240,240,101|N|6,8,15,29,29,27||59|51]Sandslash|||None|eggbomb,rest,poisonpowder,scratch||91,185,195,198,198,241|N|4,17,14,8,8,4||96|160"}
4 | >p1 move razorleaf
5 | >p2 switch 2
6 | >p1 move absorb
7 | >p2 move explosion
8 | >p1 switch 2
9 | >p2 switch 2
10 | >p1 switch 3
11 | >p2 switch 3
12 | >p1 move vinewhip
13 | >p2 move growth
14 | >p1 move slash
15 | >p2 move karatechop
16 | >p1 move dreameater
17 | >p2 switch 4
18 | >p1 move ember
19 | >p2 move megadrain
20 | >p1 switch 4
21 | >p1 move leechlife
22 | >p2 switch 5
23 | >p1 switch 5
24 | >p2 move leer
25 | >p1 move crabhammer
26 | >p2 move furyattack
27 | >p2 switch 6
28 | >p1 move whirlwind
29 | >p2 move eggbomb
30 | >p1 move substitute
31 | >p2 move rest
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x895A570B71E79B86.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[35162,22283,29159,39814]}
2 | >player p1 {"name":"Bot 1","team":"Machoke|||None|blizzard,defensecurl,visegrip,smog||169,101,77,96,96,108|N|9,2,28,2,2,4||72|115]Nidorino|||None|growth,dizzypunch,tailwhip,stomp||35,38,177,32,32,18|N|7,4,26,27,27,3||56|53]Charmander|||None|crabhammer,razorleaf,disable,doubleedge||100,247,213,53,53,210|N|7,9,19,19,19,23||78|27]Ditto|||None|doubleslap,headbutt,tackle,firepunch||156,97,197,43,43,152|N|9,2,0,7,7,28||88|204]Dugtrio|||None|thunder,harden,nightshade,sing||93,130,176,59,59,231|N|13,19,30,10,10,21||68|54]Magneton|||None|bide,poisongas,smokescreen,screech||205,142,219,198,198,182|N|2,5,12,24,24,15||73|60"}
3 | >player p2 {"name":"Bot 2","team":"Seel|||None|swordsdance,megakick,whirlwind,flamethrower||211,9,49,230,230,17|N|15,6,10,27,27,2||74|9]Koffing|||None|rollingkick,spikecannon,rage,sharpen||11,34,161,208,208,69|N|11,6,9,10,10,23||98|24]Nidorina|||None|seismictoss,hypnosis,lightscreen,amnesia||193,157,153,158,158,139|N|0,29,4,21,21,21||92|105]Jynx|||None|razorwind,lowkick,pinmissile,roar||208,19,100,74,74,155|N|4,1,26,17,17,28||66|45]Weezing|||None|confuseray,surf,thundershock,waterfall||182,101,102,49,49,26|N|15,,27,6,6,6||72|247]Raichu|||None|thrash,triattack,agility,focusenergy||10,181,176,51,51,75|N|4,21,26,0,0,1||72|178"}
4 | >p1 move blizzard
5 | >p2 move swordsdance
6 | >p1 switch 2
7 | >p2 move megakick
8 | >p1 switch 2
9 | >p2 switch 2
10 | >p1 move defensecurl
11 | >p2 move rollingkick
12 | >p1 move visegrip
13 | >p2 move spikecannon
14 | >p1 switch 3
15 | >p2 move rage
16 | >p1 move crabhammer
17 | >p2 move rage
18 | >p1 switch 4
19 | >p2 move rage
20 | >p1 move doubleslap
21 | >p2 move rage
22 | >p1 move headbutt
23 | >p2 move rage
24 | >p1 move tackle
25 | >p2 move rage
26 | >p1 switch 5
27 | >p2 move rage
28 | >p1 switch 6
29 | >p2 move rage
30 | >p1 move bide
31 | >p2 move rage
32 | >p1 move bide
33 | >p2 move rage
34 | >p1 move bide
35 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x898990C029C4E108.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[35209,37056,10692,57608]}
2 | >player p1 {"name":"Bot 1","team":"Sandslash|||None|disable,glare,solarbeam,megadrain||197,252,137,181,181,125|N|11,26,1,19,19,26||58|130]Ponyta|||None|wingattack,thunderwave,fly,barrier||107,137,54,244,244,244|N|15,3,22,10,10,30||79|232]Kingler|||None|explosion,poisonsting,ember,seismictoss||2,212,22,174,174,119|N|6,8,7,17,17,19||96|206]Onix|||None|thunderbolt,headbutt,smog,swift||225,242,224,243,243,129|N|9,27,20,10,10,16||78|63]Charizard|||None|bodyslam,whirlwind,dizzypunch,quickattack||226,171,146,222,222,94|N|1,8,12,2,2,20||69|219]Dragonite|||None|poisonpowder,furyswipes,surf,constrict||237,119,223,64,64,213|N|11,15,21,3,3,18||99|174"}
3 | >player p2 {"name":"Bot 2","team":"Squirtle|||None|reflect,leer,mist,aurorabeam||12,175,110,211,211,107|N|15,27,30,10,10,15||99|250]Muk|||None|eggbomb,peck,disable,bide||34,61,116,156,156,113|N|15,14,14,30,30,15||97|223]Rapidash|||None|thrash,waterfall,horndrill,highjumpkick||136,50,243,171,171,185|N|0,13,9,17,17,24||91|86]Hitmonchan|||None|boneclub,stunspore,barrage,payday||71,209,30,249,249,175|N|10,,0,29,29,||69|83]Starmie|||None|crabhammer,teleport,thunderpunch,hornattack||166,107,51,8,8,59|N|2,24,1,21,21,18||62|102]Mankey|||None|sharpen,hyperfang,psychic,focusenergy||214,126,198,77,77,75|N|9,11,8,27,27,24||70|48"}
4 | >p1 move disable
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 move disable
8 | >p1 move wingattack
9 | >p2 move peck
10 | >p1 switch 2
11 | >p2 move bide
12 | >p1 move disable
13 | >p2 move bide
14 | >p1 move megadrain
15 | >p2 move struggle
16 | >p1 move glare
17 | >p2 move struggle
18 | >p1 move solarbeam
19 | >p2 move struggle
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x89A935237DDA962E.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0x89A935237DDA962E.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x924FD037527C65A3.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[37455,53303,21116,26019]}
2 | >player p1 {"name":"Bot 1","team":"Pidgeotto|||None|lowkick,visegrip,toxic,sludge||51,232,15,191,191,8|N|14,6,30,0,0,2||79|66]Magnemite|||None|karatechop,absorb,focusenergy,watergun||130,172,122,81,81,154|N|2,21,0,8,8,6||82|220]Hitmonlee|||None|bind,supersonic,bite,doubleedge||137,219,32,11,11,185|N|0,24,17,13,13,20||84|168]Vulpix|||None|nightshade,hydropump,bubblebeam,fly||34,181,87,102,102,22|N|10,22,5,13,13,14||64|128]Nidorino|||None|counter,barrier,waterfall,confuseray||131,112,149,55,55,78|N|2,8,25,24,24,7||99|235]Ditto|||None|wrap,mist,lick,sandattack||151,117,154,251,251,35|N|2,1,9,21,21,11||97|27"}
3 | >player p2 {"name":"Bot 2","team":"Rhyhorn|||None|razorwind,psybeam,skullbash,psychic||53,3,90,243,243,139|N|1,29,20,23,23,12||62|19]Haunter|||None|highjumpkick,hornattack,stunspore,firepunch||78,131,228,59,59,150|N|9,15,1,30,30,0||92|22]Oddish|||None|poisonpowder,sharpen,doubleslap,surf||144,150,43,249,249,130|N|5,20,3,,,9||86|124]Bellsprout|||None|quickattack,leechlife,swordsdance,jumpkick||12,9,238,119,119,250|N|6,20,6,1,1,26||74|16]Zapdos|||None|rockthrow,thundershock,leer,haze||169,104,250,32,32,234|N|1,5,25,10,10,21||69|25]Marowak|||None|stringshot,rockslide,poisongas,bubble||214,228,150,65,65,22|N|9,6,9,19,19,12||54|178"}
4 | >p1 move lowkick
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 move highjumpkick
8 | >p1 switch 2
9 | >p2 switch 2
10 | >p1 move visegrip
11 | >p2 switch 3
12 | >p1 move toxic
13 | >p2 move poisonpowder
14 | >p1 move sludge
15 | >p2 switch 4
16 | >p1 move visegrip
17 | >p2 move quickattack
18 | >p1 move sludge
19 | >p2 move leechlife
20 | >p1 move toxic
21 | >p2 move swordsdance
22 | >p1 move sludge
23 | >p2 move jumpkick
24 | >p2 switch 5
25 | >p1 switch 3
26 | >p2 move rockthrow
27 | >p1 move bind
28 | >p2 move thundershock
29 | >p1 move bind
30 | >p2 switch 6
31 | >p1 switch 4
32 | >p2 move stringshot
33 | >p1 move nightshade
34 | >p2 move rockslide
35 | >p1 move hydropump
36 | >p2 move poisongas
37 | >p2 switch 6
38 | >p1 move bubblebeam
39 | >p2 move leer
40 | >p1 move fly
41 | >p2 move haze
42 | >p1 move fly
43 | >p2 switch 3
44 | >p1 move nightshade
45 | >p2 switch 3
46 | >p1 move nightshade
47 | >p2 switch 4
48 | >p1 switch 5
49 | >p2 move sharpen
50 | >p1 switch 6
51 | >p2 move doubleslap
52 | >p1 move wrap
53 | >p2 move surf
54 | >p1 move wrap
55 | >p2 move doubleslap
56 | >p1 move mist
57 | >p2 move surf
58 | >p1 move lick
59 | >p2 move poisonpowder
60 | >p1 move sandattack
61 | >p2 switch 4
62 | >p1 move wrap
63 | >p2 move leer
64 | >p1 move wrap
65 | >p2 switch 4
66 | >p2 switch 4
67 | >p1 move wrap
68 | >p2 move rockthrow
69 | >p1 move wrap
70 | >p2 switch 2
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x973C10A9C58D94FD.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[38716,4265,50573,38141]}
2 | >player p1 {"name":"Bot 1","team":"Vulpix|||None|eggbomb,poisonsting,stringshot,dragonrage||17,17,208,199,199,154|N|10,11,1,13,13,23||98|177]Venusaur|||None|confusion,solarbeam,reflect,sludge||109,5,148,171,171,63|N|8,3,17,21,21,28||80|118]Goldeen|||None|selfdestruct,hornattack,megakick,focusenergy||165,242,247,32,32,12|N|5,16,30,19,19,9||99|172]Articuno|||None|furyattack,hyperfang,superfang,crabhammer||33,,41,95,95,1|N|14,2,10,12,12,3||63|213]Graveler|||None|leechseed,splash,barrage,watergun||104,221,56,119,119,197|N|3,20,28,,,6||75|238]Metapod|||None|swift,seismictoss,rockthrow,smog||116,186,24,14,14,234|N|4,24,30,25,25,29||79|25"}
3 | >player p2 {"name":"Bot 2","team":"Clefairy|||None|hypnosis,waterfall,stringshot,skyattack||115,42,110,219,219,27|N|8,11,4,8,8,25||52|8]Pidgeot|||None|furyswipes,lightscreen,sleeppowder,rollingkick||35,234,41,48,48,51|N|15,7,14,2,2,3||65|124]Bellsprout|||None|tailwhip,acid,substitute,selfdestruct||241,219,70,62,62,166|N|12,,18,13,13,1||50|204]Machop|||None|rockslide,rage,headbutt,doubleslap||130,50,148,111,111,194|N|4,20,26,1,1,24||78|84]Kangaskhan|||None|spikecannon,growl,tackle,swordsdance||21,73,191,101,101,153|N|3,1,13,2,2,27||84|28]Mr. Mime|||None|flash,stomp,pinmissile,slash||182,135,61,163,163,25|N|10,30,5,13,13,26||60|239"}
4 | >p1 move eggbomb
5 | >p2 move stringshot
6 | >p1 move poisonsting
7 | >p2 move hypnosis
8 | >p1 switch 2
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p2 move sleeppowder
12 | >p1 switch 3
13 | >p2 move lightscreen
14 | >p1 move selfdestruct
15 | >p2 move rollingkick
16 | >p1 switch 4
17 | >p2 switch 2
18 | >p1 move furyattack
19 | >p2 move stringshot
20 | >p1 move hyperfang
21 | >p2 switch 3
22 | >p1 switch 5
23 | >p2 switch 4
24 | >p1 move leechseed
25 | >p2 move doubleslap
26 | >p1 move splash
27 | >p2 switch 5
28 | >p1 move barrage
29 | >p2 switch 6
30 | >p1 move watergun
31 | >p2 switch 4
32 | >p2 switch 6
33 | >p1 move leechseed
34 | >p2 move spikecannon
35 | >p1 move splash
36 | >p2 move spikecannon
37 | >p1 move barrage
38 | >p2 move spikecannon
39 | >p1 move splash
40 | >p2 move spikecannon
41 | >p1 move barrage
42 | >p2 move swordsdance
43 | >p1 move barrage
44 | >p2 move swordsdance
45 | >p1 move splash
46 | >p2 switch 4
47 | >p1 move splash
48 | >p2 switch 3
49 | >p1 move leechseed
50 | >p2 move skyattack
51 | >p1 move watergun
52 | >p2 move skyattack
53 | >p1 move leechseed
54 | >p2 move waterfall
55 | >p1 switch 6
56 | >p2 move waterfall
57 | >p2 switch 4
58 | >p1 move seismictoss
59 | >p2 move tackle
60 | >p1 move swift
61 | >p2 switch 5
62 | >p1 move swift
63 | >p2 move rage
64 | >p1 move rockthrow
65 | >p2 move rage
66 | >p1 move rockthrow
67 | >p2 move rage
68 | >p1 move seismictoss
69 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x973EF0823E0530B9.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[38718,61570,15877,12473]}
2 | >player p1 {"name":"Bot 1","team":"Charizard|||None|thunder,blizzard,thundershock,counter||153,33,196,141,141,27|N|5,8,3,27,27,8||95|228]Golbat|||None|kinesis,metronome,pinmissile,glare||37,88,142,68,68,4|N|0,0,5,24,24,8||95|21]Staryu|||None|doubleteam,cometpunch,seismictoss,ember||40,63,185,117,117,218|N|6,21,23,8,8,6||67|82]Magikarp|||None|fireblast,furyswipes,vinewhip,recover||154,25,249,114,114,233|N|11,,1,6,6,||93|247]Cubone|||None|acid,bide,skullbash,fissure||228,158,100,8,8,36|N|9,15,21,2,2,13||80|114]Spearow|||None|doublekick,toxic,boneclub,drillpeck||98,101,68,69,69,222|N|8,10,13,12,12,21||50|82"}
3 | >player p2 {"name":"Bot 2","team":"Articuno|||None|hyperfang,leechlife,karatechop,waterfall||248,25,12,95,95,123|N|2,9,24,4,4,6||97|158]Tauros|||None|slash,acidarmor,mist,razorleaf||33,198,129,91,91,14|N|5,16,27,18,18,21||89|245]Charmeleon|||None|bite,jumpkick,megapunch,takedown||36,61,195,85,85,145|N|8,7,28,28,28,24||67|138]Golem|||None|mimic,sandattack,wrap,scratch||196,189,124,55,55,4|N|7,9,7,26,26,2||69|54]Voltorb|||None|thunderwave,superfang,confuseray,poisonsting||75,104,31,44,44,246|N|13,11,26,10,10,21||52|235]Gloom|||None|psywave,transform,rockthrow,quickattack||16,90,137,59,59,210|N|13,14,22,,,0||65|168"}
4 | >p1 switch 2
5 | >p2 move hyperfang
6 | >p1 move kinesis
7 | >p2 switch 2
8 | >p1 move metronome
9 | >p2 switch 2
10 | >p1 move pinmissile
11 | >p2 move leechlife
12 | >p1 switch 2
13 | >p2 switch 3
14 | >p1 move thunder
15 | >p2 switch 4
16 | >p1 move blizzard
17 | >p2 switch 5
18 | >p2 switch 6
19 | >p1 move thundershock
20 | >p2 move psywave
21 | >p1 move counter
22 | >p2 move transform
23 | >p1 move counter
24 | >p2 move counter
25 | >p1 switch 3
26 | >p2 switch 5
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x9C329D229CD33ED7.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[39986,40226,40147,16087]}
2 | >player p1 {"name":"Bot 1","team":"Fearow|||None|takedown,rollingkick,swordsdance,confusion||147,123,58,97,97,203|N|5,8,11,11,11,9||86|176]Krabby|||None|thunderbolt,swordsdance,glare,bide||137,70,163,102,102,234|N|6,9,15,28,28,14||85|105]Raticate|||None|headbutt,fireblast,waterfall,furyattack||161,10,219,133,133,199|N|13,23,3,7,7,17||71|52]Onix|||None|doubleedge,bonemerang,scratch,seismictoss||126,71,96,58,58,43|N|11,23,8,14,14,6||79|13]Pidgey|||None|poisongas,lightscreen,jumpkick,psywave||13,93,174,45,45,240|N|12,19,19,29,29,25||72|58]Dragonair|||None|eggbomb,barrier,stunspore,vinewhip||241,114,155,135,135,70|N|5,13,19,22,22,8||57|128"}
3 | >player p2 {"name":"Bot 2","team":"Rhyhorn|||None|thunderwave,sludge,acidarmor,meditate||40,208,179,13,13,76|N|4,4,23,4,4,20||63|0]Spearow|||None|megadrain,solarbeam,withdraw,crabhammer||34,65,252,96,96,47|N|1,12,24,6,6,8||79|238]Gastly|||None|hyperbeam,strength,bodyslam,gust||156,105,157,135,135,164|N|9,23,20,26,26,25||98|95]Kingler|||None|screech,growl,conversion,defensecurl||49,129,98,155,155,169|N|7,13,23,3,3,27||90|254]Horsea|||None|horndrill,growth,megakick,minimize||48,193,53,69,69,143|N|14,30,11,13,13,||95|9]Kangaskhan|||None|teleport,fissure,peck,petaldance||85,248,61,112,112,104|N|6,16,22,29,29,7||58|174"}
4 | >p1 move takedown
5 | >p2 move meditate
6 | >p1 move rollingkick
7 | >p2 move acidarmor
8 | >p1 move swordsdance
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p2 move solarbeam
12 | >p1 switch 2
13 | >p2 move solarbeam
14 | >p1 move rollingkick
15 | >p2 switch 2
16 | >p2 switch 3
17 | >p1 move takedown
18 | >p2 move bodyslam
19 | >p1 switch 3
20 | >p2 move bodyslam
21 | >p1 move headbutt
22 | >p2 switch 4
23 | >p1 switch 4
24 | >p2 switch 5
25 | >p1 move doubleedge
26 | >p2 move megakick
27 | >p1 move bonemerang
28 | >p2 move megakick
29 | >p1 move seismictoss
30 | >p2 move megakick
31 | >p2 switch 6
32 | >p1 move doubleedge
33 | >p2 move teleport
34 | >p1 switch 5
35 | >p2 move fissure
36 | >p1 move lightscreen
37 | >p2 switch 4
38 | >p1 move jumpkick
39 | >p2 move gust
40 | >p1 move lightscreen
41 | >p2 switch 4
42 | >p1 switch 6
43 | >p2 move teleport
44 | >p1 switch 5
45 | >p2 move teleport
46 | >p1 move scratch
47 | >p2 switch 2
48 | >p1 switch 4
49 | >p2 switch 2
50 | >p1 move headbutt
51 | >p2 move petaldance
52 | >p1 move headbutt
53 | >p2 move peck
54 | >p1 switch 2
55 | >p2 move petaldance
56 | >p1 switch 4
57 | >p2 move petaldance
58 | >p1 switch 4
59 | >p1 move bide
60 | >p2 move petaldance
61 | >p1 move bide
62 | >p2 move teleport
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x9E2B535EAB26BB7E.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[40491,21342,43814,47998]}
2 | >player p1 {"name":"Bot 1","team":"Alakazam|||None|submission,absorb,smokescreen,softboiled||214,234,213,222,222,35|N|11,15,8,18,18,||55|122]Nidorino|||None|doubleslap,hyperfang,fissure,dragonrage||48,22,6,80,80,91|N|7,17,,22,22,23||98|79]Sandslash|||None|firepunch,fireblast,icebeam,rest||248,28,109,230,230,166|N|4,20,26,28,28,12||75|231]Goldeen|||None|bodyslam,gust,supersonic,doubleedge||137,127,164,65,65,67|N|8,30,12,5,5,29||50|50]Nidoking|||None|earthquake,bubble,selfdestruct,growth||160,114,37,24,24,106|N|3,20,1,26,26,27||95|114]Lapras|||None|spikecannon,rage,quickattack,amnesia||43,51,90,37,37,22|N|15,7,7,23,23,11||65|106"}
3 | >player p2 {"name":"Bot 2","team":"Electabuzz|||None|confuseray,swift,bide,substitute||186,241,209,44,44,70|N|4,8,6,20,20,29||90|237]Charmeleon|||None|payday,barrier,nightshade,thrash||2,75,157,237,237,43|N|12,18,11,20,20,29||94|231]Tentacool|||None|pound,thunderwave,haze,thunder||70,37,159,156,156,216|N|2,1,4,12,12,19||81|191]Cubone|||None|rockthrow,bite,leechlife,amnesia||33,193,151,234,234,45|N|14,6,7,9,9,26||57|72]Dodrio|||None|strength,cometpunch,focusenergy,confusion||232,160,43,232,232,9|N|15,22,19,2,2,||57|206]Slowpoke|||None|rockthrow,acidarmor,hyperfang,dizzypunch||97,115,45,3,3,148|N|6,0,11,5,5,6||67|230"}
4 | >p1 switch 2
5 | >p2 move confuseray
6 | >p1 move doubleslap
7 | >p2 move swift
8 | >p1 move hyperfang
9 | >p2 move bide
10 | >p1 move fissure
11 | >p2 move bide
12 | >p1 move dragonrage
13 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0x9FFAFACA6FEECB03.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[40954,64202,28654,51971]}
2 | >player p1 {"name":"Bot 1","team":"Cloyster|||None|razorwind,focusenergy,dragonrage,barrier||66,176,229,189,189,175|N|4,24,26,8,8,17||93|150]Farfetch’d|||None|roar,confusion,tackle,agility||90,60,248,67,67,47|N|15,18,19,2,2,15||61|169]Machamp|||None|solarbeam,recover,stringshot,payday||100,68,61,205,205,106|N|11,30,12,18,18,23||65|170]Charmander|||None|teleport,smog,poisonsting,psybeam||178,,58,243,243,54|N|12,7,19,21,21,25||70|39]Cubone|||None|bubblebeam,sharpen,skyattack,disable||39,54,23,44,44,29|N|8,3,0,16,16,13||93|227]Aerodactyl|||None|substitute,acid,constrict,slash||82,191,9,226,226,159|N|13,11,11,7,7,25||91|12"}
3 | >player p2 {"name":"Bot 2","team":"Gengar|||None|harden,pound,megakick,wingattack||249,89,140,119,119,167|N|4,28,19,9,9,24||63|104]Charmeleon|||None|submission,vinewhip,skullbash,doubleedge||142,123,166,134,134,185|N|13,22,2,26,26,12||66|53]Clefable|||None|spore,rest,psychic,megapunch||186,35,10,165,165,252|N|12,15,,28,28,16||97|187]Magikarp|||None|explosion,petaldance,supersonic,thunderwave||135,122,202,23,23,94|N|9,26,4,3,3,13||88|32]Tentacool|||None|takedown,icebeam,splash,selfdestruct||75,99,241,167,167,48|N|4,25,7,25,25,25||88|61]Pikachu|||None|cometpunch,haze,eggbomb,reflect||101,248,125,81,81,202|N|15,22,15,11,11,11||84|231"}
4 | >p1 move razorwind
5 | >p2 switch 2
6 | >p1 move razorwind
7 | >p2 move submission
8 | >p1 move focusenergy
9 | >p2 move vinewhip
10 | >p1 switch 2
11 | >p2 switch 2
12 | >p1 move roar
13 | >p2 move harden
14 | >p1 move confusion
15 | >p2 move pound
16 | >p1 switch 2
17 | >p2 move megakick
18 | >p1 switch 3
19 | >p2 switch 3
20 | >p1 move solarbeam
21 | >p2 move spore
22 | >p1 move recover
23 | >p2 move rest
24 | >p1 move stringshot
25 | >p2 move psychic
26 | >p1 switch 4
27 | >p1 move teleport
28 | >p2 move megapunch
29 | >p1 switch 5
30 | >p2 move rest
31 | >p1 switch 6
32 | >p2 move megapunch
33 | >p1 switch 5
34 | >p2 switch 4
35 | >p1 switch 2
36 | >p2 switch 2
37 | >p1 move tackle
38 | >p2 move skullbash
39 | >p1 move agility
40 | >p2 move skullbash
41 | >p1 move roar
42 | >p2 move doubleedge
43 | >p1 switch 6
44 | >p2 switch 6
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xA0406E4B3AA33F5E.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[41024,28235,15011,16222]}
2 | >player p1 {"name":"Bot 1","team":"Jynx|||None|psywave,pound,dreameater,waterfall||44,119,8,167,167,123|N|14,15,22,16,16,6||55|145]Kadabra|||None|bodyslam,superfang,reflect,karatechop||125,21,102,140,140,63|N|1,4,0,7,7,28||59|182]Raticate|||None|icebeam,gust,doublekick,poisonsting||10,237,150,61,61,34|N|3,13,4,10,10,2||81|253]Dragonite|||None|firepunch,peck,focusenergy,slam||141,106,3,169,169,33|N|11,10,1,10,10,10||99|122]Sandslash|||None|hyperbeam,submission,growth,furyattack||194,183,44,1,1,199|N|2,24,0,21,21,30||71|196]Victreebel|||None|rest,surf,psychic,rage||177,88,83,229,229,16|N|6,1,11,28,28,19||80|192"}
3 | >player p2 {"name":"Bot 2","team":"Rhyhorn|||None|swift,disable,bubblebeam,poisonpowder||87,185,160,21,21,31|N|3,13,0,30,30,23||58|115]Jolteon|||None|fissure,bide,eggbomb,spore||94,18,52,232,232,173|N|6,9,18,9,9,14||66|63]Staryu|||None|thrash,stringshot,headbutt,smog||226,22,60,,,98|N|12,22,2,0,0,8||93|246]Tentacool|||None|bite,kinesis,visegrip,recover||136,12,73,188,188,114|N|3,29,5,,,23||84|186]Bellsprout|||None|withdraw,harden,furyswipes,sharpen||197,219,203,22,22,188|N|3,28,1,18,18,22||85|220]Metapod|||None|megakick,megapunch,swordsdance,splash||168,146,116,198,198,216|N|12,2,30,1,1,5||57|55"}
4 | >p1 move psywave
5 | >p2 move swift
6 | >p1 switch 2
7 | >p2 move disable
8 | >p1 switch 2
9 | >p2 move bubblebeam
10 | >p1 move pound
11 | >p2 move poisonpowder
12 | >p1 switch 3
13 | >p2 move poisonpowder
14 | >p1 move icebeam
15 | >p2 move bubblebeam
16 | >p2 switch 2
17 | >p1 move gust
18 | >p2 switch 3
19 | >p1 switch 4
20 | >p2 move thrash
21 | >p1 switch 5
22 | >p2 move thrash
23 | >p1 move hyperbeam
24 | >p2 move thrash
25 | >p2 switch 4
26 | >p1 move submission
27 | >p2 move bite
28 | >p1 move growth
29 | >p2 switch 5
30 | >p1 move furyattack
31 | >p2 move withdraw
32 | >p1 move growth
33 | >p2 move harden
34 | >p1 switch 6
35 | >p2 move furyswipes
36 | >p1 switch 4
37 | >p2 switch 6
38 | >p1 move doublekick
39 | >p2 move megakick
40 | >p1 switch 2
41 | >p2 move megapunch
42 | >p1 move bodyslam
43 | >p2 move swordsdance
44 | >p1 move superfang
45 | >p2 move splash
46 | >p1 move reflect
47 | >p2 switch 5
48 | >p1 move karatechop
49 | >p2 move kinesis
50 | >p1 move bodyslam
51 | >p2 switch 3
52 | >p1 switch 5
53 | >p2 move fissure
54 | >p1 move firepunch
55 | >p2 move bide
56 | >p1 switch 6
57 | >p2 move bide
58 | >p1 move growth
59 | >p2 move bide
60 | >p1 move furyattack
61 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xA0F50070ADB32DED.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[41205,112,44467,11757]}
2 | >player p1 {"name":"Bot 1","team":"Primeape|||None|cut,megakick,sandattack,acid||46,188,124,176,176,141|N|4,4,,0,0,20||85|220]Gastly|||None|kinesis,scratch,razorwind,splash||63,205,138,200,200,199|N|6,16,10,8,8,3||72|210]Exeggutor|||None|strength,poisonpowder,stringshot,mist||115,216,240,117,117,252|N|9,6,20,14,14,1||64|210]Staryu|||None|hornattack,gust,swift,clamp||188,8,113,185,185,130|N|7,5,26,2,2,15||98|241]Nidorina|||None|spore,thundershock,superfang,defensecurl||86,116,25,116,116,242|N|13,18,15,30,30,25||70|133]Mew|||None|agility,psychic,eggbomb,bubble||86,49,227,16,16,96|N|10,2,17,17,17,26||62|13"}
3 | >player p2 {"name":"Bot 2","team":"Vileplume|||None|sleeppowder,sonicboom,fireblast,splash||127,200,218,189,189,62|N|1,21,1,6,6,1||72|190]Rhydon|||None|mimic,tailwhip,substitute,pinmissile||109,17,206,23,23,114|N|7,12,3,,,14||58|74]Hitmonchan|||None|barrier,roar,absorb,wingattack||57,90,84,150,150,170|N|1,12,17,26,26,29||79|195]Rattata|||None|watergun,psychic,wrap,triattack||150,50,148,199,199,166|N|3,0,8,7,7,11||64|30]Magneton|||None|fly,barrage,petaldance,eggbomb||29,151,148,128,128,144|N|13,23,22,26,26,12||57|64]Magnemite|||None|counter,surf,bite,skullbash||142,249,29,84,84,212|N|7,29,23,19,19,||63|177"}
4 | >p1 switch 2
5 | >p2 move sonicboom
6 | >p1 move razorwind
7 | >p2 switch 2
8 | >p1 move razorwind
9 | >p2 move pinmissile
10 | >p1 move razorwind
11 | >p2 move tailwhip
12 | >p1 move razorwind
13 | >p2 move mimic
14 | >p1 switch 2
15 | >p2 switch 2
16 | >p1 move cut
17 | >p2 switch 3
18 | >p1 switch 3
19 | >p2 switch 4
20 | >p1 move stringshot
21 | >p2 move wrap
22 | >p1 move mist
23 | >p2 move wrap
24 | >p1 move stringshot
25 | >p2 switch 5
26 | >p1 move poisonpowder
27 | >p2 move fly
28 | >p1 move poisonpowder
29 | >p2 move fly
30 | >p1 move poisonpowder
31 | >p2 move fly
32 | >p1 move stringshot
33 | >p2 move fly
34 | >p1 switch 4
35 | >p2 move petaldance
36 | >p1 switch 5
37 | >p2 move petaldance
38 | >p1 switch 6
39 | >p2 move petaldance
40 | >p1 switch 6
41 | >p2 move petaldance
42 | >p1 move superfang
43 | >p2 move eggbomb
44 | >p1 switch 3
45 | >p2 move petaldance
46 | >p1 move megakick
47 | >p2 move petaldance
48 | >p1 move acid
49 | >p2 move petaldance
50 | >p2 switch 6
51 | >p1 switch 4
52 | >p2 move counter
53 | >p1 move stringshot
54 | >p2 move surf
55 | >p1 move stringshot
56 | >p2 move surf
57 | >p1 move strength
58 | >p2 switch 2
59 | >p1 switch 2
60 | >p2 switch 4
61 | >p1 move splash
62 | >p2 switch 2
63 | >p1 move razorwind
64 | >p2 move counter
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xA31F27EAF9BF4E3B.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[41759,10218,63935,20027]}
2 | >player p1 {"name":"Bot 1","team":"Weedle|||None|razorwind,slash,eggbomb,icebeam||200,126,188,93,93,82|N|5,12,23,18,18,13||70|211]Blastoise|||None|highjumpkick,acidarmor,dig,counter||206,111,13,192,192,100|N|0,28,29,25,25,28||92|159]Bulbasaur|||None|hyperbeam,absorb,psywave,swift||107,239,29,1,1,189|N|3,13,13,19,19,18||98|88]Arbok|||None|sing,horndrill,submission,poisonsting||100,121,81,123,123,241|N|9,26,16,2,2,29||57|67]Pidgeot|||None|bonemerang,psybeam,doublekick,firepunch||138,12,55,79,79,101|N|14,15,,12,12,19||99|107]Flareon|||None|doubleteam,flamethrower,hornattack,barrage||200,88,206,126,126,141|N|1,1,16,18,18,12||52|64"}
3 | >player p2 {"name":"Bot 2","team":"Arcanine|||None|scratch,furyswipes,skullbash,pinmissile||164,3,93,23,23,49|N|15,30,7,6,6,19||72|10]Omanyte|||None|sandattack,seismictoss,withdraw,lightscreen||60,152,138,29,29,117|N|10,14,8,13,13,19||50|178]Raichu|||None|aurorabeam,toxic,headbutt,megadrain||128,210,34,22,22,214|N|11,18,25,10,10,||84|16]Oddish|||None|stunspore,amnesia,growth,sonicboom||89,120,65,74,74,18|N|3,20,9,18,18,11||99|32]Primeape|||None|drillpeck,crabhammer,glare,hydropump||72,153,78,142,142,148|N|12,23,3,0,0,16||91|83]Magmar|||None|bodyslam,softboiled,disable,karatechop||108,35,113,94,94,28|N|11,10,5,23,23,15||71|77"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 move highjumpkick
7 | >p2 move sandattack
8 | >p1 move acidarmor
9 | >p2 move seismictoss
10 | >p1 move dig
11 | >p2 move withdraw
12 | >p1 move dig
13 | >p2 switch 2
14 | >p1 switch 2
15 | >p2 move scratch
16 | >p1 switch 3
17 | >p2 move furyswipes
18 | >p1 move hyperbeam
19 | >p2 move skullbash
20 | >p1 move recharge
21 | >p2 move skullbash
22 | >p1 switch 4
23 | >p2 move pinmissile
24 | >p1 switch 5
25 | >p2 switch 3
26 | >p1 move bonemerang
27 | >p2 move aurorabeam
28 | >p2 switch 4
29 | >p1 move psybeam
30 | >p2 switch 5
31 | >p1 switch 6
32 | >p2 move drillpeck
33 | >p1 move doubleteam
34 | >p2 switch 6
35 | >p1 move flamethrower
36 | >p2 move bodyslam
37 | >p1 move hornattack
38 | >p2 move softboiled
39 | >p1 switch 2
40 | >p2 move disable
41 | >p1 move counter
42 | >p2 move karatechop
43 | >p1 move acidarmor
44 | >p2 switch 2
45 | >p1 move highjumpkick
46 | >p2 switch 2
47 | >p2 switch 5
48 | >p1 move highjumpkick
49 | >p2 move stunspore
50 | >p1 move acidarmor
51 | >p2 move amnesia
52 | >p1 move dig
53 | >p2 move growth
54 | >p1 move dig
55 | >p2 switch 3
56 | >p1 move highjumpkick
57 | >p2 move skullbash
58 | >p1 move counter
59 | >p2 move skullbash
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xA99BCE90DBE18670.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xA99BCE90DBE18670.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xAF52B504F51A337C.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xAF52B504F51A337C.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xB265471DCC2DDDC8.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[45669,18205,52269,56776]}
2 | >player p1 {"name":"Bot 1","team":"Blastoise|||None|furyattack,explosion,razorwind,guillotine||34,155,140,2,2,98|N|3,29,5,19,19,19||54|182]Onix|||None|harden,acidarmor,doubleteam,withdraw||226,95,83,116,116,84|N|10,27,17,25,25,6||65|0]Nidoran-F|||None|constrict,megadrain,smokescreen,doubleedge||140,137,97,80,80,20|N|4,12,18,4,4,1||68|120]Golduck|||None|headbutt,recover,thunder,icepunch||156,8,4,47,47,141|N|5,16,18,18,18,28||77|94]Dragonite|||None|leechseed,toxic,thunderbolt,screech||32,159,156,49,49,194|N|10,7,24,12,12,10||76|71]Bulbasaur|||None|barrier,sludge,guillotine,selfdestruct||34,227,130,137,137,110|N|0,16,28,13,13,4||68|7"}
3 | >player p2 {"name":"Bot 2","team":"Arcanine|||None|swordsdance,karatechop,watergun,minimize||117,100,210,184,184,228|N|6,9,23,8,8,15||67|249]Farfetch’d|||None|thrash,megadrain,flash,skyattack||119,218,26,137,137,211|N|14,11,18,21,21,15||67|57]Eevee|||None|doublekick,drillpeck,fissure,tailwhip||211,136,113,205,205,36|N|14,,7,21,21,11||71|6]Flareon|||None|firepunch,tackle,harden,poisonpowder||79,134,251,220,220,68|N|11,,0,23,23,27||89|0]Nidoking|||None|sonicboom,sing,solarbeam,confusion||87,86,217,143,143,2|N|8,14,8,20,20,8||72|136]Sandslash|||None|takedown,explosion,thunderpunch,psywave||223,215,46,238,238,240|N|15,6,15,3,3,||88|125"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 move harden
7 | >p2 switch 2
8 | >p1 switch 2
9 | >p2 switch 3
10 | >p1 switch 3
11 | >p2 move doublekick
12 | >p1 move constrict
13 | >p2 move fissure
14 | >p1 move megadrain
15 | >p2 move drillpeck
16 | >p1 switch 4
17 | >p2 move tailwhip
18 | >p1 move headbutt
19 | >p2 move drillpeck
20 | >p1 move icepunch
21 | >p2 switch 4
22 | >p1 switch 5
23 | >p2 move harden
24 | >p1 move screech
25 | >p2 move poisonpowder
26 | >p1 move leechseed
27 | >p2 move harden
28 | >p1 move screech
29 | >p2 switch 2
30 | >p1 move toxic
31 | >p2 move skyattack
32 | >p1 move screech
33 | >p2 move skyattack
34 | >p1 move toxic
35 | >p2 move megadrain
36 | >p1 switch 6
37 | >p2 switch 2
38 | >p1 switch 3
39 | >p2 move poisonpowder
40 | >p1 move furyattack
41 | >p2 move poisonpowder
42 | >p1 move explosion
43 | >p2 move poisonpowder
44 | >p1 switch 3
45 | >p2 switch 2
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xB758AB5F9D7AD36D.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[46936,43871,40314,54125]}
2 | >player p1 {"name":"Bot 1","team":"Bulbasaur|||None|thunderpunch,rockthrow,leechlife,meditate||204,93,86,235,235,243|N|6,16,7,1,1,26||89|167]Grimer|||None|swordsdance,bite,supersonic,whirlwind||91,226,196,103,103,145|N|10,15,4,1,1,7||77|206]Kabutops|||None|amnesia,karatechop,doubleslap,hydropump||136,114,195,139,139,155|N|11,23,5,11,11,23||94|77]Nidoran-F|||None|sleeppowder,aurorabeam,hyperbeam,softboiled||42,28,220,217,217,203|N|0,24,25,9,9,8||98|91]Nidoking|||None|firepunch,bubble,metronome,sing||44,108,132,220,220,208|N|10,14,25,29,29,15||95|56]Jolteon|||None|twineedle,tackle,thunderwave,recover||70,103,129,145,145,41|N|4,4,3,1,1,24||74|251"}
3 | >player p2 {"name":"Bot 2","team":"Magneton|||None|screech,solarbeam,megadrain,rage||228,93,200,53,53,185|N|4,0,23,17,17,24||80|185]Dodrio|||None|lightscreen,thunderbolt,ember,highjumpkick||139,14,230,93,93,171|N|14,14,11,20,20,22||84|89]Lickitung|||None|waterfall,growth,superfang,transform||246,151,97,158,158,228|N|14,7,11,12,12,27||91|57]Vileplume|||None|teleport,skullbash,hyperfang,cometpunch||188,132,199,251,251,166|N|10,11,0,12,12,3||62|142]Exeggutor|||None|sludge,leechseed,strength,smog||104,33,58,167,167,12|N|1,9,24,19,19,28||60|188]Oddish|||None|confuseray,guillotine,furyswipes,psychic||187,13,237,206,206,62|N|0,4,12,29,29,9||76|123"}
4 | >p1 switch 2
5 | >p2 move screech
6 | >p1 switch 2
7 | >p2 switch 2
8 | >p1 switch 3
9 | >p2 move lightscreen
10 | >p1 move amnesia
11 | >p2 switch 2
12 | >p1 move karatechop
13 | >p2 move solarbeam
14 | >p1 move doubleslap
15 | >p2 move solarbeam
16 | >p1 move hydropump
17 | >p2 move megadrain
18 | >p1 switch 4
19 | >p1 switch 5
20 | >p2 move rage
21 | >p1 move firepunch
22 | >p2 move rage
23 | >p2 switch 3
24 | >p1 switch 6
25 | >p2 move waterfall
26 | >p1 move twineedle
27 | >p2 move growth
28 | >p1 move tackle
29 | >p2 switch 4
30 | >p1 move thunderwave
31 | >p2 switch 5
32 | >p1 move recover
33 | >p2 move sludge
34 | >p1 switch 2
35 | >p2 switch 6
36 | >p1 move swordsdance
37 | >p2 switch 2
38 | >p1 switch 2
39 | >p2 switch 4
40 | >p1 move twineedle
41 | >p2 move superfang
42 | >p1 move twineedle
43 | >p2 move transform
44 | >p1 move thunderwave
45 | >p2 move tackle
46 | >p1 move thunderwave
47 | >p2 move twineedle
48 | >p1 switch 5
49 | >p1 move sleeppowder
50 | >p2 move twineedle
51 | >p1 move aurorabeam
52 | >p2 move tackle
53 | >p1 move hyperbeam
54 | >p2 move tackle
55 | >p1 move recharge
56 | >p2 move thunderwave
57 | >p1 switch 6
58 | >p2 move recover
59 | >p1 move bubble
60 | >p2 move tackle
61 | >p1 move metronome
62 | >p2 move recover
63 | >p1 move sing
64 | >p2 move thunderwave
65 | >p1 switch 3
66 | >p2 move thunderwave
67 | >p1 switch 3
68 | >p2 switch 5
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xB9131B7324E482AD.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[47379,7027,9444,33453]}
2 | >player p1 {"name":"Bot 1","team":"Abra|||None|pinmissile,substitute,softboiled,crabhammer||143,52,149,5,5,99|N|6,5,27,24,24,14||89|50]Jigglypuff|||None|meditate,glare,flash,fireblast||215,157,209,209,209,240|N|1,8,13,27,27,5||89|179]Dugtrio|||None|poisongas,leechlife,seismictoss,skyattack||224,36,161,150,150,124|N|1,29,0,7,7,5||97|120]Rattata|||None|supersonic,hornattack,psychic,acid||241,43,244,117,117,168|N|5,20,19,10,10,0||55|244]Horsea|||None|quickattack,constrict,stunspore,toxic||142,203,154,211,211,149|N|2,13,17,5,5,23||79|254]Magikarp|||None|megapunch,conversion,bite,thunderpunch||66,158,73,2,2,24|N|6,9,26,29,29,2||73|45"}
3 | >player p2 {"name":"Bot 2","team":"Charizard|||None|defensecurl,firepunch,razorwind,disable||50,247,61,1,1,200|N|9,3,28,11,11,5||96|141]Bellsprout|||None|sonicboom,psywave,acidarmor,smokescreen||79,204,,31,31,133|N|0,1,13,8,8,12||81|179]Raichu|||None|petaldance,bonemerang,blizzard,growl||194,115,12,72,72,244|N|5,25,3,27,27,1||90|171]Nidoran-M|||None|sharpen,lick,swordsdance,megakick||85,244,43,237,237,151|N|12,26,19,9,9,1||86|125]Rapidash|||None|leechseed,poisonsting,bodyslam,doubleteam||80,165,210,210,210,85|N|3,17,21,10,10,15||86|204]Blastoise|||None|reflect,flamethrower,furyswipes,focusenergy||181,67,149,147,147,251|N|2,25,28,9,9,19||58|97"}
4 | >p1 switch 2
5 | >p2 move defensecurl
6 | >p1 move meditate
7 | >p2 move firepunch
8 | >p1 move glare
9 | >p2 move razorwind
10 | >p1 switch 2
11 | >p2 move razorwind
12 | >p1 move pinmissile
13 | >p2 move disable
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xB9A1A38FCBBF6648.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[47521,41871,52159,26184]}
2 | >player p1 {"name":"Bot 1","team":"Primeape|||None|slam,fly,teleport,thunderpunch||101,211,13,97,97,229|N|15,18,10,15,15,10||56|23]Tangela|||None|nightshade,icebeam,visegrip,psywave||54,123,175,138,138,87|N|1,16,0,23,23,16||81|205]Cloyster|||None|lovelykiss,strength,focusenergy,hydropump||210,43,93,33,33,64|N|6,1,,1,1,2||59|48]Arbok|||None|bubblebeam,confuseray,stomp,furyswipes||16,172,190,50,50,48|N|13,7,3,14,14,8||65|228]Dratini|||None|flash,withdraw,stunspore,fissure||115,216,202,22,22,167|N|11,3,29,7,7,6||55|8]Venonat|||None|dreameater,horndrill,spore,scratch||206,18,77,23,23,160|N|2,8,8,13,13,15||50|204"}
3 | >player p2 {"name":"Bot 2","team":"Mankey|||None|minimize,swift,lightscreen,sing||203,194,103,75,75,61|N|6,20,22,29,29,||82|182]Meowth|||None|fireblast,leechseed,vinewhip,hornattack||13,152,98,111,111,38|N|3,12,1,10,10,6||87|223]Poliwhirl|||None|crabhammer,thrash,disable,petaldance||126,2,12,200,200,12|N|5,28,22,27,27,1||76|194]Raticate|||None|glare,lowkick,smokescreen,highjumpkick||85,189,22,137,137,190|N|8,26,20,9,9,4||70|81]Poliwrath|||None|leechlife,lick,barrier,leer||207,101,174,234,234,42|N|8,14,9,9,9,0||69|51]Moltres|||None|bodyslam,seismictoss,splash,gust||72,166,111,61,61,50|N|3,13,17,2,2,27||69|131"}
4 | >p1 move slam
5 | >p2 move minimize
6 | >p1 move fly
7 | >p2 move swift
8 | >p1 move fly
9 | >p2 move lightscreen
10 | >p1 move teleport
11 | >p2 move sing
12 | >p1 move thunderpunch
13 | >p2 move minimize
14 | >p1 move teleport
15 | >p2 move swift
16 | >p1 switch 2
17 | >p1 move nightshade
18 | >p2 move lightscreen
19 | >p1 move icebeam
20 | >p2 move minimize
21 | >p1 switch 3
22 | >p2 move minimize
23 | >p1 move lovelykiss
24 | >p2 move minimize
25 | >p1 switch 4
26 | >p2 move swift
27 | >p1 switch 5
28 | >p2 switch 2
29 | >p1 move flash
30 | >p2 move fireblast
31 | >p1 move withdraw
32 | >p2 switch 2
33 | >p1 move stunspore
34 | >p2 move minimize
35 | >p1 move fissure
36 | >p2 move minimize
37 | >p1 switch 6
38 | >p2 move lightscreen
39 | >p1 switch 4
40 | >p2 move lightscreen
41 | >p1 move strength
42 | >p2 move minimize
43 | >p1 move focusenergy
44 | >p2 move lightscreen
45 | >p1 switch 5
46 | >p2 move swift
47 | >p1 switch 4
48 | >p2 switch 3
49 | >p1 move dreameater
50 | >p2 move crabhammer
51 | >p1 switch 3
52 | >p1 move visegrip
53 | >p2 move thrash
54 | >p1 switch 5
55 | >p2 move thrash
56 | >p1 move hydropump
57 | >p2 move thrash
58 | >p1 move lovelykiss
59 | >p2 move disable
60 | >p1 move hydropump
61 | >p2 switch 4
62 | >p1 move strength
63 | >p2 move glare
64 | >p1 move lovelykiss
65 | >p2 move lowkick
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xBABA377EE1638987.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[47802,14206,57699,35207]}
2 | >player p1 {"name":"Bot 1","team":"Golbat|||None|spikecannon,solarbeam,toxic,leechseed||234,49,195,245,245,173|N|3,24,16,30,30,7||78|147]Horsea|||None|megadrain,headbutt,razorleaf,roar||137,185,43,142,142,195|N|15,23,6,,,14||66|167]Articuno|||None|thunder,waterfall,bite,tailwhip||39,55,81,208,208,185|N|6,8,2,13,13,19||64|135]Nidoran-M|||None|rage,payday,gust,cut||132,55,48,99,99,225|N|9,10,25,11,11,20||80|154]Poliwag|||None|psybeam,sing,thrash,eggbomb||12,70,68,170,170,|N|2,24,0,8,8,6||74|203]Weepinbell|||None|dizzypunch,karatechop,hydropump,mist||53,104,184,197,197,71|N|2,13,28,9,9,18||71|90"}
3 | >player p2 {"name":"Bot 2","team":"Nidorino|||None|horndrill,hyperbeam,rockslide,doubleteam||89,58,154,220,220,1|N|3,29,9,10,10,27||52|146]Porygon|||None|swift,rockthrow,lightscreen,doublekick||197,187,38,45,45,62|N|10,,20,25,25,7||76|197]Mew|||None|absorb,lick,barrage,boneclub||202,12,127,79,79,178|N|7,4,22,14,14,||96|180]Staryu|||None|cometpunch,guillotine,rest,flash||128,89,44,234,234,163|N|15,,30,10,10,19||55|128]Eevee|||None|icebeam,leechlife,earthquake,dig||54,19,183,203,203,84|N|4,21,2,8,8,17||89|10]Golem|||None|smog,icepunch,screech,doubleslap||41,104,3,171,171,91|N|7,4,26,19,19,26||54|77"}
4 | >p1 move spikecannon
5 | >p2 move horndrill
6 | >p1 switch 2
7 | >p2 move hyperbeam
8 | >p1 switch 2
9 | >p2 move recharge
10 | >p1 move solarbeam
11 | >p2 switch 2
12 | >p1 move solarbeam
13 | >p2 move swift
14 | >p1 move toxic
15 | >p2 switch 2
16 | >p1 move leechseed
17 | >p2 move rockslide
18 | >p1 switch 3
19 | >p2 switch 3
20 | >p1 switch 4
21 | >p2 move absorb
22 | >p1 move rage
23 | >p2 switch 4
24 | >p1 move rage
25 | >p2 switch 5
26 | >p1 move rage
27 | >p2 switch 6
28 | >p1 move rage
29 | >p2 move smog
30 | >p1 move rage
31 | >p2 switch 6
32 | >p1 move rage
33 | >p2 switch 6
34 | >p1 move rage
35 | >p2 move smog
36 | >p1 move rage
37 | >p2 move smog
38 | >p1 move rage
39 | >p2 move smog
40 | >p1 move rage
41 | >p2 move icepunch
42 | >p1 move rage
43 | >p2 move smog
44 | >p1 move rage
45 | >p2 move doubleslap
46 | >p1 move rage
47 | >p2 move smog
48 | >p1 move rage
49 | >p2 move icepunch
50 | >p1 move rage
51 | >p2 move doubleslap
52 | >p1 move rage
53 | >p2 move screech
54 | >p1 move rage
55 | >p2 move smog
56 | >p2 switch 3
57 | >p1 move rage
58 | >p2 switch 2
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xBB75F6633DBA4C08.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[47989,63075,15802,19464]}
2 | >player p1 {"name":"Bot 1","team":"Kabuto|||None|blizzard,sludge,lowkick,tailwhip||237,66,170,170,170,168|N|14,11,10,13,13,10||66|107]Dratini|||None|vinewhip,strength,rage,doubleslap||218,21,234,163,163,250|N|2,29,4,21,21,10||71|36]Mewtwo|||None|spikecannon,amnesia,smokescreen,watergun||47,64,82,104,104,220|N|12,15,,5,5,0||79|56]Seaking|||None|visegrip,rollingkick,dig,fissure||110,55,32,215,215,236|N|9,6,4,,,21||62|37]Tentacruel|||None|highjumpkick,peck,sing,waterfall||105,74,75,218,218,58|N|0,20,4,25,25,25||68|183]Omanyte|||None|lightscreen,sonicboom,triattack,cut||248,103,38,230,230,156|N|0,25,5,28,28,5||93|169"}
3 | >player p2 {"name":"Bot 2","team":"Nidoking|||None|disable,growth,rockthrow,karatechop||233,132,50,189,189,17|N|15,2,11,2,2,7||98|26]Vaporeon|||None|teleport,bubble,furyswipes,conversion||124,29,97,224,224,56|N|3,13,13,7,7,14||91|37]Magmar|||None|swordsdance,fireblast,bonemerang,thrash||138,111,222,200,200,113|N|3,20,24,10,10,6||60|171]Slowpoke|||None|dragonrage,razorleaf,thunder,supersonic||59,52,42,249,249,36|N|8,30,29,24,24,8||58|126]Raticate|||None|quickattack,boneclub,constrict,slam||207,87,143,104,104,237|N|3,0,4,23,23,3||65|89]Nidorino|||None|slash,barrier,psywave,confuseray||59,83,117,30,30,228|N|10,26,24,28,28,11||96|39"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 move vinewhip
7 | >p2 move teleport
8 | >p1 move strength
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p2 move disable
12 | >p1 switch 3
13 | >p2 move growth
14 | >p1 move spikecannon
15 | >p2 move rockthrow
16 | >p1 switch 4
17 | >p2 switch 3
18 | >p1 switch 5
19 | >p2 move swordsdance
20 | >p1 switch 6
21 | >p2 switch 4
22 | >p1 switch 4
23 | >p2 move dragonrage
24 | >p1 move amnesia
25 | >p2 move razorleaf
26 | >p1 switch 6
27 | >p2 move thunder
28 | >p1 move highjumpkick
29 | >p2 move supersonic
30 | >p1 move peck
31 | >p2 move razorleaf
32 | >p1 move sing
33 | >p2 move dragonrage
34 | >p1 move waterfall
35 | >p2 move supersonic
36 | >p1 move peck
37 | >p2 move supersonic
38 | >p1 move highjumpkick
39 | >p2 move razorleaf
40 | >p2 switch 5
41 | >p1 move waterfall
42 | >p2 move quickattack
43 | >p1 move peck
44 | >p2 move boneclub
45 | >p1 switch 6
46 | >p1 move smokescreen
47 | >p2 move constrict
48 | >p1 move watergun
49 | >p2 move slam
50 | >p2 switch 6
51 | >p1 switch 2
52 | >p2 move slash
53 | >p1 move rage
54 | >p2 move barrier
55 | >p1 move rage
56 | >p2 move psywave
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xBC867937B5A262F8.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[48262,31031,46498,25336]}
2 | >player p1 {"name":"Bot 1","team":"Kakuna|||None|firepunch,bubble,sludge,thrash||122,225,222,2,2,178|N|3,4,9,3,3,||57|189]Bellsprout|||None|leechseed,rest,megapunch,focusenergy||74,219,77,78,78,160|N|13,10,15,30,30,8||73|111]Paras|||None|leer,stunspore,dig,petaldance||97,40,79,159,159,112|N|2,16,21,0,0,10||73|247]Magikarp|||None|screech,leechlife,spikecannon,acid||164,31,15,198,198,124|N|3,21,12,22,22,22||88|136]Psyduck|||None|fireblast,blizzard,watergun,psybeam||25,47,190,236,236,143|N|11,10,0,27,27,||68|60]Dodrio|||None|bodyslam,triattack,rest,megapunch||116,156,172,182,182,106|N|2,1,1,24,24,10||79|240"}
3 | >player p2 {"name":"Bot 2","team":"Victreebel|||None|thunder,mist,confusion,eggbomb||76,99,206,4,4,24|N|0,9,13,16,16,17||53|152]Nidoking|||None|sonicboom,aurorabeam,softboiled,flamethrower||120,119,63,203,203,112|N|14,,6,25,25,30||89|55]Farfetch’d|||None|earthquake,dreameater,quickattack,furyswipes||192,212,156,103,103,215|N|1,8,20,27,27,13||54|130]Chansey|||None|barrage,sleeppowder,lowkick,selfdestruct||70,88,153,90,90,86|N|14,6,30,21,21,7||90|84]Kangaskhan|||None|doubleteam,leechseed,growl,doubleslap||24,34,99,68,68,231|N|12,23,10,20,20,1||54|216]Dragonite|||None|cometpunch,seismictoss,bubblebeam,razorwind||205,27,206,168,168,103|N|6,12,3,8,8,23||79|44"}
4 | >p1 switch 2
5 | >p2 move mist
6 | >p1 move leechseed
7 | >p2 move eggbomb
8 | >p1 move rest
9 | >p2 move eggbomb
10 | >p1 move megapunch
11 | >p2 move thunder
12 | >p1 move megapunch
13 | >p2 move thunder
14 | >p1 switch 2
15 | >p2 switch 2
16 | >p1 move firepunch
17 | >p2 move softboiled
18 | >p1 move bubble
19 | >p2 switch 2
20 | >p1 move sludge
21 | >p2 switch 3
22 | >p1 move thrash
23 | >p2 switch 4
24 | >p1 move thrash
25 | >p2 move lowkick
26 | >p1 move thrash
27 | >p2 move selfdestruct
28 | >p2 switch 5
29 | >p1 move thrash
30 | >p2 move leechseed
31 | >p1 move bubble
32 | >p2 move growl
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xBCC4F5F803A4C0C5.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[48324,62968,932,49349]}
2 | >player p1 {"name":"Bot 1","team":"Parasect|||None|reflect,confusion,bide,supersonic||215,90,165,76,76,15|N|6,21,7,9,9,10||53|225]Jolteon|||None|wrap,tailwhip,thunderpunch,hornattack||217,32,44,49,49,183|N|4,21,18,0,0,17||60|127]Koffing|||None|teleport,defensecurl,splash,stunspore||34,171,67,106,106,53|N|6,0,3,9,9,2||82|113]Machamp|||None|constrict,dizzypunch,lightscreen,dreameater||143,165,206,159,159,10|N|9,11,20,11,11,28||99|204]Pidgeot|||None|psywave,hypnosis,conversion,acidarmor||9,197,215,39,39,103|N|8,23,29,20,20,24||58|55]Raticate|||None|firespin,explosion,lick,flamethrower||121,131,57,2,2,45|N|3,13,21,18,18,23||65|146"}
3 | >player p2 {"name":"Bot 2","team":"Bellsprout|||None|mimic,surf,lovelykiss,solarbeam||112,34,78,250,250,199|N|11,3,1,11,11,30||88|190]Pidgeotto|||None|rage,metronome,ember,doubleteam||102,125,76,198,198,30|N|9,26,24,6,6,28||53|113]Electabuzz|||None|confuseray,bodyslam,poisongas,icebeam||60,33,200,5,5,200|N|11,15,9,10,10,23||96|215]Hitmonlee|||None|twineedle,swordsdance,rest,sludge||78,13,99,165,165,78|N|5,5,15,26,26,0||86|136]Blastoise|||None|screech,rockslide,dig,scratch||18,148,40,11,11,20|N|13,14,,6,6,25||83|249]Arbok|||None|doubleedge,sonicboom,leer,rockslide||234,10,137,191,191,35|N|13,2,3,7,7,24||74|22"}
4 | >p1 move reflect
5 | >p2 switch 2
6 | >p1 move confusion
7 | >p2 move rage
8 | >p1 switch 2
9 | >p2 move rage
10 | >p1 move wrap
11 | >p2 move rage
12 | >p1 move wrap
13 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xC1F3A1A3CBF66E2B.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[49651,41379,52214,28203]}
2 | >player p1 {"name":"Bot 1","team":"Pidgeotto|||None|bite,tailwhip,reflect,icebeam||86,160,146,128,128,68|N|10,22,24,9,9,19||93|56]Clefairy|||None|firepunch,doublekick,psybeam,amnesia||14,57,218,148,148,82|N|8,26,20,24,24,12||86|251]Beedrill|||None|whirlwind,furyswipes,megapunch,razorleaf||206,234,25,51,51,2|N|3,25,24,22,22,10||78|73]Vileplume|||None|conversion,doubleslap,barrier,rest||126,115,202,100,100,70|N|7,13,23,18,18,23||84|181]Cubone|||None|megakick,leechlife,rage,stomp||201,26,189,242,242,34|N|0,5,8,13,13,21||52|149]Raichu|||None|hornattack,earthquake,swift,splash||151,171,54,59,59,13|N|11,26,8,26,26,14||96|246"}
3 | >player p2 {"name":"Bot 2","team":"Weezing|||None|seismictoss,solarbeam,kinesis,ember||173,215,163,196,196,112|N|0,20,0,13,13,8||66|13]Charmander|||None|swordsdance,recover,peck,thundershock||189,206,197,246,246,115|N|0,21,9,25,25,0||84|5]Drowzee|||None|vinewhip,doubleteam,bonemerang,focusenergy||112,184,81,65,65,113|N|10,15,16,13,13,3||82|165]Kadabra|||None|poisonsting,screech,bide,icepunch||229,63,16,175,175,2|N|1,25,17,6,6,29||87|155]Machop|||None|fly,selfdestruct,blizzard,pound||195,,127,56,56,152|N|3,20,4,,,3||58|225]Slowpoke|||None|skullbash,acidarmor,dig,disable||32,31,3,124,124,86|N|7,28,14,27,27,23||69|18"}
4 | >p1 move bite
5 | >p2 move seismictoss
6 | >p1 move tailwhip
7 | >p2 move solarbeam
8 | >p1 move reflect
9 | >p2 move solarbeam
10 | >p1 move icebeam
11 | >p2 move kinesis
12 | >p2 switch 4
13 | >p1 switch 2
14 | >p2 move poisonsting
15 | >p1 move firepunch
16 | >p2 move screech
17 | >p1 move doublekick
18 | >p2 move bide
19 | >p1 move psybeam
20 | >p2 move bide
21 | >p1 move amnesia
22 | >p2 move bide
23 | >p1 move psybeam
24 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xC40D2C12D0F8185D.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[50189,11282,53496,6237]}
2 | >player p1 {"name":"Bot 1","team":"Kangaskhan|||None|surf,fireblast,guillotine,absorb||159,149,170,95,95,55|N|8,7,5,21,21,9||82|42]Alakazam|||None|substitute,teleport,mist,megapunch||66,129,38,128,128,202|N|12,30,2,29,29,17||85|139]Koffing|||None|softboiled,stringshot,splash,spikecannon||181,160,218,184,184,68|N|1,24,13,11,11,5||93|68]Drowzee|||None|doubleedge,crabhammer,submission,dragonrage||219,159,58,104,104,53|N|12,,15,8,8,4||90|28]Poliwhirl|||None|dig,bodyslam,psybeam,swordsdance||212,93,239,67,67,157|N|0,16,8,24,24,0||89|108]Exeggcute|||None|karatechop,doublekick,bubble,sandattack||43,152,124,147,147,143|N|6,8,6,8,8,7||66|209"}
3 | >player p2 {"name":"Bot 2","team":"Venusaur|||None|megadrain,screech,payday,earthquake||169,219,250,222,222,90|N|8,14,1,16,16,28||96|173]Raichu|||None|takedown,thrash,seismictoss,razorwind||193,80,107,91,91,80|N|13,19,10,3,3,17||70|229]Squirtle|||None|whirlwind,scratch,flamethrower,withdraw||80,76,123,132,132,31|N|12,,30,12,12,16||57|37]Charmeleon|||None|megakick,gust,fissure,sharpen||78,136,222,91,91,4|N|7,9,27,11,11,14||91|35]Pidgeotto|||None|leechseed,skyattack,psychic,defensecurl||20,35,100,197,197,135|N|12,2,10,13,13,12||55|236]Machamp|||None|constrict,focusenergy,icepunch,glare||74,67,221,170,170,213|N|0,9,4,17,17,21||64|162"}
4 | >p1 move surf
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 move takedown
8 | >p1 move substitute
9 | >p2 switch 2
10 | >p1 move teleport
11 | >p2 move megadrain
12 | >p1 move mist
13 | >p2 move screech
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xC468FF6E1CEE314D.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xC468FF6E1CEE314D.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xC8524A847B4AF353.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[51282,19076,31562,62291]}
2 | >player p1 {"name":"Bot 1","team":"Rhydon|||None|smokescreen,firepunch,boneclub,doublekick||110,186,29,86,86,51|N|5,16,30,,,5||99|80]Fearow|||None|sleeppowder,tackle,thunderbolt,bide||46,90,200,175,175,180|N|1,12,21,30,30,20||90|93]Omanyte|||None|surf,cometpunch,selfdestruct,submission||50,172,207,36,36,225|N|1,29,1,2,2,17||78|46]Zapdos|||None|absorb,twineedle,recover,drillpeck||197,17,22,196,196,245|N|8,26,16,20,20,16||87|228]Magnemite|||None|thunderpunch,reflect,dizzypunch,wingattack||54,93,52,203,203,143|N|15,,2,7,7,27||55|63]Cubone|||None|guillotine,quickattack,slash,barrier||64,57,176,36,36,39|N|15,7,,30,30,15||81|60"}
3 | >player p2 {"name":"Bot 2","team":"Arcanine|||None|focusenergy,acid,lick,slam||107,23,159,250,250,214|N|0,8,25,24,24,8||91|89]Koffing|||None|sharpen,fissure,bonemerang,furyattack||194,122,39,137,137,164|N|8,,9,17,17,0||95|243]Magikarp|||None|aurorabeam,triattack,sludge,visegrip||126,86,122,170,170,135|N|0,16,21,29,29,8||84|108]Raticate|||None|pound,substitute,fireblast,kinesis||33,84,158,251,251,129|N|2,5,24,0,0,19||60|14]Weedle|||None|confusion,gust,roar,thrash||91,26,24,72,72,150|N|15,30,,,,||62|49]Tentacool|||None|swift,megadrain,cut,flamethrower||98,30,5,51,51,126|N|1,0,29,18,18,25||72|62"}
4 | >p1 move smokescreen
5 | >p2 move focusenergy
6 | >p1 move firepunch
7 | >p2 switch 2
8 | >p1 move boneclub
9 | >p2 move sharpen
10 | >p2 switch 2
11 | >p1 move doublekick
12 | >p2 move acid
13 | >p1 move firepunch
14 | >p2 move lick
15 | >p1 switch 2
16 | >p2 switch 3
17 | >p1 move sleeppowder
18 | >p2 move aurorabeam
19 | >p1 move tackle
20 | >p2 move triattack
21 | >p1 move thunderbolt
22 | >p2 move sludge
23 | >p2 switch 4
24 | >p1 move bide
25 | >p2 move pound
26 | >p1 move bide
27 | >p2 switch 5
28 | >p1 move bide
29 | >p2 move confusion
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xCA20018840CC123.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xCA20018840CC123.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xCC64741157FC11DB.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xCC64741157FC11DB.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xCDE87ADE2DEA69C.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[3294,34733,58078,42652]}
2 | >player p1 {"name":"Bot 1","team":"Ninetales|||None|growl,gust,conversion,nightshade||9,192,160,180,180,190|N|5,16,3,27,27,16||83|54]Pikachu|||None|megadrain,bide,rage,spikecannon||231,193,54,182,182,45|N|2,16,16,24,24,19||82|138]Slowpoke|||None|selfdestruct,thunderwave,thundershock,bind||227,108,140,46,46,53|N|10,23,8,0,0,14||70|0]Diglett|||None|barrier,bodyslam,recover,thunder||135,8,188,218,218,126|N|6,1,6,13,13,22||55|194]Dodrio|||None|whirlwind,kinesis,hyperfang,megakick||178,188,74,34,34,110|N|11,30,24,27,27,6||83|217]Kabuto|||None|pound,glare,superfang,poisonpowder||105,86,58,127,127,245|N|13,,22,26,26,24||81|26"}
3 | >player p2 {"name":"Bot 2","team":"Lapras|||None|roar,poisonsting,triattack,rockslide||91,187,177,157,157,187|N|12,15,19,0,0,8||91|59]Hitmonlee|||None|teleport,furyattack,payday,sludge||30,178,51,206,206,168|N|9,7,12,14,14,9||94|236]Kakuna|||None|softboiled,icepunch,withdraw,acid||165,42,149,124,124,232|N|15,19,2,15,15,23||65|254]Metapod|||None|ember,substitute,meditate,sleeppowder||53,210,33,213,213,15|N|11,19,29,30,30,7||81|237]Mew|||None|lightscreen,solarbeam,rockthrow,doublekick||54,201,48,163,163,4|N|8,22,17,28,28,12||72|20]Koffing|||None|leechseed,wrap,counter,splash||54,116,4,54,54,82|N|1,28,20,22,22,4||65|180"}
4 | >p1 move growl
5 | >p2 switch 2
6 | >p1 move gust
7 | >p2 move teleport
8 | >p1 move conversion
9 | >p2 move furyattack
10 | >p1 move nightshade
11 | >p2 move payday
12 | >p1 switch 2
13 | >p2 switch 2
14 | >p1 move megadrain
15 | >p2 switch 3
16 | >p1 move bide
17 | >p2 switch 4
18 | >p1 switch 2
19 | >p2 move ember
20 | >p1 switch 3
21 | >p2 move substitute
22 | >p1 move selfdestruct
23 | >p2 move meditate
24 | >p1 switch 4
25 | >p2 move sleeppowder
26 | >p1 switch 5
27 | >p2 switch 5
28 | >p1 move whirlwind
29 | >p2 move lightscreen
30 | >p1 switch 6
31 | >p2 move solarbeam
32 | >p1 switch 5
33 | >p2 move solarbeam
34 | >p1 switch 3
35 | >p1 switch 4
36 | >p2 move rockthrow
37 | >p1 move thunderwave
38 | >p2 move doublekick
39 | >p1 switch 4
40 | >p2 move rockthrow
41 | >p1 switch 5
42 | >p2 move solarbeam
43 | >p1 move pound
44 | >p2 move solarbeam
45 | >p1 move glare
46 | >p2 move solarbeam
47 | >p1 move superfang
48 | >p2 move rockthrow
49 | >p1 move poisonpowder
50 | >p2 move solarbeam
51 | >p1 move superfang
52 | >p2 move solarbeam
53 | >p1 switch 5
54 | >p2 switch 6
55 | >p1 move gust
56 | >p2 move leechseed
57 | >p1 move conversion
58 | >p2 move wrap
59 | >p1 move growl
60 | >p2 move wrap
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xCE3086F839722570.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[52784,34552,14706,9584]}
2 | >player p1 {"name":"Bot 1","team":"Mewtwo|||None|furyswipes,stomp,cometpunch,blizzard||43,151,139,35,35,116|N|12,6,30,1,1,21||55|219]Charizard|||None|doubleslap,sandattack,razorwind,fissure||85,192,123,26,26,238|N|0,29,25,12,12,29||62|180]Sandslash|||None|cometpunch,megadrain,conversion,lightscreen||70,63,242,186,186,29|N|4,9,23,8,8,17||54|230]Omanyte|||None|focusenergy,haze,absorb,bubblebeam||58,9,135,114,114,152|N|0,16,12,4,4,20||53|138]Articuno|||None|splash,fly,firepunch,stunspore||62,25,230,175,175,237|N|5,1,7,27,27,21||99|167]Eevee|||None|fireblast,swift,hypnosis,rockslide||37,188,151,192,192,207|N|3,29,20,2,2,7||50|223"}
3 | >player p2 {"name":"Bot 2","team":"Bellsprout|||None|bubble,hydropump,drillpeck,ember||225,252,25,35,35,60|N|12,7,2,12,12,16||72|251]Machoke|||None|swordsdance,softboiled,lowkick,leechseed||87,234,205,193,193,185|N|10,,24,13,13,19||61|12]Snorlax|||None|triattack,selfdestruct,icepunch,pound||41,244,185,69,69,146|N|11,11,4,6,6,11||79|9]Tentacool|||None|rockthrow,furyswipes,acid,confusion||44,202,23,9,9,179|N|8,2,24,9,9,4||72|113]Dugtrio|||None|hyperfang,leer,twineedle,toxic||84,91,199,100,100,15|N|7,13,22,18,18,2||95|233]Spearow|||None|jumpkick,hyperbeam,sonicboom,barrage||103,91,52,128,128,74|N|14,14,2,13,13,27||93|165"}
4 | >p1 move furyswipes
5 | >p2 move ember
6 | >p1 move stomp
7 | >p2 switch 2
8 | >p1 move cometpunch
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p2 switch 3
12 | >p1 switch 2
13 | >p2 move selfdestruct
14 | >p1 switch 3
15 | >p2 switch 4
16 | >p1 move conversion
17 | >p2 move rockthrow
18 | >p1 move cometpunch
19 | >p2 move acid
20 | >p1 move cometpunch
21 | >p2 switch 5
22 | >p1 move lightscreen
23 | >p2 move twineedle
24 | >p1 switch 4
25 | >p1 move focusenergy
26 | >p2 move hyperfang
27 | >p1 move absorb
28 | >p2 switch 6
29 | >p1 switch 5
30 | >p2 move sonicboom
31 | >p1 switch 6
32 | >p2 move jumpkick
33 | >p1 switch 6
34 | >p1 move fly
35 | >p2 move sonicboom
36 | >p1 move fly
37 | >p2 move hyperbeam
38 | >p2 switch 6
39 | >p1 move splash
40 | >p2 move toxic
41 | >p1 switch 2
42 | >p2 move twineedle
43 | >p1 move fissure
44 | >p2 move hyperfang
45 | >p1 switch 2
46 | >p2 switch 2
47 | >p1 switch 5
48 | >p2 switch 2
49 | >p1 switch 5
50 | >p2 move hyperfang
51 | >p1 move fly
52 | >p2 move leer
53 | >p1 move fly
54 | >p2 move toxic
55 | >p1 move firepunch
56 | >p2 switch 5
57 | >p1 switch 5
58 | >p2 switch 5
59 | >p1 move focusenergy
60 | >p2 move toxic
61 | >p1 move haze
62 | >p2 switch 5
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xCE87A7774C1AAB24.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[52871,42871,19482,43812]}
2 | >player p1 {"name":"Bot 1","team":"Poliwhirl|||None|disable,nightshade,thunderpunch,waterfall||3,43,70,20,20,243|N|5,17,3,3,3,13||75|118]Bulbasaur|||None|poisonsting,hyperbeam,rest,tackle||18,153,166,250,250,58|N|11,2,12,19,19,15||55|26]Chansey|||None|screech,doubleslap,earthquake,rockslide||128,215,120,83,83,|N|11,26,5,27,27,15||80|222]Wartortle|||None|quickattack,thrash,smokescreen,explosion||81,97,244,241,241,21|N|11,11,16,6,6,26||81|222]Mankey|||None|aurorabeam,pound,supersonic,sing||244,35,66,117,117,27|N|6,1,14,4,4,2||74|210]Electrode|||None|guillotine,whirlwind,vinewhip,leechlife||204,86,130,5,5,108|N|9,22,21,15,15,8||71|134"}
3 | >player p2 {"name":"Bot 2","team":"Ekans|||None|defensecurl,doublekick,glare,hypnosis||155,9,111,8,8,166|N|8,6,13,21,21,17||52|179]Oddish|||None|petaldance,smog,flamethrower,dig||13,171,213,167,167,197|N|3,13,13,2,2,2||55|156]Magnemite|||None|swift,psybeam,thunderwave,swordsdance||153,101,206,48,48,164|N|4,1,3,16,16,0||61|167]Pinsir|||None|bide,rollingkick,surf,payday||246,1,238,61,61,54|N|9,7,5,19,19,1||97|75]Magikarp|||None|dizzypunch,haze,sleeppowder,eggbomb||132,164,180,14,14,69|N|9,18,8,14,14,29||97|128]Haunter|||None|recover,reflect,icebeam,teleport||230,158,229,69,69,100|N|0,17,5,9,9,13||85|156"}
4 | >p1 switch 2
5 | >p2 move defensecurl
6 | >p1 move poisonsting
7 | >p2 switch 2
8 | >p1 move hyperbeam
9 | >p2 move petaldance
10 | >p1 move recharge
11 | >p2 move petaldance
12 | >p1 move rest
13 | >p2 move petaldance
14 | >p1 move tackle
15 | >p2 move smog
16 | >p1 switch 2
17 | >p2 switch 2
18 | >p1 move disable
19 | >p2 switch 3
20 | >p1 move nightshade
21 | >p2 switch 4
22 | >p1 move thunderpunch
23 | >p2 switch 6
24 | >p1 switch 3
25 | >p2 move recover
26 | >p1 switch 4
27 | >p2 switch 6
28 | >p1 move quickattack
29 | >p2 move bide
30 | >p1 move thrash
31 | >p2 move bide
32 | >p1 move thrash
33 | >p2 move bide
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xCF83C12D71CE716D.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xCF83C12D71CE716D.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xD2B1817739AAF4B3.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[53937,33143,14762,62643]}
2 | >player p1 {"name":"Bot 1","team":"Mew|||None|softboiled,acidarmor,doubleslap,swordsdance||25,152,181,248,248,86|N|12,19,2,28,28,12||64|182]Nidorina|||None|headbutt,roar,blizzard,tackle||42,251,54,217,217,39|N|4,20,,20,20,24||75|205]Mankey|||None|splash,boneclub,icepunch,furyattack||108,34,158,226,226,33|N|4,8,3,25,25,9||88|249]Vileplume|||None|toxic,gust,poisonpowder,haze||192,68,170,199,199,144|N|8,22,25,8,8,5||72|153]Eevee|||None|thunderpunch,sleeppowder,rollingkick,jumpkick||163,197,21,137,137,210|N|4,25,11,12,12,29||99|184]Primeape|||None|ember,rest,razorleaf,pinmissile||171,52,24,188,188,45|N|9,10,16,7,7,24||69|53"}
3 | >player p2 {"name":"Bot 2","team":"Kakuna|||None|psybeam,eggbomb,supersonic,swordsdance||165,104,76,247,247,151|N|7,8,23,10,10,18||81|61]Dratini|||None|focusenergy,skyattack,minimize,lowkick||71,67,164,131,131,224|N|6,25,14,1,1,22||73|86]Exeggcute|||None|doubleteam,growth,barrier,meditate||206,112,241,15,15,204|N|12,,18,1,1,25||77|81]Clefairy|||None|bubblebeam,flash,tailwhip,thunderbolt||142,145,21,220,220,8|N|0,20,21,28,28,0||81|146]Abra|||None|sleeppowder,hydropump,sludge,constrict||230,231,222,166,166,116|N|6,8,6,0,0,7||60|123]Poliwhirl|||None|harden,bite,lightscreen,psywave||249,198,48,251,251,14|N|6,16,27,16,16,19||89|57"}
4 | >p1 move softboiled
5 | >p2 switch 2
6 | >p1 move acidarmor
7 | >p2 switch 2
8 | >p1 switch 2
9 | >p2 move swordsdance
10 | >p1 switch 2
11 | >p2 switch 3
12 | >p1 switch 3
13 | >p2 switch 4
14 | >p1 move splash
15 | >p2 move bubblebeam
16 | >p1 move boneclub
17 | >p2 move flash
18 | >p1 move icepunch
19 | >p2 switch 5
20 | >p1 move furyattack
21 | >p2 move sleeppowder
22 | >p1 move furyattack
23 | >p2 switch 6
24 | >p1 move icepunch
25 | >p2 move lightscreen
26 | >p1 move furyattack
27 | >p2 move lightscreen
28 | >p1 move furyattack
29 | >p2 move psywave
30 | >p1 move boneclub
31 | >p2 move psywave
32 | >p1 switch 4
33 | >p2 move lightscreen
34 | >p1 move toxic
35 | >p2 move bite
36 | >p1 move gust
37 | >p2 move lightscreen
38 | >p1 move poisonpowder
39 | >p2 move bite
40 | >p1 move haze
41 | >p2 move psywave
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xD463BA4C49D333F3.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[54371,47692,18899,13299]}
2 | >player p1 {"name":"Bot 1","team":"Flareon|||None|skullbash,strength,pinmissile,visegrip||147,171,179,73,73,2|N|12,3,27,29,29,17||99|217]Golduck|||None|nightshade,sonicboom,thunderwave,quickattack||235,8,176,12,12,45|N|3,29,8,10,10,27||86|113]Dratini|||None|jumpkick,substitute,twineedle,softboiled||204,175,172,123,123,34|N|8,3,12,0,0,29||99|120]Clefairy|||None|swordsdance,fireblast,triattack,thunderpunch||30,229,206,15,15,230|N|14,10,2,5,5,11||59|204]Sandshrew|||None|substitute,amnesia,bide,earthquake||189,80,156,132,132,193|N|12,26,23,9,9,25||74|10]Tauros|||None|megapunch,guillotine,spore,furyswipes||195,135,126,63,63,228|N|9,11,5,6,6,17||90|253"}
3 | >player p2 {"name":"Bot 2","team":"Tangela|||None|wrap,ember,vinewhip,razorwind||106,62,90,100,100,177|N|9,23,25,19,19,12||76|39]Slowpoke|||None|fly,doubleslap,flash,psychic||231,226,118,108,108,90|N|13,3,7,3,3,21||82|188]Jynx|||None|blizzard,bubble,hyperfang,teleport||110,85,79,9,9,228|N|11,30,28,,,26||74|199]Lickitung|||None|softboiled,stringshot,scratch,skyattack||170,21,57,231,231,111|N|0,4,17,20,20,13||60|50]Venonat|||None|tailwhip,recover,eggbomb,surf||10,124,78,177,177,250|N|14,23,26,13,13,14||55|71]Gastly|||None|horndrill,pound,haze,swift||130,189,77,237,237,140|N|4,28,6,12,12,1||99|87"}
4 | >p1 switch 2
5 | >p2 move razorwind
6 | >p1 move nightshade
7 | >p2 move razorwind
8 | >p1 move sonicboom
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p2 move psychic
12 | >p1 move skullbash
13 | >p2 switch 2
14 | >p1 move skullbash
15 | >p2 switch 3
16 | >p2 switch 4
17 | >p1 move strength
18 | >p2 move softboiled
19 | >p1 move pinmissile
20 | >p2 move stringshot
21 | >p2 switch 5
22 | >p1 move visegrip
23 | >p2 move eggbomb
24 | >p2 switch 6
25 | >p1 switch 3
26 | >p2 move swift
27 | >p1 switch 4
28 | >p2 move pound
29 | >p1 switch 5
30 | >p2 move swift
31 | >p1 switch 6
32 | >p2 move swift
33 | >p1 switch 6
34 | >p2 move swift
35 | >p1 move substitute
36 | >p2 move swift
37 | >p1 move substitute
38 | >p2 move swift
39 | >p1 move bide
40 | >p2 move haze
41 | >p1 move bide
42 | >p2 move horndrill
43 | >p1 move bide
44 | >p2 move haze
45 | >p1 move bide
46 | >p2 move pound
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xDAF1C0765173FF0F.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[56049,49270,20851,65295]}
2 | >player p1 {"name":"Bot 1","team":"Persian|||None|defensecurl,guillotine,strength,selfdestruct||85,233,240,216,216,169|N|14,23,27,21,21,11||74|132]Dewgong|||None|crabhammer,nightshade,reflect,rest||106,70,142,239,239,232|N|8,3,25,28,28,1||73|33]Paras|||None|sing,smokescreen,hydropump,pinmissile||213,183,225,42,42,152|N|9,26,8,11,11,0||81|120]Zapdos|||None|surf,psychic,furyattack,swift||156,4,69,61,61,119|N|1,25,24,15,15,12||68|124]Squirtle|||None|thundershock,horndrill,megapunch,fly||205,241,74,215,215,152|N|12,7,30,5,5,4||80|41]Vileplume|||None|teleport,rollingkick,confuseray,submission||16,189,43,127,127,44|N|6,4,7,20,20,7||55|170"}
3 | >player p2 {"name":"Bot 2","team":"Jolteon|||None|skullbash,flamethrower,waterfall,amnesia||128,12,249,169,169,14|N|13,,23,18,18,16||71|249]Dodrio|||None|rockslide,scratch,stringshot,blizzard||236,139,95,25,25,4|N|9,22,9,19,19,1||51|98]Mewtwo|||None|solarbeam,withdraw,thunderwave,barrage||126,19,195,42,42,157|N|6,20,10,28,28,10||81|168]Pidgeotto|||None|cometpunch,thrash,firepunch,seismictoss||33,11,147,31,31,170|N|15,6,7,19,19,2||80|88]Drowzee|||None|thunderbolt,psybeam,lick,bubblebeam||127,235,93,7,7,231|N|2,8,16,1,1,10||60|233]Slowbro|||None|furyswipes,confusion,karatechop,peck||151,230,204,98,98,23|N|12,27,,8,8,24||80|20"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 move crabhammer
7 | >p2 switch 2
8 | >p1 move nightshade
9 | >p2 move skullbash
10 | >p2 switch 3
11 | >p1 switch 2
12 | >p2 move solarbeam
13 | >p1 switch 3
14 | >p2 move solarbeam
15 | >p1 switch 4
16 | >p2 move withdraw
17 | >p1 switch 5
18 | >p2 switch 4
19 | >p1 move thundershock
20 | >p2 move cometpunch
21 | >p1 switch 6
22 | >p2 move thrash
23 | >p1 switch 4
24 | >p2 move thrash
25 | >p1 move sing
26 | >p2 move thrash
27 | >p1 move smokescreen
28 | >p2 move thrash
29 | >p1 move hydropump
30 | >p2 move thrash
31 | >p1 move pinmissile
32 | >p2 move thrash
33 | >p1 switch 2
34 | >p2 move thrash
35 | >p1 move reflect
36 | >p2 move thrash
37 | >p1 move rest
38 | >p2 move thrash
39 | >p1 move reflect
40 | >p2 move firepunch
41 | >p1 move crabhammer
42 | >p2 move seismictoss
43 | >p2 switch 5
44 | >p1 move rest
45 | >p2 move thunderbolt
46 | >p1 switch 4
47 | >p2 move psybeam
48 | >p1 switch 4
49 | >p1 move rest
50 | >p2 switch 6
51 | >p1 switch 5
52 | >p2 move furyswipes
53 | >p1 move surf
54 | >p2 move confusion
55 | >p1 move psychic
56 | >p2 switch 4
57 | >p1 move furyattack
58 | >p2 move thunderwave
59 | >p1 switch 2
60 | >p2 move barrage
61 | >p1 move pinmissile
62 | >p2 move thunderwave
63 | >p1 move smokescreen
64 | >p2 move thunderwave
65 | >p1 move hydropump
66 | >p2 move barrage
67 | >p1 move hydropump
68 | >p2 move thunderwave
69 | >p1 move pinmissile
70 | >p2 switch 4
71 | >p1 switch 3
72 | >p2 switch 2
73 | >p1 move defensecurl
74 | >p2 move rockslide
75 | >p1 move guillotine
76 | >p2 switch 2
77 | >p2 switch 2
78 | >p1 switch 3
79 | >p2 move scratch
80 | >p1 switch 6
81 | >p1 move horndrill
82 | >p2 move stringshot
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xE1C1F3089C963B91.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[57793,62216,40086,15249]}
2 | >player p1 {"name":"Bot 1","team":"Ditto|||None|submission,fly,sharpen,solarbeam||49,16,44,9,9,41|N|11,30,13,23,23,2||84|156]Poliwhirl|||None|supersonic,leechlife,eggbomb,doubleedge||25,122,3,130,130,184|N|0,1,12,4,4,28||96|157]Nidoran-F|||None|sonicboom,thunderbolt,psywave,scratch||224,150,23,173,173,131|N|3,20,0,26,26,11||60|45]Tentacool|||None|swordsdance,jumpkick,karatechop,clamp||62,200,41,181,181,191|N|1,24,24,22,22,21||86|27]Moltres|||None|bubble,earthquake,surf,horndrill||77,72,90,16,16,24|N|1,25,24,6,6,9||78|126]Meowth|||None|absorb,rockslide,wrap,stomp||111,208,163,134,134,237|N|11,15,5,22,22,26||82|156"}
3 | >player p2 {"name":"Bot 2","team":"Dugtrio|||None|highjumpkick,roar,confusion,aurorabeam||206,55,250,220,220,41|N|7,29,,11,11,18||79|23]Electabuzz|||None|defensecurl,bodyslam,cometpunch,hypnosis||156,242,206,198,198,210|N|6,20,26,17,17,3||83|19]Lickitung|||None|thunder,sleeppowder,bide,razorwind||96,193,173,227,227,78|N|12,3,18,21,21,28||52|11]Raticate|||None|reflect,doublekick,slam,haze||217,98,66,209,209,200|N|9,26,28,14,14,20||88|200]Porygon|||None|rage,skyattack,pinmissile,hyperbeam||237,50,91,192,192,147|N|8,7,5,16,16,8||70|70]Electrode|||None|icepunch,teleport,splash,peck||4,193,84,39,39,159|N|2,1,16,5,5,23||97|91"}
4 | >p1 move submission
5 | >p2 move highjumpkick
6 | >p1 switch 2
7 | >p2 switch 2
8 | >p1 switch 2
9 | >p2 move defensecurl
10 | >p1 switch 3
11 | >p2 move bodyslam
12 | >p1 move sonicboom
13 | >p2 move cometpunch
14 | >p1 switch 4
15 | >p1 switch 5
16 | >p2 move hypnosis
17 | >p1 move bubble
18 | >p2 move hypnosis
19 | >p1 move earthquake
20 | >p2 move bodyslam
21 | >p1 move surf
22 | >p2 switch 2
23 | >p2 switch 3
24 | >p1 move horndrill
25 | >p2 move thunder
26 | >p1 switch 6
27 | >p2 move sleeppowder
28 | >p1 move absorb
29 | >p2 switch 4
30 | >p1 move rockslide
31 | >p2 switch 5
32 | >p1 move wrap
33 | >p2 move rage
34 | >p1 move stomp
35 | >p2 move rage
36 | >p1 move absorb
37 | >p2 move rage
38 | >p1 move absorb
39 | >p2 move rage
40 | >p1 move absorb
41 | >p2 move rage
42 | >p1 switch 5
43 | >p2 move rage
44 | >p1 move swordsdance
45 | >p2 move rage
46 | >p1 move jumpkick
47 | >p2 move rage
48 | >p1 switch 5
49 | >p2 move rage
50 | >p1 switch 2
51 | >p2 move rage
52 | >p1 switch 2
53 | >p2 move rage
54 | >p1 move wrap
55 | >p2 move rage
56 | >p1 move wrap
57 | >p2 move rage
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xE26C9A0D11C52B93.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[57964,39437,4549,11155]}
2 | >player p1 {"name":"Bot 1","team":"Golem|||None|slash,thundershock,rest,eggbomb||195,138,96,184,184,162|N|8,19,16,13,13,5||61|211]Paras|||None|psywave,bodyslam,skyattack,leechlife||220,51,219,42,42,123|N|3,9,21,18,18,3||93|225]Blastoise|||None|metronome,recover,toxic,waterfall||34,86,27,177,177,154|N|5,17,6,3,3,29||52|180]Mew|||None|selfdestruct,stomp,lovelykiss,smog||177,3,20,221,221,99|N|0,25,9,4,4,21||87|190]Ekans|||None|pinmissile,submission,rage,peck||88,19,149,233,233,222|N|5,5,27,18,18,17||69|153]Machop|||None|absorb,jumpkick,doubleedge,bide||94,146,158,29,29,122|N|4,16,18,12,12,5||66|131"}
3 | >player p2 {"name":"Bot 2","team":"Psyduck|||None|hypnosis,megapunch,fissure,softboiled||18,156,126,35,35,155|N|3,13,5,26,26,23||90|167]Sandshrew|||None|clamp,fly,pound,slam||176,202,77,53,53,51|N|4,1,,8,8,28||64|53]Weepinbell|||None|whirlwind,poisonsting,kinesis,sludge||137,104,107,128,128,155|N|9,23,9,3,3,28||99|203]Flareon|||None|doubleslap,poisongas,hyperbeam,twineedle||183,172,110,9,9,4|N|5,1,,30,30,20||97|33]Kabutops|||None|spikecannon,wingattack,dreameater,crabhammer||28,52,218,124,124,77|N|13,23,,10,10,4||83|100]Venomoth|||None|mist,poisonpowder,boneclub,wrap||171,97,218,94,94,63|N|15,22,,18,18,18||77|53"}
4 | >p1 switch 2
5 | >p2 move hypnosis
6 | >p1 move psywave
7 | >p2 switch 2
8 | >p1 switch 2
9 | >p2 move clamp
10 | >p1 move slash
11 | >p2 move clamp
12 | >p1 move thundershock
13 | >p2 move fly
14 | >p1 move rest
15 | >p2 move fly
16 | >p1 move eggbomb
17 | >p2 move pound
18 | >p1 switch 3
19 | >p2 move slam
20 | >p1 move metronome
21 | >p2 move clamp
22 | >p1 move recharge
23 | >p2 move clamp
24 | >p1 move recharge
25 | >p2 switch 2
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xE2D929DD7D14C5F4.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xE2D929DD7D14C5F4.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xE47319978AD041B1.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[58483,6551,35536,16817]}
2 | >player p1 {"name":"Bot 1","team":"Bellsprout|||None|thundershock,guillotine,growth,megadrain||66,170,74,216,216,110|N|7,24,22,19,19,27||69|200]Kingler|||None|triattack,cometpunch,twineedle,rest||59,161,152,147,147,93|N|10,23,28,13,13,30||74|111]Magikarp|||None|barrier,pound,doubleedge,nightshade||227,226,236,36,36,189|N|12,6,23,8,8,5||68|186]Muk|||None|leechlife,razorwind,amnesia,toxic||5,146,249,39,39,50|N|0,4,20,8,8,25||98|151]Oddish|||None|payday,thunderpunch,crabhammer,bubblebeam||173,238,10,34,34,221|N|15,19,15,14,14,10||55|126]Tentacool|||None|doubleslap,defensecurl,strength,smog||196,33,111,203,203,150|N|9,26,20,15,15,24||88|88"}
3 | >player p2 {"name":"Bot 2","team":"Kabuto|||None|bubble,vinewhip,disable,dizzypunch||38,29,30,44,44,227|N|5,16,27,3,3,29||50|1]Farfetch’d|||None|thrash,visegrip,fireblast,stomp||201,126,164,230,230,75|N|8,26,12,12,12,25||68|65]Venomoth|||None|sludge,lovelykiss,headbutt,conversion||127,231,124,202,202,140|N|10,2,8,29,29,15||72|241]Psyduck|||None|glare,confuseray,thunder,sonicboom||80,112,242,187,187,39|N|9,6,17,27,27,28||57|145]Wigglytuff|||None|seismictoss,tailwhip,confusion,substitute||1,230,139,203,203,60|N|8,10,8,24,24,24||93|72]Rapidash|||None|psybeam,horndrill,sharpen,takedown||167,41,7,210,210,13|N|15,2,19,11,11,6||70|233"}
4 | >p1 switch 2
5 | >p2 move bubble
6 | >p1 switch 2
7 | >p2 switch 2
8 | >p1 move thundershock
9 | >p2 move thrash
10 | >p1 move guillotine
11 | >p2 move thrash
12 | >p1 switch 3
13 | >p1 move barrier
14 | >p2 move thrash
15 | >p1 move pound
16 | >p2 move thrash
17 | >p1 move doubleedge
18 | >p2 switch 2
19 | >p1 move nightshade
20 | >p2 move vinewhip
21 | >p1 move pound
22 | >p2 move disable
23 | >p1 move doubleedge
24 | >p2 move dizzypunch
25 | >p2 switch 3
26 | >p1 switch 4
27 | >p2 switch 4
28 | >p1 switch 5
29 | >p2 switch 5
30 | >p1 switch 6
31 | >p2 move seismictoss
32 | >p1 move doubleslap
33 | >p2 switch 6
34 | >p1 switch 6
35 | >p2 move psybeam
36 | >p1 move payday
37 | >p2 move horndrill
38 | >p1 move thunderpunch
39 | >p2 move sharpen
40 | >p1 switch 4
41 | >p2 move takedown
42 | >p1 switch 2
43 | >p1 move triattack
44 | >p2 move takedown
45 | >p1 move cometpunch
46 | >p2 move takedown
47 | >p1 move twineedle
48 | >p2 move sharpen
49 | >p2 switch 2
50 | >p1 switch 6
51 | >p2 move visegrip
52 | >p1 switch 6
53 | >p2 move fireblast
54 | >p1 switch 6
55 | >p2 move stomp
56 | >p1 switch 5
57 | >p1 move leechlife
58 | >p2 move stomp
59 | >p1 switch 6
60 | >p2 move thrash
61 | >p1 switch 6
62 | >p1 move razorwind
63 | >p2 move thrash
64 | >p1 move razorwind
65 | >p2 move thrash
66 | >p2 switch 6
67 | >p1 move amnesia
68 | >p2 move tailwhip
69 | >p1 move toxic
70 | >p2 move confusion
71 | >p1 move amnesia
72 | >p2 move substitute
73 | >p1 move toxic
74 | >p2 move substitute
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xE6412ECA6071C6D4.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xE6412ECA6071C6D4.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xE7E6B0F82286A08B.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[59366,45304,8838,41099]}
2 | >player p1 {"name":"Bot 1","team":"Sandshrew|||None|splash,superfang,disable,screech||161,247,221,222,222,126|N|0,5,16,21,21,4||91|170]Charmander|||None|tailwhip,watergun,scratch,minimize||211,113,64,95,95,174|N|10,27,28,17,17,23||57|210]Sandslash|||None|teleport,pinmissile,swift,rockslide||25,226,16,247,247,102|N|3,16,24,19,19,14||96|243]Magneton|||None|stomp,megakick,lovelykiss,lightscreen||197,24,189,111,111,147|N|14,10,18,20,20,3||55|195]Cubone|||None|sonicboom,nightshade,stringshot,dragonrage||123,91,229,18,18,140|N|2,20,13,12,12,23||72|95]Moltres|||None|confusion,bite,absorb,flash||66,173,84,108,108,187|N|12,18,14,21,21,12||97|192"}
3 | >player p2 {"name":"Bot 2","team":"Dragonite|||None|bubble,sludge,submission,mist||50,187,141,242,242,5|N|1,1,5,19,19,28||83|68]Nidoran-M|||None|jumpkick,wingattack,poisongas,ember||230,12,54,218,218,84|N|11,22,24,,,22||58|98]Jynx|||None|amnesia,cut,psybeam,strength||160,100,238,62,62,27|N|11,11,5,27,27,26||77|74]Caterpie|||None|skullbash,horndrill,thunderbolt,acid||61,63,80,2,2,13|N|9,30,13,23,23,8||50|130]Omastar|||None|growl,thunderwave,withdraw,seismictoss||76,159,174,107,107,176|N|15,19,15,23,23,23||58|75]Clefable|||None|hyperbeam,visegrip,doubleedge,leer||179,232,172,129,129,238|N|9,23,29,26,26,25||64|102"}
4 | >p1 move splash
5 | >p2 move bubble
6 | >p1 move superfang
7 | >p2 switch 2
8 | >p1 switch 2
9 | >p2 move jumpkick
10 | >p1 move tailwhip
11 | >p2 move wingattack
12 | >p1 switch 2
13 | >p2 move poisongas
14 | >p1 switch 3
15 | >p2 move ember
16 | >p1 switch 4
17 | >p2 move wingattack
18 | >p1 move stomp
19 | >p2 move ember
20 | >p1 switch 5
21 | >p2 move ember
22 | >p1 move sonicboom
23 | >p2 switch 2
24 | >p1 move nightshade
25 | >p2 switch 3
26 | >p1 move stringshot
27 | >p2 move amnesia
28 | >p1 move dragonrage
29 | >p2 move cut
30 | >p1 move nightshade
31 | >p2 move psybeam
32 | >p1 switch 6
33 | >p1 switch 5
34 | >p2 move strength
35 | >p1 move megakick
36 | >p2 move psybeam
37 | >p1 switch 4
38 | >p1 move teleport
39 | >p2 switch 4
40 | >p1 move pinmissile
41 | >p2 switch 5
42 | >p1 move swift
43 | >p2 move growl
44 | >p1 move rockslide
45 | >p2 move thunderwave
46 | >p1 move pinmissile
47 | >p2 switch 6
48 | >p1 move pinmissile
49 | >p2 move hyperbeam
50 | >p1 move pinmissile
51 | >p2 move recharge
52 | >p1 switch 2
53 | >p2 move visegrip
54 | >p1 switch 3
55 | >p1 move disable
56 | >p2 move doubleedge
57 | >p1 move screech
58 | >p2 switch 5
59 | >p1 move disable
60 | >p2 move skullbash
61 | >p1 move splash
62 | >p2 move skullbash
63 | >p1 switch 2
64 | >p2 move horndrill
65 | >p1 move pinmissile
66 | >p2 switch 2
67 | >p2 switch 3
68 | >p1 move rockslide
69 | >p2 move sludge
70 | >p1 move rockslide
71 | >p2 switch 2
72 | >p2 switch 2
73 | >p1 switch 2
74 | >p2 move submission
75 | >p1 move screech
76 | >p2 move mist
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xEBEC48B906A37945.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xEBEC48B906A37945.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xEC4103CD675CDAA1.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[60481,973,26460,55969]}
2 | >player p1 {"name":"Bot 1","team":"Pidgeot|||None|megadrain,headbutt,crabhammer,agility||247,208,241,43,43,113|N|5,28,23,3,3,12||54|25]Magikarp|||None|icepunch,psybeam,explosion,smog||73,188,41,101,101,90|N|5,4,18,,,24||66|163]Aerodactyl|||None|twineedle,acid,withdraw,thunderbolt||142,70,156,61,61,75|N|13,23,22,,,1||96|71]Golduck|||None|reflect,spore,bubble,bite||100,222,138,113,113,49|N|11,10,8,10,10,||57|7]Ninetales|||None|slam,selfdestruct,superfang,skyattack||10,136,17,21,21,164|N|1,5,24,10,10,24||66|228]Gastly|||None|fly,whirlwind,doubleteam,minimize||136,7,152,120,120,215|N|0,13,5,20,20,28||96|41"}
3 | >player p2 {"name":"Bot 2","team":"Mewtwo|||None|quickattack,splash,leechseed,swift||152,12,223,210,210,4|N|14,3,7,17,17,23||74|205]Starmie|||None|megadrain,smokescreen,bonemerang,bubblebeam||63,142,63,35,35,184|N|7,20,7,27,27,18||69|131]Zubat|||None|psychic,earthquake,slash,karatechop||87,124,247,12,12,229|N|7,21,15,23,23,27||56|186]Omanyte|||None|swordsdance,leechlife,toxic,bodyslam||73,211,71,202,202,233|N|5,24,23,3,3,0||82|25]Electabuzz|||None|supersonic,ember,aurorabeam,stringshot||86,169,47,186,186,41|N|2,1,0,24,24,27||89|21]Dragonite|||None|focusenergy,headbutt,dreameater,megapunch||32,231,75,102,102,59|N|14,23,23,0,0,18||62|156"}
4 | >p1 move megadrain
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 move megadrain
8 | >p1 move explosion
9 | >p2 switch 2
10 | >p1 switch 2
11 | >p1 move headbutt
12 | >p2 move swift
13 | >p1 move crabhammer
14 | >p2 move quickattack
15 | >p1 move crabhammer
16 | >p2 move quickattack
17 | >p1 switch 3
18 | >p2 move quickattack
19 | >p1 move thunderbolt
20 | >p2 move swift
21 | >p1 move acid
22 | >p2 move leechseed
23 | >p1 move acid
24 | >p2 switch 3
25 | >p1 move acid
26 | >p2 switch 4
27 | >p1 switch 4
28 | >p2 move toxic
29 | >p1 move bite
30 | >p2 move swordsdance
31 | >p1 switch 5
32 | >p2 move toxic
33 | >p1 move superfang
34 | >p2 switch 5
35 | >p1 switch 6
36 | >p2 move aurorabeam
37 | >p1 move fly
38 | >p2 switch 6
39 | >p1 move fly
40 | >p2 move headbutt
41 | >p1 move minimize
42 | >p2 move dreameater
43 | >p1 move doubleteam
44 | >p2 move headbutt
45 | >p1 move fly
46 | >p2 move headbutt
47 | >p1 move fly
48 | >p2 move megapunch
49 | >p1 move fly
50 | >p2 move dreameater
51 | >p1 move fly
52 | >p2 move megapunch
53 | >p1 move minimize
54 | >p2 switch 3
55 | >p1 move fly
56 | >p2 move swift
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xEC906D7B433288F0.pkmn.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xEC906D7B433288F0.pkmn.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xED1F32123199F701.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[60703,12818,12697,63233]}
2 | >player p1 {"name":"Bot 1","team":"Pikachu|||None|rockthrow,toxic,lightscreen,thunderpunch||8,57,32,186,186,13|N|3,20,0,23,23,3||72|165]Dugtrio|||None|hornattack,dizzypunch,tackle,poisongas||190,86,117,158,158,4|N|4,5,6,0,0,0||81|124]Cloyster|||None|peck,jumpkick,lovelykiss,dig||206,130,23,152,152,60|N|9,14,13,27,27,28||97|156]Arcanine|||None|drillpeck,rage,megakick,tailwhip||90,60,173,103,103,218|N|11,2,17,3,3,23||62|129]Slowpoke|||None|substitute,teleport,glare,boneclub||223,238,11,10,10,77|N|2,28,21,21,21,14||89|197]Dewgong|||None|barrage,swift,confuseray,psybeam||97,139,132,214,214,65|N|5,24,26,18,18,25||93|215"}
3 | >player p2 {"name":"Bot 2","team":"Kadabra|||None|thundershock,barrier,reflect,spore||99,141,213,191,191,113|N|15,11,3,14,14,10||84|242]Squirtle|||None|rockslide,rollingkick,flash,hypnosis||191,215,2,173,173,140|N|6,8,18,9,9,3||84|114]Lickitung|||None|firepunch,teleport,selfdestruct,minimize||63,111,208,226,226,163|N|12,19,10,16,16,21||73|77]Snorlax|||None|megakick,conversion,dragonrage,solarbeam||91,81,148,239,239,25|N|15,19,3,10,10,26||86|212]Seadra|||None|razorleaf,harden,furyswipes,rockthrow||60,163,21,210,210,80|N|6,25,26,29,29,22||98|210]Bellsprout|||None|thunderbolt,stunspore,sandattack,nightshade||50,206,205,132,132,20|N|7,21,22,2,2,27||77|42"}
4 | >p1 switch 2
5 | >p2 move thundershock
6 | >p1 move hornattack
7 | >p2 move reflect
8 | >p1 move dizzypunch
9 | >p2 move barrier
10 | >p1 move tackle
11 | >p2 move reflect
12 | >p1 switch 2
13 | >p2 move thundershock
14 | >p1 switch 3
15 | >p2 move spore
16 | >p1 move peck
17 | >p2 switch 2
18 | >p1 switch 4
19 | >p2 move hypnosis
20 | >p1 switch 5
21 | >p2 switch 2
22 | >p1 switch 6
23 | >p2 move spore
24 | >p1 move barrage
25 | >p2 move reflect
26 | >p1 move swift
27 | >p2 move barrier
28 | >p1 move confuseray
29 | >p2 move thundershock
30 | >p1 move psybeam
31 | >p2 move reflect
32 | >p1 switch 5
33 | >p2 move thundershock
34 | >p1 switch 6
35 | >p2 move reflect
36 | >p1 switch 4
37 | >p2 switch 3
38 | >p1 move jumpkick
39 | >p2 move teleport
40 | >p1 move lovelykiss
41 | >p2 switch 4
42 | >p1 move dig
43 | >p2 move megakick
44 | >p1 move dig
45 | >p2 move megakick
46 | >p1 move peck
47 | >p2 move conversion
48 | >p1 switch 3
49 | >p2 move dragonrage
50 | >p1 move rockthrow
51 | >p2 move solarbeam
52 | >p1 move toxic
53 | >p2 move solarbeam
54 | >p1 switch 5
55 | >p1 switch 2
56 | >p2 move conversion
57 | >p1 move poisongas
58 | >p2 move dragonrage
59 | >p1 move dizzypunch
60 | >p2 switch 5
61 | >p1 move dizzypunch
62 | >p2 move furyswipes
63 | >p1 move hornattack
64 | >p2 move rockthrow
65 | >p1 move tackle
66 | >p2 move razorleaf
67 | >p1 switch 2
68 | >p1 switch 4
69 | >p2 switch 6
70 | >p1 move substitute
71 | >p2 move stunspore
72 | >p1 move glare
73 | >p2 move thunderbolt
74 | >p1 switch 6
75 | >p2 move nightshade
76 | >p1 move drillpeck
77 | >p2 move stunspore
78 | >p1 move rage
79 | >p2 move sandattack
80 | >p1 move rage
81 | >p2 move nightshade
82 | >p1 move rage
83 | >p2 move stunspore
84 | >p1 move rage
85 | >p2 move thunderbolt
86 | >p1 move rage
87 | >p2 move sandattack
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xED964909377B7E8E.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[60822,18697,14203,32398]}
2 | >player p1 {"name":"Bot 1","team":"Mewtwo|||None|cut,surf,rage,smokescreen||225,24,237,237,237,33|N|1,28,8,11,11,28||97|65]Kabuto|||None|furyswipes,reflect,poisongas,firepunch||172,221,110,237,237,210|N|0,29,12,16,16,4||68|45]Cloyster|||None|crabhammer,stringshot,barrage,selfdestruct||86,5,238,173,173,232|N|14,11,15,25,25,14||75|100]Fearow|||None|bodyslam,bubblebeam,roar,wingattack||68,10,132,102,102,200|N|7,20,30,,,27||73|20]Pikachu|||None|dizzypunch,sing,meditate,seismictoss||13,186,198,189,189,246|N|12,10,15,8,8,13||62|79]Porygon|||None|defensecurl,fly,superfang,rest||40,199,240,234,234,219|N|15,7,22,7,7,19||61|209"}
3 | >player p2 {"name":"Bot 2","team":"Weepinbell|||None|growl,ember,leechseed,selfdestruct||128,164,127,214,214,183|N|14,27,18,1,1,23||51|141]Machop|||None|swordsdance,strength,whirlwind,twineedle||139,164,43,217,217,60|N|11,30,4,22,22,2||90|0]Pidgeotto|||None|rockthrow,splash,constrict,agility||32,245,119,57,57,41|N|9,11,21,22,22,8||51|207]Poliwag|||None|dig,stringshot,roar,nightshade||36,202,210,189,189,114|N|15,7,15,27,27,19||75|196]Arcanine|||None|fissure,softboiled,counter,acid||221,177,249,123,123,237|N|14,14,27,21,21,14||50|26]Magnemite|||None|barrier,toxic,wrap,triattack||18,112,132,195,195,41|N|2,1,24,21,21,22||92|57"}
4 | >p1 move cut
5 | >p2 move growl
6 | >p1 move surf
7 | >p2 move ember
8 | >p2 switch 2
9 | >p1 move rage
10 | >p2 move whirlwind
11 | >p1 move rage
12 | >p2 move whirlwind
13 | >p1 move rage
14 | >p2 switch 3
15 | >p1 move rage
16 | >p2 move agility
17 | >p1 move rage
18 | >p2 move splash
19 | >p2 switch 4
20 | >p1 move rage
21 | >p2 move stringshot
22 | >p1 move rage
23 | >p2 switch 6
24 | >p1 move rage
25 | >p2 switch 5
26 | >p1 move rage
27 | >p2 move counter
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xEFAA766A8ED2D5BF.showdown.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkmn/engine/a27b3ff330f57cd923d83f21832db2fcc0eac3a9/src/test/fixtures/gen1/0xEFAA766A8ED2D5BF.showdown.bin
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xF091D4934DA9A368.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[61585,54419,19881,41832]}
2 | >player p1 {"name":"Bot 1","team":"Dewgong|||None|teleport,hyperfang,leechlife,highjumpkick||249,242,123,94,94,245|N|14,2,27,17,17,||55|173]Drowzee|||None|poisongas,harden,petaldance,superfang||155,133,132,35,35,199|N|15,26,26,10,10,22||97|110]Lapras|||None|dizzypunch,megadrain,sludge,absorb||56,229,189,155,155,113|N|4,12,27,1,1,28||87|247]Magmar|||None|vinewhip,agility,psywave,scratch||44,220,43,,,141|N|10,7,29,25,25,23||51|108]Growlithe|||None|slam,boneclub,megakick,doubleslap||247,112,74,124,124,159|N|6,1,11,5,5,15||54|201]Meowth|||None|doubleteam,ember,wingattack,softboiled||81,14,119,135,135,172|N|12,30,18,25,25,1||84|205"}
3 | >player p2 {"name":"Bot 2","team":"Jolteon|||None|growl,fireblast,drillpeck,selfdestruct||58,118,109,219,219,245|N|7,1,,7,7,27||70|151]Pinsir|||None|cut,poisonpowder,thunderbolt,rest||64,216,167,10,10,171|N|14,7,6,1,1,30||57|206]Zubat|||None|mimic,splash,strength,razorwind||175,235,198,78,78,107|N|15,11,19,7,7,10||96|227]Caterpie|||None|mirrormove,sharpen,defensecurl,gust||84,17,89,50,50,22|N|7,1,15,7,7,6||66|85]Dugtrio|||None|payday,pinmissile,toxic,takedown||147,186,247,126,126,162|N|10,15,13,21,21,26||79|152]Pidgeot|||None|sleeppowder,explosion,quickattack,stunspore||104,215,221,137,137,162|N|2,9,20,25,25,||82|54"}
4 | >p1 switch 2
5 | >p2 switch 2
6 | >p1 switch 2
7 | >p2 move cut
8 | >p1 move teleport
9 | >p2 move poisonpowder
10 | >p1 move hyperfang
11 | >p2 switch 2
12 | >p1 move leechlife
13 | >p2 move growl
14 | >p1 switch 3
15 | >p2 switch 3
16 | >p1 move dizzypunch
17 | >p2 move mimic
18 | >p1 switch 4
19 | >p2 switch 4
20 | >p1 move vinewhip
21 | >p2 switch 5
22 | >p1 move agility
23 | >p2 move payday
24 | >p1 move psywave
25 | >p2 move pinmissile
26 | >p1 move scratch
27 | >p2 move toxic
28 | >p1 move scratch
29 | >p2 move takedown
30 | >p1 switch 5
31 | >p1 move slam
32 | >p2 move pinmissile
33 | >p1 move boneclub
34 | >p2 move payday
35 | >p1 switch 6
36 | >p2 move toxic
37 | >p1 move doubleteam
38 | >p2 move takedown
39 | >p1 move ember
40 | >p2 move toxic
41 | >p2 switch 6
42 | >p1 switch 3
43 | >p2 move sleeppowder
44 | >p1 move highjumpkick
45 | >p2 move explosion
46 | >p1 switch 2
47 | >p2 switch 3
48 | >p1 switch 6
49 | >p2 move fireblast
50 | >p1 move megakick
51 | >p2 move drillpeck
52 | >p1 switch 6
53 | >p1 move poisongas
54 | >p2 switch 4
55 | >p1 move harden
56 | >p2 move splash
57 | >p1 move petaldance
58 | >p2 switch 4
59 | >p1 move petaldance
60 | >p2 move selfdestruct
61 | >p2 switch 5
62 | >p1 move petaldance
63 | >p2 move mirrormove
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xF12F2AB7B055F0E7.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[61743,10935,45141,61671]}
2 | >player p1 {"name":"Bot 1","team":"Horsea|||None|dig,visegrip,furyswipes,watergun||120,1,209,174,174,72|N|5,21,7,18,18,5||58|54]Hitmonlee|||None|icebeam,doubleteam,bite,fissure||220,13,119,229,229,111|N|11,6,21,18,18,30||81|179]Starmie|||None|lightscreen,fly,poisonsting,selfdestruct||237,20,240,11,11,63|N|15,2,,19,19,30||82|140]Ivysaur|||None|thunderwave,stunspore,superfang,submission||194,123,168,91,91,142|N|6,1,23,8,8,30||98|11]Pikachu|||None|sonicboom,lick,disable,substitute||147,205,139,143,143,105|N|10,7,9,21,21,6||57|62]Kadabra|||None|drillpeck,sludge,wingattack,hyperfang||133,218,55,116,116,200|N|8,14,9,28,28,12||54|216"}
3 | >player p2 {"name":"Bot 2","team":"Kabutops|||None|gust,toxic,dizzypunch,bonemerang||162,195,66,81,81,51|N|11,26,25,23,23,27||90|32]Charmander|||None|quickattack,nightshade,thunderbolt,cut||107,176,39,126,126,233|N|12,18,27,0,0,17||68|2]Rapidash|||None|withdraw,razorleaf,sing,icepunch||76,149,61,57,57,15|N|7,9,11,15,15,2||89|144]Snorlax|||None|substitute,constrict,furyswipes,smog||115,142,51,163,163,73|N|2,8,21,25,25,15||98|227]Cloyster|||None|thunderpunch,leechlife,drillpeck,barrage||83,72,243,48,48,126|N|6,13,18,1,1,30||68|219]Golduck|||None|skullbash,sludge,hornattack,skyattack||140,172,79,6,6,7|N|15,14,10,19,19,15||76|158"}
4 | >p1 move dig
5 | >p2 switch 2
6 | >p1 move dig
7 | >p2 switch 2
8 | >p1 move visegrip
9 | >p2 move gust
10 | >p1 move furyswipes
11 | >p2 move toxic
12 | >p1 switch 2
13 | >p2 move dizzypunch
14 | >p1 move icebeam
15 | >p2 move bonemerang
16 | >p1 switch 2
17 | >p1 move watergun
18 | >p2 switch 3
19 | >p1 move dig
20 | >p2 move withdraw
21 | >p1 move dig
22 | >p2 move withdraw
23 | >p1 switch 3
24 | >p2 move sing
25 | >p1 move lightscreen
26 | >p2 switch 4
27 | >p1 move fly
28 | >p2 move substitute
29 | >p1 move fly
30 | >p2 switch 5
31 | >p1 move poisonsting
32 | >p2 move drillpeck
33 | >p1 move selfdestruct
34 | >p2 move barrage
35 | >p1 switch 4
36 | >p1 move thunderwave
37 | >p2 move leechlife
38 | >p1 switch 5
39 | >p2 switch 6
40 | >p1 move sonicboom
41 | >p2 move sludge
42 | >p1 move lick
43 | >p2 move skyattack
44 | >p1 move disable
45 | >p2 move skyattack
46 | >p1 move substitute
47 | >p2 move sludge
--------------------------------------------------------------------------------
/src/test/fixtures/gen1/0xF9035DA297392F5D.input.log:
--------------------------------------------------------------------------------
1 | >start {"formatid":"gen1customgame@@@Endless Battle Clause,Sleep Clause Mod,Freeze Clause Mod","seed":[63747,23970,38713,12125]}
2 | >player p1 {"name":"Bot 1","team":"Kabuto|||None|confusion,fly,swordsdance,whirlwind||184,194,197,60,60,68|N|10,10,24,17,17,3||88|156]Hitmonchan|||None|substitute,pound,haze,lick||67,94,169,4,4,219|N|14,18,7,24,24,7||65|120]Goldeen|||None|agility,firepunch,megadrain,submission||222,78,55,239,239,201|N|0,24,1,16,16,4||54|157]Horsea|||None|psychic,skyattack,selfdestruct,quickattack||151,150,209,14,14,199|N|11,15,1,3,3,11||59|161]Flareon|||None|barrage,growth,disable,bubblebeam||185,92,187,152,152,185|N|5,20,,10,10,13||79|110]Kangaskhan|||None|thundershock,poisongas,kinesis,thunderpunch||154,82,27,160,160,10|N|0,4,20,1,1,4||68|138"}
3 | >player p2 {"name":"Bot 2","team":"Bellsprout|||None|dreameater,earthquake,slam,jumpkick||8,122,243,243,243,152|N|0,28,29,17,17,13||81|46]Charizard|||None|defensecurl,sleeppowder,stringshot,fireblast||178,68,87,94,94,187|N|6,25,15,1,1,22||60|15]Nidoran-F|||None|leechseed,bind,psybeam,visegrip||226,63,90,128,128,11|N|0,0,5,16,16,25||82|171]Kingler|||None|teleport,highjumpkick,aurorabeam,seismictoss||32,94,26,122,122,174|N|9,27,12,14,14,17||53|252]Persian|||None|smokescreen,leer,icepunch,acidarmor||77,171,180,106,106,14|N|4,13,23,12,12,4||84|84]Kabutops|||None|sludge,flamethrower,recover,toxic||167,16,203,252,252,251|N|13,10,,10,10,28||70|36"}
4 | >p1 move confusion
5 | >p2 move dreameater
6 | >p1 switch 2
7 | >p2 move earthquake
8 | >p1 switch 2
9 | >p2 switch 2
10 | >p1 move fly
11 | >p2 move defensecurl
12 | >p1 move fly
13 | >p2 switch 2
14 | >p2 switch 3
15 | >p1 switch 3
16 | >p2 move leechseed
17 | >p1 move agility
18 | >p2 move bind
19 | >p1 switch 4
20 | >p2 move psybeam
21 | >p1 move psychic
22 | >p2 move visegrip
23 | >p1 move skyattack
24 | >p2 move bind
25 | >p1 move skyattack
26 | >p2 switch 4
--------------------------------------------------------------------------------
/src/test/fuzz.test.ts:
--------------------------------------------------------------------------------
1 | import {Generations} from '@pkmn/data';
2 | import {Dex} from '@pkmn/sim';
3 |
4 | import {run} from './fuzz';
5 |
6 | // Simple smoke tests just to confirm things are wired up correctly and actually execute
7 | const gens = new Generations(Dex as any);
8 | for (const gen of gens) {
9 | if (gen.num > 1) break;
10 | for (const showdown of [false, true]) {
11 | describe(`Gen ${gen.num} (${showdown ? 'showdown' : 'pkmn'})`, () => {
12 | test('run', () =>
13 | expect(run(gens, gen.num, showdown, true, '1s', 123456789n)).resolves.toBe(true),
14 | 60 * 1000);
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/fuzz.ts:
--------------------------------------------------------------------------------
1 | import 'source-map-support/register';
2 |
3 | import {execFile} from 'child_process';
4 | import * as fs from 'fs';
5 | import * as path from 'path';
6 |
7 | import {Generations} from '@pkmn/data';
8 | import {Dex} from '@pkmn/sim';
9 |
10 | import {LE} from '../pkg/data';
11 | import * as debug from '../tools/debug';
12 |
13 | const ROOT = path.resolve(__dirname, '..', '..');
14 |
15 | const usage = (msg?: string): void => {
16 | if (msg) console.error(msg);
17 | console.error('Usage: fuzz ');
18 | process.exit(1);
19 | };
20 |
21 | export async function run(
22 | gens: Generations,
23 | gen: number | string,
24 | showdown: boolean,
25 | testing?: boolean,
26 | duration?: string,
27 | seed?: bigint
28 | ) {
29 | const args = ['build', '--summary', 'failures', 'fuzz', '-Dlog', '-Dchance', '-Dcalc'];
30 | if (showdown) args.push('-Dshowdown');
31 |
32 | let input = undefined;
33 | if (typeof duration !== 'undefined') {
34 | args.push('--', gen.toString(), duration);
35 | if (seed) args.push(seed.toString());
36 | } else {
37 | input = fs.readFileSync(gen);
38 | }
39 |
40 | try {
41 | await new Promise((resolve, reject) => {
42 | const child = execFile('zig', args, {encoding: 'buffer'}, (error, stdout, stderr) => {
43 | if (error) return reject({error, stdout, stderr});
44 | resolve();
45 | });
46 | if (child.stdin && input) {
47 | child.stdin.write(input);
48 | child.stdin.end();
49 | }
50 | });
51 | return true;
52 | } catch (err: any) {
53 | const {stdout, stderr} = err as {stdout: Buffer; stderr: Buffer};
54 | const raw = stderr.toString('utf8');
55 | const panic = raw.indexOf('panic: ');
56 | if (testing || !stdout.length) throw new Error(raw);
57 |
58 | console.error(raw);
59 |
60 | const dir = path.join(ROOT, 'logs');
61 | try {
62 | fs.mkdirSync(dir, {recursive: true});
63 | } catch (e: any) {
64 | if (e.code !== 'EEXIST') throw e;
65 | }
66 |
67 | seed = LE ? stdout.readBigUInt64LE(0) : stdout.readBigUInt64BE(0);
68 | const hex = `0x${seed.toString(16).toUpperCase()}`;
69 | const file = path.join(dir, `${hex}.fuzz.html`);
70 | const link = path.join(dir, 'fuzz.html');
71 |
72 | fs.writeFileSync(file, debug.render(gens, stdout.subarray(8), raw.slice(panic), seed));
73 | fs.rmSync(link, {force: true});
74 | fs.symlinkSync(file, link);
75 |
76 | return false;
77 | }
78 | }
79 |
80 | if (require.main === module) {
81 | (async () => {
82 | if (process.argv.length < 4 || process.argv.length > 6) usage(process.argv.length.toString());
83 | const mode = process.argv[2];
84 | if (mode !== 'pkmn' && mode !== 'showdown') {
85 | usage(`Mode must be either 'pkmn' or 'showdown', received '${mode}'`);
86 | }
87 | const gens = new Generations(Dex as any);
88 | const seed = process.argv.length > 5 ? BigInt(process.argv[5]) : undefined;
89 | await run(gens, process.argv[3], mode === 'showdown', false, process.argv[4], seed);
90 | })().catch(err => {
91 | console.error(err);
92 | process.exit(1);
93 | });
94 | }
95 |
--------------------------------------------------------------------------------
/src/test/integration.test.ts:
--------------------------------------------------------------------------------
1 | import {Generations} from '@pkmn/data';
2 | import {Dex} from '@pkmn/sim';
3 |
4 | import * as addon from '../pkg/addon';
5 |
6 | import {run} from './integration';
7 |
8 | describe('integration', () => {
9 | (addon.supports(true, true) ? test : test.skip)('test', async () => {
10 | const gens = new Generations(Dex as any);
11 | expect(await run(gens, {prng: '1,2,3,4'})).toBe(0);
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/src/test/regression.test.ts:
--------------------------------------------------------------------------------
1 | import * as fs from 'fs';
2 | import * as path from 'path';
3 |
4 | import {Generations} from '@pkmn/data';
5 | import {Dex} from '@pkmn/sim';
6 |
7 | import * as addon from '../pkg/addon';
8 |
9 | import * as fuzz from './fuzz';
10 | import * as integration from './integration';
11 |
12 | const FIXTURES = path.join(__dirname, 'fixtures');
13 | const SKIP: string[] = [];
14 |
15 | const gens = new Generations(Dex as any);
16 | for (const gen of gens) {
17 | if (gen.num > 1) break;
18 | (addon.supports(true, true) ? describe : describe.skip)(`Gen ${gen.num}`, () => {
19 | const dir = path.join(FIXTURES, `gen${gen.num}`);
20 | for (const file of fs.readdirSync(path.join(dir))) {
21 | const name = file.slice(0, file.indexOf('.'));
22 | (SKIP.includes(name) ? test.skip : test)(`${name}`, async () => {
23 | if (file.endsWith('log')) {
24 | expect(await integration.run(gens, path.join(dir, file))).toBe(0);
25 | } else {
26 | const showdown = file.includes('showdown');
27 | expect(await fuzz.run(gens, path.join(dir, file), showdown, true)).toBe(true);
28 | }
29 | });
30 | }
31 | });
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/showdown.html.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Pokémon Showdown
8 |
9 |
10 |
11 |
12 |
13 | {{{ seed }}}
14 |
20 |
{{{ content }}}
21 |
22 |
87 |
90 |
91 |
--------------------------------------------------------------------------------
/src/tools/debug.ts:
--------------------------------------------------------------------------------
1 | import {execFileSync} from 'child_process';
2 | import * as fs from 'fs';
3 | import * as path from 'path';
4 |
5 | import {Generation, Generations} from '@pkmn/data';
6 |
7 | import * as data from '../pkg/data';
8 | import * as gen1 from '../pkg/gen1';
9 |
10 | import * as display from './display';
11 |
12 | const ROOT = path.resolve(__dirname, '..', '..');
13 | const ZIG = path.dirname(JSON.parse(execFileSync('zig', ['env'], {encoding: 'utf8'})).lib_dir);
14 |
15 | export function error(err: string) {
16 | return (err
17 | .replaceAll(ROOT + path.sep, '')
18 | .replaceAll(ZIG, '$ZIG')
19 | .split('\n').slice(0, -3).join('\n'));
20 | }
21 |
22 | export function render(
23 | gens: Generation | Generations,
24 | buffer: Buffer,
25 | err?: string,
26 | seed?: bigint
27 | ) {
28 | if (!buffer.length) throw new Error('Invalid input');
29 |
30 | // Peek at the start of the data buffer just to figure out whether showdown is enabled, what
31 | // generation it is, and the intial state of the Battle
32 | const view = data.Data.view(buffer);
33 |
34 | let offset = 0;
35 | const showdown = !!view.getUint8(offset++);
36 | const num = view.getUint8(offset++);
37 | const gen = 'get' in gens ? gens.get(num) : gens;
38 | if (gen.num !== num) {
39 | throw new Error(`Require generation ${num} but was passed generation ${gen.num}`);
40 | }
41 | offset += 6;
42 |
43 | const lookup = data.Lookup.get(gen);
44 | const size = data.LAYOUT[gen.num - 1].sizes.Battle;
45 |
46 | const deserialize = (buf: Buffer) => {
47 | switch (gen.num) {
48 | case 1: return new gen1.Battle(lookup, data.Data.view(buf), {inert: true, showdown});
49 | default: throw new Error(`Unsupported gen: ${gen.num}`);
50 | }
51 | };
52 | const battle = deserialize(buffer.subarray(offset, offset += size));
53 |
54 | return display.render(path.join(ROOT, 'build', 'tools', 'display', 'debug.jsx'), {
55 | gen: display.prune(gen, battle),
56 | buf: buffer.toString('base64'),
57 | error: err && error(err),
58 | seed: seed?.toString(),
59 | }, {styles: [path.join(ROOT, 'src', 'tools', 'display', 'debug.css')]});
60 | }
61 |
62 | export async function run(gens: Generations) {
63 | let input;
64 | if (process.argv.length > 2) {
65 | if (process.argv.length > 3) {
66 | console.error('Invalid input');
67 | process.exit(1);
68 | }
69 | input = fs.readFileSync(process.argv[2]);
70 | } else {
71 | let length = 0;
72 | const result: Uint8Array[] = [];
73 | for await (const chunk of process.stdin) {
74 | result.push(chunk);
75 | length += chunk.length;
76 | }
77 | input = Buffer.concat(result, length);
78 | }
79 | process.stdout.write(render(gens, input));
80 | }
81 |
82 | if (require.main === module) {
83 | run(new Generations(require('@pkmn/sim').Dex)).catch(err => {
84 | console.error(err.message);
85 | process.exit(1);
86 | });
87 | }
88 |
--------------------------------------------------------------------------------
/src/tools/display/autocomplete.old.css:
--------------------------------------------------------------------------------
1 | /** @license MIT modified from Pixabay's https://github.com/Pixabay/JavaScript-autoComplete */
2 | .autocomplete-suggestions {
3 | text-align: left;
4 | cursor: default;
5 | border: 1px solid #ccc;
6 | border-top: 0;
7 | background: #fff;
8 | box-shadow: -1px 1px 3px rgba(0, 0, 0, .1);
9 |
10 | position: absolute;
11 | display: none;
12 | z-index: 9999;
13 | max-height: 254px;
14 | overflow: hidden;
15 | overflow-y: auto;
16 | box-sizing: border-box;
17 | }
18 | .autocomplete-suggestion {
19 | position: relative;
20 | padding: 0 .6em;
21 | line-height: 23px;
22 | white-space: nowrap;
23 | overflow: hidden;
24 | text-overflow: ellipsis;
25 | font-size: 1.02em;
26 | color: #333;
27 | }
28 | .autocomplete-suggestion b {
29 | font-weight: normal;
30 | color: #1f8dd6;
31 | }
32 | .autocomplete-suggestion.selected {
33 | background: #f0f0f0;
34 | }
--------------------------------------------------------------------------------
/src/tools/display/debug.css:
--------------------------------------------------------------------------------
1 | .log {
2 | display: flex;
3 | justify-content: center;
4 | padding-bottom: 2em;
5 | }
--------------------------------------------------------------------------------
/src/tools/display/select.css:
--------------------------------------------------------------------------------
1 | /** @license MIT modified from Pixabay's https://github.com/Pixabay/JavaScript-autoComplete */
2 | .select.options {
3 | text-align: left;
4 | cursor: default;
5 | border: 1px solid #ccc;
6 | border-top: 0;
7 | background: #fff;
8 | box-shadow: -1px 1px 3px rgba(0, 0, 0, .1);
9 |
10 | position: absolute;
11 | display: none;
12 | z-index: 9999;
13 | max-height: 254px;
14 | overflow: hidden;
15 | overflow-y: auto;
16 | scrollbar-width: thin;
17 | box-sizing: border-box;
18 | }
19 | .select.option {
20 | position: relative;
21 | padding: 0 .6em;
22 | line-height: 23px;
23 | white-space: nowrap;
24 | overflow: hidden;
25 | text-overflow: ellipsis;
26 | font-size: 1.02em;
27 | color: #333;
28 | }
29 | .select.option strong {
30 | font-weight: normal;
31 | color: #1f8dd6;
32 | }
33 | .select.option.selected {
34 | background: #f0f0f0;
35 | }
--------------------------------------------------------------------------------
/src/tools/display/util.ts:
--------------------------------------------------------------------------------
1 | import {GenderName, MoveName, SpeciesName, TypeName} from '@pkmn/data';
2 |
3 | import {Battle, Choice, Data, ParsedLine, Result} from '../../pkg';
4 |
5 | export interface Frame {
6 | result: Result;
7 | c1: Choice;
8 | c2: Choice;
9 | battle: Data;
10 | parsed: ParsedLine[];
11 | }
12 |
13 | export interface Species {
14 | name: SpeciesName;
15 | num: number;
16 | genderRatio: {M: number; F: number};
17 | gender?: GenderName;
18 | }
19 |
20 | export interface Move {
21 | name: MoveName;
22 | num: number;
23 | maxpp: number;
24 | basePower: number;
25 | type: TypeName;
26 | }
27 |
28 | const format = (kwVal: any) => typeof kwVal === 'boolean' ? '' : ` ${kwVal as string}`;
29 | const trim = (args: string[]) => {
30 | while (args.length && !args[args.length - 1]) args.pop();
31 | return args;
32 | };
33 |
34 | const compact = (line: ParsedLine) =>
35 | [...trim(line.args.slice(0) as string[]), ...Object.keys(line.kwArgs)
36 | .map(k => `[${k}]${format((line.kwArgs as any)[k])}`)].join('|');
37 |
38 | export const toText = (parsed: ParsedLine[]) =>
39 | parsed.length ? `|${parsed.map(compact).join('\n|')}` : '';
40 |
41 | export const pretty = (choice?: Choice) => choice
42 | ? choice.type === 'pass' ? choice.type : `${choice.type} ${choice.data}`
43 | : '???';
44 |
45 | export const imports = (memory: [WebAssembly.Memory], decoder: TextDecoder) => ({
46 | js: {
47 | log(ptr: number, len: number) {
48 | if (len === 0) return console.log('');
49 | const msg = decoder.decode(new Uint8Array(memory[0].buffer, ptr, len));
50 | console.log(msg);
51 | },
52 | panic(ptr: number, len: number) {
53 | const msg = decoder.decode(new Uint8Array(memory[0].buffer, ptr, len));
54 | throw new Error('panic: ' + msg);
55 | },
56 | },
57 | });
58 |
--------------------------------------------------------------------------------
/src/tools/serde.ts:
--------------------------------------------------------------------------------
1 | import 'source-map-support/register';
2 |
3 | import {execFile} from 'child_process';
4 |
5 | const run = async (cmd: string, args: string[]): Promise =>
6 | new Promise((resolve, reject) => {
7 | execFile(cmd, args, {encoding: 'buffer'}, (error, stdout) =>
8 | error ? reject(error) : resolve(stdout));
9 | });
10 |
11 | const partition = (array: string[], n: number): string[][] =>
12 | array.length ? [array.splice(0, n)].concat(partition(array, n)) : [];
13 |
14 | (async () => {
15 | const buf = await run('zig', ['build', 'serde', '--', process.argv[2].toString()]);
16 | const arr = Array.from(buf);
17 | const lines = partition(arr.map(x => `0x${x.toString(16).padStart(2, '0')}`), 16);
18 | console.log(lines.map(line => line.join(', ')).join(',\n'));
19 | })().catch(err => {
20 | console.error(err);
21 | process.exit(1);
22 | });
23 |
--------------------------------------------------------------------------------
/src/tools/version.zig:
--------------------------------------------------------------------------------
1 | const builtin = @import("builtin");
2 | const std = @import("std");
3 |
4 | pub fn main() !void {
5 | const version = try std.SemanticVersion.parse("0.12.0-dev.2036+fc79b22a9");
6 | const modern = builtin.zig_version.order(version) != .lt;
7 | try std.io.getStdOut().writer().writeAll(if (modern) "modern" else "legacy");
8 | }
9 |
--------------------------------------------------------------------------------
/src/tools/vscode/LICENSE:
--------------------------------------------------------------------------------
1 | ../../../LICENSE
--------------------------------------------------------------------------------
/src/tools/vscode/README.md:
--------------------------------------------------------------------------------
1 | In order to view the `.bin` files present in the regression test [fixtures](../../test/regression/fixtures/) in Visual Studio Code:
2 |
3 | 1. Add [`pkmn-debug`](../../bin/pkmn-debug) to the path `PATH`
4 | 2. Package the extension into a `.vsix`:
5 | ```sh
6 | $ npm run extension
7 | ```
8 | 3. Install the extension in Visual Studio Code via "**Extensions: Install from VSIX...**"
9 | 4. Restart Visual Studio Code
--------------------------------------------------------------------------------
/src/tools/vscode/extension.ts:
--------------------------------------------------------------------------------
1 | import {execFile} from 'child_process';
2 |
3 | import * as vscode from 'vscode';
4 |
5 | type RenderedDocument = vscode.CustomDocument & {readonly preview: string};
6 |
7 | class PkmnDebugEditorProvider implements vscode.CustomReadonlyEditorProvider {
8 | async openCustomDocument(
9 | uri: vscode.Uri,
10 | context: vscode.CustomDocumentOpenContext,
11 | token: vscode.CancellationToken
12 | ): Promise {
13 | return {uri, preview: await preview(uri, token), dispose() {}};
14 | }
15 |
16 | resolveCustomEditor(document: RenderedDocument, webviewPanel: vscode.WebviewPanel) {
17 | try {
18 | webviewPanel.webview.options = {enableScripts: true};
19 | webviewPanel.webview.html = document.preview;
20 | } catch (error: unknown) {
21 | if (!(error instanceof Error)) throw error;
22 | vscode.window.showErrorMessage(`Error running pkmn-debug: ${error.message}`);
23 | }
24 | }
25 | }
26 |
27 | function preview(uri: vscode.Uri, token?: vscode.CancellationToken) {
28 | return new Promise((resolve, reject) => {
29 | const child = execFile('pkmn-debug', [uri.fsPath]);
30 | token?.onCancellationRequested(() => {
31 | child.kill();
32 | });
33 | let stdout = '';
34 | child.stdout?.on('data', (data: Buffer) => {
35 | stdout += data.toString();
36 | });
37 | let stderr = '';
38 | child.stderr?.on('data', (data: Buffer) => {
39 | stderr += data.toString();
40 | });
41 | child.on('error', error => {
42 | reject(error);
43 | });
44 | child.on('exit', code => {
45 | if (code === 0) {
46 | resolve(stdout);
47 | } else {
48 | reject(new Error(`pkmn-debug exited with code: ${code}\n${stderr}`));
49 | }
50 | });
51 | });
52 | }
53 |
54 | export function activate(context: vscode.ExtensionContext) {
55 | context.subscriptions.push(vscode.window.registerCustomEditorProvider(
56 | 'pkmn-debug',
57 | new PkmnDebugEditorProvider(),
58 | {webviewOptions: {
59 | enableFindWidget: true,
60 | retainContextWhenHidden: true,
61 | }},
62 | ));
63 | }
64 |
65 | export function deactivate() {}
66 |
--------------------------------------------------------------------------------
/src/tools/vscode/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pkmn-debug",
3 | "version": "0.1.0",
4 | "publisher": "pkmn",
5 | "repository": "github:pkmn/engine",
6 | "main": "extension.js",
7 | "files": ["extension.js", "LICENSE"],
8 | "scripts": {
9 | "build": "esbuild extension.ts --format=cjs --outfile=extension.js && vsce package"
10 | },
11 | "engines": {"vscode": "^1.93.0"},
12 | "activationEvents": [],
13 | "contributes": {
14 | "customEditors": [{
15 | "viewType": "pkmn-debug",
16 | "displayName": "pkmn-debug",
17 | "selector": [{ "filenamePattern": "*.bin" }]
18 | }]
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src"],
3 | "compilerOptions": {
4 | "allowUnreachableCode": false,
5 | "allowUnusedLabels": false,
6 | "baseUrl": ".",
7 | "declaration": true,
8 | "esModuleInterop": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "incremental": true,
11 | "isolatedModules": true,
12 | "jsx": "preserve",
13 | "jsxFactory": "h",
14 | "jsxFragmentFactory": "Fragment",
15 | "lib": ["es2022", "dom", "dom.iterable"],
16 | "module": "nodenext",
17 | "moduleResolution": "nodenext",
18 | "noEmitOnError": true,
19 | "noFallthroughCasesInSwitch": true,
20 | "noImplicitReturns": true,
21 | "outDir": "build",
22 | "resolveJsonModule": true,
23 | "skipLibCheck": true,
24 | "sourceMap": true,
25 | "strict": true,
26 | "target": "esnext",
27 | "tsBuildInfoFile": ".tsbuildinfo",
28 | "paths": {
29 | "@pkmn/sim/*": ["node_modules/@pkmn/sim/build/types/sim/*"]
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/vite.config.mts:
--------------------------------------------------------------------------------
1 | import {defineConfig} from 'vitest/config';
2 |
3 | export default defineConfig({
4 | test: {
5 | watch: false,
6 | globals: true,
7 | testTimeout: 60_000,
8 | exclude: ['node_modules', 'build', 'examples'],
9 | coverage: {reportsDirectory: 'coverage/js', exclude: ['src/test', '**/*.test.ts']},
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/zig.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
2 | index f8aeface59..14f3027e6c 100644
3 | --- a/src/codegen/llvm.zig
4 | +++ b/src/codegen/llvm.zig
5 | @@ -6741,7 +6741,8 @@ pub const FuncGen = struct {
6 | } else {
7 | const elem_ptr =
8 | try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");
9 | - return self.loadTruncate(.normal, elem_ty, elem_ptr, .default);
10 | + const elem_llvm_ty = try o.lowerType(elem_ty);
11 | + return self.wip.load(.normal, elem_llvm_ty, elem_ptr, .default, "");
12 | }
13 | }
14 |
15 | @@ -6912,12 +6913,13 @@ pub const FuncGen = struct {
16 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
17 | const field_ptr =
18 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");
19 | + const llvm_field_ty = try o.lowerType(field_ty);
20 | const payload_alignment = layout.payload_align.toLlvm();
21 | if (isByRef(field_ty, zcu)) {
22 | if (canElideLoad(self, body_tail)) return field_ptr;
23 | return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal);
24 | } else {
25 | - return self.loadTruncate(.normal, field_ty, field_ptr, payload_alignment);
26 | + return self.wip.load(.normal, llvm_field_ty, field_ptr, payload_alignment, "");
27 | }
28 | },
29 | else => unreachable,
30 | @@ -10915,7 +10917,8 @@ pub const FuncGen = struct {
31 |
32 | return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
33 | }
34 | - return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment);
35 | + const payload_llvm_ty = try o.lowerType(payload_ty);
36 | + return fg.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");
37 | }
38 |
39 | assert(!isByRef(payload_ty, zcu));
40 | @@ -11129,7 +11132,7 @@ pub const FuncGen = struct {
41 | if (isByRef(elem_ty, zcu)) {
42 | return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind);
43 | }
44 | - return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment);
45 | + return self.wip.load(access_kind, try o.lowerType(elem_ty), ptr, ptr_alignment, "");
46 | }
47 |
48 | const containing_int_ty = try o.builder.intType(@intCast(info.packed_offset.host_size * 8));
49 |
--------------------------------------------------------------------------------