Skip to content

Multi-threaded engine, fix lost-stop timeouts, auto update check (v1.1.0) - #1

Merged
ccharafeddine merged 1 commit into
masterfrom
claude/loving-hypatia-d1h2xo
Sep 24, 2026
Merged

ccharafeddine merged 1 commit into
masterfrom
claude/loving-hypatia-d1h2xo

Conversation

@ccharafeddine

Copy link
Copy Markdown
Owner

Summary

Fixes analysis timing out after moving quickly. The stockfish.js worker queues go while a previous search is still unwinding, but runs stop immediately. That meant a stop could land before the search it was meant for and be lost. The 3s stop watchdog then rebuilt the engine (recompiling the 113MB WASM) and analysis failed. I reproduced it in Chromium: on the old code, 16 of 35 rapid positions got no analysis. Changes:

  • stop is re-sent every 100ms until its bestmove arrives, and the stop watchdog is raised to 8s.
  • A final result whose lines all fail the legality filter now shows a retry warning instead of spinning forever.
  • New regression tests (src/engine/stockfish.test.ts) use a fake worker that mirrors the real command queueing. They fail without the fix.

Engine speed and strength

  • The app was shipping the single-threaded Stockfish build (public/stockfish.* byte-matched stockfish-18-single), so the Threads option was ignored. It now uses the multi-threaded NNUE build: about 4× nodes/sec on 4 cores.
  • The engine is served and copied from the stockfish npm package by a Vite plugin, replacing the committed 113MB LFS blob. .gitattributes and the LFS checkout in the workflows are removed.
  • Startup now waits for readyok after Threads/Hash, and the redundant ucinewgame (a second clear of the 512MB hash) is gone. Warm start is about 3.5s to the first move.
  • New think time setting (1/3/5/10s), and the analysis debounce is shorter.

Update check

  • The app now checks for updates automatically at startup. This can be turned off in the settings menu.
  • When a newer release exists, a banner appears (dismissible per version) and the settings gear shows a dot.

Electron / app

  • Fixed port with a random fallback, so localStorage settings persist across launches and the WASM code cache works.
  • Files are streamed with ETag/no-cache instead of a blocking readFileSync.
  • Single-instance lock.
  • Fonts are bundled via @fontsource. Google Fonts was blocked by the app's own CSP/COEP.
  • Version bumped to 1.1.0.

Testing

  • npm run lint, npm test (45 tests) and npm run build pass.
  • Stress-tested in Chromium with rapid position changes: no engine restarts, and the first line arrives within about 1–100ms of each change.
  • UI end-to-end run (drag moves, settings, mocked release banner) against the Electron server code.
  • I haven't launched the Electron app itself.

🤖 Generated with Claude Code

https://claude.ai/code/session_017ZHKbLKcpoa8QJGzqkbDTJ


Generated by Claude Code

…1.0)

Engine speed and strength:
- The app was shipping the single-threaded Stockfish build (the committed
  public/stockfish.* matched stockfish-18-single), so Threads was ignored.
  Switch to the multi-threaded NNUE build: ~4x nodes/sec on 4 cores.
- Serve/copy the engine from the stockfish npm package via a Vite plugin
  instead of committing a 113MB LFS blob.
- Wait for readyok after Threads/Hash at startup and drop the redundant
  ucinewgame that re-cleared the 512MB hash (warm start ~3.5s).

Reliability (analysis failing after moving quickly):
- The worker queues `go` while a search unwinds but runs `stop` at once,
  so a stop could be lost; the 3s stop watchdog then restarted the engine
  and analysis failed. Re-send `stop` every 100ms until its bestmove and
  raise the stop watchdog to 8s. Regression tests with a fake worker that
  mirrors the real command queueing.
- A final result whose lines all fail the legality filter now surfaces a
  retry warning instead of spinning forever.

App:
- Think time setting (1/3/5/10s); shorter analysis debounce.
- Automatic update check at startup (toggleable), with a banner and a dot
  on the settings gear when a newer release exists.
- Electron: fixed port so settings persist across launches and the WASM
  code cache works; streamed files with ETag; single-instance lock.
- Bundle fonts locally (Google Fonts was blocked by the app's CSP/COEP).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZHKbLKcpoa8QJGzqkbDTJ
@ccharafeddine
ccharafeddine merged commit 4ff0d79 into master Sep 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants