Back to .md Directory

Text Genie - Claude Code Instructions

Guides an AI assistant to generate MUD worlds by calling a single Docker-based Evennia function, with no intermediate scripts.

May 2, 2026
0 downloads
1 views
ai claude
View source

What this file does

Guides an AI assistant to generate MUD worlds by calling a single Docker-based Evennia function, with no intermediate scripts.

When to use it

  • You want an AI to build Evennia worlds directly without manual file creation
  • You run Evennia inside Docker and need a repeatable world generation workflow
  • You need to fix persistent admin character connection issues in Evennia
  • You want a checklist of common Evennia pitfalls and their solutions

Assumes this stack

EvenniaDockerPythonDjango

Text Genie - Claude Code Instructions

🚨 CRITICAL: ALWAYS USE DOCKER 🚨

Text Genie runs in Docker container textgenie-evennia

  • NEVER use local evennia commands
  • NEVER use source venv/bin/activate
  • ALWAYS use docker exec textgenie-evennia for all Evennia operations
  • The container name is: textgenie-evennia

🚫 NEVER CREATE NEW PYTHON FILES 🚫

CRITICAL: DO NOT create new Python files for world generation!

  • NEVER create files like create_[theme]_world.py
  • NEVER create files like build_[worldname].py
  • ALWAYS use python -c "..." to call create_world() directly
  • The ONLY script you need is scripts/world_builder.py

Quick Start

Text Genie is a MUD world generator that uses Evennia running in Docker.

When the user asks you to create a world (ANY theme - be creative!):

  1. Generate complete world data dictionary with rooms, NPCs, items, connections
  2. DIRECTLY call the world builder function - NO EXTRA SCRIPTS NEEDED:
    # Just do this directly in your response:
    from scripts.world_builder import create_world
    
    world_data = {
        "name": "World Name",
        "theme": "theme_type",
        "rooms": [...],
        "connections": [...],
        "npcs": [...],
        "items": [...]
    }
    
    create_world("World Name", "theme_type", world_data)
    
  3. The script automatically handles EVERYTHING:
    • Saves to created_worlds/[theme]_[timestamp].py
    • Creates created_worlds/build_current.py
    • Copies to Docker and builds the world
    • Creates admin character if it doesn't exist
    • Sets admin location to first room
    • Configures puppet connection
  4. Tell user: Connect via telnet localhost 4000 (admin/admin)

Project Structure

TextGenie/
β”œβ”€β”€ created_worlds/         # All generated worlds (gitignored)
β”‚   β”œβ”€β”€ [theme]_[timestamp].py  # World data files
β”‚   β”œβ”€β”€ build_current.py        # Current build script
β”‚   └── fix_admin.py            # Admin location fixer
β”œβ”€β”€ scripts/
β”‚   └── world_builder.py        # Main world creation script (THE ONLY ONE!)
β”œβ”€β”€ textgenie_game/         # Evennia game directory (gitignored)
└── Dockerfile              # Docker setup for Evennia

Prerequisites

  • Docker installed and running
  • Container running: docker ps | grep textgenie-evennia
  • If not running: docker-compose up -d or docker run -d -p 4000-4002:4000-4002 --name textgenie-evennia textgenie-evennia

World Generation Process

⚑ FAST World Creation (< 30 seconds)

When user requests ANY world:

  1. Generate world data (be creative!):
world_data = {
    "name": "World Name",
    "theme": "theme_type",
    "rooms": [
        {
            "name": "Room Name",
            "description": "Vivid 2-3 sentence description with sensory details."
        },
        # Generate 5-10 rooms minimum
    ],
    "connections": [
        {
            "from": "Room 1",
            "to": "Room 2", 
            "direction": "north",
            "reverse": "south"
        },
        # Connect all rooms logically
    ],
    "npcs": [
        {
            "name": "NPC Name",
            "description": "Physical description and personality hints.",
            "location": "Room Name",
            "dialogue": {
                "greeting": "What the NPC says when first met",
                "quest": "Optional quest or hint"
            }
        },
        # Generate 3-5 NPCs minimum
    ],
    "items": [
        {
            "name": "item name",
            "description": "What it looks like and any special properties.",
            "location": "Room Name"
        },
        # Generate 5-10 items minimum
    ]
}
  1. Call create_world() DIRECTLY using python -c - NO intermediate scripts:
python -c "
from scripts.world_builder import create_world
world_data = {...}  # Your generated world data here
create_world(world_data['name'], world_data['theme'], world_data)
"

NEVER create a new .py file to do this!

That's it! The script automatically:

  • Copies to Docker
  • Builds the world
  • Creates/fixes admin character
  • Sets proper locations
  • NO MANUAL STEPS NEEDED!

Step 3: Connect

  • Telnet: telnet localhost 4000
  • Web: http://localhost:4001
  • Login: admin/admin

Content Generation Guidelines

Rooms

  • Minimum: 5 rooms for small world, 10+ for standard
  • Description: 2-3 sentences with sensory details (sight, sound, smell)
  • Connectivity: Every room needs at least 1 exit
  • Mention exits: Naturally reference connecting areas in descriptions

