Shallow Red plays ordinary chess. It cannot make illegal moves, resign, deliberately time out, or exploit the interface.
It simply wants the wrong thing.
Its favorite outcome is being checkmated. If several lines lead to that result, it prefers the fastest one. A draw is better than accidentally winning, and checkmating its opponent is the worst possible outcome.
That sounds like a straightforward reversal of normal chess. Train an engine to choose bad moves, expose its king, and give away its pieces. How difficult could it be?
Not very, as it turned out.
The difficult part was convincing the other player to finish the job.
01
Losing, precisely defined
Shallow Red's preferences are ordered:
- Get checkmated.
- Among reliable ways to get checkmated, prefer the fastest.
- Prefer a draw or unresolved game over a win.
- Avoid checkmating the opponent whenever possible.
Reliability comes before speed. An engine that loses 95% of its games slowly is better than one that loses 85% quickly and draws the rest.
This is related to selfmate chess, but the terminology needs a qualification. In a classical selfmate problem, one side must force an unwilling opponent to deliver checkmate. I sometimes use “selfmate” more casually whenever Shallow Red succeeds in getting checkmated. Some of my searches do satisfy the strict definition by checking every possible response, but the entire engine is not a general selfmate solver.
Before training anything, I built a deterministic test system around python-chess. Think of it as both referee and lab notebook: it rejects illegal moves, records every game and board position, makes the engines replay the same openings with colors swapped, and distinguishes real draws from games that simply ran past my testing limit.
That infrastructure mattered. When winning and losing have exchanged meanings, ordinary evaluation assumptions become surprisingly easy to get wrong.
02
The opponent that made losing easy
My first two engines were deliberately simple.
- Random baseline: I selected any legal move at random.
- Hand-written baseline: I followed simple rules: give away valuable pieces, expose the king, and avoid defending.
Against Stockfish, both were checkmated in all 200 test games. Random play lasted about 34 plies on average; a ply is one player's move, so that is about 17 moves per side. The hand-written strategy reduced the average to about 30 plies.
At first, this looked like remarkable success.
It was actually my first misleading result.
Stockfish is an unusually cooperative opponent when Shallow Red's goal is to lose. It wants to attack. It accepts hanging pieces, opens lines toward the king, and finds checkmates. Shallow Red and Stockfish disagree about which side is benefiting, but they agree about what should happen on the board.
Getting checkmated by a strong conventional engine was not the hard problem.
03
Reversing Stockfish
The first neural version of Shallow Red learned from Stockfish evaluations—but backward.
I generated legal positions and asked Stockfish to evaluate every legal move. A conventional project might use those answers to teach a model to imitate Stockfish's favorite move. I did the opposite: I trained Shallow Red to prefer the moves Stockfish considered worst for the player making them.
In machine-learning terms, the model is a policy: given a board, it ranks the moves Shallow Red could make. It does not understand a written instruction such as “lose the game.” It learns statistical patterns connecting board positions with moves that a conventional engine strongly dislikes.
Under the hood, the first model looked like this:
- Input: 21 perspective-normalized 8 × 8 planes.
- Output: an AlphaZero-style policy space of 4,672 possible chess actions, with illegal actions masked out.
- Network: a small residual convolutional model.
- Training: supervised learning from Stockfish-provided examples—not reinforcement learning or self-play.
The result was already much better at losing to Stockfish:
- The learned policy was usually checkmated in about 24 plies.
- Asking Stockfish to perform the reverse analysis live reduced that to about 18 plies.
- Both lost substantially faster than random play.
But choosing one “best bad move” discarded a great deal of information. A position might contain several useful sacrifices, several harmless moves, and one catastrophic move that accidentally checkmates the opponent. Treating all but the top choice as equally wrong was too crude.
For v0.2, I ranked every legal move from most to least desirable for losing. This let the network learn that several moves could be useful, in different degrees, rather than treating one move as correct and everything else as wrong. More technically, it learned a soft probability distribution over the complete ranking. When the engine played, the policy proposed a shortlist and a reverse evaluator examined those candidates more carefully.
Against Stockfish, this worked almost absurdly well: essentially 100% losses, often within 16–18 plies.
Against a uniformly random opponent, it lost only about 70% of games with search. The raw neural policy was much worse.
That result changed the direction of the project.
04
Random players are difficult opponents
A random opponent does not understand what Shallow Red wants.
It may decline free pieces, ignore an exposed king, miss a mating attack, or wander into stalemate. A move that is terrible against Stockfish can be ineffective against an opponent that does not recognize why it is terrible.
For v0.3, I trained and engineered specifically for weak and unpredictable opposition. The main changes were:
- I added positions generated against random replies, weak versions of Stockfish, and opponents driven by simple hand-written rules.
- The evaluator tried every legal reply the random player could make next instead of relying on a small sample.
- A low-material rule helped the engine avoid giving away so much that the game ended in stalemate rather than checkmate.
- I corrected how Black's actions aligned with the perspective-normalized board representation.
- At inference time, the neural policy proposed its twelve highest-ranked legal moves, and a deterministic evaluator inspected every legal immediate reply to each candidate.
The selected v0.3 checkpoint—the saved, trained version of the model—has only 115,634 parameters: 32 channels, four residual blocks, and a file size under half a megabyte.
On a fresh 200-game random-opponent test, v0.3 was checkmated in 94% of games by 600 plies. It recorded no wins. Against Stockfish, it continued to lose almost automatically.
That became my stable research checkpoint.
It also established the first major lesson of the project:
A good losing move is not intrinsically bad. It is bad relative to the opponent who must respond to it.
05
The browser engine is not the full incompetence of Shallow Red
The full engine and the web engine I put online are two related systems. The website favors speed and accessibility. The full version explores what is possible with substantially more computation. I'm broke, so I don't wanna pay for enough compute to let everyone play against the full version online. The full system depended on Python, PyTorch, and relatively expensive search. Running it for every visitor to the website would have been impractical.
I therefore built a smaller TypeScript engine for the browser. It preserves the central behavior—legal moves, sacrifices, king exposure, stalemate awareness, and mate avoidance—but uses much cheaper inference and search.
I evaluated the TypeScript engine in a frozen 300-game random-opponent suite:
- Shallow Red was checkmated 254 times.
- 44 draws.
- Two unresolved games.
- Zero Shallow Red wins.
The web engine is good at losing, but measurably weaker than full v0.3.
Everything on the public website runs locally in the browser. The model, legal-move generation, inference, reply enumeration, and tactical scoring do not require a permanent chess server or GPU.
06
What if the opponent also wants to lose?
The project became much stranger when I tested opponents with the same objective as Shallow Red.
When both sides want to be checkmated, neither side wants to perform the checkmate. They compete to sacrifice material, decline each other's pieces, avoid mating attacks, repeat positions, and push the game into long deadlocks.
I built a population of synthetic losing opponents with different behaviors:
- Some exposed their kings.
- Some avoided capturing Shallow Red's pieces.
- Some predicted and exploited Shallow Red's policy.
- Others switched between strategies or used deliberately weakened versions of v0.3.
A few games produced genuine Shallow Red losses, but the signal was sparse. Most continued for hundreds of plies without either engine accepting the role of winner.
Locally terrible chess was no longer enough. Shallow Red needed a plan.
07
Several reasonable ideas failed
I explored exact selfmate proofs, endgame solving, fine-tuning, reinforcement learning, and policy distillation. Each worked in a limited sense. None replaced v0.3.
The pattern was remarkably consistent: an experiment would solve the narrow problem I gave it, then lose that advantage when returned to ordinary games.
- Exact selfmate proofs and endgame solving: I imported composed selfmates, independently verified them, searched backward for earlier positions, and built a runtime book that rechecked proofs against the actual game history. The system was perfect once a game reached a covered position, but ordinary games almost never did.
- Fine-tuning on proven positions: the models memorized known families but failed to generalize reliably to unseen ones, so I rejected them.
- Reinforcement learning: a two-sided PPO system rewarded being checkmated, penalized delivering checkmate, favored faster losses, and used a frozen copy of v0.3 to limit drift. After 1,024 self-play games and roughly 172,000 policy positions, it made completed checkmates shorter—but completed fewer of them. It also regressed against random opponents, losing 73 matched games where v0.3 lost 79. Later asymmetric PPO experiments failed their promotion tests as well.
- Policy distillation and DAgger: I trained a fast neural network on the slower planner's successful decisions, then let the student ask the planner for corrections. Neither approach preserved the planner's advantage on fresh games.
The important decisions depended on opponent history and future coordination. A local position-to-move label did not contain enough information.
These were not wasted experiments. Together, they pointed toward the same conclusion: the missing capability was not a better instinct for individual bad moves. It was strategic steering.
08
The breakthrough: plan around the opponent
The next version added an online hierarchical planner above v0.3.
The basic change was to stop asking only, “What is the worst move I can make right now?” Instead, Shallow Red began asking, “Given how this opponent has been playing, what sequence of moves might persuade it to checkmate me later?”
The planner watches the opponent's replies and looks for repeated evidence that its behavior matches one of the opponent types I have modeled. Only then does the planner activate. It searches sequences of future Shallow Red turns, keeps a small number of the most promising possibilities—a technique called beam search—and bundles several turns into a plan it can reuse instead of starting over after every move.
If the opponent stops behaving as predicted, the planner abandons the plan and falls back to ordinary v0.3.
- 01Neural intuition
- 02Opponent identification
- 03Long-horizon planning
- 04Safety checks
- 05Legal move
This was dramatically more effective against controlled, weakened versions of v0.3. These opponents all used the same trained model, but I deliberately made their move selection less capable in measured ways. In one previously unseen 100-game test, baseline v0.3 was checkmated six times. The guarded planner was checkmated 54 times.
Against an ordinary random opponent, the guard never activated. Every game remained move-for-move identical to v0.3.
That was the first strong evidence that explicit long-horizon planning—not another round of weight updates—was the right direction.
09
Inferring what I wasn’t told about the opponent
The strongest version of the planner does not receive the opponent's exact configuration.
It has to infer that configuration by watching the game. This is a little like estimating a player's skill from their choices, except that I constructed my test opponents in a precisely measurable way.
Technically, the planner models the opponent as v0.3 with an unknown corruption rate: the probability that v0.3's preferred move will be replaced by another legal move according to a deterministic rule. After observing each response, Shallow Red narrows the interval of corruption rates that could have produced it.
It then considers every distinct opponent response that could arise anywhere within that interval and chooses a move that survives the least favorable plausible version. The planner does not need to guess one exact setting and hope it is right.
In other words, it tries to infer both the opponent's family and its strength from behavior.
The planner searches twelve future Shallow Red turns using a small beam. Across corrupted opponents, it converted many baseline deadlocks into actual Shallow Red losses while leaving ordinary random games unchanged.
The first sealed candidate, however, won one game.
After a cached plan ended, it reached a position where every legal Shallow Red move checkmated the opponent. Its immediate mate-avoidance rule could see that every available move was bad, but the mistake had already happened on the previous turn.
Despite its much higher loss rate, that candidate was rejected.
10
The two-ply win shield
I added a final safety layer that checks every proposed move, whether it came from a cached plan or from ordinary v0.3.
For each candidate, the shield asks:
- Does this move checkmate the opponent immediately?
- Can the opponent reply in a way that leaves Shallow Red with nothing but moves that checkmate its opponent on the following turn?
This second question matters because the dangerous move may look harmless now while making an accidental victory unavoidable one turn later.
If a safe alternative exists, the shield vetoes the dangerous move. It prefers the normal v0.3 choice when that choice is safe; otherwise, it selects the strongest safe move that still pushes toward Shallow Red's own checkmate.
In a fresh 500-game candidate suite:
- Baseline v0.3 was checkmated in 6 of 400 games against corrupted opponents.
- The shielded planner was checkmated in 148.
- The new candidate won zero games.
- Across 100 ordinary-random games, it remained move-for-move identical to v0.3.
This is the current research candidate, informally called v0.4.
Despite the name, v0.4 is not a newly trained neural network. Its neural foundation is still v0.3. The improvement comes from the machinery built around it: opponent inference, hierarchical planning, cached strategies, and the win shield.
11
v0.4 versus v0.3
My latest comparison used 192 fresh opening positions. The engines played each opening twice, swapping colors, for a total of 384 games.
Under the website's current terminal rules, where repetition and orthodox move-count thresholds do not automatically end play:
- v0.4's successful losses took a median of 87.5 plies.
- The win shield changed 28 decisions across 17 games.
By the project's objective, v0.4 beat v0.3 by 38–0.
That headline needs context. Nearly 90% of the games were still going after 200 plies, with neither engine willing to help the other one lose. Shallow Red has become substantially better at inducing another losing engine to checkmate it, but general adversarial selfmate chess is nowhere near solved.
12
What Shallow Red actually learned
The current research engine has three layers:
- Neural intuition: v0.3 proposes moves that are naturally bad at ordinary chess.
- Strategic steering: v0.4 watches how the opponent behaves and coordinates plans across many turns.
- Safety: exact proofs and the win shield prevent known forms of accidental victory.
The neural network learned how to expose a king, surrender material, and create tactical opportunities for the opponent.
The planner learned something more subtle: those opportunities matter only if the opponent is likely to accept them. Against a player with a conflicting objective, Shallow Red must model behavior, conceal or reveal its intentions at the right time, and coordinate actions across many turns.
I have strong empirical evidence that the current engine is extremely reluctant to win. I do not have a mathematical guarantee that it never will.
The next practical challenge is bringing more of the full engine to the public game. That may mean finding a better way to distill its planning, or serving the full engine remotely with a limited amount of computation per game.
The scientific problem is even less settled.
I began by asking how to make a chess engine play badly. The more interesting question turned out to be how one agent can persuade another agent—with its own objective, habits, and model of the game—to produce the outcome it wants.
In Shallow Red's case, that outcome just happens to be its own checkmate.
Teaching a chess engine to lose was the easy part.
Teaching it how to make someone else win was harder.