PROCESSING
Keep this window open.
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
- battle_start: validate both teams and record the opening snapshot.
- 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).
- 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.
- 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.
- battle_end: record winner, reason, rounds played.
Action order
Each round, alive fighters act in this priority:
- Primary: speed descending, faster acts first.
- Secondary: rarity descending, Legendary > Epic > Rare > Common on speed ties.
- 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. 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. 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. Skyhunter bonus
Skyhunter adds 2 damage against a target with Lift-Drive before class mitigation and armor absorption.
-
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. 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. 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. 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. 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. 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.
- died: fighter is removed from action order.
- on_death_trigger: abilities like Killstreak (on-kill stat bonus for the attacker) and Overrun (chain attack) fire here.
- 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.
- 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:
- End-of-round ruleset hooks: Tectonic Resonance deals 2 true damage to every non-Lift-Drive fighter.
- Hemobane tick: every Poisoned fighter takes 2 damage. Resolved once per round at the type level (not per-bearer).
- 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.
- Solo-survivor sweep: confirms Final Defiance activations triggered by mid-round deaths.
- 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