How to write the engine: block that defines a game variant. This is the primary interface for adding new games to the engine.
Every game variant in moddable-rules has a Markdown file with YAML frontmatter. The engine: block tells the engine everything it needs to render the board and (eventually) play the game.
---
title: My Variant
engine:
topology:
type: grid
rows: 8
cols: 8
surface: parchment
render:
cellColor: checkered
labels: true
setup: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
pieces:
set: mce-chess
players: [white, black]
---
Defines the spatial structure. Required for any game with a board. The type field determines which topology is used and what other fields are valid.
Visual theme. Either a named string (parchment, slate, etc.) or an inline object with custom colours.
Controls how the board is drawn: cell colouring, labels, decorations, coordinate style, and the ops pipeline.
Initial position. Format depends on topology type (FEN for grids, coordinate pairs for hex, etc.).
Which piece set to use and optional configuration (borders, vocabulary mapping, FEN overrides).
Rectangular boards. Chess, draughts, go, xiangqi, shogi, pachisi.
| Field | Required | Description |
|---|---|---|
type | Yes | Must be grid |
rows | Yes | Number of rows |
cols | Yes | Number of columns |
layout | No | cells (default), intersections, or cross |
layers | No | Number of boards for multi-board games (Alice Chess) |
layer_labels | No | Array of board names ([Board A, Board B]) |
cells = pieces on squares (chess). intersections = pieces on line crossings (go, xiangqi). cross = pachisi-shaped cross pattern.Hexagonal boards. Hex, nukes, hex-chess variants.
| Field | Required | Description |
|---|---|---|
type | Yes | Must be hex |
shape | No | hexagonal or triangular |
radius | No | Hex radius (for hexagonal shape) |
rows / cols | No | Rectangular hex grid dimensions |
grid | No | Explicit array of [q, r] coordinates |
orientation | No | pointy (default) or flat |
sideLength | No | For triangular shape |
shape + radius, or rows + cols, or explicit grid array.Linear paths. Backgammon, Landlord's Game.
| Field | Required | Description |
|---|---|---|
type | Yes | Must be track |
positions | Yes | Number of positions on the track |
Mancala-family sowing games.
| Field | Required | Description |
|---|---|---|
type | Yes | Must be pit |
cols | Yes | Pits per side |
rows | No | Number of rows (default 2) |
stores | No | Whether end stores exist (default true) |
Arbitrary node-edge structures. Morris, stern-halma, nyout, asalto.
| Field | Required | Description |
|---|---|---|
type | Yes | Must be graph |
structure | Yes | concentric-rings, perimeter-cross, grid-cross, or star |
params | No | Structure-specific: rings, midpoints, diagonals |
nodes | No | Explicit node definitions (for custom graphs) |
edges | No | Explicit edge definitions |
A surface provides default colours for the board. Reference by name or define inline.
# Named surface
surface: parchment
# Inline colours
surface:
colors:
cell-light: "#dcb35c"
cell-dark: "#d4a843"
stroke: "#3d2b1a"
background: "#2c2c2c"
Available named surfaces:
| Name | Character |
|---|---|
wood-classic | Traditional wood tones (chess default) |
wood-light | Lighter wood (go boards) |
felt-green | Green baize (card table) |
parchment | Aged paper |
earth | Brown/terracotta |
slate | Cool grey stone |
jungle | Deep greens |
military | Olive/khaki tactical |
cosmic | Dark space theme |
Each topology type has its own notation for initial positions.
# Standard chess
setup: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
# Multi-board (Alice Chess) — array of FENs
setup:
- rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
- 8/8/8/8/8/8/8/8
# 4-player (comma-separated, colour-prefixed)
setup: rR,rN,rB,rQ,rK,rB,rN,rR/rP,rP,rP,rP,...
# Large shogi (bracket notation for multi-char pieces)
setup: [ln][kn][ph][ig][fk]...
# q,r:piece format
setup: "0,0:mount,0,1:grass,1,0:grass,-1,0:base"
# Backgammon: position:countOwner pairs
setup: "0:2W,5:5B,7:3B,11:5W,12:5B,16:3W,18:5W,23:2B"
# Format: south-pits;south-store;north-pits;north-store
setup: "4,4,4,4,4,4;0;4,4,4,4,4,4;0"
# Morris/Halma: empty string means no initial pieces
setup: ""
# With pieces placed
setup: "n1:W,n4:B,n7:W"
Game definitions use inheritance. The family rulebook provides defaults, and each variant overrides only what differs.
# Family rulebook.md — shared by all variants
engine:
topology:
type: grid
rows: 8
cols: 8
surface: wood-classic
render:
cellColor: checkered
labels: true
ops:
- op: cells
pattern: checkered
- op: border
pieces:
set: mce-chess
# Variant (e.g. capablanca.md) — only overrides what changes
engine:
topology:
cols: 10
setup: rnabqkbanr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNABQKBANR
The cascade resolver deep-merges: surface defaults → family engine → variant engine. Variants inherit everything from the family and only specify differences.
---
title: Capablanca Chess
engine:
topology:
type: grid
rows: 8
cols: 10
setup: rnabqkbanr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNABQKBANR
pieces:
set: mce-chess
---
---
title: "Nukes: Standard"
engine:
topology:
type: hex
shape: hexagonal
radius: 3
orientation: pointy
players: [player1, player2]
render:
cellSize: 24
cellColor: terrain
frame: true
setup: "0,0:mount,0,1:grass,1,0:grass,1,-1:trees"
---
---
title: Oware
engine:
topology:
type: pit
cols: 6
stores: false
players: [south, north]
render:
cellSize: 24
setup: "4,4,4,4,4,4;0;4,4,4,4,4,4;0"
---