Claude is good at narration, but pretty awful at spatial reasoning.
While it’s fine to play encounters using the theatre of the mind without explicit tracking of character and monster locations, it can be fun to manage tactical positioning and get an overview of the party’s surroundings.
In order to solve this problem I defined a domain-specific language — DungML — that lets Claude generate tactical maps on the fly. Rooms, corridors, doors, windows, secret passages, and lighting are all declarative; the model only has to describe intent, not coordinates:
map "Quickstart" {
grid { bounds 30 x 18 }
renderer "hatched"
background "#CCCCCC"
}
room "antechamber" {
rect 2,4 12 x 10
label "Antechamber"
description "Cracked flagstones. Pillars hold up a sagging ceiling."
feature pillar at 4,6
feature pillar at 4,12
feature pillar at 12,6
feature pillar at 12,12
feature brazier at 8,6
}
room "sanctum" {
rect 18,4 10 x 10
label "Inner Sanctum"
description "A statue of a forgotten god still keeps watch."
feature statue at 23,7
feature altar at 23,11 scale 1.2
}
# Short corridor bridging the 4-unit gap between the rooms.
corridor "passage" {
width 2
segment line from 14,9 to 18,9
}
# Default door — wooden, closed, width 1. Three more lines of property
# would let you change those.
door at 14,9 {
connects room.antechamber, corridor.passage
}
door at 18,9 {
connects room.sanctum, corridor.passage
type iron
state locked
description "Old keyed lock. The wards still hum faintly."
}
# Windows on the antechamber's west wall — exterior light.
window at 2,7 { in room.antechamber width 1.5 }
window at 2,11 { in room.antechamber width 1.5 }
# A secret door in the antechamber's south wall — discoverable only
# on a successful Perception check.
door at 8,14 {
connects room.antechamber
type secret
description "A pivot stone. Catch the seam and the wall turns."
}Renders to:

Using a structured language allows definition of more complex tactical maps:

The system is flexible enough to render houses, caves, outdoor maps and the like:

Rendering is performed by a small JavaScript component embedded in the Chronicler application, allowing the system to update the map as locations are discovered and players move around:

The DungML editor allows saving of locations as PDF in old-school module format:
