An Atomic Theory of the Pokémon TCG

A model that sees cards as compositions of recurring elements, continuously learning and adapting in an ever-changing game.

Thesis

The Pokémon Trading Card Game is constantly changing. New cards are regularly released and the oldest are rotated out of format. The best players keep winning because they excel at adapting to the opportunities and constraints of each new format. Our approach is a system that can understand the game the same way.

Goals

We entered the competition with three goals:

  • Generality: a single model that plays any deck.
  • Scalability: performance that improves predictably with more compute.
  • Adaptability: support for new cards without major redesign or retraining.

Model

We determined that rules-based agents would not achieve our goals, as there are too many situations to enumerate across deck archetypes. This led us to deep learning. We chose a transformer to let cards, game context, and legal actions interact through attention across the entire position. Attention excels at understanding “global context,” which we hypothesized would be useful for generalization over many cards. Pokémon’s board also lacks the spatial structure that motivates convolutions in games such as Go.

Encoder

When designing our encoder, we prioritized a dense representation of the board without compressing useful information. We decompose the game state and set of legal actions into an unordered set of rows: one for each card (agent and opponent), one for each action, and a few for global attributes. The transformer reads the whole set and returns a policy score for each action row and a value score estimating win probability, which we call the “judge.”

Figure 1. One position, card by card. Card-centric: one row per card, one column per location.
Figure 2. Encoder input schema. The board becomes card and state rows; the engine supplies legal-action rows.
Figure 3. From encoded rows to policy and value. The transformer reads all rows together to score legal actions and estimate win probability. Probabilities shown are illustrative.

Card Effect Decomposition

Card rows are constructed from mechanical primitives of the game, so learning transfers across common card effects. Each holds three distinct segments:

  • Printed: 194 features derived from card text.
  • Instance: current state of the card.
  • Learned: a vector tuned per card.

Encoding cards this way means what the model learns about one card generalizes to similar ones.

Figure 4. Anatomy of a card row. Each row combines printed card-text features, live instance state and a learned identity.
Figure 5. Shared primitives across cards. Similar at a glance, different in utility: the primitives distinguish protection from card draw. Shared primitives enable knowledge transfer: Sylveon, rare in training, can reuse what the model learns from Crustle.

Actions are built the same way: each row is composed of an action type, its mechanical features, and pointers to relevant card rows. Thus, the model generalizes across the combinatorial space of actions, allowing it to reason about any action composition, even ones it was not directly trained on.

Figure 6. Different attacks, shared building blocks. Different attacks share a feature vocabulary, allowing learned relationships to transfer across moves.

Pre-Training

We trained the base model on highly-rated public ladder games using imitation learning. Each gameplay action is packaged as a “decision”: the acting agent’s board view plus the action taken. We used a desktop PC with an NVIDIA RTX 3090.

Figure 7. Pre-training pipeline. Recorded games become decision examples: the acting player’s view, action taken and game result. Imitation learning trains the base model’s policy and value; the daily games also refresh archetype decklist data.

Hyperparameters

We tested model sizes, training settings, data selection, and deck-specific training. Our submissions run a search system within Kaggle’s ten-minute limit, so we chose the following hyperparameters to balance cost and performance:

Architecture

Parameters
12,258,002
Transformer layers
5
Hidden dimension
384
Attention heads
8
Feed-forward dimension
1,536
Activation
GELU
Normalization
Pre-layer normalization
Dropout
0.1

Optimization

Optimizer
AdamW
Adam betas
0.9, 0.999
Weight decay
0.01
Peak learning rate
0.0003
Learning-rate schedule
100-step linear warmupcosine decay to zero
Gradient clipping
Global norm 1.0

Training

Effective batch size
8,192 decisions
Training steps
9,651
Training corpus
28 million decisions
Training precision
BF16 mixed precision

Loss functions

Policy loss
Weighted cross-entropycoefficient 1.0
Value loss
Binary cross-entropycoefficient 1.0
Figure 8. General pretraining configuration. Complete general pretraining configuration: model architecture, optimization, training scale and the policy and value objectives.

A Pokémon turn contains many actions and imperfect information, so choosing the right action sequence is critical. We present two search systems, designed for planning multi-action turns and adapting to new information throughout a turn.

Figure 9. Two search systems. VCGS compares policy-proposed routes at the turn boundary. BC-PUCT uses judge feedback to guide further exploration.

