← Home

Play my AI

Chess and Combat, against models I trained from scratch.

Every model on this page started from random weights and learned only by playing against itself. No human games, no chess engine, no opening book. I wrote the training code, ran it on rented GPUs, and the models now run right here in your browser.

  • 0human games or engine labels used
  • 3–4 hoursto train each chess model on one RTX 4090
  • 45k–60kself-play chess games per model
  • Top 3of 63 chess and 29 Combat models I’ve trained and rated

Chess

Pick a model under Opponent and play. Each move, the model runs 100 steps of tree search, guided by its own network, before choosing. The first move takes a few seconds while the model (38 MB) downloads. Tick Agents play each other to watch two models play.

Black
White• to move
Environment API

Plain chess, FIDE rules: castling, en passant, promotion, checkmate, stalemate, threefold repetition, fifty-move rule, insufficient material. ChessEnv.reset() and step(action) move one side per step. Actions: from·64 + to (a1 = 0 … h8 = 63) for ordinary moves and queen promotions, 72 under-promotion ids from 4096. Observation: 19 × 8 × 8 planes from the mover's view (own pieces, their pieces, colour, castling rights, en-passant file, fifty-move clock). Reward: 1 for delivering checkmate, 0 otherwise, −1 for an illegal action. Pieces: cburnett set (Colin M.L. Burnett).

Combat

A two-player shooter I designed: each fighter has 3 hit points on a random map of walls, and walls block both movement and shots. WASD to move, mouse to aim, click or hold to shoot. You can also set up to 10 fighters and let the models fight each other.

Loading Combat models…

How I trained them

Both games use the AlphaZero recipe, which I implemented myself in PyTorch:

  1. Start from nothing. A neural network with random weights. It sees the board (chess) or what its fighter senses (Combat) and outputs two things: how promising each move looks, and who is likely to win.
  2. Play against itself. Before every move it runs a tree search (100 simulations in chess, 32 in Combat) that looks ahead using the real game rules and its own network. Many games run in parallel, thousands per hour.
  3. Learn from those games. The network is trained to predict the moves its search preferred and the final result. The only reward is winning: +1 for a win, −1 for a loss, 0 for a draw. A better network makes a better search, which makes better training data.
  4. Rate them fairly. Finished models play 128-game matches against each other and against fixed baselines. All results are fitted together into one Elo rating per game.

The chess rules engine is my own code, not an outside chess library. Training ran on an automated GPU farm I built that rents GPUs within a daily budget and keeps them busy. Models are saved every hour, so the longer runs continue from the previous hour’s saved model, going back to the same random start.

Technical details
  • Chess network: 6 residual convolutional blocks × 96 channels, 9.6M parameters. Input: 19 planes of 8×8 from the mover’s view (pieces, castling rights, en passant, fifty-move clock). Output: 4,168 move ids with illegal moves masked, plus a value.
  • Chess self-play: 100-simulation PUCT search, Dirichlet noise (α 0.3, 25%) at the root, moves sampled for the first 30 plies, 512-ply limit. AdamW, batch 512, weight decay 1e-4, 300k-position replay window. Learning rate 2e-3, or 6e-4 for the “LR” models.
  • “Q50” models: the value target blends the game result with the search’s own value estimate, 50/50. This cut the final value loss from 0.136 to 0.045 at the same stage.
  • Combat network: residual MLP with LayerNorm. Input: the last 4 observations of 90 numbers each (own position and health, opponents relative to you, nearest shots, 16 wall-distance rays, line of sight). Output: 153 actions (9 moves × 17 aim choices), plus a value.
  • Combat self-play: 32-simulation decoupled search over both fighters with the exact game rules, 256-decision limit (a timeout counts as nobody winning).
  • Fast copy (Combat #1): a 1.4M-parameter student trained on 38k games played by #2. It learns #2’s search choices and value estimates. It then beat its teacher 79–41, at 60% of the size.
  • In the browser: networks are exported to ONNX and run with onnxruntime-web. The tree search is reimplemented in TypeScript and checked to give the same results as the Python version. Each model file is checked against its SHA-256 before use.

Metrics

Chess: top 3 of 63 rated models
ModelEloRated gamesSizeSelf-play gamesTraining time
#1 CHESS-AZQ50LR-A5P-9.6MLower learning rate and a blended value target; stopped early (21 of 60 minutes in its last stage).19355129.6M50,8893 h 41 min
#2 CHESS-AZQ50-A4-9.6MValue target = half game result, half search value.18351,2809.6M44,7453 h 20 min
#3 CHESS-AZLR-A5-9.6MPlain game-result target; fifth hour at a lower learning rate.17136409.6M60,1804 h 19 min

Baselines in the same chess pool: random moves 279 · untrained network 483 · search with no network 495. The #1 model beat #2 by 116 wins to 49 over two seeds (a 63% score, counting draws as half). The first hour of training was already enough to beat search-with-no-network 82–4.

Combat: top 3 of 29 rated models
ModelEloRated gamesSizeSelf-play gamesTraining time
#1 WALLS-AZQHILR-J1-2.4M-FAST-1.4MA smaller, faster copy of #2, distilled from its search. Starts from random weights; learns from #2’s games.13957681.4M38,204 (teacher)31 min + 41 min
#2 WALLS-AZQHILR-J1-2.4MOne 30-minute self-play run from scratch, higher learning rate.12761,4082.4M33,72831 min
#3 WALLS-AZQ1024-C3-13.3MLarge network (1024 wide, 6 blocks), three one-hour stages.126138413.3M116,2202 h 28 min

Baselines in the same Combat pool: untrained network 317 · search with no network 730. #2 beat #3 60–53 despite being 5× smaller and trained 5× shorter.

About these numbers. Elo here is my own rating pool, fitted to all head-to-head results among my models and baselines and anchored near 1000. It is not comparable to human chess (FIDE) ratings. “Training time” is wall-clock time on a single RTX 4090, counted back to the random start, with self-play and learning running together. Figures as of October 30, 2026.