A strong, modern UCI chess engine written in Rust featuring an embedded NNUE evaluation network, cross-platform support (CLI, Web/WASM, Android).
- Building
- Web & Docker
- Implemented Algorithms & Techniques
- UCI Protocol & Options
- Benchmarks & Testing
- Workspace Architecture
- Acknowledgments & Credits
- License
- Rust toolchain (Rust 1.98+ / 2024 edition compatible).
- Git LFS — the NNUE network weights (
chess_engine/src/nnue/*.bin) are stored with Git LFS. Rungit lfs pullafter cloning if your git client doesn't fetch LFS objects automatically.
Build the optimized release executable:
cargo build --release --bin lucky_chessFor maximum performance on your current machine:
RUSTFLAGS="-C target-cpu=native" cargo build --release --bin lucky_chessThe resulting binary will be at target/release/lucky_chess (or lucky_chess.exe on Windows).
LuckyChess can run entirely in the browser via WebAssembly using Web Workers.
docker build -t lucky-chess .
docker run -p 8080:8080 lucky-chessThen visit http://localhost:8080 to play against the engine in your browser.
cargo build-wasmMove Generation
- Bitboards with PEXT slider attacks when BMI2 is available, magic bitboards otherwise (tables generated at build time)
- Staged move picker: TT move → captures → quiets → bad captures (evasions only when in check)
- Pseudo-legal generation with a legality filter;
gives_checkfrom a per-nodeCheckInfo - Static Exchange Evaluation (SEE) for move ordering and pruning
Search
- Alpha-Beta Pruning (Negamax framework)
- Principal Variation Search (PVS)
- Iterative Deepening with Aspiration Windows
- Transposition Table with aging and depth-preferred replacement, storing static eval, prefetched after each move
- Internal Iterative Reductions (IIR)
- Quiescence Search
Reductions & Pruning
- Late Move Reductions (LMR) with history-based adjustment
- Late Move Pruning (LMP)
- Null Move Pruning (NMP) with eval-scaled reduction
- Reverse Futility Pruning (RFP) & Futility Pruning
- SEE Pruning for captures and quiets
- History Pruning (linear depth-scaled margin)
- Delta Pruning & Global Delta Pruning (in Quiescence Search)
Move Ordering
- TT move (scored highest)
- Good captures (SEE + MVV-LVA)
- Killer Move Heuristic (2 killer moves per ply)
- History Heuristic with gravity updates (clamped to ±10,000)
- Multi-layer Continuation History (1-ply and 2-ply reads)
- Bad captures deferred after quiets
Evaluation
- NNUE:
(768×8 → 1536)x2 → 1×8architecture, SCReLU activation, QA = 255 / QB = 64- 8 king buckets on the input side, mirrored horizontally (king on files e–h flips the board)
- 8 output buckets selected by piece count
- Perspective network (vertically mirrored for black)
- Lazy accumulator stack: incremental updates from the parent ply, with Finny-table refreshes when a king changes bucket
- Fused SIMD update + SCReLU dot-product kernels via
fearless_simd - Win-probability scaled evaluation (~400 units/pawn)
- Trained on 20B positions of Leela-derived data (linrock's test77/test79 sets) using the
bulletframework
Time Management
- Soft and hard time limits; best-move stability decides whether to start another iteration
- Supports
wtime/btime/winc/binc/movestogo,movetime,depth,nodesandinfinite - Configurable
Move Overheadfor GUI and network lag
uci, isready, setoption, ucinewgame, position, go, stop, quit.
eval— static NNUE evaluation of the current positiond/display— print the current boardperft <depth>/go perft <depth>— move generation/validation performance test
The lucky_chess binary also accepts these, on stdin or as arguments (e.g. lucky_chess bench 12):
bench [depth]— deterministic search over a fixed set of positions (default depth 10, 16 MB hash)perft-suite [depth]— perft over a suite of reference positions
| Option | Type | Default | Range | Description |
|---|---|---|---|---|
Hash |
spin | 64 |
1 – 1024 MB | Transposition table memory size |
ClearHash |
button | — | — | Clears the transposition table |
Move Overhead |
spin | 10 |
0 – 5000 ms | Time buffer for communication / GUI lag |
Threads |
spin | 1 |
1 – 1 | Single-threaded search (accepted for GUI compatibility) |
cargo test --all runs the suite in chess_engine/tests/: perft, per-piece move generation, legality, make/undo,
FEN, SEE, Zobrist hashing, draw detection, time management, and NNUE accumulator-stack vs from-scratch evaluation.
benchmarks/sprt_self_play.sh [elo0] [elo1] [tc] builds the current tree and plays it against a saved baseline
(benchmarks/save_baseline.sh) with fastchess. Defaults: 8+0.08,
bounds [0, 5].
benchmarks/gauntlet_ccrl_blitz.sh [tc] [rounds] [concurrency] runs a CCRL Blitz-style gauntlet (8moves_v3 book,
CCRL adjudication, 1 thread) against Pawn 4.0, Prune 4.0.1, Oxide 3.0 and Akimbo 1.0.0; each round is 8 games.
Latest result (v5 net, 160 games per engine, before Akimbo replaced Ursus):
| Rank | Engine | Elo | Score |
|---|---|---|---|
| 1 | LuckyChess (v5) | +50.3 ± 29.0 | 57.2% |
| 2 | Pawn 4.0 (3557) | +43.7 ± 31.0 | 56.2% |
| 3 | Sirius 9.0 (3528) | +2.2 ± 34.4 | 50.3% |
| 4 | Oxide 3.0 (3530) | −6.5 ± 24.5 | 49.1% |
| 5 | Ursus (3509) | −91.1 ± 31.7 | 37.2% |
Against a field averaging ~3,530 CCRL Blitz this is roughly 3,580; with ±29 Elo of noise, the badge gives a range.
├── chess_core/ # Core types: bitboards, squares, pieces, moves, castling rights
├── chess_engine/ # Board state, move generation, search, NNUE evaluation, time management, UCI protocol, perft
├── chess_cli/ # Native CLI binary executable (lucky_chess)
├── chess_web/ # C-FFI / WebAssembly cdylib & browser frontend
├── chess_android/ # JNI bindings and Android / Wear OS companion app
├── nnue_trainer/ # NNUE training pipeline and utilities
└── benchmarks/ # SPRT testing scripts, opening books, gauntlet suites
While the codebase is original, LuckyChess stands on the shoulders of the open-source chess programming community:
- Stockfish
- Alexandria
- jw1912 — creator of the
bullettraining framework - linrock — Leela-derived NNUE training data
- Chess Programming Wiki — invaluable resource for chess algorithms, magic bitboards, and search techniques
- Tools & Libraries:
fearless_simdfor portable SIMD accelerationfastchessfor automated SPRT testing
LuckyChess is an original engine. In the interest of transparency within the chess programming community: AI assistants (LLMs) were used during development for tests and fixtures, profiling and benchmark analysis, and code review. The engine's architecture, design decisions and training runs are the author's, and every engine change was validated by SPRT.
LuckyChess is free and open-source software licensed under the GNU General Public License v3.0.