We developed Variance-Controlled Gate Search (VCGS) for CPU-only Kaggle containers under a ten-minute limit. It explores promising routes proposed by the policy, then has the judge compare the positions they produce at a stable boundary, typically the end of a turn. VCGS takes the following inputs:

  • B (beam width): how many policy-proposed routes we retain per root action.
  • ρ (policy mass): how much cumulative policy probability we cover when choosing root actions.
  • δ (override margin): how much better an action must score before replacing policy.
  • K: how many outcomes to sample at an “information gate,” where hidden information resolves, such as a draw.
Figure 10. VCGS route construction. VCGS keeps root actions until their policy probability reaches ρ, follows up to B routes each, samples K outcomes at information gates, and scores every route by the average value of its continuations at the turn boundary.

VCGS retains the highest-probability actions until their combined policy probability reaches ρ. For each, it follows policy-proposed continuations, keeping up to B routes, which can differ in the sequence and number of actions.

When a route reaches an information gate, VCGS samples K possible outcomes and plays each to the end of the turn, where the judge evaluates the resulting position. The route’s value is the average across those K continuations, which controls variance: a route is scored on its expected outcome, not on a single draw. VCGS then selects the route with the highest value.

Our submissions used K=4, B=2, ρ=0.90, and δ=0 for efficiency within container limitations. VCGS achieved modest performance gains over raw policy.

1.Dragapult2.Raging Bolt3.Festival Lead4.Alakazam5.Lopunny6.Rocket’s Mewtwo7.N’s Zoroark8.Cynthia’s Garchomp9.Hydrapple10.Basic Box11.Grimmsnarl12.Crustle+6+7+9.5+3.5+6.5+11.5+9+9+5.5+8+7.5+14+25+15+5+10.5+15.5+24+12+6.5+22.5+11+4+12+7+9+9+1.5+7.5+14.5+13.5+10+20.25−6+9.5+15+0.5+11.5+10+4.5+11+9+19+5+5+4+9.5+5.5+4.5+2+14+6+16.5+10+12+7.5+21+19+7+6+19.5+11.5+10.5+8+4+4+4+20+1+4.5+6+15.5+24+11+3+5+10.5+5Deck B123456789101112
Figure 11. VCGS versus raw policy. August 15 model · 200 games per matchup, with each model playing 100 per side: 100 with search, 100 without. VCGS scored above 50% in 77 of 78 deck pairs.

We developed Belief-Conditioned PUCT (BC-PUCT) for larger search budgets, offline training, and GPU-assisted evaluation. It uses policy priors, estimated values, and an exploration bonus to allocate effort among possible continuations.

Figure 12. BC-PUCT: search across sampled beliefs. Search expands sampled outcomes, batches leaf evaluations, and feeds values back to guide the next visits.

At each position, we use the Search API to fork the game into states representing different chosen actions, continuing until search reaches an information gate. There, it samples K possible outcomes by manipulating the random seed before the gate, then continues through each, with a global budget capping total branches at N. Each branch is conditioned on a single belief about how the hidden information resolved, so search below the gate proceeds deterministically.

Figure 13. Sample outcomes, then bring values back. Search each sampled hand, evaluate the leaves together, and average their values. Updated values and visits guide further exploration.

We evaluate newly reached positions in GPU batches and propagate their values back through the explored paths. Chance outcomes contribute probability-weighted averages, while decision points compare available continuations. Promising branches grow deeper until the search budget is exhausted or the visit leader cannot be overtaken, and visit counts guide the final action choice.

Figure 14. Lillie’s Determination: measured value distribution. One fixed Dragapult opening, 1,024 sampled shuffle-draws. Six prizes remain, so Lillie draws eight cards. Values are model estimates immediately after drawing, before further play.

This lets us exploit Pokémon’s inherent variance. Where random MCTS would break up action chains, playing the policy through many sampled beliefs gives a stable average value for high-variance actions such as shuffle-draw Supporters and chained draw Abilities.

Unlike VCGS, where the policy alone constructs routes for the judge to compare, BC-PUCT uses the judge’s feedback to decide what to explore next. Search improved winrate across nearly every deck pair we tested, by a median of about 9.3 percentage points.

