The Problem
Existing chess libraries (Chessboard.js, chess.js, Lichess components) are designed for standard chess. If you want Atomic Chess, Racing Kings, or any variant with non-standard rules, you're forking entire codebases and fighting architectures that assume one set of rules. There was no engine that treated chess variants as a first-class extension point. Certainly nothing you could build an entirely different game on top of.
Architecture
The engine separates concerns into layers that can be independently replaced or extended by consumers:
- Board geometry — supports boards from 4x8 to 12x8 with configurable square properties
- Move generation — base engine handles standard moves; variants override via hooks for custom piece behaviour, capture rules, and victory conditions
- AI system — Web Worker-threaded search with iterative deepening, transposition tables, quiescence search, move ordering, opening books (26 variants), and variant-specific evaluators
- Rendering — pure SVG with renderer extension hooks:
tilePainterfor custom tile visuals,pieceProviderfor custom piece graphics,afterRenderfor overlays,legalMoveRendererfor move indicators - Plugin interface — tiered architecture (Tier 1: rule overrides, Tier 2: engine extensions, Tier 3: effects/mutations/action moves). Each variant is a single file calling
registerVariant()
Consumer Game SDK (v0.9.1)
The engine evolved beyond chess variants into a reusable game framework. Native ESM throughout (no build step, same source serves browser, Worker, and Node.js). Consumer APIs let other games use MCE's move engine, AI, and renderer without being chess:
- createGameController() — reusable game loop with turn cycling, AI scheduling, and interaction hooks
- createReplay() — move-by-move playback module for any game built on MCE
- Renderer extensions — tilePainter, pieceProvider, legalMoveRenderer, suppressHighlights, excludePiece
- Unit template system — config-driven piece registration for non-chess units
- Terrain predicates — generic system replacing hardcoded game-specific checks
- Effect lifecycle hooks — before/after move callbacks for game-specific logic
Proof: Dungeon Chess is an asymmetric skirmish game with 4 factions, dungeon terrain, and XP-budgeted drafting. It runs entirely on MCE's consumer SDK. Custom tilePainter renders dungeon walls and water; custom pieceProvider renders fantasy units; the game controller handles multi-faction turn cycling. Zero engine forks.
MCP Tools (AI-Callable)
Seven chess tools exposed at tools.moddable.games via MCP protocol, REST API, OpenAPI, and llms.txt. Any MCP-compatible AI agent can analyse positions, validate moves, generate puzzles, and probe opening books:
- chess_list_variants — browse all 70 variants with rules and metadata
- chess_get_legal_moves — legal move generation for any position in any variant
- chess_analyze_position — AI evaluation with best-move analysis
- chess_validate_move — move legality checking with explanations
- chess_make_moves — apply move sequences and return resulting position
- chess_get_opening_book — probe variant-specific opening books
- chess_generate_puzzle — create mate-in-N puzzles for training
The Developer Experience
This is a DevRel problem as much as an engineering one. The question isn't "can the engine support more variants?" but "can someone add one without understanding the engine internals?"
Developer guides walk through increasing complexity: building a basic variant, then Crazyhouse (hooks and piece drops), then Poison Chess (beforeMove effects). The plugin interface fails loudly with clear error messages when the contract is violated. Example variants ship as reference implementations at every level.
Try It
Play against the AI below. Switch variants to see how the same engine handles completely different rule sets, from exploding pieces to fog of war to racing your king.
Live embed: variant switcher controls the iframe URL, background matched, no scrolling
Embed API
Any variant can be embedded on any website with a single iframe. URL parameters handle initial configuration:
?variant=atomic— select the variant?difficulty=hard— AI level (beginner, easy, medium, hard, expert)?embed=1&boardonly=1— minimal chrome for embedding?theme=transparent&bg=0B0F1A— visual theming
PostMessage API
Once embedded, control the engine at runtime without rebuilding the iframe. Switch variants, themes, difficulty, or start new games via postMessage:
chess:setVariant— switch to any variant instantlychess:setTheme— change visual themechess:setDifficulty— change AI level (beginner → expert)chess:newGame— reset the board with current settingschess:setBg— change background colour