pipeworks_mud_mapper.models.room
Room and coordinate models for PipeWorks MUD Mapper.
This module defines the core room-related data structures used by the mapper. Two room types exist to support the two-file workflow:
Room: Game truth representation (no coordinates)
MapRoom: Authoring representation (includes coordinates)
The separation reflects the principle that coordinates are “authoring scaffolding” - they help humans visualize the map but are not part of the game state.
Direction System
MUDs traditionally use cardinal directions for navigation. This mapper supports
six directions as decided in goblin_cartography.md Section 1.7:
Direction |
Axis |
Typical Use |
|---|---|---|
north |
+Y |
Horizontal movement |
south |
-Y |
Horizontal movement |
east |
+X |
Horizontal movement |
west |
-X |
Horizontal movement |
up |
+Z |
Vertical (stairs, ladders) |
down |
-Z |
Vertical (trapdoors, basements) |
The decision to use 6 directions (not 4) allows rooms to have both a “south” exit AND a “down” exit going to different places - essential for multi-story structures like The Crooked Pipe pub.
Coordinate System
The mapper uses a 3D Cartesian coordinate system:
+Y (North)
│
│
-X ───────┼─────── +X
(West) │ (East)
│
-Y (South)
Z: +Z (Up) / -Z (Down)
The origin [0, 0, 0] is conventionally the zone’s spawn room.
Examples
Creating a room for game truth (Zone export):
room = Room(
id="spawn",
name="The Crooked Pipe",
description="A low-ceilinged goblin pub...",
exits={"north": "front_parlour", "down": "cellar"},
items=["ale_mug", "chalk"],
)
Creating a room for authoring (MapFile):
map_room = MapRoom(
id="spawn",
name="The Crooked Pipe",
description="A low-ceilinged goblin pub...",
coords=Coords(x=0, y=0, z=0),
exits={"north": "front_parlour", "down": "cellar"},
items=["ale_mug", "chalk"],
)
Converting MapRoom to Room (strips coordinates):
room = map_room.to_room()
See also
-, -
Attributes
Valid MUD movement directions. |
|
All valid directions as a tuple for iteration. |
|
Mapping of each direction to its opposite. |
|
Coordinate offsets for each direction. |
|
Short labels used in the UI for direction indicators. |
|
Reverse mapping for checkbox values back to full direction names. |
Classes
Three-dimensional coordinates for room placement. |
|
A room in game truth format (no coordinates). |
|
A room in authoring format (includes coordinates and LLM metadata). |
Module Contents
- pipeworks_mud_mapper.models.room.Direction
Valid MUD movement directions.
Constrained to six values matching the decision in goblin_cartography.md: - Horizontal: north, south, east, west - Vertical: up, down
Up/Down are semantically distinct from North/South - they represent vertical traversal (stairs, ladders, trapdoors) rather than horizontal movement on a conceptual map.
- pipeworks_mud_mapper.models.room.DIRECTIONS: tuple[Direction, Ellipsis] = ('north', 'south', 'east', 'west', 'up', 'down')
All valid directions as a tuple for iteration.
- pipeworks_mud_mapper.models.room.OPPOSITE_DIRECTION: dict[Direction, Direction]
Mapping of each direction to its opposite.
Used for bidirectional exit creation - when creating an exit from A to B, the opposite direction is used for the return exit from B to A.
- pipeworks_mud_mapper.models.room.DIRECTION_OFFSETS: dict[Direction, tuple[int, int, int]]
Coordinate offsets for each direction.
These represent the unit vector for movement in each direction: - X axis: East (+1) / West (-1) - Y axis: North (+1) / South (-1) - Z axis: Up (+1) / Down (-1)
Note: Actual room spacing may vary. These offsets indicate direction only, not distance. Use for determining which direction a target room lies relative to a source room.
- pipeworks_mud_mapper.models.room.DIRECTION_SHORT: dict[Direction, str]
Short labels used in the UI for direction indicators.
- pipeworks_mud_mapper.models.room.SHORT_TO_DIRECTION: dict[str, Direction]
Reverse mapping for checkbox values back to full direction names.
- class pipeworks_mud_mapper.models.room.Coords(/, **data)[source]
Bases:
pydantic.BaseModelThree-dimensional coordinates for room placement.
Coordinates are authoring metadata - they help humans visualize and validate the map layout but are not used by the game engine. The MUD server operates on pure topology (room connections) not geometry.
Examples
>>> coords = Coords(x=0, y=0, z=0) # Origin (typically spawn room) >>> coords = Coords(x=5, y=-5, z=0) # 5 units east, 5 units south >>> coords = Coords(x=0, y=0, z=-1) # One level below origin (basement)
Notes
The coordinate system follows standard mathematical conventions: - Origin at (0, 0, 0) - Right-hand rule for axis orientation - Integers only (no fractional positions)
- to_tuple()[source]
Convert coordinates to a tuple.
- Returns:
Coordinates as (x, y, z) tuple.
- Return type:
tuple[int,int,int]
Examples
>>> Coords(x=1, y=2, z=3).to_tuple() (1, 2, 3)
- to_list()[source]
Convert coordinates to a list.
This format matches the JSON serialization used in map files.
- Returns:
Coordinates as [x, y, z] list.
- Return type:
list[int]
Examples
>>> Coords(x=1, y=2, z=3).to_list() [1, 2, 3]
- classmethod from_list(coords)[source]
Create Coords from a list.
- Parameters:
coords (
list[int]) – Coordinates as [x, y, z] list.- Returns:
New Coords instance.
- Return type:
- Raises:
ValueError – If coords does not have exactly 3 elements.
Examples
>>> Coords.from_list([1, 2, 3]) Coords(x=1, y=2, z=3)
- offset(direction)[source]
Return new coordinates offset in the given direction.
- Parameters:
direction (
Direction) – The direction to offset towards.- Returns:
New Coords offset by one unit in the given direction.
- Return type:
Examples
>>> origin = Coords(x=0, y=0, z=0) >>> origin.offset("north") Coords(x=0, y=1, z=0) >>> origin.offset("down") Coords(x=0, y=0, z=-1)
- class pipeworks_mud_mapper.models.room.Room(/, **data)[source]
Bases:
pydantic.BaseModelA room in game truth format (no coordinates).
This model represents a room as it appears in exported zone files - the format consumed by the MUD server. Coordinates are excluded because the game engine operates on topology (connections) not geometry (positions).
- id
Unique identifier within the zone. Used as dictionary key and in exit references. Should be lowercase with underscores (e.g., “front_parlour”).
- Type:
- description
Room description shown when a player enters or looks. Can be multiple sentences. Defaults to empty string.
- Type:
- exits
Mapping of direction to target room ID. Target can be same-zone (e.g., “front_parlour”) or cross-zone (e.g., “docks:east_pier”).
- Type:
dict[Direction,str]
- items
List of item IDs present in this room. Items must be defined in the zone’s items dictionary.
- Type:
list[str]
Examples
>>> room = Room( ... id="spawn", ... name="The Crooked Pipe", ... description="A low-ceilinged goblin pub with sticky floors.", ... exits={"north": "front_parlour", "down": "cellar"}, ... items=["ale_mug"], ... )
See also
MapRoomRoom with coordinates for authoring.
ZoneContainer for rooms in game truth format.
- classmethod validate_id(v)[source]
Validate room ID format.
Room IDs must start with a letter and contain only lowercase letters, numbers, and underscores.
- Parameters:
v (
str) – The room ID to validate.- Returns:
The validated room ID.
- Return type:
- Raises:
ValueError – If the ID format is invalid.
- class pipeworks_mud_mapper.models.room.MapRoom(/, **data)[source]
Bases:
pydantic.BaseModelA room in authoring format (includes coordinates and LLM metadata).
This model represents a room as it appears in map files - the format used by the mapper tool during authoring. It extends the game truth Room with:
Coordinates: Position in 3D space for visualization
LLM generation metadata: Provenance info for AI-generated descriptions
Description validation metadata: Latest validator output for the description
Both fields are “authoring scaffolding” - they help humans create and understand the map but are not part of the game state. When exporting to a zone file, both are stripped using
to_room().- exits
Mapping of direction to target room ID.
- Type:
dict[Direction,str]
- items
List of item IDs present in this room.
- Type:
list[str]
- llm_generation
Metadata about the last LLM generation for this room’s description. Only present if the description was generated by Ollama. Contains model name, seed, parameters, and prompts for reproducibility. Stripped during zone export (like coords).
- Type:
OllamaGenerationInfo | None
- description_validation
Metadata about the last validator run for this description. Stripped during zone export (like coords).
- Type:
DescriptionValidationInfo | None
Examples
>>> map_room = MapRoom( ... id="spawn", ... name="The Crooked Pipe", ... description="A low-ceilinged goblin pub.", ... coords=Coords(x=0, y=0, z=0), ... exits={"north": "front_parlour"}, ... items=["ale_mug"], ... )
Converting to game truth format (strips coords and llm_generation):
>>> room = map_room.to_room() >>> hasattr(room, 'coords') # False - stripped False >>> hasattr(room, 'llm_generation') # Also stripped False
See also
RoomGame truth format (no coordinates or LLM metadata).
MapFileContainer for MapRooms.
OllamaGenerationInfoLLM generation metadata model.
- classmethod validate_id(v)[source]
Validate room ID format.
Room IDs must start with a letter and contain only lowercase letters, numbers, and underscores.
- to_room()[source]
Convert to game truth format by stripping authoring metadata.
Removes coordinates and LLM generation metadata, producing a Room suitable for zone export. The MUD server only needs topology (room connections) and content (description, items), not authoring aids.
- Returns:
A Room instance without coordinates or LLM metadata.
- Return type:
Notes
The following fields are intentionally NOT copied to the output:
coords: Visualization aid, not game statellm_generation: Provenance tracking, not game statedescription_validation: Validator output, not game state
Examples
>>> map_room = MapRoom( ... id="spawn", ... name="Spawn", ... coords=Coords(x=0, y=0, z=0), ... ) >>> room = map_room.to_room() >>> hasattr(room, 'coords') False
- classmethod from_dict(data)[source]
Create MapRoom from a dictionary (legacy format support).
This method handles various input formats:
Legacy coords as
[x, y, z]list (converted to Coords object)Files without
llm_generationfield (defaults to None)Files with
llm_generationas dict (validated by Pydantic)
- Parameters:
data (
dict) –Room data dictionary. May contain:
coordsas[x, y, z]list orCoordsobjectllm_generationas dict,None, or missing entirely
- Returns:
New MapRoom instance with all fields properly typed.
- Return type:
Examples
Basic room without LLM metadata (legacy format):
>>> data = { ... "id": "spawn", ... "name": "Spawn", ... "coords": [0, 0, 0], ... "exits": {}, ... "items": [], ... } >>> room = MapRoom.from_dict(data) >>> room.coords Coords(x=0, y=0, z=0) >>> room.llm_generation is None True
Room with LLM generation metadata:
>>> data = { ... "id": "spawn", ... "name": "Spawn", ... "coords": [0, 0, 0], ... "exits": {}, ... "items": [], ... "llm_generation": { ... "model": "gemma2:2b", ... "actual_seed": 12345, ... "template_id": "custom", ... "temperature": 0.7, ... "top_k": 40, ... "top_p": 0.9, ... "num_ctx": 4096, ... "num_predict": 512, ... "system_prompt": "...", ... "user_prompt": "...", ... "generated_at": "2024-01-15T10:30:00Z", ... }, ... } >>> room = MapRoom.from_dict(data) >>> room.llm_generation.model 'gemma2:2b'