A photorealistic chess game played in first person, seated at a waxed wooden table in a sunlit royal hall, against a porcelain robot driven by Stockfish. Everything is rendered by an in-house engine written for this game on OpenGL 4.6 (no third-party engine): procedural geometry, real-time material shaders, physically based lighting.
The releases hold the game for Windows x64 and Linux x86-64; both need a GPU with OpenGL 4.6, and Stockfish 19 is built in.
Scacelith-<version>-windows-x64.zip anywhere and run Scacelith.exe (or
download the executable alone).Scacelith-<version>-linux-x86_64.tar.gz and run ./scacelith;
./install.sh adds the game to your applications menu (in ~/.local, no root needed) and
./install.sh --uninstall removes it. It needs glibc 2.34 and OpenSSL 3 (Ubuntu 22.04,
Debian 12, Fedora 36, RHEL 9 and later), X11 or Wayland with XWayland, and plays its sound
through ALSA (libasound2; PulseAudio and PipeWire through their ALSA plugins). Without
libasound2 or a sound device the game runs silent, the coach in subtitles.At the table the game draws its own pointer, which shows what a click will do: a gold ring over a piece you can touch or over the clock, a sight with a gold centre over a square the piece in hand can go to (Options > Gameplay > Game pointer switches back to the system arrow).
A new game asks for the opponent's strength (Stockfish presets, or custom Skill Level / Elo / depth / move time / nodes) and the time control (unlimited, 1+0, 3+0, 3+2, 5+0, 5+3, 10+0, 10+5, 15+10, 30+0, 30+20, 90+30, or custom with increment and delay). Your colour is random for the first game, then alternates. Every physical action (touching, moving, capturing, promoting, pressing the clock) takes exactly the same time for both players, and each clock only stops when the lever is actually pressed.
Illegal moves are only possible when legal-move hints are turned off (Options > Gameplay). As in tournaments, the arbiter then restores the position, gives the opponent extra time, and a second illegal move loses the game.
As in tournaments, both players record the game on their own scoresheet, a pad lying on the side of the table opposite the clock. Right after every clock press each player writes the move down with the hand on the pad side, while the other hand stays free to play and press the clock, so keeping score never costs clock time. The player whose clock stands on the left therefore plays with the left hand and writes with the right. The header is filled in when the game starts (event "Scacelith", date, round, the players' names and ratings: your name from Options > Player, "Human" by default (translated with the interface), and "Stockfish"), a full page of 40 moves is turned over the top of the pad, and the result is written before the final handshake. You hear the pen on the paper and the page being turned.
Each player has a handwriting of their own (Caveat, Marck Script or Bad Script for Latin and Cyrillic; names in other scripts are written in Aref Ruqaa, Klee One or LXGW WenKai), and moves use the piece letters of the interface language.
Your rating is computed after every game against Stockfish as FIDE computes tournament ratings (FIDE Rating Regulations, 2024), with the same rules as the online server's:
The opponent's rating is the preset's (Novice 800 up to Stockfish Max 3500; a custom opponent is
rated from its Skill Level or UCI Elo). A game counts once both players have moved; leaving a
game, or closing the game, resigns it. The title page shows your rating, record and peak, the new
game page the score you can expect against the selected opponent, and the game over card the
change (Elo 1512 → 1524 (+12)). Watched games are never rated. Games are rated one by one, where
FIDE rates a month's games together.
Set Opponent to Human, same PC on the new game page to play a friend at the same computer, each from their own robot's eyes. The page asks for both names (White defaults to your name from Options > Player, Black to "Player 2"), each player's handwriting, the time control, the side of the clock (at White's or at Black's right: the player whose clock is on their left plays with the left hand), and whether the game is rated. Swap colours exchanges the two players.
A two-player game is friendly by default and never changes your rating against Stockfish. A rated
one keeps a separate rating per name ([local_player_N] in the settings file; a new name starts
unrated at 1500, with the same FIDE rules), updated for both players against each other's rating
before the game (a game between two unrated names counts for both, unless it is lost by a name
that has not drawn or won yet: FIDE then ignores it for both); leaving a game early rates
nothing.
Coach on the title page seats you in front of a robot with "COACH" on its chest, a teacher
who plays you at your level and talks you through the game. The Coach page chooses the level and
your colour (White, Black, or alternating from one game to the next); the choice is remembered
([coach] in the settings file).
The coach speaks with a voice synthesised on your computer (Supertonic 3). Its model is not part of
the game: the first time you open the Coach page (or switch Options > Audio > Coach voice on), the
game offers to download it, about 145 MB, from Hugging Face (or, if that fails, from the sherpa-onnx
release on GitHub), into the game's folder of application data: %APPDATA%\scacelith\coach\ on
Windows, $XDG_DATA_HOME/scacelith/coach/ (by default ~/.local/share/scacelith/coach/) on Linux.
The prompt shows the model's licence (OpenRAIL-M) and its use restrictions; "Not now" switches the
coach's voice off. A small panel in the corner shows the download while you keep playing, and an
interrupted download continues where it stopped. Without the model, with Coach voice off, or
without a sound device, the coach speaks through subtitles only. Options > Audio > Subtitles shows
its words at the bottom of the screen (Automatic: when it does not speak the language of the menus,
as with Chinese menus where it speaks English), and Options > Audio > Voice volume sets its volume.
[tts] in the settings file tunes the synthesis: threads (0 = 2), voice (-1 = the default
voice), steps (5) and arch (auto, or avx512, avxvnni, avx2, sse2, scalar when
troubleshooting).
Watch a Game on the title page lets two Stockfish players (one preset per side, and a time
control) play each other while you move freely around the hall, invisible to them. The choice is
remembered ([viewer] in the settings file).
The players claim and offer draws like the opponent of a normal game (repetition, fifty moves, an equal position late in the game), and the game over card offers to watch another game.
Play Online on the title page plays people through a Scacelith server, still in the first person: your opponent sits in the other chair as a robot that moves with them, live: it takes the piece they touch, holds it over the square they aim at, looks where they look and leans in when they do.
caissa.scacelith.com (port 443, secure web API and
secure WebSocket on the same port). Options > Online server > Custom server takes a community
server instead: host (domain or IP), HTTPS/API port, WSS port (empty = the API port) and, for a
server with a self-signed certificate, its Certificate fingerprint (SHA-256) as its owner
gives it (64 hexadecimal characters, colons allowed; empty = the Windows certificate store).
Test connection shows the server's name, message and whether it runs a compatible
version. Google sign-in works only when the server is added under the public host name and API
port its owner gives. You sign in separately on each server: an account and its sign-in are
never shared between servers, and nothing secret is written to Scacelith.ini.1500? while it is
provisional, with games and wins / draws / losses), changes the password, turns two-factor
authentication on (QR code or key, then ten recovery codes shown once) or off, makes new
recovery codes, and signs you out here or everywhere.XXXX-XXXX-XXXX) to the other, who joins with them. The page says whether the
router opened the port, when to forward it by hand, and when the internet provider shares the
address (carrier-grade NAT: try IPv6 or a VPN).Anyone can run a server: see DarkCenobyte/scacelith-chess-server. The game speaks the realtime protocol v1 with it, whose specification is kept in this repository too, in protocol/.
Development: --online-mock replaces the network with an in-process fake server and a fake
direct-match friend (any password works; see src/game/online_mock.h for the inputs that try
error paths), and --start-online [category] goes straight to a game (with --online-mock the
opponent is a random mover whose hands and head move like a player's; --online-manual-clock
leaves the clock press to the players, and --play e2e4,... makes your moves). In a mock game F9
makes the opponent disconnect for a while and F10 drops your own connection. --scene ui --ui-screen online-play (and the other online-* and direct-* screens listed in
src/ui/ui_viewer.cpp) shows the pages on the fake server.
docs/ONLINE_CLIENT.md describes the client side. QR codes are drawn with
Nayuki's QR Code generator (MIT licence,
third_party/qrcodegen/).
Settings are stored in Scacelith.ini in %APPDATA%\scacelith\ (on Linux
$XDG_CONFIG_HOME/scacelith/, by default ~/.config/scacelith/), with the saved logins
(Scacelith.credentials) and the log (scacelith.log). A Scacelith.ini next to the executable
makes a portable install (versions up to 1.0.0-beta.1 put it there): the game then keeps all three
in the executable's folder, as it also does when the user folder cannot be written. A file given with --ini <file> is read and written there only, with the
logins beside it (the log warns when it cannot be written). All of them are
editable from the Options page: display mode and resolution, V-sync, render scale, quality
preset, motion blur, depth of field, brightness, volumes, ambience, legal-move hints, auto-press
clock, the opponent's head movements, mouse sensitivity, the game pointer, and the hand-over
between the two players of a game on one PC (a camera flight, or an instant cut). An option
marked with a small circled i after its name has a definition: rest the pointer on the name
or on the mark, or keep the keyboard focus on the row for a moment, to read it.
The first start opens on a brightness calibration: three squares, black on the left, mid grey and
white on the right, each with a black knight, drawn exactly as the 3D hall would show them at the
brightness of the slider. Move the slider until the knight on the black square is barely visible,
or no longer visible, and Continue (Esc keeps the current value); Options > Graphics >
Brightness changes it later. Until Continue or Esc, every start opens on it: a first start closed
during the loading, or a first run straight into a game, shows it the next time (screenshot runs
never do). --calibrate opens the page again, and the UI viewer shows it with
--scene ui --ui-screen calibration.
The interface speaks English, French, German, Spanish, Ukrainian, Russian, Arabic (laid out right
to left), Japanese, Simplified Chinese and Traditional Chinese. The first start follows the
system language; Options > Display > Language changes it at once. Options > Player holds your
name and the handwriting in which you fill in your scoresheet, with a preview. Translations live
in assets/i18n/<code>.lang (one key = text per line, English is the reference and the
fallback); --lang <code> overrides the language for one session.
Requirements: CMake 3.21+, Ninja, GCC with GNU binutils (tested with GCC 13; on Windows,
MinGW-w64 GCC with POSIX threads; Clang cannot build the embedded Stockfish variants), and
Python 3 for the instruction-set audits and the Windows exception table check that run at every
build (a Windows Release build, the shipped exe, does not configure without it; other builds skip
them with a warning). The Linux build also needs the OpenSSL 3, X11 and OpenGL development files
(for example libssl-dev, libx11-dev and libgl-dev); ALSA is loaded at run time
(libasound.so.2), not linked, and a Linux Release build links libstdc++ and libgcc in, so that
the executable runs on other distributions than the build machine's. The Windows build is produced with
MinGW-w64 (native or cross-compiled from Linux) and is a single self-contained executable
(Stockfish 19 and its neural network are embedded). Stockfish is compiled once per x86-64
instruction set, from plain x86-64 to AVX-512, and the game runs the best one the CPU supports;
-DSCACELITH_SF_VARIANTS=x86-64-avx2 (or another variant the CPU runs) builds a single one, for
quicker local builds (see third_party/stockfish/README.scacelith.md). The first configure also
downloads the coach's voice model archive (129 MB, from the sherpa-onnx release on GitHub) into
the build folder, for the unit tests and --coach-dir build/coach:
-DSCACELITH_SUPERTONIC_DIR=<extracted folder> or -DSCACELITH_SUPERTONIC_ARCHIVE=<.tar.bz2>
take a local copy instead, and -DSCACELITH_SUPERTONIC_DOWNLOAD=OFF does without it (the tests
that need the model are then skipped; see third_party/supertonic3/README.scacelith.md).
# Windows x64 (cross-compiled from Linux)
cmake -B build-win -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/mingw-w64-x86_64.cmake -DCMAKE_BUILD_TYPE=Release
ninja -C build-win # -> build-win/Scacelith.exe
# Linux x86-64 (the game, its tests and headless screenshots)
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
ninja -C build
./build/scacelith_tests
# The Windows tests under Wine (ninja -C build-win scacelith_tests first)
tools/test_win.sh # [filter-substring]
Wine names the Linux files in the character set of the host locale: in the POSIX locale (LANG
unset, common in containers) that is ASCII, a file named after "Élodie" cannot be created and the
saved games' tests fail although Windows takes the name. tools/test_win.sh and
tools/shot_win.sh run Wine in a UTF-8 locale (LC_ALL=C.UTF-8) when the current one is not.
Development options: --scene <name> runs a viewer scene (--list-scenes), --data-dir .
reads shaders from disk and F5 reloads them, F12 saves a screenshot,
--shot out.png --frames N --size 1280x720 renders headlessly (leaving the settings file and the
saved games as they are). tools/shot.sh and tools/shot_win.sh do this under Xvfb (Linux build
and Windows build through Wine). The Windows exe has no console: redirect what it prints
(Scacelith.exe --list-scenes > scenes.txt, or | more), or configure with
-DSCACELITH_CONSOLE=ON for a console build.
The game itself (--scene game, the default) takes --start (a game against Stockfish at once;
--human white|black), --viewer (a watched game at once; --white-preset N --black-preset N
with N an index of the preset list, --viewpoint 0..9), --tc N (time control index), --cam x,y,z [--look x,y,z] [--fov deg] (initial observer camera when watching; a detached camera in a
normal game), --handover-preview (watching through the players' eyes with the clock frozen during
each camera handover, the same hand-over as hot-seat), --no-intro,
--warp <seconds> (with --shot: simulate before the first frame), --moves e2e4,e7e5,..., --touch <square>,
--mouse fx,fy (pointer position as fractions of the window; the view follows it, 0.5,0.03 looks
up at the opponent), --glance (start looking at the scoresheet), --calibrate (the brightness
calibration before the title page, as on a first start) and --ini <file>.
Two players on one PC: --start --hotseat starts one at once, with --white-name N, --black-name N, --clock-right white|black, --rated and --handover <seconds> (0 = instant cut). --play e2e4,e7e5,... plays the human moves by hand, the way a player would (touch, carry, press the
clock): both sides on one PC, the human's side against Stockfish; with --warp it takes
screenshots of a game in progress, for instance the hand-over halfway (--start --hotseat --no-intro --play e2e4 --warp 2.35). The UI viewer has the hot-seat screens (--scene ui --ui-screen newgame-hotseat|hotseat-hud|hotseat-confirm|hotseat-gameover).
Coach mode: --start --coach starts a coach game at once, at the level and colour of the Coach
page unless --coach-level 0..6 (0 = the rules lesson) or --coach-colour white|black say
otherwise; --coach-dir <folder> reads (and downloads) the voice model files in that folder instead
of the default one (--coach-dir build/coach: the copy a development build prepares).
SCACELITH_COACH_SOURCE=github in the environment skips Hugging Face (to try the fallback), and
--scene ui --ui-screen coach-flow [--coach-dir <folder>] runs the download flow over the title
page (coach-download* screens: the prompt and the panel with sample figures).
--coach-stage-test (alone, or with --start) runs a fixed sequence through the scene's coach
stage without the session: a line spoken and subtitled, the coach pointing at g1 and
tracing the knight's jump to f3 on their words, a mark and a highlight, two demonstration moves
taken back by hand, then the takeback card (--coach-stage-test lesson: on the lesson's first
position); its log gives the time of each step, for --warp. --coach-auto-answer yes|no answers
the takeback card by itself after 1.5 s, for runs with --play.
See docs/ARCHITECTURE.md for how the engine is organised.
GitHub Actions builds and tests every push to master and every pull request
(.github/workflows/ci.yml): the Linux build and its unit tests, the Windows build cross-compiled
with MinGW-w64 and its unit tests under Wine (both as above), and a lint of the workflows
(actionlint and zizmor). The Windows executable of each run is kept for 14 days as a workflow
artifact, for testing. CodeQL (.github/workflows/codeql.yml) scans the shipped C++ code
(without third_party/ and tests/) and the workflows; its alerts are in the Security tab.
The version is set in cmake/version.cmake: SCACELITH_VERSION_CORE (1.0.0) and, for a
pre-release, SCACELITH_VERSION_PRERELEASE (beta.2); cmake -P cmake/version.cmake prints it
in full. Pushing the tag v + that version (v1.0.0-beta.2) publishes a release: the release
workflow (.github/workflows/release.yml) checks that the tag matches the version, runs the CI
again on the tagged commit, builds the game from scratch (no compiler cache) for Windows x64 and
for Linux x86-64 (on Ubuntu 22.04, the oldest toolchain supported, where the unit tests run again
and the executable is checked to need only system libraries and glibc 2.34), attests the build
provenance of the files with actions/attest and publishes a GitHub release (a pre-release when the
version has a suffix) with Scacelith-<version>-windows-x64.zip (the executable, its licence and
the licence texts of what it embeds), the Windows executable alone,
Scacelith-<version>-linux-x86_64.tar.gz (the executable, its launcher and icons, install.sh
and the same licences) and SHA256SUMS. Started by hand, the
workflow builds the same files and keeps them as workflow artifacts without publishing anything,
unless it runs on a tag with "Publish" ticked. To check a downloaded file with the GitHub CLI:
gh attestation verify Scacelith-1.0.0-beta.2-windows-x64.zip --repo DarkCenobyte/scacelith-chess
Dependabot (.github/dependabot.yml) keeps the actions the workflows use up to date (pinned by
commit SHA); the code vendored in third_party/ is updated by hand.
Scacelith is free software under the GNU General Public License v3.0 (see LICENSE), because it
embeds Stockfish (GPL-3.0), whose source is in
third_party/stockfish/ with its own copyright notices. Stockfish's neural network was trained on
data provided by the Leela Chess Zero project, which is made available under the Open Database
License (ODbL). The Cinzel, EB Garamond and Amiri (Khaled Hosny) interface fonts and the handwriting
fonts Caveat (Impallari Type), Marck Script (Denis Masharov), Bad Script (Gaslight), Aref Ruqaa
(Abdullah Aref, Khaled Hosny), Klee One (Fontworks) and LXGW WenKai / WenKai TC (LXGW) are under the
SIL Open Font License 1.1; the Arabic and CJK fonts (Amiri, Aref Ruqaa, Klee One, LXGW WenKai /
WenKai TC) are subset and renamed from the upstream files by tools/prepare_fonts.py, the others
are the upstream files unchanged. The chess figures of the promotion picker come from a subset of
GNU FreeFont FreeSerif (GPL-3.0+ with the font exception). All licence texts are in assets/fonts/
and assets/fonts/hand/. The coach's voice model (Supertonic 3) is not part of the program nor of
its release package: the game downloads it from its publishers at the player's request. It has its
own licence (BigScience Open RAIL-M), whose use restrictions the download prompt shows; see
third_party/supertonic3/README.scacelith.md.
C++
95.2%
GLSL
3.0%
Python
1.3%
A photorealistic chess game played in first person, seated at a waxed wooden table in a sunlit royal hall, against a porcelain robot driven by Stockfish. Everything is rendered by an in-house engine written for this game on OpenGL 4.6 (no third-party engine): procedural geometry, real-time material shaders, physically based lighting.
The releases hold the game for Windows x64 and Linux x86-64; both need a GPU with OpenGL 4.6, and Stockfish 19 is built in.
Scacelith-<version>-windows-x64.zip anywhere and run Scacelith.exe (or
download the executable alone).Scacelith-<version>-linux-x86_64.tar.gz and run ./scacelith;
./install.sh adds the game to your applications menu (in ~/.local, no root needed) and
./install.sh --uninstall removes it. It needs glibc 2.34 and OpenSSL 3 (Ubuntu 22.04,
Debian 12, Fedora 36, RHEL 9 and later), X11 or Wayland with XWayland, and plays its sound
through ALSA (libasound2; PulseAudio and PipeWire through their ALSA plugins). Without
libasound2 or a sound device the game runs silent, the coach in subtitles.At the table the game draws its own pointer, which shows what a click will do: a gold ring over a piece you can touch or over the clock, a sight with a gold centre over a square the piece in hand can go to (Options > Gameplay > Game pointer switches back to the system arrow).
A new game asks for the opponent's strength (Stockfish presets, or custom Skill Level / Elo / depth / move time / nodes) and the time control (unlimited, 1+0, 3+0, 3+2, 5+0, 5+3, 10+0, 10+5, 15+10, 30+0, 30+20, 90+30, or custom with increment and delay). Your colour is random for the first game, then alternates. Every physical action (touching, moving, capturing, promoting, pressing the clock) takes exactly the same time for both players, and each clock only stops when the lever is actually pressed.
Illegal moves are only possible when legal-move hints are turned off (Options > Gameplay). As in tournaments, the arbiter then restores the position, gives the opponent extra time, and a second illegal move loses the game.
As in tournaments, both players record the game on their own scoresheet, a pad lying on the side of the table opposite the clock. Right after every clock press each player writes the move down with the hand on the pad side, while the other hand stays free to play and press the clock, so keeping score never costs clock time. The player whose clock stands on the left therefore plays with the left hand and writes with the right. The header is filled in when the game starts (event "Scacelith", date, round, the players' names and ratings: your name from Options > Player, "Human" by default (translated with the interface), and "Stockfish"), a full page of 40 moves is turned over the top of the pad, and the result is written before the final handshake. You hear the pen on the paper and the page being turned.
Each player has a handwriting of their own (Caveat, Marck Script or Bad Script for Latin and Cyrillic; names in other scripts are written in Aref Ruqaa, Klee One or LXGW WenKai), and moves use the piece letters of the interface language.
Your rating is computed after every game against Stockfish as FIDE computes tournament ratings (FIDE Rating Regulations, 2024), with the same rules as the online server's:
The opponent's rating is the preset's (Novice 800 up to Stockfish Max 3500; a custom opponent is
rated from its Skill Level or UCI Elo). A game counts once both players have moved; leaving a
game, or closing the game, resigns it. The title page shows your rating, record and peak, the new
game page the score you can expect against the selected opponent, and the game over card the
change (Elo 1512 → 1524 (+12)). Watched games are never rated. Games are rated one by one, where
FIDE rates a month's games together.
Set Opponent to Human, same PC on the new game page to play a friend at the same computer, each from their own robot's eyes. The page asks for both names (White defaults to your name from Options > Player, Black to "Player 2"), each player's handwriting, the time control, the side of the clock (at White's or at Black's right: the player whose clock is on their left plays with the left hand), and whether the game is rated. Swap colours exchanges the two players.
A two-player game is friendly by default and never changes your rating against Stockfish. A rated
one keeps a separate rating per name ([local_player_N] in the settings file; a new name starts
unrated at 1500, with the same FIDE rules), updated for both players against each other's rating
before the game (a game between two unrated names counts for both, unless it is lost by a name
that has not drawn or won yet: FIDE then ignores it for both); leaving a game early rates
nothing.
Coach on the title page seats you in front of a robot with "COACH" on its chest, a teacher
who plays you at your level and talks you through the game. The Coach page chooses the level and
your colour (White, Black, or alternating from one game to the next); the choice is remembered
([coach] in the settings file).
The coach speaks with a voice synthesised on your computer (Supertonic 3). Its model is not part of
the game: the first time you open the Coach page (or switch Options > Audio > Coach voice on), the
game offers to download it, about 145 MB, from Hugging Face (or, if that fails, from the sherpa-onnx
release on GitHub), into the game's folder of application data: %APPDATA%\scacelith\coach\ on
Windows, $XDG_DATA_HOME/scacelith/coach/ (by default ~/.local/share/scacelith/coach/) on Linux.
The prompt shows the model's licence (OpenRAIL-M) and its use restrictions; "Not now" switches the
coach's voice off. A small panel in the corner shows the download while you keep playing, and an
interrupted download continues where it stopped. Without the model, with Coach voice off, or
without a sound device, the coach speaks through subtitles only. Options > Audio > Subtitles shows
its words at the bottom of the screen (Automatic: when it does not speak the language of the menus,
as with Chinese menus where it speaks English), and Options > Audio > Voice volume sets its volume.
[tts] in the settings file tunes the synthesis: threads (0 = 2), voice (-1 = the default
voice), steps (5) and arch (auto, or avx512, avxvnni, avx2, sse2, scalar when
troubleshooting).
Watch a Game on the title page lets two Stockfish players (one preset per side, and a time
control) play each other while you move freely around the hall, invisible to them. The choice is
remembered ([viewer] in the settings file).
The players claim and offer draws like the opponent of a normal game (repetition, fifty moves, an equal position late in the game), and the game over card offers to watch another game.
Play Online on the title page plays people through a Scacelith server, still in the first person: your opponent sits in the other chair as a robot that moves with them, live: it takes the piece they touch, holds it over the square they aim at, looks where they look and leans in when they do.
caissa.scacelith.com (port 443, secure web API and
secure WebSocket on the same port). Options > Online server > Custom server takes a community
server instead: host (domain or IP), HTTPS/API port, WSS port (empty = the API port) and, for a
server with a self-signed certificate, its Certificate fingerprint (SHA-256) as its owner
gives it (64 hexadecimal characters, colons allowed; empty = the Windows certificate store).
Test connection shows the server's name, message and whether it runs a compatible
version. Google sign-in works only when the server is added under the public host name and API
port its owner gives. You sign in separately on each server: an account and its sign-in are
never shared between servers, and nothing secret is written to Scacelith.ini.1500? while it is
provisional, with games and wins / draws / losses), changes the password, turns two-factor
authentication on (QR code or key, then ten recovery codes shown once) or off, makes new
recovery codes, and signs you out here or everywhere.XXXX-XXXX-XXXX) to the other, who joins with them. The page says whether the
router opened the port, when to forward it by hand, and when the internet provider shares the
address (carrier-grade NAT: try IPv6 or a VPN).Anyone can run a server: see DarkCenobyte/scacelith-chess-server. The game speaks the realtime protocol v1 with it, whose specification is kept in this repository too, in protocol/.
Development: --online-mock replaces the network with an in-process fake server and a fake
direct-match friend (any password works; see src/game/online_mock.h for the inputs that try
error paths), and --start-online [category] goes straight to a game (with --online-mock the
opponent is a random mover whose hands and head move like a player's; --online-manual-clock
leaves the clock press to the players, and --play e2e4,... makes your moves). In a mock game F9
makes the opponent disconnect for a while and F10 drops your own connection. --scene ui --ui-screen online-play (and the other online-* and direct-* screens listed in
src/ui/ui_viewer.cpp) shows the pages on the fake server.
docs/ONLINE_CLIENT.md describes the client side. QR codes are drawn with
Nayuki's QR Code generator (MIT licence,
third_party/qrcodegen/).
Settings are stored in Scacelith.ini in %APPDATA%\scacelith\ (on Linux
$XDG_CONFIG_HOME/scacelith/, by default ~/.config/scacelith/), with the saved logins
(Scacelith.credentials) and the log (scacelith.log). A Scacelith.ini next to the executable
makes a portable install (versions up to 1.0.0-beta.1 put it there): the game then keeps all three
in the executable's folder, as it also does when the user folder cannot be written. A file given with --ini <file> is read and written there only, with the
logins beside it (the log warns when it cannot be written). All of them are
editable from the Options page: display mode and resolution, V-sync, render scale, quality
preset, motion blur, depth of field, brightness, volumes, ambience, legal-move hints, auto-press
clock, the opponent's head movements, mouse sensitivity, the game pointer, and the hand-over
between the two players of a game on one PC (a camera flight, or an instant cut). An option
marked with a small circled i after its name has a definition: rest the pointer on the name
or on the mark, or keep the keyboard focus on the row for a moment, to read it.
The first start opens on a brightness calibration: three squares, black on the left, mid grey and
white on the right, each with a black knight, drawn exactly as the 3D hall would show them at the
brightness of the slider. Move the slider until the knight on the black square is barely visible,
or no longer visible, and Continue (Esc keeps the current value); Options > Graphics >
Brightness changes it later. Until Continue or Esc, every start opens on it: a first start closed
during the loading, or a first run straight into a game, shows it the next time (screenshot runs
never do). --calibrate opens the page again, and the UI viewer shows it with
--scene ui --ui-screen calibration.
The interface speaks English, French, German, Spanish, Ukrainian, Russian, Arabic (laid out right
to left), Japanese, Simplified Chinese and Traditional Chinese. The first start follows the
system language; Options > Display > Language changes it at once. Options > Player holds your
name and the handwriting in which you fill in your scoresheet, with a preview. Translations live
in assets/i18n/<code>.lang (one key = text per line, English is the reference and the
fallback); --lang <code> overrides the language for one session.
Requirements: CMake 3.21+, Ninja, GCC with GNU binutils (tested with GCC 13; on Windows,
MinGW-w64 GCC with POSIX threads; Clang cannot build the embedded Stockfish variants), and
Python 3 for the instruction-set audits and the Windows exception table check that run at every
build (a Windows Release build, the shipped exe, does not configure without it; other builds skip
them with a warning). The Linux build also needs the OpenSSL 3, X11 and OpenGL development files
(for example libssl-dev, libx11-dev and libgl-dev); ALSA is loaded at run time
(libasound.so.2), not linked, and a Linux Release build links libstdc++ and libgcc in, so that
the executable runs on other distributions than the build machine's. The Windows build is produced with
MinGW-w64 (native or cross-compiled from Linux) and is a single self-contained executable
(Stockfish 19 and its neural network are embedded). Stockfish is compiled once per x86-64
instruction set, from plain x86-64 to AVX-512, and the game runs the best one the CPU supports;
-DSCACELITH_SF_VARIANTS=x86-64-avx2 (or another variant the CPU runs) builds a single one, for
quicker local builds (see third_party/stockfish/README.scacelith.md). The first configure also
downloads the coach's voice model archive (129 MB, from the sherpa-onnx release on GitHub) into
the build folder, for the unit tests and --coach-dir build/coach:
-DSCACELITH_SUPERTONIC_DIR=<extracted folder> or -DSCACELITH_SUPERTONIC_ARCHIVE=<.tar.bz2>
take a local copy instead, and -DSCACELITH_SUPERTONIC_DOWNLOAD=OFF does without it (the tests
that need the model are then skipped; see third_party/supertonic3/README.scacelith.md).
# Windows x64 (cross-compiled from Linux)
cmake -B build-win -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/mingw-w64-x86_64.cmake -DCMAKE_BUILD_TYPE=Release
ninja -C build-win # -> build-win/Scacelith.exe
# Linux x86-64 (the game, its tests and headless screenshots)
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
ninja -C build
./build/scacelith_tests
# The Windows tests under Wine (ninja -C build-win scacelith_tests first)
tools/test_win.sh # [filter-substring]
Wine names the Linux files in the character set of the host locale: in the POSIX locale (LANG
unset, common in containers) that is ASCII, a file named after "Élodie" cannot be created and the
saved games' tests fail although Windows takes the name. tools/test_win.sh and
tools/shot_win.sh run Wine in a UTF-8 locale (LC_ALL=C.UTF-8) when the current one is not.
Development options: --scene <name> runs a viewer scene (--list-scenes), --data-dir .
reads shaders from disk and F5 reloads them, F12 saves a screenshot,
--shot out.png --frames N --size 1280x720 renders headlessly (leaving the settings file and the
saved games as they are). tools/shot.sh and tools/shot_win.sh do this under Xvfb (Linux build
and Windows build through Wine). The Windows exe has no console: redirect what it prints
(Scacelith.exe --list-scenes > scenes.txt, or | more), or configure with
-DSCACELITH_CONSOLE=ON for a console build.
The game itself (--scene game, the default) takes --start (a game against Stockfish at once;
--human white|black), --viewer (a watched game at once; --white-preset N --black-preset N
with N an index of the preset list, --viewpoint 0..9), --tc N (time control index), --cam x,y,z [--look x,y,z] [--fov deg] (initial observer camera when watching; a detached camera in a
normal game), --handover-preview (watching through the players' eyes with the clock frozen during
each camera handover, the same hand-over as hot-seat), --no-intro,
--warp <seconds> (with --shot: simulate before the first frame), --moves e2e4,e7e5,..., --touch <square>,
--mouse fx,fy (pointer position as fractions of the window; the view follows it, 0.5,0.03 looks
up at the opponent), --glance (start looking at the scoresheet), --calibrate (the brightness
calibration before the title page, as on a first start) and --ini <file>.
Two players on one PC: --start --hotseat starts one at once, with --white-name N, --black-name N, --clock-right white|black, --rated and --handover <seconds> (0 = instant cut). --play e2e4,e7e5,... plays the human moves by hand, the way a player would (touch, carry, press the
clock): both sides on one PC, the human's side against Stockfish; with --warp it takes
screenshots of a game in progress, for instance the hand-over halfway (--start --hotseat --no-intro --play e2e4 --warp 2.35). The UI viewer has the hot-seat screens (--scene ui --ui-screen newgame-hotseat|hotseat-hud|hotseat-confirm|hotseat-gameover).
Coach mode: --start --coach starts a coach game at once, at the level and colour of the Coach
page unless --coach-level 0..6 (0 = the rules lesson) or --coach-colour white|black say
otherwise; --coach-dir <folder> reads (and downloads) the voice model files in that folder instead
of the default one (--coach-dir build/coach: the copy a development build prepares).
SCACELITH_COACH_SOURCE=github in the environment skips Hugging Face (to try the fallback), and
--scene ui --ui-screen coach-flow [--coach-dir <folder>] runs the download flow over the title
page (coach-download* screens: the prompt and the panel with sample figures).
--coach-stage-test (alone, or with --start) runs a fixed sequence through the scene's coach
stage without the session: a line spoken and subtitled, the coach pointing at g1 and
tracing the knight's jump to f3 on their words, a mark and a highlight, two demonstration moves
taken back by hand, then the takeback card (--coach-stage-test lesson: on the lesson's first
position); its log gives the time of each step, for --warp. --coach-auto-answer yes|no answers
the takeback card by itself after 1.5 s, for runs with --play.
See docs/ARCHITECTURE.md for how the engine is organised.
GitHub Actions builds and tests every push to master and every pull request
(.github/workflows/ci.yml): the Linux build and its unit tests, the Windows build cross-compiled
with MinGW-w64 and its unit tests under Wine (both as above), and a lint of the workflows
(actionlint and zizmor). The Windows executable of each run is kept for 14 days as a workflow
artifact, for testing. CodeQL (.github/workflows/codeql.yml) scans the shipped C++ code
(without third_party/ and tests/) and the workflows; its alerts are in the Security tab.
The version is set in cmake/version.cmake: SCACELITH_VERSION_CORE (1.0.0) and, for a
pre-release, SCACELITH_VERSION_PRERELEASE (beta.2); cmake -P cmake/version.cmake prints it
in full. Pushing the tag v + that version (v1.0.0-beta.2) publishes a release: the release
workflow (.github/workflows/release.yml) checks that the tag matches the version, runs the CI
again on the tagged commit, builds the game from scratch (no compiler cache) for Windows x64 and
for Linux x86-64 (on Ubuntu 22.04, the oldest toolchain supported, where the unit tests run again
and the executable is checked to need only system libraries and glibc 2.34), attests the build
provenance of the files with actions/attest and publishes a GitHub release (a pre-release when the
version has a suffix) with Scacelith-<version>-windows-x64.zip (the executable, its licence and
the licence texts of what it embeds), the Windows executable alone,
Scacelith-<version>-linux-x86_64.tar.gz (the executable, its launcher and icons, install.sh
and the same licences) and SHA256SUMS. Started by hand, the
workflow builds the same files and keeps them as workflow artifacts without publishing anything,
unless it runs on a tag with "Publish" ticked. To check a downloaded file with the GitHub CLI:
gh attestation verify Scacelith-1.0.0-beta.2-windows-x64.zip --repo DarkCenobyte/scacelith-chess
Dependabot (.github/dependabot.yml) keeps the actions the workflows use up to date (pinned by
commit SHA); the code vendored in third_party/ is updated by hand.
Scacelith is free software under the GNU General Public License v3.0 (see LICENSE), because it
embeds Stockfish (GPL-3.0), whose source is in
third_party/stockfish/ with its own copyright notices. Stockfish's neural network was trained on
data provided by the Leela Chess Zero project, which is made available under the Open Database
License (ODbL). The Cinzel, EB Garamond and Amiri (Khaled Hosny) interface fonts and the handwriting
fonts Caveat (Impallari Type), Marck Script (Denis Masharov), Bad Script (Gaslight), Aref Ruqaa
(Abdullah Aref, Khaled Hosny), Klee One (Fontworks) and LXGW WenKai / WenKai TC (LXGW) are under the
SIL Open Font License 1.1; the Arabic and CJK fonts (Amiri, Aref Ruqaa, Klee One, LXGW WenKai /
WenKai TC) are subset and renamed from the upstream files by tools/prepare_fonts.py, the others
are the upstream files unchanged. The chess figures of the promotion picker come from a subset of
GNU FreeFont FreeSerif (GPL-3.0+ with the font exception). All licence texts are in assets/fonts/
and assets/fonts/hand/. The coach's voice model (Supertonic 3) is not part of the program nor of
its release package: the game downloads it from its publishers at the player's request. It has its
own licence (BigScience Open RAIL-M), whose use restrictions the download prompt shows; see
third_party/supertonic3/README.scacelith.md.
C++
95.2%
GLSL
3.0%
Python
1.3%