All MicroEvals
Chess Engine Sable
Create MicroEval
Header image for Chess Engine Sable

Chess Engine Sable

Prompt

1. Board representation: 0x88 mailbox β†’ bitboards + magic bitboards (biggest win) This is the single largest bottleneck. 0x88 move generation and attack detection are branch-heavy; magic-bitboard sliding attacks are O(1) table lookups. This alone typically buys several-fold more nodes/second, which directly translates to searching deeper in the same time budget β€” often worth more Elo than any single search tweak. It's a large rewrite (board.ts is 930 lines) but it's the correct next step before tuning anything else further. 2. Real shared-memory Lazy SMP (currently it's "root voting," not true SMP) I checked useEngine.ts: each worker runs a fully independent search with its own TT, and the main thread just picks whichever worker's result looks best (pickBest) after they all finish. That's "N independent searches, take the best" β€” not the real trick behind Lazy SMP, which is a shared transposition table so threads with different move-ordering perturbations feed each other's TT and jointly explore more of the tree. Swapping the per-worker Int32Array TT for a SharedArrayBuffer + Atomics-guarded probe/store would let threads actually cooperate, giving much better scaling with core count than the current setup. 3. Replace/augment HCE with a small NNUE-style network This was the actual jump that took Stockfish from strong to dominant. You don't need to copy anything β€” a compact, efficiently-updatable (incremental on make/unmake) network trained from scratch on self-play games generated by this engine is completely original and is the highest-ceiling upgrade on the list. It's also the most work: you'd need a data-generation pipeline (self-play games + search-score labels), a trainer (can be done offline in Python, weights exported to a binary blob loaded by the JS engine), and quantized int8/int16 inference in the worker for speed. 4. Endgame tablebases beyond the hand-coded specialists endgame.ts covers KPK/KRK/KQK/KBNK/KBBK specifically. A generalized 3-to-5-piece WDL/DTZ tablebase (generated in-house via retrograde analysis, same technique already used for the KPK bitbase, just scaled up) would give provably perfect play in far more endgames instead of falling back to heuristic eval. 5. Automated parameter tuning (SPSA / Texel tuning) Every constant in search.ts (LMR table coefficients, RFP/futility margins, aspiration delta, time-management factors) and the eval's PST/mobility/king-safety weights currently look hand-set. Running self-play SPSA tuning (engine plays thousands of games against itself while a script perturbs each parameter and keeps improvements) is exactly how Stockfish's fishtest squeezes out Elo from an already-strong base β€” and it's original since it's just optimizing your parameters against your engine. 6. Smaller, still-valuable fixes Opening book: currently a short list of named hardcoded lines; a larger weighted repertoire tree (still original, built from your own analysis/self-play rather than copied databases) would extend book depth and improve transposition handling. Extend correction-history to more buckets (pawn corr-hist, non-pawn corr-hist, per-piece) if it's currently a single table β€” worth checking, since this is one of the more recent low-cost Elo-gainers in the SF-lineage. Multicut / history-based pruning extensions in the main search for extra selectivity at high depth. A proper regression suite (STS/WAC-style tactical test positions + self-play Elo regression) so future tuning has a measurable feedback loop rather than guesswork.