5.8 KiB
🧰 Developer Notes — System Architecture & Implementation
This section explains how the Code of Conquest Battle System is structured behind the scenes for developers and modders.
🧮 1. Formula Layers
Combat calculations occur in three distinct layers, each responsible for a specific part of the logic:
| Layer | Purpose | Example |
|---|---|---|
| Base Layer | Core attributes and level-based growth. | STR, DEX, INT, etc. |
| Derived Layer | Recalculates combat-ready stats from base values and equipment. | ATK, DEF, ACC, etc. |
| Resolution Layer | Executes battle outcomes using deterministic formulas. | Damage, Crit, AlignmentBonus, etc. |
Each layer feeds cleanly into the next.
This modular approach ensures stats can be recalculated at any time without breaking the combat state.
⚙️ 2. Suggested Class Structure
The system can be built around data-driven classes:
class Character:
name: str
level: int
alignment: int
attributes: Attributes # STR, DEX, INT, etc.
equipment: Equipment
derived_stats: DerivedStats
class Attributes:
str: int
dex: int
int: int
wis: int
lck: int
cha: int
class DerivedStats:
atk: int
mag: int
def_: int
mdef: int
acc: float
eva: float
crit: float
res: float
All formulas (like ATK = STR × 2 + WeaponBonus) live inside the DerivedStats.recalculate() method.
Skills and combat outcomes can then safely reference character.derived_stats.
📜 3. Skill Definitions
Skills should be stored as external data files (YAML or JSON) for easy modification and expansion.
Example:
# skills/power_slash.yaml
id: power_slash
name: Power Slash
type: melee
description: A strong physical strike with reduced accuracy.
modifiers:
damage_multiplier: 1.5
accuracy_multiplier: 0.9
crit_bonus: 0.0
conditions:
requires_weapon_type: sword
When combat is resolved, the system loads the skill data dynamically:
damage *= skill.damage_multiplier
accuracy *= skill.accuracy_multiplier
This keeps gameplay logic data-driven and easily expandable.
🧠 4. Combat Resolution Flow
A full attack resolves in five modular steps:
- Precheck Phase — confirm turn order, skill requirements, status effects.
- Accuracy Phase — roll for hit using
ACCvs targetEVA. - Damage Phase — calculate raw damage using formulas.
- Modifier Phase — apply critical hits, alignment bonus, buffs/debuffs.
- Finalize Phase — subtract HP, trigger effects, narrate outcome.
Each step can be represented by its own method or even subclass (useful for custom battle systems later).
⚖️ 5. Alignment & Morality Hooks
Alignment is stored as a simple integer between –100 and +100.
When calculating damage:
alignment_difference = abs(attacker.alignment - target.alignment)
alignment_bonus = (alignment_difference / 10) / 100
damage *= 1 + alignment_bonus
Later expansions might include:
- Morality events that shift alignment based on choices.
- Faction modifiers (e.g., “Paladin vs Undead” adds extra scaling).
- Spells that interact directly with alignment (“Smite Evil,” “Corrupt Heart”).
🍀 6. Luck Integration Strategy
Luck is treated as a global adjustment factor that nudges probability outcomes and variance rolls upward slightly. Instead of directly changing RNG, it biases existing rolls.
def apply_luck_bias(base_value: float, luck: int) -> float:
bias = 1 + (luck * 0.002) # +0.2% per point of Luck
return base_value * bias
This keeps outcomes unpredictable yet fair — luckier characters simply lean toward better odds over time.
📈 7. Level Scaling Curves
Scaling should be class-specific and controlled via external tables:
# growth_curves/guardian.yaml
str_growth: high
dex_growth: low
int_growth: low
wis_growth: medium
lck_growth: low
cha_growth: medium
When leveling up:
new_value = old_value + growth_table.get(attribute).calculate(level)
You can easily balance or tweak these tables without touching core logic.
🧩 8. Extensibility Hooks
Future systems can layer naturally on top of this design:
- Elemental Affinities: Fire, Ice, Lightning resistances.
- Buff & Debuff States: stored as timed modifiers.
- Equipment Enchantments: simple additive multipliers.
- Status Effects: stored as objects (e.g.,
Status("Burning", duration=3, dot=5)).
Each additional system only needs to plug into the Resolution Phase as a pre/post modifier.
🧱 9. Design Philosophy for Developers
- Transparency over randomness — deterministic math first, variance second.
- Data before code — YAML or JSON defines skills, growth, and buffs.
- Layered structure — base → derived → resolution → output.
- Alignment matters — every moral choice has mechanical consequence.
- Luck is universal — a soft bias across all rolls, never a chaos driver.
- Readable outputs — easy for AI or human narrators to describe battle results.
🧾 10. Future Expansion Notes
- Elemental Damage Types (
fire,ice,holy,dark). - Combo Systems (chain attacks between party members).
- Morale System (CHA and WIS affecting group performance).
- Dynamic Battle Narration (AI-driven storytelling from combat logs).
- Procedural Skill Fusion (merge abilities to create new ones).
Implementation Tip: Keep every formula centralized in a single
FormulasorBattleMathclass. This ensures balancing changes never require refactoring gameplay code.
Developer Reference Version: 1.0 Author: Code of Conquest Systems Design Team Document Last Updated: October 2025