Juggernaut 2.0 Released
Fifteen months ago I released Juggernaut 1.0 with a deliberately modest brief: build a rock-solid Delphi chess engine that could survive ultra-fast games without crashing, losing on time, or misbehaving under the UCI protocol. The search was plain alpha-beta with a quiescence search bolted on, the evaluation was nothing more than piece-square tables, and the estimated strength was around 2100 Elo on the CCRL scale.
Today I’m releasing Juggernaut 2.0. The evaluation is still just piece-square tables. Everything else has changed.
The plan for 2.0, as I sketched it in the original announcement, was to add the conventional search enhancements that every serious engine relies on. That has happened, one technique at a time, across fifty-odd intermediate versions. Each change was tested in self-play before it was kept, and each one is recorded in the development log with its measured Elo gain. Add up the log and the total comes to more than 800 Elo in self-play. Self-play gains are notoriously inflated, so don’t expect every point of that to show up on the rating lists, but the engine that emerges is a very different beast from the one I released in June 2025.
There is also one genuinely new development on the download side. Juggernaut 2.0 ships as two builds: the familiar Windows x64 executable, and a native Windows ARM64 build. More on that below.
The Ten Biggest Changes Since 1.0
Here are the changes that mattered most, roughly in the order they earned their place in the engine.
1. Null move pruning. The single largest gain in Juggernaut’s history, worth around 150 Elo on its own when it arrived in version 1.10. The idea is old and simple: if I can pass my turn and still hold a position, the position is probably good enough to stop looking. Juggernaut uses a reduction of three plies, never plays two null moves in a row, and runs a verification search at depth eight and above to catch zugzwang. A later refinement, deepening the null-move search when the static evaluation sits below beta, added another 46 Elo in version 1.43.
2. Late move reductions. Moves that sort to the back of the list rarely turn out to be best, so Juggernaut searches them to a reduced depth and only re-searches at full depth if they surprise. This came in three stages: a basic implementation, a round of tuning, and then, unusually, applying reductions in PV nodes too, which alone was worth 41 Elo. The reduction tables are separate for PV, cut and all nodes, and the reduction amount is now adjusted by the move’s history score.
3. Late move pruning. The natural next step after reducing late moves is to stop searching them altogether at shallow depth. Late move pruning arrived in version 1.50 and turned out to be the second-largest single gain in the whole project at 51 Elo. It is a reminder that in a well-ordered search, the moves at the end of the list are almost pure noise.
4. Reverse futility pruning, futility pruning and razoring. Three related ideas that use the static evaluation to skip work near the leaves. Reverse futility pruning fails high when the position is already comfortably above beta at shallow depth. Futility pruning skips quiet moves that cannot plausibly raise a hopeless position back to alpha. Razoring drops straight into quiescence search when the position is far below alpha. Together they contributed roughly 75 Elo, and the 2.1x releases have continued to squeeze reverse futility pruning by giving it different margins depending on whether the evaluation is improving.
5. Singular extensions and multi-cut. When the hash move is so much better than every alternative that no other move comes close, it deserves an extra ply of search, because the whole line hinges on it. Singular extensions were worth 34 Elo in version 1.41. The same singular search also gives a cheap multi-cut test, and a related change re-searches at reduced depth when a null move reveals a mate threat. A recapture extension rounds out the extension family.
6. A complete move-ordering overhaul. Version 1.0 ordered captures by MVV/LVA and quiet moves by a plain history table. Juggernaut 2.0 has a staged move generator that produces the hash move, then captures filtered by static exchange evaluation, then two killer moves, then the counter-move, then quiet moves scored by a butterfly history table with symmetric bonuses and penalties and a one-ply continuation history, and finally the losing captures. Each of these stages was a separate tested step, and between them they account for well over 100 Elo.
7. A sharper quiescence search. The quiescence search now includes quiet checking moves as well as captures, filters captures by static exchange evaluation so it doesn’t waste time on losing exchanges, and applies mate-distance pruning. The check extension in the main search was also refined so that only checks that don’t lose material are extended. Checking moves in quiescence alone were worth 15 Elo, and the SEE-gated check extension 39.
8. Transposition-table refinements. The transposition table saw several rounds of work: a Fruit-style dual-bound experiment that was later reverted, a re-search when the hash move unexpectedly fails low, careful handling of draw scores stored in the table, and internal iterative reductions when no hash move is available. The lockless design that lets multiple threads share one table is unchanged.
9. Time management that can survive anything. Version 1.0’s brief was to play ultra-fast games without losing on time. Version 2.0 takes that seriously. The time allocation is now re-evaluated after every iteration, which was worth 33 Elo by itself, and the search threads are now woken by an event rather than by polling. That last change sounds like a detail, but it removed about 14 milliseconds of latency from every move, and at a time control of 0.2 seconds plus 0.002 it was the difference between flagging in every game and flagging in none.
10. Raw speed, and a native ARM build. Two changes made the engine faster without changing what it searches. Sliding-piece move generation now uses the PEXT instruction on processors that support it, and a rewrite of the bit-scanning primitives, which had been tripping over a slow instruction pattern, gave a 42 Elo gain purely from speed in version 1.58. Then the biggest speed win of all: Juggernaut now compiles natively for Windows on ARM. On an ARM machine the native build runs 84% faster than the x64 build running under emulation, which makes it the fastest Juggernaut there is.
Bug Fixes and Robustness
The other half of the work since 1.0 has been less glamorous. A tournament-preparation pass in version 1.54 found an operator-precedence bug in queen move generation that had been silently leaving rook attacks unmasked, a hash-size calculation that overflowed on machines with more than 4 GB of memory, and a handful of loop counters that could wrap around on long move lists. Version 1.56 fixed a buffer overflow in games longer than 600 moves. Version 2.01 taught the Polyglot book reader to translate castling moves into standard UCI notation. Version 2.10 fixed an off-by-one in repetition detection and seeded the draw stack with the starting position, so repetitions involving the root are now caught.
Juggernaut still supports everything it did in 1.0: multi-threaded search, MultiPV, pondering, Chess960, Polyglot opening books with adjustable randomness, and a full UCI implementation. It also gains a bench command for deterministic performance measurement, which has proved invaluable for checking that a speed change is real.
What’s Next
The most obvious gap is endgame knowledge, and Syzygy tablebase support is the next item on the list. After that, the roadmap I sketched in the 1.0 announcement still stands.
Downloads
Juggernaut 2.0 is available in two builds. Each zip contains the executable and the Polyglot opening book.
- Windows x64 (Intel and AMD): Juggernaut-2.00.zip. Requires a 64-bit processor with the BMI2 instruction set (Intel Haswell or later, AMD Zen 3 or later for full speed).
- Windows ARM64 (Snapdragon and other ARM processors): Juggernaut-2.00-ARM.zip. This is the fastest build of Juggernaut. If you have a Windows-on-ARM machine, use this one rather than running the x64 build under emulation.
Estimated strength: 2750 Elo on the CCRL scale.
As always, bug reports and testing results are very welcome.





