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.).