View: Multi-Page Single Page

Battle Core

The Battle class is the heart of SimpleJRPG — a plain C# instance that orchestrates combat through lifecycle methods, combat verbs, and events.

Battle Lifecycle

Start()

public void Start(List<ICombatant> combatants, ITurnSystem turnSystem)

Initializes the battle. Pass in your list of combatants and a turn system implementation. Internally, this method:

  1. Stores the combatants and turn system references.
  2. Resets the turn counter and battle history.
  3. Calls turnSystem.Init(combatants) so the turn system can set up its internal state.
  4. Sets State to BattleState.WaitingForCommands.
  5. Fires the OnBattleStart event.

Start() will silently return if the battle state is anything other than NotStarted. You cannot restart a battle instance — create a new one.

EndBattle()

public void EndBattle(BattleState result)

Ends the battle with the given outcome. Pass BattleState.Victory, BattleState.Defeat, or BattleState.Fled. This method:

  1. Sets State to the given result.
  2. Clears CurrentActor.
  3. Creates a BattleResult containing the outcome, total turns taken, surviving combatants, and the full battle history.
  4. Fires the OnBattleEnd event with the battle instance and the resulting state.

If the battle has already ended (state is Victory, Defeat, or Fled), calling EndBattle() again does nothing.

Turn Flow

BeginNextTurn()

public ICombatant BeginNextTurn()

Advances to the next turn. Asks the turn system for the next actor via GetNextActor(), increments the turn counter, sets state to Executing, and fires OnTurnStart. Returns the actor whose turn it is, or null if no actor is available.

Can only be called when state is WaitingForCommands or Executing.

EndTurn()

public void EndTurn()

Ends the current turn. Fires OnTurnEnd, notifies the turn system via OnTurnEnd(), clears CurrentActor, then automatically calls CheckBattleEnd(). If the battle hasn't ended, state returns to WaitingForCommands.

Can only be called when state is Executing.

State Machine

The battle progresses through a simple state machine. All transitions are driven by the methods described above.

NotStarted ──Start()──> WaitingForCommands │ BeginNextTurn() │ ▼ Executing │ EndTurn() │ ▼ WaitingForCommands │ CheckBattleEnd() / \ Victory Defeat Fled
Note Fled is reached via Flee(), which calls EndBattle(BattleState.Fled) directly — it can happen from any active state, not just after CheckBattleEnd().

Combat Verbs

Combat verbs are the imperative methods you call to make things happen in battle. You do the math — we orchestrate the result.

DealDamage

public void DealDamage(ICombatant source, ICombatant target, int amount,
    string damageType = "", string element = "", bool isCrit = false)

Deals damage to a single target. The flow is:

  1. Fires OnBeforeDamage with a BeforeDamageEvent. Subscribers can modify Amount, DamageType, Element, IsCrit, or set Cancel = true to prevent the damage entirely.
  2. If not cancelled, calls target.TakeDamage(amount) with the (potentially modified) amount.
  3. Fires OnDamageDealt with the final DamageEvent.
  4. If the target is no longer alive, automatically fires OnKO and notifies the turn system.

There is also a group overload that accepts IList<ICombatant> targets and fires OnGroupDamageDealt after processing all individual hits.

Heal

public void Heal(ICombatant source, ICombatant target, int amount)

Heals a single target. The flow mirrors damage:

  1. Fires OnBeforeHeal with a BeforeHealEvent. Subscribers can modify Amount or set Cancel = true.
  2. If not cancelled, calls target.Heal(amount).
  3. Fires OnHealed with the final HealEvent.

Group overload available — fires OnGroupHealed after all individual heals.

Kill

public void Kill(ICombatant target, ICombatant killer = null)

Forces a KO regardless of the target's current HP. Calls target.TakeDamage(int.MaxValue), then fires OnKO and notifies the turn system. Does nothing if the target is already dead. This bypasses the before-event system — there is no OnBeforeDamage for Kill.

Revive

public void Revive(ICombatant target, int hpAmount)

Revives a dead combatant by calling target.Heal(hpAmount), then notifies the turn system via OnActorAdded() so the revived combatant is re-inserted into the turn order. Fires OnRevived. Does nothing if the target is already alive.

Status & Buff

Event-only — no internal tracking Battle does NOT maintain a list of active statuses or buffs. These methods exist solely to fire events. Your game's status system subscribes to these events and handles all tracking, stacking, duration, and removal logic.

ApplyStatus / RemoveStatus

public void ApplyStatus(ICombatant source, ICombatant target, string statusId, int duration = -1)
public void RemoveStatus(ICombatant target, string statusId)

ApplyStatus fires OnStatusApplied with a StatusEvent containing the source, target, status ID string, and optional duration. RemoveStatus fires OnStatusRemoved with the target and status ID. Both have group overloads that fire OnGroupStatusApplied.

The statusId is a pass-through string — Battle doesn't know or care what "Poison" or "Blind" means. Your system decides.

ApplyBuff / RemoveBuff

public void ApplyBuff(ICombatant source, ICombatant target, string buffId, float amount, int duration = -1)
public void RemoveBuff(ICombatant target, string buffId)

ApplyBuff fires OnBuffApplied with a BuffEvent containing source, target, buff ID, numeric amount, and optional duration. RemoveBuff fires OnBuffRemoved. Group overloads fire OnGroupBuffApplied.

Same pass-through philosophy — buffId and amount are yours to interpret. "ATK_UP" with amount 1.5 could mean +50% attack, or 1.5 flat — your call.

Flee

public void Flee(ICombatant who)

Fires OnFled with the fleeing combatant, then immediately calls EndBattle(BattleState.Fled). The battle ends — no further actions are possible.

Whether the flee attempt succeeds is your game's decision. Only call Flee() after you've already determined the attempt was successful. If you want a chance-based flee, do your roll first, and only call this if it passes.

CheckBattleEnd

public bool CheckBattleEnd()

Checks whether the battle should end based on which teams still have living combatants. Returns true if the battle ended, false otherwise.

The logic:

  • Team 0 = player team. All other team numbers are considered enemies.
  • If no enemies are alive (only team 0 remains) — EndBattle(BattleState.Victory).
  • If no team 0 members are alive — EndBattle(BattleState.Defeat).
Automatic calls CheckBattleEnd() is called automatically at two points: inside EndTurn(), and inside HandleKO() (which fires whenever a combatant dies from DealDamage or Kill). You typically don't need to call it yourself, but you can if you want to check mid-turn.
↓ ↑