How the analysis works
RookSac runs a real chess engine on your device and turns its evaluations into a report. This page explains what the engine is, how positions are scored, and where the method's limits are.
Last updated: September 15, 2026
The engine
Analysis uses Stockfish 17.1 Lite WASM (compiled to WebAssembly), running in the browser. The bundled single-threaded engine build is about 7 MB — substantially stronger than the former Stockfish 10 default while remaining practical for large local batches and browsers that do not support shared-memory engine threads.
Games are analysed across a pool of Web Worker engines, defaulting to your CPU core count,
so several games are in flight at once. You can raise or lower the worker count, the search
depth, and the number of candidate lines in the engine settings panel. If you want more
strength, you can host a stronger NNUE build's .js, .wasm and
.nnue files and point the Engine source field at it; the bundled dev
server already sends the cross-origin isolation headers a multi-threaded build needs.
Win% and accuracy
The engine reports an evaluation in centipawns (or a mate distance). RookSac converts that to a win probability for the side to move using the Lichess model, so a +1.5 in a sharp middlegame and a +1.5 in a dead-drawn endgame are treated differently in practical terms.
A move's quality is the drop in win% it caused: the win% of the position before your move minus the win% after it. Per-move accuracy maps that drop onto a 0–100 scale with an exponential curve (again the Lichess model). Game accuracy applies a Stockfish-17-specific calibration fitted to 25 Chess.com-reviewed games (50 player scores): its mean absolute error is 2.97 points with -0.11 overall bias on that fixture. Reports made with the former Stockfish 10 default retain the legacy formula recorded with those reports. Move loss is capped so that a single mate-score swing does not distort an otherwise normal game's average.
Moves made in a flag race — started with under two seconds on the clock and no increment to win time back — keep their label but are left out of accuracy. At that point a premove is deciding the game, not the player's judgement, and one of them would otherwise outweigh an entire well-played game.
Because saved analyses store win% as well as the raw score, an older report can be recalibrated onto the current classification path without re-running the engine.
Searching each position once
A naive review searches every position, then searches again to check the move that was actually played. RookSac avoids most of that second pass: the position reached after a move is reused as the "before" position for the next move. Top moves come out at exactly zero loss, and a game needs roughly one engine search per ply instead of one search plus a second search for every error. The cost is minor depth-to-depth evaluation noise, which is why very small win% differences are grouped rather than ranked.
What the engine says, kept whole
Stockfish reports more than one number. Alongside the evaluation it gives a win/draw/loss estimate for the position, and for a forced mate it reports the mate itself rather than a very large score. RookSac keeps both with every move. A score on its own cannot separate a winning advantage from one that is drawn with the material left on the board — the outcome model can, so the review says so, and an exercise accepts a different move that reaches the same result.
Questions a position cannot answer
Some things are only true in comparison. Zugzwang is one: it is not a pattern on the board but the fact that having to move is worse than being allowed to pass. In an ending, after a quiet move, RookSac asks the engine both questions — the position as it stands, and the same position with the other side to move — and says so when moving is what costs the material. It is the one explanation here that spends extra search time, so it is asked only where it could be true, and only about a position that a free move would have kept playable.
Fast bulk review
With Fast bulk review on (the default), the full-game pass uses a single principal line, played moves are not re-searched, and the engine's transposition table is kept warm between games. Turning it off applies your chosen number of candidate lines to every position. Live puzzle positions request multiple lines regardless, where the extra branches are actually needed.
Two things apply in both modes. Each engine thread works through a stretch of a game's positions in order, so every search starts with the previous position's work still in the engine's memory. And positions inside known opening theory are searched to depth 8 rather than the full depth: those moves are labelled book and count as fully accurate whatever the engine says, so the search there only draws the evaluation graph.
Opening names
Opening names come from the CC0 lichess-org/chess-openings library and are matched by position, not by the text of the game header. Transpositions are therefore named correctly, and the name updates as you explore a different line on the review board.
Book moves
Book detection starts with that named-opening catalog, then continues through a compact, bundled set of positions reached repeatedly in a fixed sample of CC0 Lichess rated games. The extended set uses standard games where both players were rated at least 2000 and the time control was blitz or slower. Only position hashes are shipped with RookSac; no player or game data is included.
The extended book is loaded only when a game goes beyond the named catalog. It is local, makes no opening-explorer request, requires no login or API token, and gives the same result in every browser. This also keeps analysis from waiting on a network service. The selection is deliberately conservative, so rare sidelines and recent theory may still be evaluated by Stockfish rather than labelled as book moves. A small, reviewable supplement covers confirmed theory lines that are too rare to survive the sample threshold; each line stops before the first move that has not been accepted as theory.
Move classification
The label on each move (Best, Forced, Inaccuracy, Blunder…) is derived from the win% drop plus a few special cases — only-moves, missed wins, sound sacrifices, and endgame moves that lose precision while still retaining a clear win. Forced is rules-based: it means there was only one legal move. The full policy is on the move classifications page and lives in one file in the source so it is easy to audit and tune.
What this is not
- Not a coach. The engine tells you the objectively best move. It does not know which mistakes are worth fixing first for a human at your level — that is what the improvement plan tries to approximate, but it is a heuristic.
- Not depth-unlimited. The default depth is chosen for throughput. In genuinely complex positions a deeper search, or a stronger engine build, can disagree with the report.
- Not a cheat detector. High accuracy in one game means one game went well, nothing more.
Privacy
Every step above happens in your browser. Your games are read from the public Chess.com or Lichess API by your own device and are never uploaded to us or stored on a server. See the privacy policy for the full detail, including what Google AdSense does.