Getting Started

This guide will help you get PipeWorks MUD Server up and running.

Prerequisites

  • Python 3.12 or 3.13

  • pip (Python package manager)

  • Git

Installation

Clone and Setup

# Clone the repository
git clone https://github.com/pipe-works/pipeworks_mud_server.git
cd pipeworks_mud_server

# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install the package
pip install -e .

Initialize Database

# Initialize the database schema
mud-server init-db

This creates the SQLite database with required tables. If MUD_ADMIN_USER and MUD_ADMIN_PASSWORD are set and no users exist, init-db also attempts superuser bootstrap.

By default, init-db also bootstraps canonical policy artifacts for discovered worlds using latest.json pointers from the policy export repo (pipe-works-world-policies). To control this behavior:

  • Set MUD_POLICY_EXPORTS_ROOT to an explicit export-repo root path.

  • Use mud-server init-db --skip-policy-import to skip bootstrap import.

Create Superuser

The server requires a superuser account for administration. Passwords must meet the STANDARD security policy requirements:

  • Minimum 12 characters (NIST SP 800-63B recommended)

  • Not a commonly used password (checked against 150+ known weak passwords)

  • No sequential characters (abc, 123, xyz)

  • No excessive repeated characters (aaa, 1111)

Choose one method:

Interactive mode (recommended for local development):

mud-server create-superuser
# Password requirements will be displayed
# Real-time feedback on password strength

Environment variables (for CI/deployment):

export MUD_ADMIN_USER=myadmin
export MUD_ADMIN_PASSWORD="MySecure#Pass2024"  # Must meet policy requirements
mud-server create-superuser

Note

The password policy ensures strong passwords are used from the start. See Security for complete details on the password policy.

Running the Server

Start the Server

mud-server run

This starts:

Press Ctrl+C to stop the server.

First Login

  1. Open the admin web UI at http://localhost:8000/admin

  2. Login with the superuser credentials you created

  3. Explore the interface and start building your world

Creating Your First World

Worlds are self-contained packages under data/worlds/<world_id>/. A minimal package contains:

data/worlds/<world_id>/
├── world.json
├── zones/
│   └── <zone>.json

world.json defines the world metadata and which subsystems are enabled:

{
  "name": "My World",
  "description": "A custom world package.",
  "version": "0.1.0",
  "default_spawn": {"zone": "my_world", "room": "spawn"},
  "zones": ["my_world"],
  "global_items": {},
  "translation_layer": {
    "enabled": true,
    "model": "gemma2:2b",
    "prompt_policy_id": "prompt:translation.prompts.ic:default",
    "active_axes": ["demeanor", "health"]
  },
  "axis_engine": {"enabled": true}
}

prompt_policy_id is the authoritative runtime selector for translation prompt templates from canonical policy activation state.

The room and item data lives in zones/<zone>.json:

{
  "id": "my_world",
  "name": "My World",
  "rooms": {
    "spawn": {
      "id": "spawn",
      "name": "Spawn Zone",
      "description": "A central gathering point.",
      "exits": {"north": "library"},
      "items": []
    }
  },
  "items": {}
}

To create your own world:

  1. Create data/worlds/<world_id>/world.json.

  2. Add one or more zone files under data/worlds/<world_id>/zones/.

  3. Initialize DB:

    mud-server init-db
    
  4. Import canonical policy artifact for the world (if needed):

    mud-server import-policy-artifact --artifact-path /abs/path/publish_<manifest_hash>.json
    
  5. Verify effective activation for the world scope:

    curl -s "http://127.0.0.1:8000/api/policy-activations?scope=<world_id>&effective=true&session_id=<sid>"
    
  6. Restart the server so the world package is loaded.

No code changes are required.

Development Setup

For development work:

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest -v

# Run tests with coverage
pytest --cov=mud_server --cov-report=html

# Lint code
ruff check src/ tests/

# Format code
black src/ tests/

# Type checking
mypy src/ --ignore-missing-imports

Running Components Separately

API Server Only

python -m mud_server.api.server

Admin TUI (Terminal Interface)

For SSH/tmux workflows or terminal-based administration:

# Install TUI dependencies
pip install -e ".[admin-tui]"

# Run the terminal UI (connects to localhost:8000 by default)
pipeworks-admin-tui

# Connect to a remote server
pipeworks-admin-tui --server http://remote-server:8000

The TUI provides:

  • Login screen with username/password authentication

  • Dashboard with server status and quick actions

  • Create user workflow (role selection + password confirmation)

  • Keyboard shortcuts for common operations

Requires API server to be running.

Guest Registration

The public /register and /register-guest endpoints create temporary guest accounts for testing/dev. /register-guest generates the username server-side, while /register accepts a client-supplied username. Character provisioning is now explicit:

  • /register creates an account only (no character).

  • /register-guest creates both account + the requested character.

Account-first flow for normal signup:

  1. POST /register to create account

  2. POST /login to create account session

  3. POST /characters/create for a world with available slots

  4. POST /characters/select to enter world gameplay

