pipeworks_mud_mapper.services.zone_service ========================================== .. py:module:: pipeworks_mud_mapper.services.zone_service .. autoapi-nested-parse:: Zone service for file I/O operations. This module handles loading, saving, and exporting zone/map files. It supports the export workflow described in ``goblin_cartography.md``: - **Map JSON exports** (`*.map.json`): Authoring exports with coordinates - **Zone JSON exports** (`*.json`): Game truth without coordinates The Export Workflow ------------------- :: Author edits: SQLite DB (data/mapper.db) │ ▼ ┌─────────────┐ │ MapFile │ (in memory) └──────┬──────┘ │ ┌─────────────┴─────────────┐ ▼ ▼ save_map_file() export_zone() │ │ ▼ ▼ data/exports/maps/*.map.json data/zones/my_zone.json (authoring export) (game truth, no coords) File Format Detection --------------------- The service detects file type by: 1. Extension: ``.map.json`` = map file, ``.json`` = zone file 2. Content: presence of ``coords`` in rooms indicates map file When loading a zone file (no coords), rooms are auto-placed at origin. A warning is returned to indicate coordinates need assignment. .. admonition:: Examples Loading a map file:: from pathlib import Path from pipeworks_mud_mapper.services import zone_service map_file = zone_service.load_map_file(Path("data/exports/maps/tutorial.map.json")) Saving changes:: zone_service.save_map_file(map_file, Path("data/exports/maps/tutorial.map.json")) Exporting for game server:: zone_service.export_zone(map_file, Path("data/zones/tutorial.json")) Creating a new zone:: map_file = zone_service.create_new_map_file( zone_id="new_zone", name="New Zone", spawn_room_name="Starting Room", ) .. seealso:: :py:obj:`-`, :py:obj:`-`, :py:obj:`-` Functions --------- .. autoapisummary:: pipeworks_mud_mapper.services.zone_service.load_map_file pipeworks_mud_mapper.services.zone_service.save_map_file pipeworks_mud_mapper.services.zone_service.export_zone pipeworks_mud_mapper.services.zone_service.create_new_map_file pipeworks_mud_mapper.services.zone_service.load_zone pipeworks_mud_mapper.services.zone_service.get_suggested_export_path pipeworks_mud_mapper.services.zone_service.list_map_files pipeworks_mud_mapper.services.zone_service.list_zone_files Module Contents --------------- .. py:function:: load_map_file(path) Load a map file from disk. Handles both map files (with coords) and zone files (without coords). When loading a zone file, rooms are placed at origin with a warning. :param path: Path to the map or zone file. :type path: :py:class:`Path` :returns: The loaded map file, ready for editing. :rtype: :py:class:`MapFile` :raises FileNotFoundError: If the file does not exist. :raises json.JSONDecodeError: If the file is not valid JSON. :raises pydantic.ValidationError: If the JSON does not match the expected schema. .. admonition:: Examples >>> map_file = load_map_file(Path("data/exports/maps/tutorial.map.json")) >>> len(map_file.rooms) 5 .. py:function:: save_map_file(map_file, path, *, bump_revision = True) Save a map file to disk. Saves in the legacy format with coords as [x, y, z] lists for compatibility with existing tools and data files. :param map_file: The map file to save. :type map_file: :py:class:`MapFile` :param path: Destination path. Parent directories are created if needed. :type path: :py:class:`Path` :param bump_revision: When True, increment ``metadata.map_revision`` before saving. This is the default for explicit save actions. :type bump_revision: :py:class:`bool`, *optional* .. admonition:: Examples >>> save_map_file(map_file, Path("data/exports/maps/tutorial.map.json")) .. py:function:: export_zone(map_file, path) Export a map file as a zone file (strips coordinates and authoring metadata). This creates the "game truth" file that the MUD server consumes. Coordinates and LLM generation metadata are removed because the game engine operates on topology (connections) not geometry (positions), and doesn't need authoring provenance data. Stripped Fields --------------- The following "authoring scaffolding" fields are removed during export: - **coords**: Room coordinates are visualization aids, not game state. Movement in a MUD is topological (room A connects to room B via "north"), not metric (room B is at position [1, 0, 0]). - **llm_generation**: LLM generation metadata (model, seed, prompts, etc.) exists for authoring purposes only - it enables reproducibility and provenance tracking during map creation, but has no meaning to the game server. This separation reflects the pipe-works philosophy that authoring scaffolding supports the creation process but is not part of the final game state. :param map_file: The map file to export. :type map_file: :py:class:`MapFile` :param path: Destination path for the zone file. :type path: :py:class:`Path` .. admonition:: Examples >>> export_zone(map_file, Path("data/zones/tutorial.json")) .. admonition:: Notes The exported zone file can be loaded back, but coordinates and LLM metadata will be lost. Always keep the original map file as the authoring source. .. seealso:: :py:obj:`MapRoom.to_room` Primary stripping mechanism (model conversion). :py:obj:`OllamaGenerationInfo` The metadata model that gets stripped. .. py:function:: create_new_map_file(zone_id, name, spawn_room_name = 'Spawn Room', description = '') Create a new empty map file with a spawn room. :param zone_id: Unique identifier for the zone (e.g., "tutorial_area"). :type zone_id: :py:class:`str` :param name: Human-readable display name (e.g., "Tutorial Area"). :type name: :py:class:`str` :param spawn_room_name: Display name for the initial spawn room. :type spawn_room_name: :py:class:`str`, *default* ``"Spawn Room"`` :param description: Zone description text. :type description: :py:class:`str`, *optional* :returns: A new map file with a single spawn room at origin. :rtype: :py:class:`MapFile` .. admonition:: Examples >>> map_file = create_new_map_file( ... zone_id="my_dungeon", ... name="My Dungeon", ... spawn_room_name="Entrance Hall", ... ) >>> map_file.spawn_room 'spawn' >>> map_file.rooms["spawn"].name 'Entrance Hall' .. py:function:: load_zone(path) Load a zone file (game truth format). This loads a zone file without coordinates. Use this when you need to work with the game truth format directly. :param path: Path to the zone file. :type path: :py:class:`Path` :returns: The loaded zone. :rtype: :py:class:`Zone` .. admonition:: Examples >>> zone = load_zone(Path("data/zones/tutorial.json")) .. py:function:: get_suggested_export_path(map_path, zones_dir = None) Get the suggested zone export path for a map file. Converts ``data/exports/maps/foo.map.json`` to ``data/zones/foo.json``. :param map_path: Path to the map file. :type map_path: :py:class:`Path` :param zones_dir: Optional override for the zones directory. When provided, exports will be placed in this directory regardless of the map path. :type zones_dir: :py:class:`Path | None` :returns: Suggested path for the exported zone file. :rtype: :py:class:`Path` .. admonition:: Examples >>> get_suggested_export_path(Path("data/exports/maps/tutorial.map.json")) PosixPath('data/zones/tutorial.json') .. py:function:: list_map_files(directory) List map files in a directory. Returns sorted ``*.map.json`` files for map export inspection. .. py:function:: list_zone_files(directory) List zone files in a directory. Returns sorted ``*.json`` files for the zone file browser.