NPCs

  • Minimum: 3-5 NPCs
  • Placement: Distribute across different rooms
  • Description: Visual appearance + personality hints
  • Dialogue: At least greeting, optionally quest/hints

Items

  • Minimum: 5-10 items
  • Types: Mix functional and atmospheric items
  • Distribution: Scatter throughout world

Connections

  • Directions: north, south, east, west, up, down, in, out
  • Bidirectional: Always create reverse exits
  • Logical: Connections should make spatial sense

World Themes - Quick Templates

Cyberpunk

  • Neon-lit streets, rain, corporate towers
  • NPCs: Hackers, corporate agents, street vendors
  • Items: Credsticks, neural implants, encrypted datapads

Fantasy

  • Medieval villages, dark forests, ancient ruins
  • NPCs: Wizards, merchants, guards, mysterious strangers
  • Items: Potions, scrolls, weapons, treasure

Space Station

  • Observation decks, engineering, quarters, docking bays
  • NPCs: Engineers, traders, pilots, security
  • Items: Keycards, tools, cargo manifests, personal effects

Horror

  • Abandoned locations, darkness, unsettling atmosphere
  • NPCs: Survivors, mysterious figures, helpful/unhelpful locals
  • Items: Flashlights, notes/journals, keys, strange artifacts

Docker Commands (USE THESE!)

# Check if container is running
docker ps | grep textgenie-evennia

# Start container if not running
docker start textgenie-evennia

# Restart Evennia inside Docker
docker exec textgenie-evennia evennia restart

# Check Evennia status
docker exec textgenie-evennia evennia status

# View logs
docker logs textgenie-evennia --tail 50

# Shell into container
docker exec -it textgenie-evennia bash

🚨🚨🚨 CRITICAL: AFTER CREATING A WORLD, ALWAYS RESTART EVENNIA! 🚨🚨🚨

docker exec textgenie-evennia evennia restart

WHY: Evennia caches object properties like has_account. Even if you set everything correctly, the cached values won't update until Evennia restarts. This WILL cause "Character does not exist" errors if you don't restart!

Troubleshooting - CRITICAL FIXES THAT MUST ALWAYS BE APPLIED

πŸ”΄ FIX #1: Foreign Key Constraint Errors (PERMANENT FIX IN PLACE)

Problem: Django crashes with "FOREIGN KEY constraint failed" when admin tries to connect.

Root Cause: Puppet references weren't properly cleared before deleting rooms.

THE FIX (Now in world_builder.py):

# Step 1: Clear ALL puppet/character references FIRST
for acc in AccountDB.objects.all():
    acc.db._last_puppet = None
    acc.db._default_character = None
    acc.save()

# Step 2: Move characters to Limbo BEFORE deleting anything
# Step 3: Delete exits first (they reference rooms)
# Step 4: Delete other objects (items, rooms)
# Step 5: Finally delete non-admin characters

πŸ”΄ FIX #2: "Character does not exist" Error (COMPLETE SOLUTION)

Problem: Admin connects but gets "This character does not exist" error.

Root Causes (ALL must be fixed):

  1. The _last_puppet attribute is None
  2. The character's db_account field is None (character doesn't know its account!)
  3. CRITICAL: Evennia's has_account property gets cached and stuck at 0 even after fixing the above!

THE COMPLETE FIX (Now in world_builder.py + restart):

  1. Link character to account (use ObjectDB directly for reliability):
# Use ObjectDB.objects.get() to ensure we have the real database object
char_obj = ObjectDB.objects.get(id=admin_char.id)
char_obj.db_account = admin  # THIS IS THE KEY LINE!
char_obj.save()
  1. Set puppet references on account:
admin.db._last_puppet = char_obj  # Use the reloaded object
admin.db._default_character = char_obj
admin.save()
  1. Verify with direct database check:
# Don't trust cached properties - check the actual database
test_char = ObjectDB.objects.get(id=admin_char.id)
if test_char.db_account != admin:
    # Force it with raw SQL if needed
    from django.db import connection
    with connection.cursor() as cursor:
        cursor.execute(
            "UPDATE objects_objectdb SET db_account_id = %s WHERE id = %s",
            [admin.id, admin_char.id]
        )
  1. RESTART EVENNIA TO CLEAR CACHES:
docker exec textgenie-evennia evennia restart

