← Back home

How Chess Gimmicks works

A short tour of the engine setup, how positions are evaluated, and how we simulate play weaker than Stockfish's native minimum rating.

The Stockfish setup

Every game and analysis runs entirely in your browser using a single-threaded Stockfish 18 WebAssembly build. We spin up two workers side by side: one dedicated to the opponent's actual moves, and a second one dedicated to background analysis (eval bar, move ranking, and the move-quality labels). Splitting them keeps the opponent responsive even while the analysis engine is still thinking.

You control two knobs that apply to every search: search depth (how many plies deep the engine looks) and a max think time (a safety cap so a single move can't hang forever). If depth completes first, the engine returns early; if the timer fires first, we take the best move found so far.

Position evaluation

The eval bar and the analysis card both use Stockfish's own centipawn score. A centipawn is one one-hundredth of a pawn, so "+150" means White is up roughly a pawn and a half of material and position combined. Mate scores are shown as "M5" for "mate in five", and always pin the eval bar fully to that side.

Move quality (best / excellent / good / inaccuracy / mistake / miss / blunder) is derived by comparing the eval before your move to the eval after, from your side's perspective. Small drops are fine, big drops in a winning position are labelled harshly, and a move that hangs mate is always a blunder.

Simulating weaker play

Stockfish's built-in UCI_Elo knob only reaches down to about 1320, and even in its supported range it works by capping search depth and adding random noise to the top candidates — which means blunder magnitude is unbounded (Stockfish at 1800 will still occasionally hang a queen). We don't use that knob for the opponent. Instead, at every Elo below full strength we ask the engine to score every legal move (MultiPV), then pick from that list ourselves against a centipawn-loss ceiling tied to the target rating.

The rule of thumb: the lower the target rating, the more centipawns of loss we tolerate when picking a move. A "very weak" bot happily picks a move that loses a full piece; a "moderately weak" bot might only accept losing a pawn or two. We also apply a couple of safety filters — the bot won't blindly walk into mate, and it won't hang a queen for nothing unless that's the flavour of weakness we're simulating. The result is a bot that makes plausible human-looking mistakes rather than a bot that plays random moves.

Modes with special behaviours (steering for a draw, mimicking your piece type, blundering on purpose, chasing captures) layer the same idea on top: score every candidate, then pick from the pool that fits the rule — and if no move fits, fall back to a normal move at the current rating.

Credits

The game modes here were primarily inspired by the "I Want Checkmate" YouTube channel, whose videos on tweaking, weakening, and stress-testing Stockfish sparked most of these ideas. Go watch his stuff — it's great: youtube.com/@iwantcheckmate.

Under the hood — realism tweaks

On top of the centipawn-loss ceiling, a few extra layers push the weak-opponent's moves toward something that looks human rather than like a random-move generator:

  • Elo-scaled tactical blindness. The hang-detector has an Elo-dependent severity threshold. A ~400-rated bot won't filter its own hangs at all; a ~700-rated bot will only refuse to hang a queen; a ~1200-rated bot avoids minor-piece hangs; stronger bots avoid anything above a pawn drop. Weak players really do drop pieces, and this makes that happen at the right rating rather than at every rating.
  • Material greed. When choosing among the moves its ceiling allows, the bot gives a small preference to captures and checks — scaled by rating, so a beginner grabs almost any pawn on offer while a strong club player is only nudged. This is the "humans reach for material" instinct, deterministic and bounded so it never overrides the weakness ceiling.
  • Per-game randomness (seeded, not stochastic). Each new game mints one seed. Within a game, the same position always produces the same choice — undo/redo is stable — but a fresh game against the same opponent from the same position picks a different plan. No probability-based blundering: the seed only breaks ties among moves the ceiling and greed layers already consider equally acceptable.
  • Tiny opening book. For the first few plies, if the position matches a common opening line, the bot plays from a small hand-curated book instead of searching. The book only activates above roughly 900 Elo, so weak bots still wander into their own openings, and the seeded pick means the same line won't repeat every game.

The rating cap is exposed as 3600, which is above Stockfish's commonly-cited 3190 ceiling. In practice long-time-control Stockfish 18 reaches into that range, and the higher rungs of the ladder give it the depth and time budget to actually play there.