finished out skills per level, added skill trees to professions templates

This commit is contained in:
2025-11-02 19:08:36 -06:00
parent fd572076e0
commit 31aa0000cc
16 changed files with 361 additions and 26 deletions

291
docs/char_gen.md Normal file
View File

@@ -0,0 +1,291 @@
# 🧩 Code of Conquest — Character Generation (Flask API)
## Overview
This document describes how **character generation** operates inside the Flask API.
The goal is to produce a fully realized `Entity` (hero, enemy, or NPC) based on **race**, **profession**, **abilities**, and **level** using YAML-defined data and procedural logic.
---
## ⚙️ Directory Overview
```
app/
├── blueprints/
│ ├── main.py # Root routes
│ └── char.py # Character creation and progression endpoints
├── game/
│ ├── generators/ # Procedural content
│ │ ├── abilities_factory.py # Generates abilities / skills
│ │ ├── entity_factory.py # Builds complete entity objects
│ │ ├── level_progression.py # XP and level curve logic
│ │ └── ... (compiled files)
│ │
│ ├── loaders/ # YAML loaders for static templates
│ │ ├── profession_loader.py
│ │ ├── races_loader.py
│ │ └── spells_loader.py # May be deprecated in favor of skills
│ │
│ ├── models/ # Dataclasses for core game objects
│ │ ├── abilities.py
│ │ ├── entities.py
│ │ ├── professions.py
│ │ ├── races.py
│ │ └── enemies.py
│ │
│ ├── systems/
│ │ └── leveling.py # Handles XP gain, set_level, and skill growth
│ │
│ ├── templates/
│ │ ├── ability_paths.yaml # Defines thematic skill sets (paths)
│ │ ├── professions/*.yaml # Defines all professions
│ │ └── races/*.yaml # Defines all playable races
│ │
│ └── utils/
│ └── common.py
├── models/ # Shared models for the Flask layer
│ ├── hero.py
│ ├── enums.py
│ └── primitives.py
└── utils/
├── catalogs/ # Compiled catalog data for fast lookups
│ ├── race_catalog.py
│ ├── hero_catalog.py
│ └── skill_catalog.py
├── api_response.py
└── settings.py
```
---
## 🧬 Entity Generation Pipeline
### 1. `entity_factory.build_entity()`
Creates a base entity by combining **Race** and **Profession** definitions.
**Steps:**
1. Load race + profession data from YAML via loaders.
2. Apply racial ability modifiers.
3. Apply profession base stats and per-level growth rates.
4. Initialize HP, MP, XP, and skill lists.
---
### 2. `leveling.set_level(entity, target_level)`
Handles level setting and skill gain.
* Calculates XP using `level_progression.py`.
* Calls `calculate_skills_gained()` (randomized 30% chance per level).
* Generates new skills via `abilities_factory`.
---
## 🧝 Races
Located in `app/game/templates/races/`.
Each race defines:
* Base ability modifiers (STR, DEX, CON, INT, WIS, CHA)
* Optional descriptive text
* Tags for gameplay classification
Example (`elf.yaml`):
```yaml
name: Elf
description: Graceful and attuned to magic.
ability_mods:
DEX: 2
INT: 1
CON: -1
tags: ["playable"]
```
---
## ⚔️ Professions
Located in `app/game/templates/professions/`.
Each profession file defines:
* Base HP / MP
* Scaling per level
* Primary stat (INT, WIS, etc.)
* Flavor / lore fields
Example (`warlock.yaml`):
```yaml
id: warlock
name: Warlock
description: A wielder of forbidden demonic power.
primary_stat: CHA
base_hp: 40
base_mp: 80
physical_attack_per_level: 1.0
physical_defense_per_level: 0.5
magic_attack_per_level: 2.5
magic_defense_per_level: 1.5
tags: ["caster","dark"]
```
---
## 🧠 Ability / Skill Generation
### Path Themes
Defined in `templates/ability_paths.yaml`:
```yaml
Hellknight:
elements: ["fire", "shadow"]
adjectives: ["Infernal", "Hellfire", "Brimstone", "Abyssal"]
nouns: ["Edict", "Judgment", "Brand", "Smite"]
of_things: ["Dominion", "Torment", "Cinders", "Night"]
```
### Generator Function
Located in `abilities_factory.py`:
```python
def generate_spells_direct_damage(
class_name: str,
path: str,
level: int,
per_tier: int = 2,
content_version: int = 1,
primary: str = "INT"
) -> List[Spell]:
...
```
**Features:**
* Deterministic random seed based on `(class, path, level, version)`
* Generates direct-damage only
* Scales power and cost by level
* Names and effects are thematically consistent
### Example Output
```
Infernal Judgment — Deal fire damage (power 120, CHA+125%). MP 30, CD 1
Brand of Cinders — Deal shadow damage (power 118, CHA+125%). MP 30, CD 0
```
---
## 📈 Level Progression
Handled in `level_progression.py`.
* Defines XP thresholds per level (exponential curve)
* Provides helper: `get_xp_for_level(level)`
* Ensures `entity.xp_to_next_level` is always accurate after XP updates.
---
## 🎲 Skill Gain Logic
Implemented in `systems/leveling.py`.
```python
def calculate_skills_gained(current_level, target_level, chance_per_level=0.3):
levels_gained = max(0, target_level - current_level)
if levels_gained == 0:
return 0
gained = sum(1 for _ in range(levels_gained) if random.random() < chance_per_level)
if levels_gained < 3:
gained = max(gained, 2)
cap = math.ceil(levels_gained * 0.4)
return min(gained, cap)
```
* **30% random chance** per level to gain a new skill
* Guarantees **≥ 2** if leveling fewer than 3 levels
* Caps maximum growth to **40%** of total levels gained
---
## 🧮 XP / Level Curve Example
| Level | XP Needed (example) | XP Delta | Notes |
| ----- | ------------------- | -------- | ----------------- |
| 1 | 0 | — | Starting level |
| 2 | 100 | +100 | Fast early growth |
| 5 | 625 | +175 | Moderate |
| 10 | 2500 | +350 | Midgame plateau |
| 20 | 10000 | +750 | Late-game scaling |
*(Values may differ depending on `level_progression.py` formula)*
---
## ⚙️ API Integration
### Blueprint: `char.py`
Handles player-facing endpoints such as:
* `POST /char/create` → build entity from race + profession
* `POST /char/level` → level up existing entity and add new skills
* `GET /char/:id` → return current character stats, XP, and skills
Example:
```python
@char_bp.route("/create", methods=["POST"])
def create_character():
data = request.json
entity = build_entity(data["race"], data["profession"])
return jsonify(entity.to_dict())
```
---
## 📁 Data Flow Summary
```mermaid
graph TD
A[API Request] --> B[char.py Blueprint]
B --> C[entity_factory.build_entity()]
C --> D[races_loader / profession_loader]
C --> E[level_progression]
C --> F[abilities_factory]
F --> G[ability_paths.yaml]
C --> H[Entity Model]
H --> I[API Response JSON]
```
---
## 🧾 Design Notes
* All YAML templates are static assets — easy to edit without code changes.
* Procedural factories (`abilities_factory`, `entity_factory`) ensure deterministic generation for the same input.
* Systems (`leveling.py`) handle simulation and logic, isolated from API routes.
* `utils/catalogs` may eventually cache or precompute available skills, professions, and races for faster response times.
* The entire pipeline can operate **statelessly** inside Flask routes or **persisted** in a database later.
---
## 🔮 Future Ideas
* Add **passive traits** per race or profession.
* Implement **rarity** or **tiered skills** (common → legendary).
* Generate **enemy entities** using the same system with difficulty scaling.
* Add a **training system** or **skill mastery** mechanic tied to XP.
* Create **hero_catalog.py** entries for pre-built templates used in story mode.