Rarog is a UCI-compatible chess engine written in Rust. The engine is intended for use from a chess GUI or engine-testing tool that speaks the UCI protocol.
Rarog was released as Lynx through version 1.4.3. The project was renamed
starting with version 2.0.0 to avoid confusion with an existing chess engine.
- Custom bitboard board representation with incremental make/unmake
- Legal move generation for all standard chess rules, including castling, en passant, promotions, repetition, the fifty-move rule, and insufficient material detection
- Strict FEN validation with canonical en passant hashing so positions without a legal en passant capture share the same transposition key
- Zobrist hashing, transposition table, and pawn evaluation cache
- Iterative deepening negamax/PVS search with aspiration windows
- Configurable Lazy SMP-style parallel search with persistent workers, shared
stop/node/accounting state, weighted helper result selection, and a full-key
validated shared transposition table through the UCI
Threadsoption - Capture-focused quiescence search with delta pruning, capture futility, threshold SEE pruning, and bounded check evasions
- Null-move pruning with verification, ProbCut, singular extensions, futility pruning, late move pruning, and late move reductions
- Staged move picking with a validated TT move first, good captures before lazy quiet generation, and bad captures delayed until after quiet moves
- Move ordering using TT moves, threshold SEE, killers, countermoves, main history, eight-ply low-ply history, pawn history, capture history, continuation history, and a direct-check bonus for quiet checking moves
- Direct legal validation for raw UCI and TT-shaped moves, including canonicalized captures, castling, en passant, and promotions
- Multi-table and continuation correction history
- Tapered, Texel-tuned evaluation fit to a self-play dataset: material and piece-square tables, a non-linear king-danger model, threat and per-count mobility tables, pawn-structure and passed-pawn terms, material imbalance, exact KPK and scale-factor endgame knowledge, a whole-position eval cache, a lazy-eval fast path, and fifty-move-rule dampening
- Soft/hard time allocation with
movestogo, increment, and move-overhead handling - Optional Syzygy tablebase probing through the UCI
SyzygyPath,SyzygyProbeDepth,SyzygyProbeLimit, andSyzygy50MoveRuleoptions, with root DTZ ranking, WDL fallback, load summaries, andtbhitsreporting - Built-in
benchUCI command for repeatable search benchmarks
Supported commands include:
uciisreadyucinewgameposition startpos [moves ...]position fen <fen> [moves ...]gowithdepth,nodes,movetime,wtime,btime,winc,binc,movestogo,mate,searchmoves,ponder,perft, andinfinitestopponderhitquitbench [depth]
Supported options:
Hashdefault64Clear HashPonderdefaultfalseMove Overheaddefault10Threadsdefault1, min1, max1024SyzygyPathdefault emptySyzygyProbeDepthdefault1, min1, max100SyzygyProbeLimitdefault7, min0, max7Syzygy50MoveRuledefaulttrue
SyzygyPath may contain one or more Syzygy directories separated by the
platform path separator (; on Windows, : on Unix-like systems). When the
path is empty, tablebase probing is disabled. Rarog uses WDL probes inside the
search and DTZ-ranked root probing when DTZ tables are available. If root DTZ
probing is unavailable but WDL tables are present, Rarog falls back to WDL root
move filtering. Search info includes tbhits when tablebase probes are used.
Set SyzygyProbeLimit to 0 to disable probing without changing the path.
Run the built-in benchmark from a UCI session:
bench
bench 13
The bench command searches a fixed suite of positions and reports a repeatable search fingerprint and speed data. It is useful for comparing local changes, compiler settings, and machine performance.
The benchmark uses the current UCI options, including Threads, so a threaded
search benchmark can be run with:
setoption name Threads value 8
bench
Run the board implementation benchmark with:
cargo bench --bench boardThis benchmark measures legal move generation, direct legal move validation, capture generation, make/unmake, check detection, SEE over captures, game-simulation-style move generation, and start-position perft depth 4.
Install Rust and Cargo, then build an optimized release binary:
cargo build --releaseThe executable is created at:
target/release/rarogtarget/release/rarog.exeon Windows
Release builds use LTO and a single codegen unit for engine speed.
Local release builds also use target-cpu=native, so cargo build --release
optimizes Rarog for the CPU on the build machine.
Portable release-asset builds can be produced with the cross-platform xtask
helper:
cargo xtask build
cargo xtask build --arch avx2
cargo xtask build --arch pext
cargo xtask build --arch arm64cargo xtask build defaults to the compatible x86-64 asset on x86-64 hosts and
to the ARM64 asset on ARM64 hosts. The helper writes renamed binaries to
target/dist.
Profile-guided optimization can be enabled for a native target:
cargo xtask build --arch pext --pgoPGO builds first create an instrumented engine, train it with the built-in
bench command, merge the generated LLVM profile, and rebuild the optimized
binary. PGO assets add -pgo before the executable suffix, so they do not
overwrite non-PGO builds. Use --bench-depth <n> to adjust the training
workload. The helper installs the Rust target with rustup target add when
rustup is available. For PGO it also looks for llvm-profdata and attempts
rustup component add llvm-tools-preview if the tool is missing.
For quick local testing:
cargo run --releaseRun the release test suite:
cargo test --releaseThe suite covers:
- FEN parsing and round-tripping
- Strict FEN legality checks, castling-right validation, and en passant canonicalization
- Legal move generation and special moves
- Direct legal move validation for raw UCI/TT-shaped moves
- Perft reference positions
- Hashing and make/unmake correctness
- Incremental pawn, minor-piece, and non-pawn structure keys
- Draw and terminal-result handling
- Insufficient-material draw handling at search root and interior nodes
- Legal
bestmovereporting from root draw positions where legal moves still exist - Quiescence maximum-ply protection and regression coverage for tournament-derived illegal-move artifacts that were caused by a search panic
- Search limits, invalid limit parsing, and stop/quit behavior
- UCI
go searchmovesroot filtering andgo matedepth conversion - Time-management behavior for fast clocks,
movetime, side-to-move clocks, explicitmovestogo, and unbounded fixed-depth searches - Single-thread determinism and thread-count reconfiguration
- Threaded search node-limit, stop, quit, UCI info accounting, and ponderhit behavior
- Threshold SEE behavior for captures and promotions
- Staged move-picker ordering for bad captures after quiet moves
- Direct-check quiet move-ordering bonus
- Eight-ply low-ply history scoring and update boundaries
- Syzygy option parsing, result decoding, root move conversion, root tablebase probing, tablebase path counting, and disabled-path probe behavior
- UCI command ordering, priority quit/stop handling, and stale-search cancellation
- UCI ponder and infinite-search
bestmoverelease timing - UCI PV replay legality for tournament-derived TT/hash-move regression positions at one and eight search threads
- FEN compatibility for tournament managers that emit non-standard fullmove
0 - Quiet/capture move-generation partitioning
- Evaluation and transposition table behavior
- Current-generation
hashfullaccounting for local and shared transposition tables - Fifty-move-rule evaluation dampening
- Rule-50-aware transposition-table mate score recovery
- TT-first move-picker behavior and TT-derived ponder fallback
- UCI command handling and invalid
setoptionpreservation
- Build or download a Rarog executable.
- Add it as a UCI engine in your chess GUI.
- Configure
HashandMove Overheadas needed. - Start an engine game or analysis session.
Tested GUI families include Arena, ChessBase/Fritz, ChessOK Aquarium, and Hiarcs Chess Explorer. Other UCI-compatible GUIs should also work.
Current documented release: 2.1.0.
2.1.0 is a Phase 1 search-tuning release. It keeps the safe hot-path cleanup
from the codex-work baseline, adds repo-local fastchess/weather-factory tooling,
and bakes in the SPRT-confirmed pruning/margin SPSA tune. The accepted tune
changed futility, razoring, null-move, LMP, SEE, aspiration, and singular-beta
defaults and passed self-play with nElo +6.17 ± 4.88 after 19,458 games.
The tuned bench 13 search fingerprint is 5,318,762 nodes.
The LMR weighted-term SPSA candidate was tested separately and rejected as
inconclusive after large confirmation runs, so LMR values remain
default-equivalent while the UCI-tunable infrastructure stays available behind
--features tune.
2.0.2 is a tournament-stability patch. It fixes a rare quiescence-search
panic where a deep tactical/check sequence could reach the final fixed
search-stack slot and crash before reporting bestmove; some GUIs reported
that crash as an illegal-move artifact. The release also adds direct regression
coverage for the maximum-ply guard and for the two Little Blitzer artifact
positions.
2.0.1 is a patch release delivering search improvements for higher playing
strength. Changes include IIR for PV nodes, negative history updates for good
captures searched before a beta cutoff, correction history updates for Lower and
Upper bound nodes, and a unified capture history bonus formula.
2.0.0 renames the project from Lynx to Rarog. The UCI engine identity,
Cargo package, executable names, release assets, repository metadata, and
documentation now use the Rarog name. Lynx releases remain available through
1.4.3.
Release-preparation checks for 2.1.0:
cargo fmt --check
cargo test --lib
cargo test --test engine_coverage --test search_strength
cargo test --release --test uci_process -- --test-threads=1
cargo test --release
cargo build --release --features tune
cargo xtask build --arch pext --pgo
cargo xtask build --arch avx2 --pgoThe final Lynx-branded release was 1.4.3. It was checked with internal
bench 13, PGO/non-PGO speed comparisons, and Cutechess regression matches
against the 1.4.2 development baseline and Basilisk 1.4.9. Bench-only PGO
remained faster than the tested Lynx-specific EPD PGO profile on the final
1.4.3 code, so the release build helper keeps bench-only PGO training.
Release assets may include standalone executables for Windows, Linux, and
Apple Silicon macOS. Intel macOS release assets are not published.
GitHub release binaries are built with explicit portable CPU targets instead of
target-cpu=native, so they can be shared safely. Local cargo build --release
builds continue to use target-cpu=native through .cargo/config.toml.
Use the most advanced binary your CPU supports:
| Asset suffix | Use when |
|---|---|
x86-64 |
You need the most compatible Intel/AMD 64-bit build. |
avx2 |
Your Intel/AMD CPU supports x86-64-v3/AVX2; this is the usual optimized x64 choice. |
pext |
Your Intel/AMD CPU supports BMI2/PEXT; benchmark it against avx2 on your CPU. |
arm64 |
You are on ARM64 Linux, Windows on ARM, or Apple Silicon macOS. |
If unsure, use the plain x86-64 or arm64 asset for your operating system.
GPL-3.0-or-later. See LICENSE.
Rarog is an independent engine, but it benefits from the open chess-engine community's published ideas, testing practices, and protocol conventions. Special thanks to Stockfish and its team for the inspiration their work provides to chess engine authors and testers.
