A cinematic Electron chess app with a marble board, smoked-glass pieces, direct Three.js rendering, Stockfish-powered AI modes, clocks, replay, and analysis.
- Human vs Human, Play against AI, and AI Play from the same 3D board flow
- Stockfish 18 launched as a bundled native child process from the Electron main process
chess.jsremains the single rules authority for legal moves, FEN, PGN, game-end detection, and move history- Analysis mode with live evaluation, best move, MultiPV candidate lines, and replay-time move review
- Untimed, Bullet, Blitz, Rapid, and Custom clocks
- Save/load game snapshots, PGN export/import, FEN copy/load, and replay stepping/autoplay
- Electron Playwright regression coverage plus unit/integration tests for parser, controller, clocks, and persistence
npm install
npm run devOn first install, postinstall runs npm run prepare:stockfish, which validates the pinned bundled Stockfish binaries already committed under resources/stockfish. If a required asset is missing or invalid, the script re-downloads the pinned official release asset automatically.
Useful scripts:
npm run prepare:stockfish
npm run build
npm run package:mac:dir
npm run test:unit
npm run test:e2e
npm run test:packaged-smoke
npm run check
npm run package:macnpm run prepare:stockfish maintains the pinned Stockfish 18 release assets for:
resources/stockfish/darwin-arm64/stockfishresources/stockfish/darwin-x64/stockfish
Packaged builds copy that folder into the app bundle with electron-builder:
Onyx Gambit.app/Contents/Resources/stockfish/darwin-arm64/stockfishOnyx Gambit.app/Contents/Resources/stockfish/darwin-x64/stockfish
The Electron main process resolves the binary from process.resourcesPath/stockfish/<platform>-<arch>/stockfish in packaged builds and from resources/stockfish/<platform>-<arch>/stockfish in development.
To explicitly refresh the pinned assets even when the local bundle is already valid, run:
npm run prepare:stockfish -- --forceHuman vs Human: local board play with clocks, undo, replay, and analysis.Play against AI: choose human color, configure per-side AI difficulty/time/depth, then start a new game. Input locks while the engine is thinking.AI Play: both sides are AI. Use autoplay delay plus pause/resume to watch a self-play game.Analysis mode: toggle it on to show current evaluation, best move, and top candidate lines. Completed games now precompute full move-review annotations so replay scrubbing and the move ledger stay instant after the game ends.Replay: use First/Previous/Next/Last or Autoplay Replay. Stepping away from the final ply pauses live play until you return to the last position.
- Choose
Human vs Human,Play against AI, orAI Playfrom the right-side mode panel. - Set clock preset, AI difficulty/time/depth, autoplay delay, and optional analysis mode.
- Press
Start / Newto apply the setup and begin from the initial position. - Click a piece, then a destination square to move. In
Play against AI, the board locks during engine thinking. InAI Play, usePauseandRestartto control autoplay. - Use
Undo,Resign,Flip view, replay controls, PGN/FEN tools, and save/load controls from the sidebar as needed.
The app also keeps an autosave in Electron user data and restores it on launch before exposing the renderer as ready.
Save gameandLoad gameuse a JSON snapshot that preserves mode, players, clocks, current position, replay state, and analysis metadata.Export PGNwrites move history in PGN format.Import PGNrestores a game from PGN.Copy FENcopies the currently displayed board state.Load FENrestores an exact board position from the sidebar input.- Replay/autoplay operate on the currently loaded game state, including imported PGN and loaded FEN positions.
A short implementation note lives in docs/architecture.md.
Current code layout:
electron/
main.js BrowserWindow bootstrap, IPC, dialogs, autosave, Stockfish lifecycle
preload.js Safe contextBridge surface for engine/storage APIs
stockfish-parser.js UCI line parsing helpers
stockfish-service.js Native engine process manager
resources/
stockfish/ Bundled Stockfish binaries and source/license pointers
scripts/
fetch-stockfish.mjs Official release downloader for bundled engine assets
src/
main.js Renderer bootstrap + DOM wiring
game-controller.js Authoritative gameplay, AI, clocks, replay, analysis state flow
clock.js Chess clock model
persistence.js Save/load, PGN/FEN, replay helpers
scene.js Three.js board rendering, picking, animation
tests/
electron.spec.mjs Desktop Playwright regression
integration/ Controller integration tests
unit/ Parser, clock, persistence tests
CIrunsnpm run test:unitandnpm run test:e2eon macOS for pushes, pull requests, and manual dispatches.Releasebuilds and smoke-tests macOS packages on Intel and Apple Silicon, then publishes.zipand.dmgassets to a GitHub Release when av*tag is pushed or when manually dispatched with a tag.
- Save/load snapshots are JSON files; PGN export/import is separate by design so clock and mode metadata are not pushed into PGN comments.
- Local packaging is covered by
npm run test:packaged-smoke; notarization is not configured yet.