CHOMP — Technical Documentation
Version 3.0.0 · Last updated 2026-10-13 Written in ASD-STE100 Simplified Technical English. Organised with the Diátaxis model.
0. About this document
0.1 Purpose
This document tells you how to run, test and maintain CHOMP v1, the team-preview solver in ABRA. For results and
figures, read the white paper: docs/CHOMP-whitepaper.md. This document does not repeat them.
0.2 Where the code is
The code of CHOMP v1 is in the ABRA repository, https://github.com/willhoop/abra, in the folder solver/chomp/.
This repository (willhoop/chomp) holds the CHOMP documents and the retired browser tool (Part 5).
0.3 Structure
- Part 1 — Tutorial. Get one CHOMP answer.
- Part 2 — How-to guides. Do one specific task.
- Part 3 — Reference. Find files, inputs, outputs and settings.
- Part 4 — Explanation. Understand the design.
- Part 5 — Retired. The old browser userscript (Reg M-B).
0.4 Terms
Use these terms with these meanings only.
| Term | Meaning |
|---|---|
| a sheet | The open team sheet of one player: six Pokémon with species, item, ability and moves. |
| an option | One choice at team preview: four Pokémon to bring, and two of the four to lead. Each sheet has 90 options. |
| a cell | One pair of options: my option and the opponent option. The table has 90 × 90 = 8,100 cells. |
| the scorer | The model that gives each cell a win probability. File solver/chomp/v1/scorer.js. |
| the mix | A probability for each of my 90 options. CHOMP samples its choice from the mix. |
| a release | A frozen copy of the ABRA simulator MEDICHAM. CHOMP v1 was tested on release eaa5becc54eb. |
| ROTOM | The ABRA client that plays on Pokémon Showdown. |
| an arm | A ROTOM configuration file in solver/rotom/arms/. |
PART 1 — TUTORIAL
Get one CHOMP answer. Do these steps one time.
1.1 Get the code
- Clone ABRA:
git clone https://github.com/willhoop/abra.git. - Clone the Reg M-C Showdown checkout next to it, as
pokemon-showdown-mc. ABRA reads the format from it. - Make sure that the folder
data/releases/eaa5becc54ebis in the ABRA checkout. Git does not track this folder. If it is not there, copy it from a checkout that has it.
1.2 Solve one preview
Open a terminal in the ABRA folder. Run this command:
ABRA_REGULATION=regmc node -e "
const CH = require('./solver/chomp/v1/chomp1.js').create({ release: 'eaa5becc54eb' });
const { parseShowteam } = require('./solver/human/parse_game.js');
const P = require('./solver/rotom/teams/regmc-pool.json');
const r = CH.solve({ mine: parseShowteam(P.teams['0'].packed), theirs: parseShowteam(P.teams['1'].packed) });
console.log(r.support.map(s => s.p.toFixed(3) + ' ' + s.label).join('\n'));
console.log('value', r.value.toFixed(3));
"
The command uses two teams from the ABRA team pool. It prints the options that have weight in the mix, and the value of the game for you.
Caution: Set ABRA_REGULATION=regmc. If you do not set it, ABRA reads the retired Reg M-B data and the solve
stops with the error does not build.
PART 2 — HOW-TO GUIDES
Do one task.
2.1 How to run the CHOMP tests
In the ABRA folder, run:
node solver/tests/test-chomp1.js
node solver/tests/test-chomp.js
Each test prints its failed clauses. Each test has deliberate breaks. A deliberate break must make the test fail.
On Windows, start heavy runs through tools\lownode.cmd.
2.2 How to use CHOMP in a ladder arm
- Open an arms file in
solver/rotom/arms/. - In the arm, set
"preview": "chomp". - Set
"preview_max_ms"to the time budget for the preview, in milliseconds. - Save the file.
ROTOM then asks CHOMP for every preview. The arm solver/rotom/arms/gen5-chomp-top.json is an example.
Caution: A ladder run uses a real rating. Only the owner (Will) starts a ladder run.
2.3 How to read what CHOMP did in a ladder run
- Run
node solver/rotom/report.js ladder <run folder>. - Read
preview_byin the summary. It shows which policy answered each preview. - Read the counters
chomp:threwandchomp:illegal. If one of them is more than 0, CHOMP failed on that preview and ROTOM used the team's own recorded bring.
2.4 How to train a new scorer
Do not replace v1 without a gate. A new scorer must pass gate (a) against v1 first. CHOMP v2 did not pass, so v1 stayed.
- Write a pre-registration before you play the first game. Use
solver/chomp/v1/prereg.jsas the model. - Make the targeted games with
solver/chomp/v1/gen.js. - Make the rows with
solver/chomp/v1/build_rows.js. - Train with
python solver/chomp/v1/train.py. It reads gate (a) one time, on the test set. - Run the label-shuffle break (
CHOMP1_BREAK=shuffle). The break must fail.
The full commands are in the ABRA report docs/_reports/2026-09-27-chomp-v1.md §6.
PART 3 — REFERENCE
3.1 Files (ABRA repository)
| File | Function |
|---|---|
solver/chomp/options.js |
The 90 options of one sheet, in a fixed order. |
solver/chomp/v1/chomp1.js |
The solver: create, solve, sample. |
solver/chomp/v1/features.js |
The engine facts for each pair of Pokémon, and the 22 cell features. |
solver/chomp/v1/scorer.js |
The cell scorer, in JavaScript. |
solver/chomp/v1/model/chomp1.json |
The trained v1 model. |
solver/chomp/v1/preregistration.json |
The gates, written before the first game. |
solver/chomp/v1/train.py |
The training script and the gate (a) read. |
solver/slowking/matrix.js |
solveLP: the exact matrix-game solve. |
solver/chomp/arms.js |
The arena arms that use CHOMP. |
solver/rotom/policy.js |
ROTOM's preview hook (previewChomp). |
solver/tests/test-chomp1.js |
The v1 tests. |
solver/chomp/chomp.js, solver/chomp/v2/ |
v0 and v2. They are not used live. |
3.2 Interface
const CH = require('./solver/chomp/v1/chomp1.js').create({ release }) // or { API }
const r = CH.solve({ mine, theirs }, { deadline, series: { oppLast } })
const op = CH.sample(r, u) // u in [0, 1)
| Input | Meaning |
|---|---|
mine, theirs |
The two sheets, as arrays of six sets. |
deadline |
Optional. A time limit for the scoring. |
series.oppLast |
Optional. Games 2 and 3 only: { brought, leads, won } for the opponent's previous game. |
| Output field | Meaning |
|---|---|
options |
The 90 options. |
mix, oppMix |
My equilibrium mix and the opponent equilibrium mix. |
value |
The value of the game for me. |
win[i] |
For option i: the win chance against their mix, against a uniform opponent, and in the worst case. |
support |
The options with weight, with labels. |
bo3 |
The best-of-three adjustment. It is null in game 1. |
counters, ms, engine, model |
The receipt. |
3.3 Settings
| Setting | Value | Where |
|---|---|---|
| Best-of-three weight λ | 0.5 | LAMBDA in solver/chomp/v1/chomp1.js (pre-registered) |
| Repeat rates of human players | read at run time | solver/out/meta/bo3.json |
| Model version | v1 | CHOMP_VERSION environment variable (v0 selects v0) |
| Preview in an arm | "preview": "chomp" |
the arms file |
3.4 Data
- The simulator: MEDICHAM, frozen release
eaa5becc54eb. - The team pool:
data/team-pool-frozen-regmc. - The format:
gen9championsvgc2026regmc, read from the Reg M-C Showdown checkout.
PART 4 — EXPLANATION
4.1 Why CHOMP gives a mix and not one answer
Both players choose at the same time. If CHOMP always gives the same answer, an opponent can learn it and beat it. The equilibrium mix has a value that the opponent cannot make lower.
4.2 Why the scorer is antisymmetric
The two players are in the same game. If I win a cell with probability p, the opponent wins the mirror cell with probability 1 − p. The model has this property by construction, so a mirror match scores exactly 1/2.
4.3 Why the solve is exact
The table has only 90 × 90 cells. A linear program solves a table of this size exactly in milliseconds, so CHOMP does not use an approximate method.
4.4 Why the gates use a frozen release
The simulator changes over time. If the simulator changes during a test, the two halves of the test measure different things. A frozen release keeps the simulator the same for the full test.
4.5 Limits
Read the white paper, §6.
PART 5 — RETIRED: THE BROWSER USERSCRIPT (REG M-B)
Status: retired in 3.0.0. Do not use it for Reg M-C. It targets Reg M-B, and its species data is old. The code stays in this repository as history.
5.1 What it was
A Tampermonkey userscript for Pokémon Showdown. At team preview it showed one recommended bring and lead, from a single-ply damage calculation. It also had a replay analyzer and a damage calculator.
5.2 Files
| File | Function |
|---|---|
app/plugin/chomp-bring4.user.js |
The userscript. It contains a copy of the engine. |
engine/champ-model.js |
The old damage and matchup engine. The FORMAT block is at the top. |
app/chomp-replay-app.html |
The replay analyzer. |
build/build_v2_userscript.py, build/build_replay_app.py |
The builders. They copy the engine into the userscript and the analyzer. |
tests/ |
The old engine tests. CI runs them. |
5.3 How to rebuild it
- Change
engine/champ-model.js. - Run
python3 build/build_v2_userscript.py. - Run
python3 build/build_replay_app.py.
Caution: If you do not rebuild, the userscript keeps the old engine.
5.4 Its validation
Read the white paper, §9, and docs/VALIDATION-REPORT.md. All of its figures are Reg M-B.
References
- The white paper:
docs/CHOMP-whitepaper.md. - ASD-STE100 Simplified Technical English, Issue 8, ASD, 2021.
- D. Procida. Diátaxis: a systematic framework for technical documentation. diataxis.fr.