Skip to content

Repository files navigation

MazeWorld — GenAI-Orchestrated Game World Generation

A 2D RPG where every NPC, item, weapon, quest, portrait, music track, and sound effect is generated by AI. One input — a STORY_SEED string — produces a playable, coherent world through a pipeline that orchestrates five AI modalities. Turn-based combat, multi-room exploration, LLM-driven NPC dialogue.

▶ Play it now

No install, no API keys, no Python — just download and run. Grab the zip for your OS from the latest release (~1 GB, includes all portraits, music, and sound effects).

macOS (Apple Silicon — M1/M2/M3/M4)

  1. Download MazeWorld-macos-arm64.zip and double-click to unzip.
  2. The app is unsigned, so macOS Gatekeeper will block it on first launch. Open Terminal and run:
    xattr -cr ~/Downloads/MazeWorld.app && open ~/Downloads/MazeWorld.app
    (Adjust the path if you moved the app. You only need this once.)
  3. Play.

Saves and crash logs: ~/Library/Application Support/MazeWorld/saves/.

Intel Macs are not currently supported.

Windows (10 / 11, 64-bit)

  1. Download MazeWorld-windows-x64.zip, right-click -> "Extract All".
  2. Open the extracted MazeWorld folder and double-click MazeWorld.exe.
  3. SmartScreen will warn "Windows protected your PC" (unsigned binary). Click More info -> Run anyway. You only need this once.

Saves and crash logs: %APPDATA%\MazeWorld\saves\.

If the game won't launch

Check crash.log in the saves folder (paths above). Startup errors get written there so console-less builds still leave a trail — paste the contents into a GitHub issue and I can help debug.

GenAI Architecture

Multi-Model Pipeline — World generation orchestrates 5 AI modalities across a single pipeline run, with the ability to run locally and generate with local resources/models.

Modality API Backend Local Backend
Text / Story Claude Sonnet 4 (Anthropic) Llama 3.2 3B (HuggingFace)
Portraits fal.ai (nano-banana) FLUX.1 (CUDA) / SDXL Turbo (MPS)
Music Google Lyria 3
SFX ElevenLabs
Narrative Claude Llama 3.2

Agentic Validation Pipeline — Generated content passes three audits:

  1. Checker — per-entity structural validation (required fields, type constraints, puzzle solvability).
  2. Validator — cross-reference integrity (every quest target exists, every item reference resolves, no circular dialogue dependencies).
  3. World Editor — coherence audit against the World Bible.

On failure, the specific failure reason is fed back to the LLM as context for the retry. This one pattern did more for quality than switching models did.

Skeleton-Driven Generation — Mechanical properties (weapon dice, spell stats, encounter DCs) are pre-rolled as skeletons before the LLM call. The LLM generates only name and flavor text, then skeletons are merged back. This ensures balanced gameplay while preserving creative variety.

Generation Pipeline

flowchart TD
    subgraph phase1 ["Phase 1: Story and World"]
        StorySeed["STORY_SEED + config"] --> StoryGen["Overarching Story\n(faction, arc, boss)"]
        StoryGen --> Bible["World Bible\n(cross-reference index)"]
    end

    subgraph phase2 ["Phase 2: Per-Room Content"]
        Skeletons["Pre-rolled Skeletons\n(weapons, spells, events)"]
        LLM["LLM: Claude / Llama"]
        Skeletons -->|"mechanics"| Merge["Skeleton + LLM Merge"]
        LLM -->|"name + flavor"| Merge
        Merge --> RoomData["Room Data\n(NPCs, items, monsters,\nevents, quests)"]
    end

    subgraph phase3 ["Phase 3: Assets"]
        ImageGen["fal.ai / FLUX\n(portraits)"]
        MusicGen["Lyria 3\n(music tracks)"]
        SFXGen["ElevenLabs\n(sound effects)"]
    end

    subgraph phase4 ["Phase 4: NPC Dialogue"]
        TreeGen["Dialogue Tree Generation\n(retry + validation)"]
        Greetings["Opening Greetings\n+ Personality Notes"]
    end

    subgraph phase5 ["Phase 5: Validation"]
        Checker["Checker\n(per-entity)"]
        Validator["Validator\n(cross-reference)"]
        EditorNode["World Editor\n(coherence)"]
        Checker --> Validator --> EditorNode
        EditorNode -->|"feedback"| LLM
    end

    phase1 --> phase2 --> phase3
    phase2 --> phase4
    phase2 --> phase5
    Bible --> phase3
    phase5 -->|"WorldBible"| DataFolder["data/ folder\n(all JSON, portraits,\nmusic, SFX)"]
    phase3 --> DataFolder
    phase4 --> DataFolder
