Lynx is a chess engine developed by @eduherminio.
It's written in C# (.NET 9).
You can find Lynx:
-
As a lichess bot.
-
As a self-contained executable, downloadable from Releases.
Lichess bot can be played directly, but a chess GUI that supports UCI protocol is needed to play against the self-contained version.
See Releases for the complete list of versions.
Here are the ones 'properly' rated over at least a few hundred of games:
Version | Date | Estimated elo0 |
CCRL 40/15 |
CCRL Blitz |
MCERL | CEGT 40/20 |
CEGT 40/4 |
CEGT 5+3 pb |
---|---|---|---|---|---|---|---|---|
1.8.0 | 2024-12-20 | 3150 | 3124 | 3152 | 3139 | 3012 | ||
1.7.0 | 2024-10-05 | 3101 | 3105 | 3127 | 3216 | 2974 | 2936 | 2959 |
1.6.0 | 2024-08-15 | 2952 | 2983* | 3059 | ||||
1.5.1 | 2024-06-21 | 2830 | 2853 | 2660 | 2690 | |||
1.5.0 | 2024-06-09 | 2817 | 2817 | |||||
1.4.0 | 2024-03-21 | 2747 | 2752 | |||||
1.3.0 | 2024-02-04 | 2651 | 2685 | 2653 | 2839 | |||
1.2.0 | 2024-01-11 | 2611 / 25511 | 2586 | 2850 | ||||
1.1.0 | 2023-12-14 | 2533 | 2506 | 2426 | 2599 | |||
1.0.1 | 2023-11-20 | 2511 | 2433 | 2430 | 2571 | |||
0.19.0 | 2023-10-27 | 2434 | 2348 | 2510 | ||||
0.18.0 | 2023-10-21 | 2283 | 2387 | |||||
0.17.0 | 2023-09-19 | 2178 | 2367 | |||||
0.16.0 | 2023-08-26 | 2053 | 1978 | |||||
0.15.0 | 2023-08-13 | 2039 | 2093 | |||||
0.14.1 | 2023-07-30 | 1670 | ||||||
0.13.0 | 2022-11-25 | 1637 | 1774 | |||||
0.11.0 | 2022-09-18 | 1477 | ||||||
0.10.0 | 2022-05-09 | 1426 | ||||||
0.9.0 | 2021-11-29 | 1449 | ||||||
0.6.0 | 2021-10-19 | 1263 | ||||||
0.4.0 | 2021-09-20 | 1208 |
* Not enough games
0 CCRL Blitz elo estimation, based on 40+0.4 gauntlets vs other engines
1 After 2024-01-13 CCRL blitz elo recalculation, where Lynx 1.0.1 went from 2497 to 2432
Lynx release artifacts are self-contained and require no dependencies to be run.
However, you can also choose to build Lynx yourself.
- .NET 9 SDK. You can find instructions about how to install it in your preferred OS/Distro either here or here.
If you're a Linux user and are new to .NET ecosystem, the conversation in this issue may help.
-
Clone the repo, and preferably checkout one of the released tags.
-
Run
make
to build a self-contained binary similar to the pre-compiled ones.Disclaimer: I do not use the Makefile myself, which means it is not fully tested and may occasionally get out of date.
-
Alternatively, you can get the exact
dotnet publish (...)
command fromrelease.yml
that is used by the CI to create the binaries and run it yourself (with the right runtime identifier).Examples:
dotnet publish src/Lynx.Cli/Lynx.Cli.csproj -c Release --runtime linux-x64 --self-contained /p:Optimized=true -o /home/your_user/engines/Lynx dotnet publish src/Lynx.Cli/Lynx.Cli.csproj -c Release --runtime win-x64 --self-contained /p:Optimized=true -o C:/Users/your_user/engines/Lynx
-
The previous steps will generate an executable named
Lynx.Cli(.exe)
and a settings file namedappsettings.json
, which are enough to run Lynx chess engine.
Feature list
Beware, most of the provided links contain outdated information and don't reflect the current implementation or the state of the art of computer chess programming, at this point they remain here mostly for historical reasons.
-
NegaMax [1]
-
Quiescence Search [1]
-
Principal Variation Search (PVS) [1]
-
Late Move Pruning (LMP)
-
Futility Pruning (FP)
-
Reverse Futility Pruning (RFP)
-
History pruning
-
Internal Iterative Reduction (IIR)
-
Check extensions [1]
-
Static Exchange Evaluation (SEE) for move ordering, reduction and QSearch pruning
-
Razoring [1]
-
Killer heuristic [1]
-
History heuristic: quiet history, capture history, continuation history, history malus [1]
-
Countermoves
-
Improving [1]
-
Piece-Square Tables (PSQT) [1]
-
King-bucketed PSQT
-
Enemy king PSQT
-
Mobility (knight, bishop, rook, queen)
-
Bishop pair
-
Bishop penalty for same color pawns
-
Bishop penalty for blocked central pawns
-
Rook in open and semi-open files
-
King pawn shield, king virtual mobility, king in open and semi-open files
-
Isolated pawns
-
Passed pawns, including bonus for not opponent pieces ahead and friend/opponent king distance to it
-
Pawn phalanx
-
Pieces protected and attacked by pawns
-
Pieces capable of deliverying checks
-
Eval scaling with pawn count and 50 moves rule
-
50 moves rule eval scaling
-
Hard/soft time limits
-
Node time management
-
Best move stability
-
Score stability
Lynx supports the usage of multiple threads for searching since v1.8.0.
It can be configured using Threads
UCI command or via appsettings.json
configuration file. A change in Threads
using UCI will only take place after a ucinewgame
command is sent to the engine (same behavior as with Hash
command).
It's interesting to measure how much strength an engine gains when you allow it to use more cores (see Stockfish's Threading efficiency and Elo gain)
This is how Lynx v1.8.0 scales with multiple threads (elo measured playing against itself N threads vs 1 using a balanced book, see links for details):
Threads # | 1 | 2 | 4 | 8 |
---|---|---|---|---|
ELO @ 8+0.08 | - | +100.96 | +195.65 | +263.42 |
ELO @ 40+0.4 | - | +83.35 | +167.44 | +220.54 |
NPS | 1.21 Mnps | 2.47 Mnps | 4.88 Mnps | 10.07 Mnps |
Here are the extended results, with NPS being measured in a 14-core machine:
Threads | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ELO @ 8+0.08 | 0 | +100.96 | +195.65 | +263.42 | ||||||||||
ELO @ 40+0.4 | 0 | +83.35 | +167.44 | +220.54 | ||||||||||
NPS | 1.21 Mnps | 2.47 Mnps | 3.64 Mnps | 4.88 Mnps | 6.29 Mnps | 7.43 Mnps | 8.74 Mnps | 10.07 Mnps | 11.17 Mnps | 12.47 Mnps | 13.68 Mnps | 14.95 Mnps | 16.06 Mnps | 16.80 Mnps |
Lynx supports pondering/permanent brain since v1.5.0.
It can be enabled using Ponder
UCI command or via appsettings.json
configuration file. The engine doesn't ponder by default even if Ponder
flag is enabled, it only does so when receiving a go
command with a request to ponder.
CEGT maintains a pondering rating list.
v1.8.0 results of pondering vs no-pondering (40+0.4, Hash 256, balanced book):
Score of Lynx 1.8.0 vs Lynx 1.8.0: 552 - 218 - 1730 [0.567] 2500
... Lynx 1.8.0 playing White: 329 - 83 - 839 [0.598] 1251
... Lynx 1.8.0 playing Black: 223 - 135 - 891 [0.535] 1249
... White vs Black: 464 - 306 - 1730 [0.532] 2500
Elo difference: 46.7 +/- 7.5, LOS: 100.0 %, DrawRatio: 69.2 %
SPRT: llr 0 (0.0%), lbound -inf, ubound inf
Pondering can be enabled together with multithreading.
v1.8.0 results of 2 threads + pondering vs 1 thread (40+0.4, Hash 256, balanced book):
Score of Lynx 1.8.0 vs Lynx 1.8.0: 903 - 81 - 1516 [0.664] 2500
... Lynx 1.8.0 playing White: 518 - 34 - 698 [0.694] 1250
... Lynx 1.8.0 playing Black: 385 - 47 - 818 [0.635] 1250
... White vs Black: 565 - 419 - 1516 [0.529] 2500
Elo difference: 118.6 +/- 8.1, LOS: 100.0 %, DrawRatio: 60.6 %
SPRT: llr 0 (0.0%), lbound -inf, ubound inf
The following non-standard UCI commands are supported:
-
bench
: searches a predetermined set of positions at a certain depth and returns the number of searched nodes, as well as the nodes per second (nps) based on the time the search took. -
verbosebench
:bench
, but showing the actual engine output. -
fen
: shows the current position's FEN. -
eval
: shows the current position's static evaluation. -
printsysteminfo
: shows some internal behavior based on the system where Lynx is running.
Lynx development would simply not have been possible without:
-
BitBoard Chess Engine in C
YouTube playlist, where @maksimKorzh explains how he developed his BBC engine
I would also like to extend my gratitude to:
-
Engine Programming discord group. Without it, Lynx wouldn't be as strong as it is nowadays. Especial mention for Jamie Whiting (Akimbo), Antares (Altair), Ciekce (Stormphrax), Rak (Mess), mcthouacbb (Sirius), CJ (Alexandria), etc.
-
The community Discord around SebLague/Chess-Challenge, which allowed me to discover EP discord and to revisit the basics, this time explained by very knowledgeable developers (such as the ones above) to people without any previous chess engine programming knowledge
-
Marcel Vanthoor and his blog about how he created his engine, Rustic
-
Gedas for his texel-tuner tool
-
SF developers for their WDL_model tool
-
Andrew Grant for OpenBench
-
lichess developers for lichess-bot
-
Open source chess engines with permissive licenses. Their existence encourages knowledge sharing and really helps pushing the Chess Engine Developer community forward. Some engines are credited inside the codebase itself, where relevant
-
Countless other developers and online resources, who/which I should probably remember, but don't come to my mind right now
Thanks also to all the testers that invest their time in computer chess, especially those ones that test lower rated engines (as opposed to only top ones).