1.Dragapult2.Raging Bolt3.Festival Lead4.Alakazam5.Lopunny6.Rocket’s Mewtwo7.N’s Zoroark8.Cynthia’s Garchomp9.Hydrapple10.Basic Box11.Grimmsnarl12.Crustle+0.5+11+11+6+9.5+14+6+12.5+5+6.5+7+15+23+10.5+7+23+12.5+17+10.5+8+19.5+17.5+12+9+11.5+10.5+8.5+8.5+4+12.5+8.5+12+6.5−1.7+9+24.5+6.5+9+8+3+6+7+18+7+13.5+5+18+7+8+6.5+23+8+16.5+11+14.5+11+10.5+13+6+3.5+16+8.5+4+13+7+6+10.5+21.5+11+0.5+2+13.5+15+8+6.5+10+6.5+14Deck B123456789101112
Figure 15. Search advantage across deck pairs. Across 78 deck pairs, search improved winrate over raw policy in nearly every matchup.

These results span a 12-deck matchup matrix, with 2000 games per matchup. The experiment used a maximum search budget of 1000 routes per decision (B1000), with an average tree depth of 6 decisions.

BC-PUCT scales significantly beyond this. We saw further improvements at B3000, B5000, and B10000 budgets, but gameplay is too slow for a 144,000 game experiment. We tested search budgets up to 100,000 on NVIDIA RTX 3090, pushing our agent to spend nearly thirty minutes thinking about each game.

Performance Optimizations

Search produces many positions that need the same neural evaluation, so we batch them into a single GPU call. We benchmarked up to 4,096 positions per batch on an NVIDIA RTX 3090, achieving up to 42.4x the throughput of CPU inference.

We also cache model outputs, avoiding 68% of requested neural evaluations over a 10,000 game sample, and retain explored branches after a move, cutting whole-game time by 11.5%. GPU evaluation is fast enough that our search is now CPU-bound.

Figure 16. Batched inference throughput. September 4 general model, best tested settings: 12,617 evaluations/second on RTX 3090 versus 298 on CPU—a 42.3× throughput gain. Batch sizes and precision differ as shown.

Self-Play

If search plays better than policy, we can use it to generate high-quality games to train our model, starting the “flywheel” of self-improvement. We present two systems for this: one that trains on searched games, and one that trains the judge directly.

Direct Gameplay Training

We generated ~10,000 searched games across a 24-deck matrix on an NVIDIA RTX 3090, repacked them into decisions, and fine-tuned our existing model.

1.Dragapult2.Raging Bolt3.Festival Lead4.Alakazam5.Lopunny6.Rocket’s Mewtwo7.N’s Zoroark8.Cynthia’s Garchomp9.Hydrapple10.Basic Box11.Grimmsnarl12.Crustle+3.6+2.3+2.6+2.7+2.1+1.0+0.5+1.9+3.3+1.6+1.8+3.7+0.2+1.4+0.3+0.9+0.7−2.3+0.2+0.9+0.1+0.1+1.9+0.5+0.1+2.3+1.6+0.7+0.8+2.9+0.8+0.8+0.7+2.3+0.4−3.1+0.8+1.6+3.3+0.1+0.6+0.1+0.2+0.1+0.4+0.3+1.7+0.3+0.1+0.6+1.4+0.4+0.4+1.3+0.2+0.0+0.7−3.5+0.0+0.4−2.1+0.7+1.1+1.2+1.2+0.3+0.2+0.7+3.0+0.5+1.3+5.50.0+0.1+0.7+0.6+0.0+0.5Deck B123456789101112
Figure 17. v22 vs v37 fine-tune, policy-only. Each cell shows the gain in percentage points for one deck pair.

Early on we patched weaknesses by pruning and suggesting specific lines, shaping what search considered without overriding evaluation. As training data accumulated, the model learned these behaviors and we removed the rules with no loss in performance.

Winrate improvements were modest, but suggest this strategy may compound over generations. We only had the resources for two fine-tunes, but plan to scale and continue the method in the coming weeks.

Winrate Approximation Training

Since our search leans heavily on the judge, we sought a more direct path to improving its accuracy. Inspired by the MCTS methods behind AlphaGo and AlphaZero, we trained the judge against measured winrates:

  1. Select many positions from policy-only self-play.
  2. From each position, fork the game 1,000 times by manipulating the random seed.
  3. Play each fork to the end using policy and save the winrate.
  4. Use the winrate as a training target for the judge at that position.

GPU batching makes this far cheaper than mining searched games. We labeled over 37.8 million positions, improving the judge’s accuracy by ~2%.

Figure 18. Judge accuracy and search performance. Judge prediction error fell from 11.87 to 9.59–9.97 percentage points (16–19% less error than BASE). B1000 gameplay showed no clear strength gain; all paired 95% confidence intervals include 50%.

We observed no clear strength gain in searched gameplay. We hypothesize this is due to insufficient scale. Even with 37.8 million positions, they originated from only 37,800 roots. That is likely not enough data to avoid overfitting, so we plan to continue experimentation.

With sufficient compute, labeling millions or billions more positions should improve judge accuracy further, and with it search quality. Whether this method is more efficient than mining search gameplay remains to be seen.

Deck

A decklist is the product of two decisions, made under uncertainty: which archetype the format rewards, and which sixty cards best express it. We made both empirically, from real-world data and controlled testing.

Kaggle Metagame

The meta kept shifting, so a general model paid off: early training data was valuable even for archetypes we did not ultimately choose, and our model reached a high level across several of them. When the field settled, we could pick from an informed position.

Share on Aug 30
  1. Dragapult32.0%
  2. Hydrapple19.0%
  3. Slowking16.9%
  4. Alakazam11.1%
  5. Crustle5.2%
  6. Lopunny5.0%
  7. Festival Lead2.6%
  8. Grimmsnarl1.0%
  9. Other7.3%
Figure 19. Archetype share over time. Archetype share across the competition period. The field shifted repeatedly before settling ahead of the deadline.
Figure 20. Ratings achieved across archetypes. Each dot is a scored upload, colored by archetype; rings mark selected submissions. Peak ratings: Alakazam 901.7, Grimmsnarl 1,023.0, Dragapult 1,040.2. Historical peaks through August 16, from different checkpoints—not a controlled same-model comparison.

Dragapult

Most archetypes have a linear strategy: each turn, attack with the best option available. Dragapult instead spends turns setting up, disrupting the opponent, and spreading damage. We chose Dragapult because its demands match what our system does well:

  • Information gate sampling: Drakloak’s Ability, the main draw engine, reveals cards and asks which to keep; our search samples at the gate and evaluates each choice at the turn boundary.
  • Multi-action planning: three energy types, flexible damage placement, and an arsenal of varied attacks create many interacting choices and competing lines each turn; our search plans and sequences them together.
  • Turn-level evaluation: a setup turn’s value is in the threats it builds for later turns; our judge scores the full position, which is where that value lives.
Figure 21. Why Dragapult suits this system. Sample reveals, plan turns, and evaluate positions. Green boxes show estimated win probability.

Decklist Construction

We built a library of archetype decklists from ladder and over-the-board data, giving us the share of lists in each archetype that play a given card. This informs our own builds and feeds search, where our model can roll out the opponent’s turn from a predicted list.

Darkness Energy100%
Psychic Energy100%
Fire Energy100%
Boss’s Orders100%
Buddy-Buddy Poffin100%
Budew100%
Crispin100%
Dragapult ex100%
Drakloak100%
Dreepy100%
Fezandipiti ex100%
Lillie’s Determination100%
Meowth ex100%
Munkidori100%
Night Stretcher100%
Poké Pad100%
Ultra Ball100%
Unfair Stamp100%
Judge99.6%
Crushing Hammer99.4%
Jamming Tower77.7%
Dawn71.7%
Team Rocket’s Watchtower16.9%
Risky Ruins15.0%
Dudunsparce12.4%
Team Rocket’s Venture Bomb9.2%
Dunsparce (JTG)6.7%
Xerosic’s Machinations5.9%
Dunsparce (TEF)5.7%
Chi-Yu5.6%
Figure 22. Dragapult decklist statistics. Weighted card inclusion across 17 Dragapult ladder lists. Blue marks cards included in at least 95% of lists; gold marks less common choices.

Dragapult’s “skeleton,” the cards appearing in 95% or more of lists, already fixed 54 of 60 slots. We built two lists from there: Control, which maximized consistency, and Meta-predict, which anticipated what the field would bring.

Figure 23. Two builds from one skeleton. The skeleton fixed 54 of 60 slots. Control filled the remaining six for consistency, Meta-predict for the field we expected.

Control played Dudunsparce, one of the most common cards in our training data, for draw consistency. Meta-predict played Chi-Yu, which knocks out Crustle in one hit, a difficult matchup we expected to resurge as Dragapult became popular. It also played Watchtower, which disrupted archetypes relying on Dudunsparce and Mega Kangaskhan ex, both common in the top meta. Holding the pilot and seeds constant with seats swapped, we tested variations of both builds to isolate the contribution of specific cards and card combinations.

