Play Brainfuck Chess in your browser
Watch on YouTube
Watch on Google Drive
Watch or download the MP4
Real, local two-player chess whose complete rules engine is directly authored in
Brainfuck. No compiler, transpiler, macro system, optimizer, source generator,
or prebuilt chess implementation emitted it, and no JavaScript rules fallback
backs it. The browser runs a persistent 8-bit Brainfuck machine in a Web Worker,
passes it atomic move attempts, treats it as a small byte-protocol server, and
renders the state that Brainfuck owns and returns. The standalone page needs no
build step, server, account, runtime network request, or dependency bundle. The
engine is the eight canonical instructions you can inspect in
engine/brainchess.bf.
- A genuine 8 by 8 chess game for two humans sharing one screen.
- Ordinary moves, captures, checks, checkmate, stalemate, promotion and underpromotion, en passant, and both sides of castling.
- Fifty-move, threefold-repetition, and insufficient-material draws.
- Transactional rejection: an illegal attempt cannot partially mutate the position, clocks, rights, history, or any other persistent tape cell.
- A responsive, keyboard-accessible standalone UI with board flip, sound, move animation, engine telemetry, and an embedded-source inspector.
- An independent test VM, orthodox-chess oracle, adversarial fixtures, random differential games, protocol checks, pointer/tape invariants, and a static anti-cheat audit.
For this local two-player build, the third occurrence and 100th halfmove end the game automatically. Literal FIDE tournament procedure normally makes those two thresholds claim-based (with fivefold/75-move automatic); the engine-owned predicates are kept separate so a future protocol can add claims without moving rule authority into the browser.
Brainfuck Chess was deliberately conceived as a capability test and showcase for advanced coding models: could one directly author, integrate, and verify a complete chess engine in raw Brainfuck, without a compiler, source generator, or JavaScript rules fallback? AI authorship is the subject of the experiment, not a shortcut around a conventional implementation.
Paweł conceived and creatively directed the project, defining its product vision, direct-Brainfuck constraint, UX goals, and acceptance decisions. OpenAI Codex, running GPT-5.6 Sol, served as the implementation author end to end, including the Brainfuck engine, standalone browser UI, verification suite, and documentation through iterative collaboration with Paweł.
The initial July 12 foundation through boundary commit
fdd73a9
established the purity and protocol contracts, UI shell, reset, and early pawn
mechanics. Subsequent work, especially the July 18–19 integration history,
meaningfully extended it into the finished product: the remaining chess rules;
transaction and safety work; terminal and draw adjudication; canonical UI
embedding; independent VM, oracle, module, and milestone tests; mandatory CI;
and final UX polish.
Representative post-boundary history includes the first direct-BF knight
transaction (3170f24),
activated terminal search (860afd6),
completed draw adjudication (778da7b),
mandatory release validation (a154c78),
and final UX polish (c1d1e44).
Bulk-synced checkpoints are evidence of repository integration dates, not claims
about when their underlying work was originally authored.
- Open the live GitHub Pages build,
or download the repository and open
index.htmldirectly for fully local, offline play. - Click or focus a source square, then a destination square.
- Choose the standing promotion preference at any time; the same byte is sent with every attempt and the BF engine ignores it unless promotion applies.
- Use F to flip the board, M to mute, or the visible controls.
The interface deliberately shows no browser-generated legal-move dots. That is not a missing convenience: the browser does not know what a legal move is. It stages two coordinates and lets the tape accept or reject the complete record.
clicks / keys
|
v
browser: encode two square addresses + promotion preference
|
v
persistent canonical BF VM: all chess rules and state transitions
|
v
framed binary STATE record
|
v
browser: render bytes, animate, announce, and play presentation sound
The browser host may:
- execute the eight Brainfuck instructions with wrapping 8-bit cells;
- queue bytes and map a fixed visual-square address to a fixed mailbox address;
- decode the engine's documented output frames;
- render piece/state bytes, animate, play sound, and keep a presentation log.
It may not:
- determine ownership, turn, attack, check, or legal movement;
- generate, validate, repair, or reject a move;
- implement a capture, castle, en-passant move, or promotion;
- determine checkmate, stalemate, or any draw condition;
- generate or transform any part of the Brainfuck source.
If the embedded BF source is removed, the board is inert and the UI reports a hard engine error. It has no fallback position or dormant JavaScript rules path.
The 64 visible squares sit inside a 10 by 12 sentinel mailbox on the tape.
Movement is therefore expressible as fixed pointer deltas: 1 horizontally,
10 vertically, 9/11 diagonally, and the usual eight signed knight deltas.
Off-board probes land on 255 sentinels instead of requiring division, modulo,
or host-side coordinate geometry.
Every candidate passes through one transaction path:
- Read and classify the source and destination through handwritten indirect tape access.
- Prove piece geometry and obstruction.
- Apply the complete candidate position, including special-move side effects.
- Run the shared attack service against the moving king.
- Restore the exact prior position for an illegal move or a search probe.
- Commit public metadata only for a surviving real move.
The same transaction is probed by the reply enumerator after a commit. No legal reply plus check becomes mate; no legal reply without check becomes stalemate. Repetition uses reversible move records and full position comparisons, including side, castling rights, and en-passant identity. Terminal precedence is decided before automatic draw bookkeeping.
The canonical source contains one physical MOVE body and one copy of each
pinned safety, reply-streamer, insufficient-material, and draw-adjudicator
literal. Semantic traces require a real nonterminal move to enter the material
service and adjudicator exactly once, while rejection, checkmate, and stalemate
enter neither. The lifecycle, forced-reply, draw-history, terminal, and
late-slider evidence is indexed in docs/proof-ledger.md.
See docs/architecture.md, docs/tape-map.md, and docs/protocol.md for the
white-box design and byte-level contracts. CONTRIBUTING.md defines the strict
direct-authorship boundary for any future engine change, while
docs/proof-ledger.md indexes the pinned standalone BF evidence.
Node.js is used only for tests. Nothing in tests/ is shipped as an engine and
nothing there writes or translates BF source.
node tests/self-test.mjs
node tests/browser-worker-vm.mjs
node tests/test-atomic-protocol.mjs
node tests/milestones/terminal-search-cycle.mjs
node tests/milestones/legal-replies.mjs
node tests/milestones/draw-literals.mjs
node tests/diagnostics/trace-draw-integration-seam.mjs
node tests/diagnostics/trace-draw-staging-activation.mjs --ep
node tests/milestones/draws.mjs
node tests/milestones/terminals.mjs
node tests/test-reset-direct.mjs
node tests/run-tests.mjs index.html --protocol binary
node tests/run-tests.mjs index.html --protocol binary --extended
node tests/audit-shell.mjs index.htmlThe important evidence is layered:
- The BF engine is exercised directly in a separate strict interpreter, without the HTML/JavaScript renderer.
- A separate chess oracle supplies expected state; malformed and legal records are compared byte-for-byte, and rejected transactions must preserve the tape.
- Standalone direct-BF modules exhaustively prove awkward primitives such as indirect reads/writes, slider rays, attack detection, castling predicates, snapshots, repetition history, and material classification.
- The browser VM is differentially tested against the strict test VM.
- The release audit strips the embedded BF block, inventories the remaining JS, rejects chess-decision functions/tables and hidden runtimes, and requires the embedded opcode stream to equal the canonical engine.
Static inspection alone cannot prove that arbitrary code is honest. A visible source, two independent interpreters, an oracle, whole-tape invariants, pinned hashes, and a deliberately dumb renderer make the claim falsifiable in several different ways.
- Wrapping unsigned 8-bit cells
- Right-growing tape
,suspends when no input byte is available- Canonical
><+-.,[]behavior otherwise
Non-opcode source text uses only uppercase letters, digits, underscores, colons, and whitespace. This matters because Brainfuck has no comment delimiter: normal punctuation can accidentally be executable.
index.html: standalone game, worker VM, renderer, and verbatim release embedengine/brainchess.bf: canonical directly authored rules enginetests/modules/: independently verified handwritten BF servicestests/milestones/: integration and chess-rule fixturestests/: interpreters, oracle, protocol, differential replay, and purity auditdocs/: architecture, tape allocation, protocol, and integration proofs
0 comments
log in to comment.