πŸ›‘ THE COMPLETE WORLD CREATION CHECKLIST:

  1. Clear ALL references BEFORE deleting ANYTHING (avoid foreign key errors)
  2. Use db_typeclass_path NOT db_is_typeclass (field name is critical)
  3. Create/find admin character
  4. Link character to account with ObjectDB.objects.get() (don't trust the character object)
  5. Set character location to first room
  6. Set BOTH _last_puppet AND _default_character
  7. Verify with database query, not object properties
  8. ALWAYS RESTART EVENNIA AFTER WORLD CREATION

⚠️ Common Pitfalls That WILL Break Everything:

  • Using char.db_account without reloading: The object might be cached
  • Trusting has_account property: It gets cached and stuck at 0
  • Not using ObjectDB.objects.get(): Working with stale objects
  • Forgetting to restart Evennia: Caches WILL cause login failures
  • Using wrong field names: It's db_typeclass_path not db_is_typeclass

πŸ”§ EMERGENCY Manual Fix Commands:

# COMPLETE fix for admin connection issues
docker exec -i textgenie-evennia sh -c 'cd /app/textgenie_game && echo "
from evennia.accounts.models import AccountDB
from evennia.objects.models import ObjectDB

admin = AccountDB.objects.filter(username=\"admin\").first()
if admin:
    # Get or create character
    chars = list(admin.characters.all())
    if not chars:
        from typeclasses.characters import Character
        char = Character.create(\"admin\", admin)[0]
        chars = [char]
    
    # Use ObjectDB directly - NEVER trust the character object
    char_obj = ObjectDB.objects.get(id=chars[0].id)
    
    # Fix the bi-directional link
    char_obj.db_account = admin
    char_obj.save()
    
    # Set puppet references
    admin.db._last_puppet = char_obj
    admin.db._default_character = char_obj
    admin.save()
    
    # Verify it worked
    test = ObjectDB.objects.get(id=char_obj.id)
    print(f\"Fixed: Character {test} linked to {test.db_account}\")
    print(f\"Admin puppet: {admin.db._last_puppet}\")
    
    # If still broken, force with SQL
    if test.db_account != admin:
        from django.db import connection
        with connection.cursor() as cursor:
            cursor.execute(
                \"UPDATE objects_objectdb SET db_account_id = %s WHERE id = %s\",
                [admin.id, char_obj.id]
            )
        print(\"Forced fix via SQL\")
" | evennia shell'

# THEN ALWAYS RESTART
docker exec textgenie-evennia evennia restart

πŸ“‹ Debug Commands:

# Check admin setup
docker exec -i textgenie-evennia sh -c 'cd /app/textgenie_game && echo "
from evennia.accounts.models import AccountDB
from evennia.objects.models import ObjectDB

admin = AccountDB.objects.filter(username=\"admin\").first()
if admin:
    puppet = admin.db._last_puppet
    if puppet:
        char_obj = ObjectDB.objects.get(id=puppet.id)
        print(f\"Admin: {admin}\")
        print(f\"Puppet: {puppet}\")
        print(f\"Character account: {char_obj.db_account}\")
        print(f\"Match: {char_obj.db_account == admin}\")
        print(f\"Has account property: {puppet.has_account}\")  # This lies if cached!
" | evennia shell'

Other Issues

  • Connection refused: Check Docker container is running: docker ps | grep textgenie-evennia
  • Old world showing: Just run create_world() again - it clears old world first
  • NEVER use local evennia: ALWAYS use docker exec textgenie-evennia

⚑ Quick Generation Workflow (WITH RESTART!)

When user says "Create a [theme] world" or provides an image/weird request:

  1. Check Docker is running: docker ps | grep textgenie-evennia
  2. Generate world data dictionary directly in your response
  3. Call create_world() DIRECTLY using python -c - NO NEW FILES:
    python -c "
    from scripts.world_builder import create_world
    
    world_data = {
        'name': 'Cool World',
        'theme': 'whatever',
        'rooms': [...],
        'connections': [...],
        'npcs': [...],
        'items': [...]
    }
    
    create_world(world_data['name'], world_data['theme'], world_data)
    "
    
    DO NOT create a new Python file! Use python -c directly!
  4. CRITICAL: RESTART EVENNIA TO CLEAR CACHES:
    docker exec textgenie-evennia evennia restart
    
  5. Tell user: "World created! Connect: telnet localhost 4000 (admin/admin)"

CRITICAL REMINDERS:

  • NEVER create separate build scripts (like build_terminus.py, create_synth_world.py, etc.)
  • NEVER create ANY new Python files for world generation
  • NEVER manually copy files or run Docker commands
  • ALWAYS call create_world() directly using python -c "..."
  • ALWAYS use single quotes inside the python -c command to avoid quote conflicts
  • The function handles EVERYTHING automatically including admin setup

Remember

  • 🐳 ALWAYS USE DOCKER - Container name: textgenie-evennia
  • Generate first, ask questions later
  • Minimum 5 rooms, prefer 8-10 for better experience
  • Every room needs exits (bidirectional!)
  • Include NPCs and items for atmosphere
  • Admin must have location (use fix_admin.py if needed)
  • Be creative with odd requests (images, weird themes, etc.)

What's inside

8 sections covering Docker usage, world data format, generation workflow, troubleshooting, and debug commands

Change this for your project

  • Replace textgenie-evennia with your own Docker container name
  • Replace scripts/world_builder.py with your own builder script path
  • Replace admin with your own admin account username
  • Replace telnet localhost 4000 with your own connection details

Where it goes

Save as CLAUDE.md in your repository root. Claude Code reads it automatically at the start of every session.

Worth borrowing

  • Using python -c to execute code inline instead of creating temporary files
  • Clearing cached object references before deleting database records to avoid foreign key errors
  • Verifying database state with raw queries instead of trusting cached properties

Related Documents