To unify the semantic MUD graph, the 2D spatial grid, and the temporal event
stream, a JSON-Lisp AST (Abstract Syntax Tree) structure is highly efficient.
By representing data as S-expressions formatted in JSON arrays (e.g.,
["node_type", "id", {attributes}, [children]]), you get a format that is both
compact for lock-free memory indexing and natively suited for serializing
directly into execution states or an AST-MD snapshot file.
Here is a proposed structure that cleanly separates the topological,
geometric, and temporal data while keeping them linked.
The Root AST Structure
The root of the document acts as the master state array. It contains three
primary branches: zones (the spatial/semantic graph), entities (the
actors/props), and timeline (the event stream WAL).
[ "world", { "title": "Generated Story World", "tick": 0 },
[ "zones",
// Room AST Nodes go here
],
[ "entities",
// NPC / Prop AST Nodes go here
],
[ "timeline",
// Event Stream AST Nodes go here
]
]
1. The Room Node (Semantic + Geometric)
The room node acts as the source of truth for both the MUD REPL and the
Rogue-like grid renderer. The MUD engine reads the description and exits
array, while the 2D visualizer strictly reads the grid attribute to carve out
the WebGL or Canvas rendering.
[ "room", "CH1_LIVING_ROOM",
{
"name": "The Dusty Living Room",
"description": "A sprawling room with a broken window.",
"source_refs": [ {"page": 12, "line": 40}, {"page": 45, "line": 12} ],
"grid": {
"x": 100,
"y": 200,
"w": 5,
"h": 5,
"type": "cavern",
"tiles": [ 0, 0, 1, 1, 0 ] // Optional: pre-computed tile indexes
}
},
[
// MUD Exits are child nodes
[ "exit", "north", "CH1_KITCHEN", { "desc": "A dark hallway", "type":
"walkable" } ],
[ "exit", "portal", "CH2_FOREST", { "desc": "A sudden shift in reality",
"type": "teleport" } ]
]
]
2. The Entity Node (Actors & Props)
Entities are stored flat rather than nested inside rooms. This allows them to
move freely between rooms without requiring complex tree mutationsthey simply
update their location property. This structure is ideal for eventually
compiling down into standard virtual machine objects.
[ "npc", "NPC_GOBLIN_1",
{
"name": "Snarling Goblin",
"base_stats": { "hp": 10, "atk": 2 },
"location": "CH1_LIVING_ROOM",
"inventory": [ "ITEM_RUSTY_KEY" ]
},
[
// Dialogue or logic trees as child AST nodes
[ "dialogue", "greet", { "text": "Who goes there?", "requires": null } ],
[ "action", "attack", { "target": "player", "condition": "has_aggro" } ]
]
]
3. The Timeline Node (Event Stream)
Using page numbers (or standardized story ticks), the timeline acts as an
immutable Write-Ahead Log. Instead of hardcoding when a quest starts, the
engine streams these events sequentially as the player explores.
[ "event_stream", "main_plot", {},
[
[ "event", {
"tick": 12,
"actor": "NPC_GOBLIN_1",
"action": "SPAWN",
"target": "CH1_LIVING_ROOM"
}],
[ "event", {
"tick": 15,
"actor": "NPC_GOBLIN_1",
"action": "MOVE",
"target": "CH1_KITCHEN"
}],
[ "event", {
"tick": 45,
"actor": "PLAYER",
"action": "QUEST_UNLOCK",
"target": "FIND_RUSTY_KEY"
}]
]
]
Engine Integration Workflow
When the pipeline finishes generating this AST:
* The MUD Server parses the zones to build its fast in-memory exit graph,
completely ignoring the grid properties. It mounts the timeline to start
dispatching NPC movements based on the current tick.
* The Map Visualizer queries all room nodes, reads their grid properties, and
plots them onto a 2D memory arena. When it sees an exit of type walkable, it
algorithms a tunnel between CH1_LIVING_ROOM.grid and CH1_KITCHEN.grid.
* CRDT Sync: Because the state is expressed as targeted JSON-Lisp arrays
(e.g., ["set_loc", "NPC_GOBLIN_1", "CH1_KITCHEN"]), state mutations from
player actions can be easily broadcast as CRDT operations over a WebSocket
relay to synchronize all connected clients.