Guest accounts are automatically purged after 24 hours (the user is deleted, characters are unlinked).

Example: POST /register (client-supplied username)

curl -s -X POST http://localhost:8000/register \\
  -H "Content-Type: application/json" \\
  -d '{
    "username": "guest_demo",
    "password": "SecurePass#1234",
    "password_confirm": "SecurePass#1234"
  }'

Response (200):

{
  "success": true,
  "message": "Temporary account created successfully! You can now login as guest_demo. Character creation is a separate step."
}

Example: POST /register-guest (server-generated username)

curl -s -X POST http://localhost:8000/register-guest \\
  -H "Content-Type: application/json" \\
  -d '{
    "password": "SecurePass#1234",
    "password_confirm": "SecurePass#1234",
    "character_name": "Guest Wanderer"
  }'

Response (200):

{
  "success": true,
  "message": "Temporary guest account created successfully! You can now login as guest_00421.",
  "username": "guest_00421",
  "character_id": 42,
  "character_name": "Guest Wanderer",
  "world_id": "pipeworks_web",
  "entity_state": {
    "seed": 0,
    "world_id": "pipeworks_web",
    "policy_hash": "420079743c68fba68936162bb3f46f7cbddecd9d3ff704a52c702cd6c0b6aec4",
    "axes": {
      "age": {"label": "old", "score": 0.5},
      "demeanor": {"label": "resentful", "score": 0.5},
      "health": {"label": "weary", "score": 0.5}
    }
  },
  "entity_state_error": null
}

entity_state is sourced from the in-database axis snapshot by default. If local snapshot state is unavailable and the external entity integration is configured, the server can attempt integration fallback. Registration remains fail-open either way and still succeeds when entity_state is null.

Example: POST /characters/create (self-service generated name)

curl -s -X POST http://localhost:8000/characters/create \\
  -H "Content-Type: application/json" \\
  -d '{
    "session_id": "YOUR_ACCOUNT_SESSION_ID",
    "world_id": "pipeworks_web"
  }'

Returns 403 when a world is invite-locked for the account and 409 when the per-world slot limit is reached.

Environment Variables

Optional configuration:

Variable

Default

Description

MUD_HOST

0.0.0.0

Server bind address

MUD_PORT

8000

API server port

MUD_SERVER_URL

http://localhost:8000

Client API endpoint

MUD_ADMIN_USER

(none)

Superuser username for create-superuser or init-db bootstrap

MUD_ADMIN_PASSWORD

(none)

Superuser password for create-superuser or init-db bootstrap

MUD_POLICY_EXPORTS_ROOT

(auto-resolved)

Override root path used by init-db artifact bootstrap + publish/import flows

MUD_REQUEST_TIMEOUT

30

HTTP request timeout (seconds) for TUI

MUD_CHAR_DEFAULT_SLOTS

2

Legacy global slot default (kept for compatibility)

MUD_CHAR_MAX_SLOTS

10

Legacy global slot cap (kept for compatibility)

MUD_REGISTRATION_MODE

open

Account registration mode (open or closed)

MUD_GUEST_REGISTRATION_ENABLED

true

Enable/disable /register-guest

MUD_PLAYER_SELF_CREATE_ENABLED

true

Enable player /characters/create

MUD_CHAR_CREATE_DEFAULT_MODE

invite

Default world creation mode (open or invite)

MUD_CHAR_CREATE_DEFAULT_NAMING

generated

Default world naming mode (generated or manual)

MUD_CHAR_CREATE_DEFAULT_SLOT_LIMIT

10

Default per-world slot limit per account

MUD_ENTITY_STATE_ENABLED

true

Enable entity-state generation during /register-guest

MUD_ENTITY_STATE_BASE_URL

https://entity-state-api.luminal.local

Entity-state API base URL used by guest onboarding

MUD_ENTITY_STATE_TIMEOUT_SECONDS

3.0

Timeout for entity-state API calls

MUD_ENTITY_STATE_INCLUDE_PROMPTS

false

Include prompt strings in the returned entity_state payload

World-specific overrides can be set in config/server.ini using:

[world_policy.pipeworks_web]
creation_mode = open
naming_mode = generated
slot_limit_per_account = 10

CLI Reference

The mud-server CLI provides these commands:

mud-server init-db           Initialize database schema
mud-server import-policy-artifact  Import one canonical publish artifact
mud-server create-superuser  Create a superuser account
mud-server run               Start the server

Policy bootstrap/import helpers:

mud-server init-db --skip-policy-import
mud-server import-policy-artifact --artifact-path /abs/path/publish_<manifest_hash>.json
mud-server import-policy-artifact --artifact-path /abs/path/publish_<manifest_hash>.json --no-activate

The pipeworks-admin-tui CLI (requires [admin-tui] extra):

pipeworks-admin-tui                    Connect to localhost:8000
pipeworks-admin-tui -s URL             Connect to specified server
pipeworks-admin-tui -t SECONDS         Set request timeout

For help on any command:

mud-server --help
mud-server init-db --help
pipeworks-admin-tui --help

Next Steps