Loading

Runtime Architecture

flowchart LR
    subgraph models [Models]
        Player
        NPC
        Maze
        Encounter
        Quest
        Spell
    end

    subgraph controllers [Controllers]
        GC["GameController"]
        CIH["CombatInputHandler"]
        EIH["EventInputHandler"]
    end

    subgraph views [Views]
        MazeView
        CombatView
        DialogueView
        EncounterView
    end

    subgraph systems [Systems]
        QuestMgr["QuestManager"]
        SaveMgr["SaveManager"]
        Survival["SurvivalSystem"]
        FogOfWar
        MusicDir["MusicDirector"]
    end

    GC --> CIH
    GC --> EIH
    GC --> models
    GC --> systems
    controllers --> views
    views --> PygameDisplay["pygame display"]
Loading

Three-Mode Architecture

Mode .env value Description
Offline (Static) offline_static Pre-generated content with scripted dialogue trees. Fully self-contained, no API keys needed.
Offline (Local) offline_local NPC dialogue generated by locally hosted LLM. Requires local GPU.
Online (API) online NPC dialogue generated via Claude API. Requires internet + API key.

Game Features

  • Multi-room maze exploration with fog of war and day/night cycle
  • Turn-based combat with initiative, weapon stat scaling, spell modifiers
  • 4 class archetypes (warrior, mage, healer, jester) with AI-generated stat blocks, names, and portraits per environment
  • 5-element magic system (fire, water, forest, light, dark) with RPS multipliers
  • 3 encounter types: combat, puzzle (tool / ability / spell solutions), event (multi-choice with DC rolls)
  • 6 quest types: fetch, kill, escort, delivery, dialogue, multi-step chains
  • Environment-themed monster pools with elemental affinities and loot tables
  • Gate bosses per room, climax boss on the final room
  • NPC followers, shops, survival (hunger / thirst / stamina), save/load

Quick start (from source)

git clone <repo>
cd mazeworld
pip install -e ".[api,dev]"
cp .env.example .env            # add keys for any providers you want
python main.py --dev            # generate a world, then play it
python main.py --dev --skip-gen # play an already-generated world

Building the .app yourself

From a generated world:

python main.py --dev --exe

PyInstaller needs a framework-built Python on macOS, so the --exe flag uses a separate .venv-build:

/Library/Frameworks/Python.framework/Versions/3.12/bin/python3 -m venv .venv-build
.venv-build/bin/pip install 'pygame>=2.6' 'pydantic>=2.9' 'python-dotenv>=1.1' \
                             'Pillow>=10.0' 'protobuf>=4.25' 'pyinstaller>=6.11'

Requires Python 3.12 from python.org. Saves from the packaged app live at ~/Library/Application Support/MazeWorld/saves/ (including crash.log on failed launches).

Releasing (macOS + Windows via CI)

PyInstaller can't cross-compile, so Windows .exe builds run on GitHub Actions. The .github/workflows/release.yml workflow packages both platforms and attaches the zips to a GitHub Release.

One-time setup

Because the generated data/ folder is ~1 GB (dominated by portraits) it stays out of git. It lives on a dedicated world-data-vN release tag and is consumed by the build jobs.

  1. Generate a world locally (python main.py --dev).

  2. Publish the data bundle as a release asset:

    ./scripts/publish_world_data.sh        # auto-picks the next world-data-vN tag
  3. Point CI at that tag by setting a repository variable (Settings -> Secrets and variables -> Actions -> Variables, or via CLI):

    gh variable set WORLD_DATA_TAG --body "world-data-v1"

Cutting a release

Either push a version tag:

git tag v0.1.0 && git push origin v0.1.0

Or run the workflow manually (GitHub Actions UI -> Release -> Run workflow) and supply a version like v0.1.0-test. The workflow:

  • Builds MazeWorld.app on macos-14 (arm64) via mazeworld.spec.
  • Builds MazeWorld.exe on windows-latest via mazeworld_win.spec.
  • Downloads the pinned world-data-vN zip on each runner and unpacks it into data/ before PyInstaller runs.
  • Publishes both zips to the release tag with generated release notes.

To ship a new world without touching code, regenerate, re-run scripts/publish_world_data.sh (it picks a new world-data-vN), bump WORLD_DATA_TAG, and cut a fresh version tag.

Requirements

  • Python 3.11+
  • Pygame 2.6, Pydantic 2.9+
  • Anthropic SDK (online mode)
  • PyTorch 2.4+, Transformers, Diffusers (offline_local mode only)

See requirements.txt for pinned versions.

License

MIT.

About

A python 2D dungeon crawler with Generative Characters and world settings

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages