Skip to main content

Battle System Architecture

MCE's battle system is built on a modular component architecture. The BattleManager orchestrates 15+ specialized modules, each responsible for a single aspect of combat. A BattleStateMachine drives the turn flow, and the entire system is wired together via Zenject dependency injection.

Architecture Overview​

BattleLauncher
└─ BattleManager (orchestrator)
├─ BattleStateMachine (turn flow)
├─ BattlersModule (battler instances)
├─ HealthModule (HP, fainting)
├─ MovesModule (move execution, PP)
├─ ItemsModule (in-battle items)
├─ CaptureModule (catch mechanics)
├─ AIModule (enemy decisions)
├─ AnimationModule (battle animations)
├─ AudioModule (music, SFX)
├─ StatusesModule (burn, poison, sleep...)
├─ BattlerStatsModule (stat stages)
├─ BattlerSwitchModule (party switching)
├─ RostersModule (party management)
├─ ScenariosModule (battle type config)
├─ MegaModule (Mega Evolution)
└─ CharactersModule (trainer sprites)

BattleManager​

The BattleManager is the central coordinator. It does not contain battle logic itself -- instead, it delegates to its modules. Its responsibilities are:

  • Initializing all modules when a battle begins.
  • Providing a shared reference point for inter-module communication.
  • Receiving commands from the UI (player actions) and the AI (enemy actions).
  • Signaling battle start and end events.

The BattleManager implements IBattleManager, which is the internal interface used by modules to communicate with each other.

BattleStateMachine​

The BattleStateMachine controls the turn-based flow:

BattleStart
→ Introduction (show opponents, play music)
→ TurnStart
→ ActionSelection (player picks Fight/Bag/Monster/Run)
→ ActionExecution (resolve all actions in speed order)
→ TurnEffects (weather, status damage, end-of-turn abilities)
→ FaintCheck (check if any battler fainted)
→ ReplaceFainted (player/AI sends in next monster)
→ TurnEnd
→ [loop to TurnStart if battle continues]
→ BattleEnd (determine winner)
→ Results (XP, EVs, money, capture result)
BattleCleanup

Each state is a discrete class. Transitions are deterministic -- there is no ambiguity about which state follows which.

Battle Modules Deep Dive​

BattlersModule​

Manages the Battler instances for both sides. A Battler is the in-battle representation of a MonsterInstance:

  • Tracks current HP, PP for each move, stat stages, volatile statuses.
  • Holds references to the underlying MonsterInstance and MonsterEntry.
  • Calculates effective stats (base + IVs + EVs + nature + stat stages).

HealthModule​

Handles all HP changes:

  • Damage application (after type effectiveness, STAB, critical hits, stat stages).
  • Healing (items, moves, abilities).
  • Fainting detection and faint processing.
  • Substitutes and Focus Sash-type effects.

MovesModule​

The core damage engine:

  • Move selection and validation (PP check, disabled moves, choice-locked moves).
  • Damage calculation using Gen V+ formulas.
  • Type effectiveness lookup.
  • Critical hit determination.
  • Multi-hit moves, fixed-damage moves, OHKO moves.
  • Accuracy and evasion checks.
  • Move effects (stat changes, status infliction, field effects).

ItemsModule​

In-battle item usage:

  • Healing items (Potion, Super Potion, etc.).
  • Status cure items (Antidote, Awakening, etc.).
  • Battle items (X Attack, X Defense, etc.).
  • Items are consumed from the player's bag on use.

CaptureModule​

Wild monster capture mechanics:

  • Catch rate calculation based on species catch rate, current HP %, status condition, and ball type.
  • Ball shake animation (1-3 shakes before capture or escape).
  • Critical capture chance.
  • Adds caught monster to the player's party or PC storage.

AIModule​

Delegates to a pluggable IBattleAI strategy:

  • Receives the current battle state.
  • Returns a BattleAction (which move to use, whether to switch, whether to use an item).
  • See Battle AI for details on built-in and custom strategies.

StatusesModule​

Manages non-volatile and volatile status conditions:

Non-Volatile (only one at a time):

  • Burn, Freeze, Paralysis, Poison, Bad Poison, Sleep.

Volatile (can stack):

  • Confusion, Infatuation, Flinch, Trapped, Leech Seed, and more.

Each status applies its effects at the correct time in the turn cycle (e.g., burn damage at turn end, paralysis check before move execution).

BattlerStatsModule​

Handles stat stage modifications:

  • Stat stages range from -6 to +6.
  • Each stage applies a multiplier: +1 = 1.5x, +2 = 2.0x, ..., -1 = 0.67x, etc.
  • Tracks which stats have been modified and by how much.
  • Handles abilities that prevent stat drops (Clear Body, White Smoke).

MegaModule​

Mega Evolution support:

  • Checks if the active battler's species has a Mega form.
  • Checks if the player has the required Mega item.
  • Triggers the Mega Evolution animation.
  • Applies the Mega form's stat and type overrides.
  • Only one Mega Evolution per battle per trainer.

Battle Flow Example​

Here is what happens when the player selects "Fight" and picks a move:

  1. ActionSelection -- Player chooses a move from the 4-slot move panel.
  2. Priority Calculation -- All actions (player + AI) are sorted by:
    • Move priority (e.g., Quick Attack has +1 priority).
    • Speed stat (higher goes first, with random tiebreaker).
  3. Move Execution (for the faster battler):
    • Check accuracy -- does the move hit?
    • Calculate damage (if damaging): ((2*Level/5+2) * Power * Atk/Def) / 50 + 2
    • Apply modifiers: STAB, type effectiveness, critical hit, random factor (0.85-1.0), items, abilities, weather.
    • Apply secondary effects (stat changes, status conditions).
  4. Move Execution (for the slower battler, if still standing).
  5. TurnEffects -- Weather damage, status damage, held item effects, ability triggers.
  6. FaintCheck -- If a battler has 0 HP, process fainting (give XP/EVs, check for evolution).

Wild vs Trainer Battles​

AspectWild BattleTrainer Battle
Can captureYesNo
Can runYes (with flee check)No
Opponent party1 monster1-6 monsters
Prize moneyNoYes (based on trainer class + level)
AI behaviorTypically randomConfigurable per trainer
RematchRandom encounterScripted (CommandGraph)

Battle Configuration​

The BattleConfigurationFile ScriptableObject controls global battle settings:

  • Default battle speed.
  • Animation skip preferences.
  • Critical hit rate.
  • Weather effects.
  • Experience formula modifiers.
  • Capture rate modifiers.

Access it at Assets/OpenMon/Core/Runtime/Configuration/.

Listening to Battle Events​

All Tiers (SDK)​

IBattleSystem battle = engine.Battle;
battle.OnBattleStarted += () => Debug.Log("Battle started");
battle.OnBattleEnded += (won) => Debug.Log($"Battle ended, won: {won}");

Source Tier (Internal Events)​

With source access, you can subscribe to granular internal events on individual modules (damage dealt, status applied, capture attempted, etc.).