pipeworks_mud_mapper.models.zone
Zone model for game truth representation.
This module defines the Zone model - the “game truth” format that the MUD server consumes. Zone files contain everything the game engine needs to run: rooms, exits, items, and metadata. They explicitly exclude coordinates because the engine operates on topology (connections) not geometry (positions).
The Two-File Philosophy
As described in goblin_cartography.md Section 2.3, there’s a deliberate
separation between:
Zone files (game truth): What the server needs. Pure topology.
Map files (authoring source): What humans need. Includes coordinates.
Zone files are “build artifacts” - they’re generated from map files by stripping coordinates. This separation ensures:
The server never sees or depends on visual layout
Authors can freely rearrange map layouts without affecting gameplay
Zone files remain clean and focused on game logic
Zone Structure
A zone is a self-contained region of the MUD world:
{
"id": "crooked_pipe",
"name": "Crooked Pipe District",
"description": "A warren of goblin pubs...",
"spawn_room": "spawn",
"rooms": {
"spawn": { ... },
"front_parlour": { ... }
},
"items": {
"ale_mug": { ... }
}
}
Cross-Zone Exits
Exits can reference rooms in other zones using the format zone:room:
"exits": {
"north": "front_parlour", # Same zone
"west": "cobbled_street:market" # Cross-zone
}
The engine parses the : delimiter and loads the target zone if needed.
Examples
Creating a zone programmatically:
zone = Zone(
id="tutorial",
name="Tutorial Area",
spawn_room="spawn",
rooms={
"spawn": Room(id="spawn", name="Arrival Chamber", exits={"north": "hall"}),
"hall": Room(id="hall", name="Main Hall", exits={"south": "spawn"}),
},
)
Serializing to JSON:
json_str = zone.model_dump_json(indent=2, exclude_none=True)
See also
MapFileAuthoring format that includes coordinates.
RoomIndividual room within a zone.
Classes
A zone in game truth format (no coordinates). |
Module Contents
- class pipeworks_mud_mapper.models.zone.Zone(/, **data)[source]
Bases:
pydantic.BaseModelA zone in game truth format (no coordinates).
Zones are self-contained regions of the MUD world. Each zone has its own spawn point, rooms, and items. Zones connect to each other through cross-zone exits.
This model represents the format consumed by the MUD server. It excludes coordinates because the game engine operates on topology, not geometry.
- id
Unique zone identifier. Used in cross-zone references and as filename. Should be lowercase with underscores (e.g., “crooked_pipe”).
- Type:
- metadata
Versioning metadata that accompanies exported zone files.
- Type:
ZoneMetadata
- rooms
Mapping of room ID to Room objects.
- Type:
dict[str,Room]
- items
Mapping of item ID to item definitions. Item structure is flexible to support future item system expansion.
- Type:
dict[str,dict]
Examples
>>> zone = Zone( ... id="tutorial", ... name="Tutorial Area", ... spawn_room="spawn", ... rooms={"spawn": Room(id="spawn", name="Start")}, ... )
Validation ensures spawn_room exists:
>>> Zone( ... id="bad", ... name="Bad Zone", ... spawn_room="nonexistent", ... rooms={}, ... ) Traceback (most recent call last): ... pydantic_core._pydantic_core.ValidationError: ...
See also
MapFileAuthoring format with coordinates.
RoomIndividual room model.
- classmethod validate_id(v)[source]
Validate zone ID format.
Zone IDs must start with a letter and contain only lowercase letters, numbers, and underscores.
- validate_spawn_room_exists()[source]
Ensure spawn_room references an existing room.
- Returns:
The validated zone instance.
- Return type:
- Raises:
ValueError – If spawn_room is not in the rooms dictionary.
- validate_room_ids_match_keys()[source]
Ensure room IDs match their dictionary keys.
- Returns:
The validated zone instance.
- Return type:
- Raises:
ValueError – If any room’s ID doesn’t match its dictionary key.
- get_room(room_id)[source]
Get a room by ID.
- Parameters:
room_id (
str) – The room ID to look up.- Returns:
The room if found, None otherwise.
- Return type:
RoomorNone
Examples
>>> zone.get_room("spawn") Room(id='spawn', ...) >>> zone.get_room("nonexistent") None
- validate_exits()[source]
Validate all exit targets exist (within this zone).
Cross-zone exits (containing :) are skipped as they reference other zones that may not be loaded.
- Returns:
List of warning messages for invalid exit targets.
- Return type:
list[str]
Examples
>>> zone.validate_exits() ["Room 'spawn' has exit 'north' to nonexistent room 'bad_room'"]
- find_unreachable_rooms()[source]
Find rooms that cannot be reached from the spawn room.
Uses breadth-first search from spawn_room to find all reachable rooms, then returns any rooms not in that set.
- Returns:
List of room IDs that are unreachable from spawn.
- Return type:
list[str]
Examples
>>> zone.find_unreachable_rooms() ['isolated_room', 'another_orphan']
- find_dead_ends()[source]
Find rooms with no outgoing exits.
Note: Dead ends are not always errors - some rooms are intentionally terminal (treasure rooms, trap rooms, etc.).
- Returns:
List of room IDs with no exits.
- Return type:
list[str]
Examples
>>> zone.find_dead_ends() ['treasure_room', 'pit_of_doom']