7.5 KiB
🧩 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
│
└── 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:
- Load race + profession data from YAML via loaders.
- Apply racial ability modifiers.
- Apply profession base stats and per-level growth rates.
- 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):
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):
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:
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:
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_levelis always accurate after XP updates.
🎲 Skill Gain Logic
Implemented in systems/leveling.py.
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 + professionPOST /char/level→ level up existing entity and add new skillsGET /char/:id→ return current character stats, XP, and skills
Example:
@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
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/catalogsmay 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.