Skip to main content
Closed alpha is live now
Charter live Back the founding campaign and claim your reserved perks. Back the Charter

Combat

Combat Engine

A single Stellarch match resolves in deterministic phases. Once teams are validated and pre-battle abilities apply, the engine runs the combat loop until one team is wiped out. From round 21 onward, escalating end-of-round damage hits every fighter so no match can stall, and a 200-round hard cap is a never-reached safety net. Each round walks every alive fighter in action order, dispatches an attack, resolves the hit pipeline, applies damage, then handles death and reflects.

Battle pipeline

Every battle moves through these phases in order. The engine is a thin shell around a deterministic RNG (SeededRng) and four pure-function combat engines (Targeting, AttackResolver, DeathResolver, RoundResolver).

  battle_start
       |
       v
  pre_battle_phase    -- rulesets first, then abilities
       |
       v
  combat_loop  ------>+
       |              |
       |              v
       |        round_start
       |              |
       |              v
       |        per_turn ability hooks   (Heal, TankHeal)
       |              |
       |              v
       |        RoundResolver            (Targeting, AttackResolver,
       |              |                   DeathResolver per actor)
       |              v
       |        end_of_round rulesets    (Earthquake)
       |              |
       |              v
       |        poison_tick + cleanup
       |              |
       |              v
       |        round_end_summary  ------+
       |                                 |
       |   <--  exit when one side hits 0 alive
       v
  compute_result
       |
       v
  battle_end
  1. battle_start: validate both teams and record the opening snapshot.
  2. pre_battle_phase: apply ruleset hooks (Reinforced Hulls grants team armor, Aegis Protocol grants shields), then friendly buff abilities (Rally-Cry, Bulwark, Reinforce) on both teams, and only then the enemy debuff abilities (Corrode, Sap-Field, Null-Hex and the rest), so a debuff always bites the value a buff just granted. Tectonic Resonance is NOT applied here; it is an end-of-round effect (see below).
  3. combat_loop: runs round by round (200-round safety cap). Each round: round_start, per-turn ability hooks, RoundResolver, end-of-round rulesets, poison tick, sudden-death tick (round 21+), cleanup.
  4. compute_result: the winner is the team with surviving fighters. The round-21+ sudden-death damage forces a result; a total-alive-HP tiebreak at the 200-round safety cap is the last-resort fallback.
  5. battle_end: record winner, reason, rounds played.

Action order

Each round, alive fighters act in this priority:

  1. Primary: speed descending, faster acts first.
  2. Secondary: rarity descending, Legendary > Epic > Rare > Common on speed ties.
  3. Tertiary: deterministic RNG jitter, so the same seed and same teams produce the same order every time.

Eligibility ladder

Whether a fighter can attack at all depends on its EFFECTIVE position (its 1-indexed rank among alive teammates) and its attack type. When the front fighter dies, the next one slides up and inherits position 1.

Position Magic Ranged Melee
1 (front) Yes No Yes
2 Yes Yes Spearline only
3+ Yes Yes No

Boarding Action overrides this entire ladder: every melee fighter is eligible regardless of position.

The 5-stage hit pipeline

Every swing walks these stages in order. The pipeline only mutates target HP/armor and (on reflects) attacker HP. The returned event list is frozen, so replay tools deserialize it byte-for-byte.

  1. 1. Hit roll: two-phase ladder

    Magic attacks ALWAYS hit (chance 1.0); they skip the entire speed-and-evasion ladder. True Strike also guarantees a hit. For melee and ranged attacks the chance runs in two phases. Phase 1 (speed-difference): base chance starts at 1.0. If the target is faster, subtract (target.speed minus attacker.speed) times 0.10. Floor at 0.50, so the speed math alone never produces a sub-50% chance.

    Phase 2 (ability evasion): starting from Phase-1's floored chance, subtract 0.25 each for Lift-Drive (defender, vs a non-Lift-Drive melee or ranged attacker) and Slipstream (defender, vs melee or ranged). This stack CAN push the final chance below 0.50. The lone exception to magic always hitting is Blink-Shift: a defender with Blink-Shift has a 25% chance to evade an incoming magic attack.

  2. 2. Class mitigation

    Plate halves physical damage (melee + ranged), min 1. Null-Field halves magic damage, min 1. Aegis Bubble nullifies the first hit entirely, then breaks.

  3. 3. Armor absorb

    Melee and ranged damage absorbs through armor by default. Magic skips armor, unless the defender has Null-Plate, which routes magic through the armor track too. Armor absorbs the ENTIRE swing even when the hit exceeds the remaining armor: leftover damage does NOT spill to HP. A 10-damage hit into 1 armor strips the armor to 0 and deals 0 to HP; the next swing hits HP directly.

  4. 4. HP application

    Whatever damage remains hits HP. The damage_applied event fires even when remaining damage is 0.

  5. 5. Reflects

    Fired only when damage > 0 hit HP AND the attacker is still alive. Recoil-Plate reflects a fixed 2 vs melee. Counter-Volley reflects ceil(raw / 2) vs ranged. Spell-Mirror reflects ceil(raw / 2) vs magic. Reflects use the raw pre-mitigation damage as the basis.

    On a connecting hit, some abilities also apply a status at 50% chance: Hemobane applies Poisoned (2 damage at the end of every round) and Shock makes the target skip its next turn.

Death + on-death triggers

When a fighter's HP hits 0, the DeathResolver flips its alive flag, emits one on_death_trigger event per on-death ability the fighter carries, and checks whether the remaining team should activate Final Defiance.

  1. died: fighter is removed from action order.
  2. on_death_trigger: abilities like Killstreak (on-kill stat bonus for the attacker) and Overrun (chain attack) fire here.
  3. revive: Rebirth self-revives the fighter once at 1 HP; Resurrect revives a fallen ally once at 1 HP; Redemption deals 1 true damage to every enemy as the fighter dies.
  4. last_stand_activated: if the death leaves a single alive teammate carrying Final Defiance, its stats scale 1.5x for the rest of the match.

End of round

After every fighter acts, the engine runs:

  1. End-of-round ruleset hooks: Tectonic Resonance deals 2 true damage to every non-Lift-Drive fighter.
  2. Hemobane tick: every Poisoned fighter takes 2 damage. Resolved once per round at the type level (not per-bearer).
  3. Sudden-death tick (round 21+): every fighter takes escalating true damage each round (round 21 = 1, round 30 = 10) so the match can never stall. This damage bypasses armor, mitigation, and reflects.
  4. Solo-survivor sweep: confirms Final Defiance activations triggered by mid-round deaths.
  5. Round-end summary: alive counts on both teams. If either side hits 0, the loop exits.

Security

Determinism is the contract. Same seed + same teams = byte-identical events. See the security page for how to verify a replay against the source seed.

Security