Figure 24. Different metas reward different Dragapult builds. Matched meta, pilot and seeds. Basic: highest-played cards. Jamming swap: Meta-predict with the more common Jamming Tower replacing Watchtower, our hypothesized high-value choice.

Results

We won 57.4% of 1,999 games and peaked at a rating of 1124, inside the top twenty. Meta-predict outperformed Control against Crustle and archetypes utilizing Dudunsparce, consistent with its Chi-Yu and Watchtower card choices.

Dragapult13.6%
Lopunny11.8%
Alakazam10.7%
Hydrapple9.1%
CrustleMeta-predict +20.5 pp6.4%
Grimmsnarl5.7%
Festival LeadControl +21.7 pp4.4%
Slowking3.4%
Figure 25. Matchup share and winrate. Share of 1,999 games and winrate by opponent. Matchups shown have at least 30 games per build. Lines show 95% confidence intervals.

We built an internal ladder to measure progress, pairing model versions, search configurations, and decks against a field resembling the real Kaggle metagame.

1Sep 4 readerDragapult JudgeBC-PUCT 3,0001165.3
2Sep 4 readerDragapult JudgeBC-PUCT 2,0001138.9
3Sep 4 readerDragapult JudgeBC-PUCT 5,0001137.2
4Sep 3 readerDragapult JudgePolicy1133.6
5Sep 2 generalDragapult HammersPolicy1126.8
6Sep 4 readerDragapult JudgeBC-PUCT 1,0001104.2
7Sep 4 readerDragapult JudgeBC-PUCT 10,0001103.5
8Aug 14 Pult2x · 23MGrimmsnarl FroslassPolicy1092.8
9Aug 25 faithful refresh · 23MDragapult JudgePolicy1091.0
10Aug 15 hyperrecent · 12MGrimmsnarl FroslassPolicy1067.7
11Aug 23 faithful refresh · 12MDragapult JudgePolicy1055.3
12Aug 14 elite900r · 23MGrimmsnarl FroslassPolicy1055.1
13Sep 2 generalDragapult JudgePolicy1050.2
14Aug 25 faithful refresh · 23MMega LopunnyPolicy1044.9
15Sep 4 readerDragapult JudgePolicy1043.7
16Sep 4 readerDragapult HammersPolicy1043.0
17MWO Risky RuinsDragapult Risky RuinsVCGS1040.5
18Aug 14 general · 64MGrimmsnarl FroslassPolicy1040.4
19Sep 2 generalCrustlePolicy1040.1
20Aug 25 faithful refresh · 23MGrimmsnarl FroslassPolicy1035.0
21Aug 14 general · 40MDragapult JudgePolicy1033.6
22Aug 15 elite900r seed 2 · 23MGrimmsnarl FroslassPolicy1033.0
23Aug 14 hyperrecent · 23MGrimmsnarl FroslassPolicy1031.4
24Aug 14 wide · 66MCrustlePolicy1027.4
25Aug 14 deep · 65MGrimmsnarl FroslassPolicy1027.3
26MWO WatchtowerDragapult WatchtowerVCGS1027.0
Figure 26. Internal ladder. Normalized internal ladder scores for 26 model, deck and play-style combinations. The supplied leader scores 1165.3; MWO Risky Ruins and MWO Watchtower score 1040.5 and 1027.0. Shaded rows mark the two MWO submissions.

We ranked the ladder with OpenSkill, normalized to our final Kaggle score. Our top internal ladder player is currently rated about 1165, peaking at 1221. We expect further gains with more self-play and higher search budgets.

Like the Kaggle leaderboard, our internal ladder exhibits cyclical and inconsistent behavior based on player luck. This makes any specific “snapshot” of the leaderboard unreliable, but still sufficiently shows that our top models are much stronger than our Kaggle submission.

Figure 27. Rating trajectory. The submitted model’s author-reported peak was 1124. The current model wins 63.5% of seat-swapped games against it, projecting to a rating of roughly 1221.

Outlook

The Pokémon Trading Card Game is constantly evolving, and we believe the best models, like the best players, carry knowledge from format to format. We have seen early signs of this: tested on archetypes from past and future formats, our model competently played cards it had never seen.

Figure 28. Effects recur across formats. Shared effects let learned decisions transfer to unseen cards.

We now have the systems in place to build on this atomic theory of the game: a model that adapts, predicts, and innovates over and over again.