Skip to content

Repository files navigation

    ▄▄▄       ▓█████▄  ██▒   █▓▓█████  ███▄    █ ▄▄▄█████▓ █    ██  ██▀███  ▓█████
   ▒████▄     ▒██▀ ██▌▓██░   █▒▓█   ▀  ██ ▀█   █ ▓  ██▒ ▓▒ ██  ▓██▒▓██ ▒ ██▒▓█   ▀
   ▒██  ▀█▄   ░██   █▌ ▓██  █▒░▒███   ▓██  ▀█ ██▒▒ ▓██░ ▒░▓██  ▒██░▓██ ░▄█ ▒▒███
   ░██▄▄▄▄██  ░▓█▄   ▌  ▒██ █░░▒▓█  ▄ ▓██▒  ▐▌██▒░ ▓██▓ ░ ▓▓█  ░██░▒██▀▀█▄  ▒▓█  ▄
    ▓█   ▓██▒ ░▒████▓    ▒▀█░  ░▒████▒▒██░   ▓██░  ▒██▒ ░ ▒▒█████▓ ░██▓ ▒██▒░▒████▒
    ▒▒   ▓▒█░  ▒▒▓  ▒    ░ ▐░  ░░ ▒░ ░░ ▒░   ▒ ▒   ▒ ░░   ░▒▓▒ ▒ ▒ ░ ▒▓ ░▒▓░░░ ▒░ ░

⚔️ Four heroes. One seed. Everything you carry is at risk.

CI Python PostgreSQL Socket.IO Version

Changelog · Development · Architecture · Economy · Dungeons · Contributing


You take four into the dark. What you bring back is yours. What you drop down there stays down there.

Adventure is a browser-based, MUD-style dungeon crawler built on Flask and Socket.IO. Everything happens in real time over WebSockets — movement, combat, chat, loot — with no page reloads. Dungeons are procedurally generated and deterministic per seed: the same seed always produces the same layout, but no two parties spend it the same way.

The hook is extraction. Your run-purse is at risk from the moment you step through the door. Only what you carry out becomes permanent, banked into your Hoard. A party wipe loses the run's haul — and a character who dies and is not raised can be looted, then left behind for good.


🎲 The Loop

flowchart LR
    A["🏰 Town<br/>roster · train · trade"] --> B["🗝️ Delve<br/>pick a seed"]
    B --> C["🕯️ Explore<br/>rooms · doors · traps"]
    C --> D["⚔️ Fight<br/>turn-based, per character"]
    D --> C
    C --> E{"Push on<br/>or leave?"}
    E -->|push| C
    E -->|extract| F["💰 Hoard<br/>haul banked, XP kept"]
    E -->|wipe| G["💀 Lost<br/>haul gone"]
    F --> A
    G --> A
Loading

The whole design lives in that fork. Going deeper is where the good loot is; every step deeper is more you stand to lose.


⚔️ What You Actually Do

🧙 Party & Progression

Roll up to twelve classes — fighter, barbarian, monk, mage, sorcerer, cleric, paladin, druid, ranger, rogue, bard, warlock — and field four at a time. Each class has its own signature skill tree on top of a shared archetype line, so no two classes play the same.

Twenty levels, and every one of them unlocks something. Talent points buy skills you choose; you will never have enough for all of them.

🗡️ Combat

Turn-based and initiative-driven, where every character acts on their own turn — not as one lumpy "party turn". Attack, defend, flee, drink, or spend a skill.

Server-authoritative with optimistic-concurrency versioning, so the screen can never disagree with the real fight.

🏰 The Dungeon

Rooms, corridors, locked doors, secret passages and teleport pads — all generated from a seed and fully reproducible.

Movement and searching advance a shared game clock that paces encounters and patrols. The world only moves when you do.

💎 Loot

Procedural gear with prefixes and suffixes — Brutal Longsword of the Bear — where rarity changes what an item is worth, not just how many words it has.

Deeper tiers roll better. Gear wears down and can be repaired.

Note

Two systems ship switched off while their numbers get playtested: multi-enemy packs (combat_pack_max) and monster AI (ai_enabled). The engine handles both; turning either on makes fights markedly harder, so they are deliberately opt-in. Monsters currently attack and nothing else.


🧭 Getting Started

Important

PostgreSQL is required. SQLite is explicitly rejected at startup — the app raises unless DATABASE_URL points at Postgres.

📜 Quick start
# 1. Database
createdb adventure

# 2. Environment
export DATABASE_URL="postgresql://username:password@localhost/adventure"
export SECRET_KEY="your-secret-key-here"

# 3. Dependencies
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# 4. Schema
alembic upgrade head

# 5. Seed the world — idempotent, safe to re-run
python run.py reseed-items
python run.py seed-merchants
python run.py seed-skills
# (or all three: ./manage.sh db seed)

# 6. Open the doors
python run.py server        # http://localhost:5000
🪄 Or let the bootstrap script do it

Handles .env generation, migrations and an admin account for you:

python scripts/setup_adventure.py
🧪 Tests, lint, format
pytest -q
ruff check .
black --check .

The suite needs an explicit test database — see docs/TESTING.md. Conventions and the admin CLI are in docs/DEVELOPMENT.md.


🗺️ Where Things Live

app/models/ Database models
app/routes/ Flask blueprints — auth, dashboard, dungeon, combat, admin
app/services/ Game logic — combat, progression, loot, status effects, the clock
app/dungeon/ Procedural generation pipeline
app/websockets/ Socket.IO event handlers
app/static/, app/templates/ Frontend assets and Jinja templates
migrations/ Alembic schema migrations
tests/, e2e/ pytest suite and Playwright browser smoke

📚 The Library

Open the full documentation index
Topic Doc
Release history CHANGELOG.md
Local dev, lint/test conventions, admin CLI docs/DEVELOPMENT.md
System architecture docs/architecture.md
Economy, currency, hoard, progression docs/ECONOMY_PROGRESSION.md
Combat system — actions, formulas, balance docs/COMBAT_SYSTEM.md
Combat visual effects docs/COMBAT_EFFECTS.md
Loot — rarity, placement algorithm docs/LOOT_SYSTEM.md
Dungeon generation & invariants docs/DUNGEON_GENERATION.md
Teleports docs/TELEPORTS.md
Monster AI docs/MONSTER_AI.md
Locked doors & lockpicking docs/LOCKED_DOORS.md
Party system docs/PARTY_SYSTEM.md
Skill trees docs/SKILL_TREE_SYSTEM.md
Achievements docs/ACHIEVEMENT_SYSTEM.md
Trading docs/TRADING_SYSTEM.md
Frontend style guide docs/STYLE_GUIDE.md
Art assets & licences docs/ASSETS.md
Testing conventions docs/TESTING.md
Deployment docs/DEPLOYMENT.md · docs/DOCKER_SETUP.md
Release process docs/RELEASING.md

🎨 Credits

Dungeon tile art: Dungeon Gathering — Under The Castle Set by SnowHex — lovely 16×16 work, and worth your money.

Warning

The art is licence-restricted and is not included in this repository. Run scripts/import_tiles.sh against a copy you own to enable it — or just play without it, and the map renders procedurally. See docs/ASSETS.md.


🤝 Contributing

Coding conventions, pre-commit policy, asset guidelines and test instructions are in docs/CONTRIBUTING.md.


Built with Flask, Socket.IO, PostgreSQL — and an unreasonable number of tests.

About

A web-based multiplayer dungeon crawler — build a party, descend into procedurally generated dungeons, and decide how far to push your luck before extracting with the loot.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages