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 twenty-one onward, escalating end-of-round damage hits every fighter so no match can stall, and a two-hundred-round hard cap is a never-reached safety net. Each round walks every alive fighter in action order, dispatches an attack, resolves the 9-stage 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 9-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. Under Time Dilation this speed comparison runs the other way: the attacker pays for being FASTER, so the slower Fighter is the harder target.

    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. Pre-mitigation ruleset override

    Solar Flare adds 1 only to positive base magic damage. It changes the base before class mitigation and armor absorption, so ordinary halving and armor routing still apply.

  3. 3. Skyhunter bonus

    Skyhunter adds 2 damage against a target with Lift-Drive before class mitigation and armor absorption.

  4. 4. Killing-Blow multiplier

    Killing-Blow doubles the running damage when the target is the sole surviving enemy. This happens before class mitigation and armor absorption.

  5. 5. Class mitigation

    Mitigation runs in order: Plate halves physical damage, Null-Field halves magic damage, Bulwark-Field caps the running swing at 1 when printed attack is at least 5, then Aegis Bubble nullifies the first hit entirely and breaks.

  6. 6. Armor absorption

    Melee and ranged damage routes through armor by default. Magic skips armor unless Null-Plate routes it there too. A normal armor-routed swing never overflows into HP, even when it exceeds the remaining armor. Hull-Breaker is the exception: excess melee or ranged damage carries through armor into HP.

  7. 7. Post-armor ruleset override

    After armor, Overkill Doctrine doubles a positive remaining value against a Shocked target. Focus Fire adds 2 on the second and later connected hits against the same target in the same round. These post-armor changes bypass armor.

  8. 8. HP application

    HP receives the result after the post-armor fold. The damage_applied event fires even when the remaining value is 0, so a connected swing does not always remove HP.

  9. 9. Reflects

    A connected, non-nullified, non-counter swing can reflect even when armor absorbed all direct damage. Missed swings, swings nullified by Aegis Bubble or a defender hook, and counter swings do not reflect. Recoil-Plate reflects a fixed 2. Counter-Volley and Spell-Mirror reflect half the raw pre-mitigation swing, rounded up.

    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