Skip to main content

Misty

A fog-of-war chess engine.

Fog of war (dark) chess is chess where you only see the squares your own pieces could move to. You never see your opponent's moves, only their consequences: a piece of yours disappears, a square you watch changes. Playing it well means reasoning over every position consistent with what you've observed so far, and mid-game that set can run into the millions.

Misty follows the architecture of Obscuro (Zhang & Sandholm, ICLR 2026), the first superhuman fog-of-war chess AI:

concern approach
belief exact enumeration of all positions consistent with the observation history
search scope knowledge-limited subgames over sampled information sets
search one-sided growing-tree CFR with PCFR+
evaluation Stockfish at depth 1 on subgame leaves
commit purification plus a resolve gadget at move selection

The hot paths (belief updates, visibility, observation derivation) run in Rust, measured at roughly 500x over the Python reference on the enumeration loop. The Python implementations stay maintained as the oracle: the test suite replays real games and requires Rust and Python to agree byte-for-byte at every ply.

Misty plays live at mistboard.com. Strength is gauged against humans; engine-vs-engine results only gate development.

Install

pip install misty-chess
brew install stockfish   # or: apt-get install stockfish

The package imports as fow_chess. Python 3.11+. Stockfish is invoked as a subprocess for leaf evaluation and must be on PATH (or set FOW_STOCKFISH).

The PyPI package is pure Python and runs everywhere; results are identical to the accelerated build but the belief hot path is ~500x slower, and the engine logs a warning saying so. For real strength at real time controls, build the Rust extension (binary wheels are planned):

git clone <repo> && cd misty
pip install -e '.[dev]'
cd fow_rust && maturin develop --release

Play a game

from fow_chess import EngineV2Strategy, RandomStrategy
from fow_chess.selfplay import play_game

result = play_game(
    EngineV2Strategy(seed=0, time_budget_seconds=5.0),
    RandomStrategy(seed=1),
)
print(result.winner, result.end_reason, result.plies)

Strength configurations are named profiles in fow_chess.engine_profile.PROFILES. The served engine is a named profile, so a bakeoff and production run identical configuration by construction.

Analyze a game

The engine ships with a post-game analyzer built for imperfect information. TruthGrader runs Stockfish at a fixed depth on the true board of a finished game; analyze_game_deep replays the game through the engine's exact belief and its own search, then classifies each mistake three ways: the true position was missing from the belief, it was absent from the sampled search set, or it was seen and the engine still chose badly. That split (belief / sample / decision) says which lever would have prevented the mistake.

import chess
from fow_chess import TruthGrader, analyze_game_deep

moves = [chess.Move.from_uci(u) for u in ("f2f3", "e7e5", "g2g4")]
with TruthGrader(depth=12) as grader:
    rows = analyze_game_deep(moves, chess.WHITE, grader=grader)
for r in rows:
    if r.verdict:
        print(r.ply, r.uci, f"-{r.grade.cp_loss}cp", r.verdict)

Serving

The engine speaks a JSON protocol over stdio, documented in docs/protocol/engine-protocol.md. scripts/live_move_worker.py is the long-lived worker; scripts/live_move_runner.py is the one-shot fallback. The server sends redacted observations only. The engine never receives hidden opponent state, and post-game full-information analysis is a separate request type, never a flag on the live one.

Development

pip install -e '.[dev]'
cd fow_rust && maturin develop --release && cd ..
pytest -n auto                                  # full suite, ~40s
cargo test --manifest-path fow_rust/Cargo.toml  # native parity pins

FOW_REQUIRE_RUST=1 makes a missing or stale Rust extension fatal instead of silently falling back to the slow Python path. Every architectural change ships behind a flag defaulting to prior behavior, then gets validated by bakeoff before the default flips.

License

GPL-3.0-or-later.

Metadata

Release files for misty-chess 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for misty-chess 0.1.2
File Size Uploaded
misty_chess-0.1.2.tar.gz 385.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for misty-chess 0.1.2
File Interpreter ABI Platform
misty_chess-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 661.0 kB

Release files / misty_chess-0.1.2.tar.gz

Download URL misty_chess-0.1.2.tar.gz
Size 385.7 kB
Tags Source
SHA-256 checksum
How to use checksums
fd2c7badc9ef3ebac0f28b88373e99e3896259763a95de8890090526060cfe60
BLAKE2b-256 checksum
How to use checksums
8c6a3e368c2d941bc050c5cb4b1bccc38be78e3771d51614de376023135d7cc6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / misty_chess-0.1.2-py3-none-any.whl

Download URL misty_chess-0.1.2-py3-none-any.whl
Size 275.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc1dc13ed5fab19aacfe80107674c3cd8340c17012842668643b0d252a4d3245
BLAKE2b-256 checksum
How to use checksums
746d3c9b73a3f1811d4268943026b420c3757d6b3db7b4d37336a8952556f313
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page