Mudmap is a line-based plain-text format for describing the top-down layout of a level. It is meant to be written by an AI agent and read by a human.
Each section keyword starts a line and is case-insensitive. Lines beginning with // are comments and are ignored everywhere, including inside a grid.
map: TITLE — the display title.cell: 2m — scale hint, shown as “1 cell = 2m”.legend: — custom symbol definitions, one per line.grid: FLOOR NAME — starts a grid. One grid: block per floor; several become tabs.notes: — annotations, one per line.Each line after grid: is one row, one character per cell, taken verbatim — leading and trailing spaces are cells. A space is empty space (void, the page background shows through). Ragged rows are padded out to the widest row. Truly empty lines are skipped rather than treated as rows; use a line of spaces for an empty row. Rows end at the next section keyword or at the end of the text.
Always active — a legend: line for the same character overrides its default. Symbols are case-sensitive; the default markers are capitals.
In addition - | + / \ all default to wall, so a plain ASCII box map with no legend renders correctly (it still needs its grid: line). Watch out for one collision: a row starting with // is read as a comment, not as two / walls — mudmap warns when a skipped comment looks like a wall row.
CHAR TYPE [LABEL] [#HEXCOLOR] — the character is exactly one non-whitespace character. A lone = or : right after it is tolerated and skipped, so # = wall works. If the last token is a hex colour (#RGB or #RRGGBB) it overrides the colour; everything between the type and the colour is the label, which may be wrapped in double quotes.
legend: # wall = floor "Rope bridge" #a97142 b enemy "Bandit" #ef4444
Known types:
wall floor void water lava grass pitdoor gate (a coloured bar on a floor tile) and window (a pale slit on a wall tile) — the bar turns to match the wall run it sits innpc enemy spawn chest item key trigger exitstairs treeAn unknown type still renders — as a generic magenta marker showing the character (or in your #HEXCOLOR if you gave one) — and adds one warning. A grid character with no legend entry and no default is auto-registered the same way, but takes a deterministic colour derived from the character itself, so different stray symbols stay tellable apart.
TARGET TEXT. The target is either a single character (the note then applies to that legend entry everywhere, on every floor, and shows in tooltips and the legend panel) or a coordinate.
Columns are letters A, B, C… left to right (then AA, AB…); rows are numbers 1, 2, 3… top to bottom. So B3 is column B, row 3. The numeric form is x,y, 1-based from the top-left — B3 is 2,3. A coordinate note attaches to the most recently started grid:, so put a notes: section directly after the floor it describes. Unresolvable targets produce a warning, never an error.
map: Guard Post cell: 2m legend: = floor "Rope bridge" #a97142 grid: Ground floor ########## #..C...N.# D..~~~...# #..===...# #..~~~.E.# ####S##### notes: N Guard on patrol A3 Side door, locked
Hover any cell for its coordinate, symbol, type, label and notes. Click a cell to copy its coordinate token (e.g. B7) — that is how you tell the agent where to change something. Ctrl/⌘ + scroll zooms; fit scales the floor to the pane.