Skip to content

Latest commit

 

History

History
129 lines (102 loc) · 6.26 KB

README.md

File metadata and controls

129 lines (102 loc) · 6.26 KB

deploy/: running the Lichess bot

The engine speaks UCI, so a standard bridge (lichess-bot) can host it on Lichess. This directory holds the configuration and the setup script for that.

Bringing the bot back up after a long gap

Development is finished, but the bot is meant to keep playing on demand. If it has been off for months, start here rather than at Setup, which assumes a fresh machine.

cd ~/PycharmProjects/PyCheckmate
git pull                       # the engine runs from the working tree, see below
./deploy/setup.sh              # idempotent: re-pushes config, re-applies the patch
bot up && bot status

I checked all of the following on 2026-08-05, so if something here is no longer true, that is your broken thing:

Thing State Why it matters
lichess-bot clone on the KNOWN_GOOD pin, rate-limit patch applied upstream drift cannot surprise you
<clone>/.token present, chmod 600 the likeliest thing to have decayed, since a revoked or deleted token fails at startup
clone virtualenv Python 3.12 setup.sh rebuilds it if missing
engines/engine.sh cds into this repo and runs engine.uci under PyPy nothing is pinned, so the bot plays whatever is in your working tree and git pull is the entire upgrade
PyPy 3.11 installed via uv uv python install pypy3.11 if not

Two startup failures have actually happened here. One is an expired or missing token. The other is an HTTP 429 lockout from restarting repeatedly while editing config, so batch every config edit and then do exactly one up/down cycle. Orphaned multiprocessing children hold streams open where a normal process check cannot see them, so run ps aux | grep "lichess-bot/.venv" and sweep them before retrying. The full manual is docs/LICHESS_BOT.md.

One change is committed but unplayed. polyglot.enabled went to false on 2026-08-05, so the next time the bot runs, books/book.json picks the opening for the first time ever. The book is verified end to end under python -m engine.uci, and book.py confirms the move is legal in the exact position before returning it, so it cannot cause a forfeit. It has still never played a rated game. Watch the first one. If you want the safer path for a demo, set it back to true and re-run setup.sh.

Setup

setup.sh and the bot control script are POSIX shell, so this path is macOS/Linux. On Windows, run them under WSL, or drive lichess-bot directly with the config.yml here, since the engine itself is plain UCI and platform-neutral.

git clone https://github.com/pdloc06/PyCheckmate.git
cd PyCheckmate && uv sync

./deploy/setup.sh

setup.sh clones lichess-bot, builds its virtualenv, applies the patch below, installs the config, and generates the launcher that points it at this engine. It is idempotent, so re-running it is safe, and it reports anything it cannot supply itself. Set LICHESS_BOT_DIR to put the clone somewhere other than ~/PycharmProjects/lichess-bot.

Two things it cannot do for you:

  1. The API token. Create one at lichess.org/account/oauth/token with the bot:play scope, on a dedicated BOT account, and save it to <clone>/.token (one line, chmod 600). It is a credential: keep it out of git.
  2. A polyglot book, if you leave polyglot.enabled: true in the config. Either drop a .bin into the clone's engines/, or set it to false.

Then link the control script and start:

ln -sf "$PWD/bot" ~/.local/bin/bot
bot up

What is in here

File What it is
config.yml The tuned lichess-bot config: matchmaking, rated play, opponent bounds, time controls. 91 lines of deliberate divergence from upstream's default, each commented. This repo is its source of truth, because setup.sh overwrites the clone's copy, so edit it here.
rate-limit.patch Six lines on lib/lichess_bot.py: sleep out a 429 cooldown rather than retrying every second and burying the log in tracebacks.
setup.sh The installer described above.

Operating it

bot up / bot down / bot status / bot log, from the control script at the repo root. Two things happen automatically:

  • Game records write themselves. bot up also starts engine/tools/sf_watch.py, which grades each finished game with Stockfish in the idle gap before the next one begins and appends a record to ~/.local/share/pycheckmate/game_analysis.jsonl. bot down waits for the current game and its analysis before stopping; bot down now skips both.
  • The engine version stamps itself. sf_watch reads the git revision at startup and labels every record with it, writing the cut to version_cuts.json. Never average results across two labels. Override with BOT_ENGINE_VERSION=<rev> bot up when a run spans a docs-only commit; the bot script explains exactly when that is correct.

Full operations manual, including the traps: docs/LICHESS_BOT.md.

Resolved: the polyglot book shadowed the engine's own

config.yml used to set polyglot.enabled: true with engines/komodo.bin and max_depth: 20. lichess-bot consults that book before it asks the engine, in lib/engine_wrapper.py where get_book_move sits at the top of search, so for the first 39 plies of every game the polyglot book chose the move and books/book.json was never reached. The 13,230-position book this project built for itself got shipped and then measured nothing, across every rated game played up to 2026-08-05.

It went to false on 2026-08-05 while closing the project out. Re-run setup.sh to push that to the clone. Whoever next brings the bot up gets the first games in which our own book chooses a move, so take a fresh version cut when you do, because it changes what the bot plays.

The shape of the mistake is worth keeping. A shadowed book and a useless book produce identical evidence, so no amount of game-record analysis could have surfaced this. What would have caught it is a question asked before collecting anything: by what path does this code actually get executed in the thing I am about to measure? The book was verified under python -m engine.uci, which is precisely the path lichess-bot skips.