|
|
||
|---|---|---|
| app | ||
| data | ||
| frontend | ||
| scripts | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| DESIGN.md | ||
| nexus-rpg.code-workspace | ||
| README.md | ||
| requirements.txt | ||
| run_backend.sh | ||
| run_frontend.sh | ||
nexus-rpg
A self-hosted browser RPG with hero progression, real-time quests, wilderness exploration, dungeon crawls, faction reputation, and a Diablo 1-inspired dark fantasy aesthetic.
Stack
| Layer | Tech |
|---|---|
| Backend | Python 3.12 · FastAPI · SQLAlchemy · SQLite · PyYAML |
| Frontend | React 18 · Vite · React Router v6 · react-i18next · Leaflet |
| Auth | JWT (python-jose) · Argon2 password hashing |
| i18n | DE / EN / RO — locale files per namespace in frontend/src/locale/ |
Projektstruktur
nexus-rpg/
├── app/
│ ├── main.py # FastAPI app, startup migrations, seeding
│ ├── core/
│ │ ├── config.py # Pydantic settings (.env)
│ │ ├── database.py # SQLite engine & session
│ │ ├── game_config.py # Gameplay constants
│ │ └── i18n.py # YAML index loading, t() helper
│ ├── models/
│ │ ├── hero.py # Hero, HeroClass, HeroAbility — ability_slots_max, kaserne training
│ │ ├── item.py # Item (stat_requirements_json), HeroItem
│ │ ├── quest.py # Quest, QuestStatus, QuestEventInstance
│ │ ├── city.py # State, City, CityNPC
│ │ ├── guild.py # Guild, HeroGuild, GuildType
│ │ ├── wilderness.py # WildernessEncounter
│ │ └── user.py # User
│ ├── routers/
│ │ ├── auth.py # Register, Login, /me
│ │ ├── heroes.py # Hero CRUD, sheet, stats, level-up
│ │ ├── abilities.py # Learn/equip abilities & spells, skill requirements
│ │ ├── items.py # Inventory, equip/unequip (stat requirement check)
│ │ ├── shop.py # Buy / sell items
│ │ ├── quests.py # Quest generation & resolution loop
│ │ ├── guilds.py # Guild membership
│ │ ├── wilderness.py # Roam, dungeon, rest (Traglast stamina multiplier)
│ │ ├── kaserne.py # Bounties, training yard, ability training timer
│ │ ├── magier_gilde.py # (spell learning via abilities router)
│ │ ├── tavern.py # Rest, buffs, rumours
│ │ ├── blacksmith.py # Item upgrades
│ │ ├── markt.py # Market / shop
│ │ ├── temple.py # Blessings
│ │ ├── reputation.py # Faction reputation helpers
│ │ └── admin.py # Admin endpoints
│ ├── scripts/
│ │ ├── seed_classes.py # YAML → DB class seeding
│ │ └── seed_items.py # YAML → DB item seeding (upserts stat_requirements)
│ └── auth/
│ └── dependencies.py # JWT, get_current_user
├── data/
│ ├── classes/ # YAML class definitions (base + prestige)
│ │ └── prestige/ # Tier 1 & 2 prestige classes
│ ├── abilities/
│ │ ├── combat.yaml # Combat abilities (skill_requirements, source: kaserne)
│ │ └── magic.yaml # Spells (skill_requirements, source: magier_gilde)
│ ├── items/
│ │ ├── armor.yaml # Armor (stat_requirements for chain/plate tier)
│ │ ├── weapons.yaml # Weapons (stat_requirements for heavy weapons)
│ │ ├── consumables.yaml
│ │ ├── herbs.yaml
│ │ ├── artifacts.yaml
│ │ ├── adventure.yaml
│ │ ├── materials.yaml
│ │ └── contraband.yaml
│ ├── quest_templates/ # YAML quest templates per type
│ ├── dungeon_rooms/ # Dungeon room pool (dungeon.yaml)
│ └── bounties/ # Bounty board definitions
└── frontend/ # → see frontend/README.md
Quickstart
# Backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # add SECRET_KEY
uvicorn app.main:app --reload # seeds DB on first start
# Frontend
cd frontend && npm install && npm run dev
API docs: http://localhost:8000/docs
Core Systems
Hero
- 5 base stats: STR / DEX / INT / VIT / WIL
effective_skill = invested + (governing_stat // 5)- Level-up grants
level × 5skill points - Ability slots:
floor(level / 5)slots (min 1) for equipped combat abilities - Spell slots:
floor(base_intelligence / 3)slots (min 1) — spells don't occupy ability slots, always available when learned
Fähigkeiten (Abilities & Spells)
Abilities are YAML-driven with skill_requirements: {skill: min_val} and source (kaserne / magier_gilde).
| Type | Learned at | Slots | Cost |
|---|---|---|---|
| Combat | Kaserne | Ability slot | Gold + 2h timer |
| Spell | Magier-Gilde | Spell slot | Gold |
Inventar & Ausrüstung
- Paper-doll slots:
main_hand,off_hand,head,chest,legs,hands,feet - Items have
stat_requirements(e.g.base_strength: 12) — equipping fails if hero stats are below threshold - Traglast / Stamina-Multiplikator: total inventory weight vs.
STR × 1500 gcarry capacity
| Load | Multiplier |
|---|---|
| ≤ 50 % | ×1.0 |
| 50–75 % | ×1.25 |
| 75–100 % | ×1.5 |
| > 100 % | ×2.0 |
Wilderness & Dungeon
POST /heroes/{id}/roam— starts a wilderness encounter chain (intention → events → resolution)POST /heroes/{id}/dungeon— enters a dungeon (3–5 rooms, skill checks, loot)- Stamina cost scaled by Traglast multiplier; rest events restore stamina
Quest System
Templates in data/quest_templates/ (YAML), filtered by biome, guild type, hero level.
Phases: passive → choice → check. Rewards scale +5 % per level above minimum (max +50 %).
Gilden
Rivalitäten: merchants ↔ thieves, mages ↔ fighters. Join via quest. Prestige classes gated by guild rank.
Weltkarte
Basiert auf Azgaar's Fantasy Map Generator.
Kartendaten sind nicht im Repository — export nach frontend/public/:
world_cities_only.png, cells.geojson, markers.geojson, routes.geojson, fullworld.json.
Dependencies
fastapi · uvicorn · sqlalchemy · pydantic · pydantic-settings
passlib[argon2] · argon2-cffi · python-jose[cryptography]
python-dotenv · pyyaml