Combat mechanics
Four against four on the game's grid. Drag players off the live top-100 leaderboard into either team, place them on their half of the board, then run a thousand fights or watch one play out on the turn clock. Every fighter carries the sheet the server reports for that player and the Techniques and Charms they have equipped, each at its own rank and level. Tap any skill on a team card to swap it, clear it, or change its rank and level, and try a setup the player does not run today.
Drag a row onto a team (or tap a row, then a team slot). This week’s Tournament bracket, played on this engine: Tournament projection.
Copy your character, or any player’s Player Info, from the game: the stats list as it prints it, your class, level and rank, and the four Techniques and four Charms. Fighters you add stay in this browser, at the top of the list, marked yours. How to fill it in.
For a team captain collecting teammates’ templates from chat: paste one or several (each starts
at its Name: line) and press Add. Small typos in skill or stat names are corrected and listed below.
A roster export (the JSON tools/liveproto/roster.py fighters writes) can be pasted here too.
The same seeded run the scene plays. The odds come from a thousand of these with fresh rolls.
| t | turn | actor | skill | targets | hits | damage |
|---|
Where the numbers come from. Every fighter's sheet is the BattleProps block the server sends
for that player, the same block the Character Stats screen displays; one was checked against the screen stat by
stat. That block is the out-of-fight set: in a fight every equipped skill also adds its passive stats
(SkillPropChunck, CalcSkillPassiveProps at the skill's rank, its own level and the player's
sub-rank), and the captured block leaves that chunk out — Elexarie's sheet shows 79.6% Block Rate, her Block
Awareness brings it to 166%. So this page adds every Technique's and Charm's passive stats on top of the sheet. Each
Technique and Charm keeps the rank and level it is equipped at. The leaderboard is the top 100 by combat rating as the server
listed it, with every player whose sheet has been captured.
Trying another setup. Tap any Technique or Charm on a team card to swap it for another from the fighter's class line (or from any class), to clear the slot, or to set the rank and level it is equipped at. A swapped skill changes both what fires during the fight and the stats its passive chunk adds. A changed loadout is marked edited on the card and can be put back with ↻; edits live in this browser only.
The board is the game's. Team Challenge 4v4 (stage 9998) fights on battlefield 910: a 21 by 20 grid,
Y up, distance counted in cells (Pos2d.Distance is Manhattan). Each side deploys inside a 5-wide,
4-deep box around its entry cell (stage.TeamChangePosRange = {5, 4}: columns 9–13, rows
7–10 for Team 1 and rows 11–14 for Team 2), one fighter per cell, and the two boxes touch. The page
shows the boxes with two cells of margin; fighters may wander further during the fight.
Reach and area come from each skill's prefab. A skill lists the cells, relative to the caster, where its
aim point may be placed (FightSkillComponentInfo.Range, near to far), and every hit lists the cells
it covers around that aim point, or around the caster when the hit acts on its source
(HitScopCfg, HitCfg.ActOnSouce; a summoning hit's area is its SummonScope).
Areas are authored facing up and turned to face the aim as CalcLocalToWorldDir does: the facing is
Pos2d.LookDirection (exact diagonals resolve sideways), and the area flips on X when the aim is to the
caster's left (CalcFlipX). What the aim may sit on is the skill's SkillTargetType: an
Entity skill needs a unit on the aim, a PosCanStand skill a free cell. Heart of Challenge, for
instance, has no reach of its own but covers every cell within three of the Paladin; Meteoric Flames reaches five
cells away and covers the 3×3 square there.
A turn is move, then cast; the choice follows the client's own AI lists. Whoever comes due next on
the SPD clock acts (equal times keep queue order) and casts every ready Technique in slot order, each onto its
own cooldown counted in that fighter's turns. For each cast the fighter weighs every free cell within its remaining Movement of where it stands
(the client's CalcAllMovablePos: the diamond of cells within that many steps, keeping each one it
can stand on; fighters and walls in between do not block, only the destination has to be free) together with every
aim the skill allows from there, and ranks them by the skill's AiPriorityTypes list, criterion by criterion: most targets
hit, then the shorter walk, then the lower target HP, then the nearer aim, then an aim that sits on a unit. Hits flagged
IgnoreAICount do not count as targets, and "more marked targets" (MoreHitStatusCount) counts
units carrying a status whose AI.MoreHit is set, such as the Sigils that "prioritize the inflicted target".
"Lower target HP" is read as the targets' total current HP, not their HP share — an inference: in a real 4v4 a
reader reported, Elexarie's Heart of Challenge took Nlilee, Awry and Wei (Awry has 1.60M HP) over Nlilee, hami and Wei
(hami 1.62M), both three targets three steps away at full health, which the share cannot tell apart.
Skills with no list of their own use the chain the designers wrote out on the skills that carry one; the
server's true default is not in the client. The last cast of a turn by a ranged skill (RangeType Far)
uses LastAIPriorityTypes, which swaps "shorter walk" for "safer cell" (farther from every enemy), unless
the skill is flagged DontKeepDistance. Movement is a pool per turn, in the game's words: "Usually,
characters can move up to 4 grids per turn. Movement from skills is separate and does not count towards this limit."
So the walks before a turn's casts share those cells, and a dash or leap costs none. Movement is
(MoveDist + FixedMoveDist) × (1 + MoveDistPercent), which is how Cripple's
−25% a stack bites; summons use their own MoveDist, which may be 0. There is no basic attack in the
client, and the game's Approach note gives the rest of the turn: "Before the caster's turn ends, if a Technique is
ready but out of range, spends remaining Movement to approach the nearest target." A fighter with nothing ready stays
where it is; one taunted closes on its taunter. A fallen player keeps its cell (DestroyOnDie = false), so
a body blocks that cell as a destination. Skills move fighters too: the caster's own dash or leap (SourceMoveList, Doom
Blade) and the victim's pull or knockback (the damage's MoveCfg, Hunter's Judgment, Lunarwater
Threads) land on the nearest free cell in the client's ring order when the exact cell is taken; a Frozen,
Immobilized or Super Armor unit is not moved, an Immobilized or Restricted caster's own leap does not happen (the
skill still lands), and a knockback whose chance is AffectedByProp rolls Effect Hit against Effect RES
like a status. A leap skill (PosSkillDirectionCanStand) needs its landing cell free, or with
CanExpandOffset one of the four around the aim. Every hit of a cast finds its targets where they stand when it
lands, so a pull that drags enemies in front of the caster is followed by strikes on the cells they were
dragged to.
Damage, hit by hit. Every hit runs the client's Damage(): attack times the skill's
coefficient over the target's per-rank PvP scaler, plus the flat term, times ATK/(ATK+DEF), times the elemental
ratio, times the percent block, over the class scaler, times the skill's PvpPropScale. The elemental
ratio is the client's split: the attacker's Affinity is divided by the target's base Elemental DMG RES and
its Mastery by the target's base Elemental RES, while the target's Elemental RES is divided by the
attacker's bases. A further stage multiplies by (1 + the attacker's Status DMG Bonus + the target's Status
DMG Taken) over (1 + the target's Status DMG RES), which is how Curse Resonance and its kin pay out.
Every hit rolls in the client's order (CalcDamageTypeImpl): the attacker's Blind chance, then the
target's Dodge, then block, then crit — a blinded or dodged hit deals nothing and applies no status, and a
blocked hit cannot crit. The chances add the flat value forms over their per-rank bases (Crit Rate + Crit Rate
Value / base, Block Rate + Block Value / base, and the attacker's Accuracy against both), a crit multiplies by at
least 1.3, a block divides by at least 1.5. Blind is a chance, not a certainty: the status grants its holder a 50%
Blind chance for one Technique, so half its hits still land. Heals
run Cure(): max HP, attack or the target's max HP times the skill's cure coefficient plus the fixed
cure, times (1 + Healing Boost + Healing Received + their value forms over their bases), times the final cure scale.
The PvP governor (PVPSkillPropsScaleOnBattleProcessor, shown under the odds) scales only the damage
of skills whose prop group is AffectedBySkillRank; heals and shields are never governed. A hit
typed HitDamageType.None deals nothing itself but still applies its statuses, forced moves and child
skills: Wind's Delight's damage is its child skill, seven waves each hitting the plus around a random enemy, and
Hunter's Judgment's grab is what drags the target. A child skill (ChildSkillCfg) is cast on every unit
its parent hit covered, with its own numbers. Per-target falloff (FightStatusDamageFalloffComponent)
multiplies each repeat hit on the same target by (1 − p): Wind's Delight decays 35% per repeat,
Divine Wrath 40%. Random-target hits (FightHitRandomTargetComponent) draw one cell per pick, with
replacement, from the group's pool; empty cells count unless AllowEmptyScope is off, and
MiniHitTargetCount picks must land on a unit.
Charms fire on the events their components name. A when-hit Charm's component
(FightStatusDamageSkillComponent) carries its own conditions and they are honoured: Rebound strikes
back only on a hit the wearer blocks (Block = true), Counter Blade on any damage taken, a Charm
with ConditionCount every Nth event, one with EachRoundMaxCount at most that often per
round. On-hit Charms (FightStatusHitSkillComponent, Radiant Sear, Blade of Judgment) fire per
damaging hit under the same flags. The strike a Charm fires is a skill of its own, and when that skill's
CanTriggerChild is off (Radiant Sear's, Rebound's, a Burn tick) it cannot set off further hooks;
this page also stops any hook chain at depth four as a guard of its own. Also run from the prefabs: Linked
Misfortune, Shadow Erosion, Curse Resonance and Pursuit of Victory, Resurrection, Reflective Armor, Repelling Wind,
Gale Shield, Ripple Impact, Blade of Lament, Soul Splash, Defensive Assault, Eye for an Eye, and the HP-unit
Charms whose stacks come off again as HP climbs back. The top-100 capture of 12 September brought the
fourth-tier classes' Charms, all run from their components: Tactical Adaptation keeps its damage-up status while
three or fewer enemies stand within two cells and swaps to its damage-down status when more do
(TargetCountAffectStatusOwnerSetting, re-checked at every turn start, move, spawn and death);
Soul Breaker adds one unit of its bonus per 15% of the target's max HP missing, five at most
(FightStatusHitApplyDamageComponent); Holy Aegis grows the wearer's DEF-based shields by its
percentage (FightStatusPropByStatusComponent); Explosive Spirit stacks its crit-rate status on every
Fire Technique cast (FightStatusSkillStartComponent with an element condition); Iron Will and
Aberrancy add the Charm's reduction to the damage stage when the attacker is taunted, or carries any debuff
(FightStatusDamageProcessComponent, FightStatusDamageReducePerComponent); Summoner's
Frenzy and Soul Spark put their status on the wearer's summons as they appear, Soul Spark's cutting the summon's
lifespan by two turns to a floor of one (FightStatusHitSummonComponent,
FightStatusReduceStatusLifeComponent); Soul Impact fires its Dark burst around a summon of the
wearer's that falls or fades; Soul Pact Resonance holds its attack status while the wearer has a summon on the
field (FightStatusRoleSummonCountComponent).
Summoned creatures. Waterling Summon, Frenzy Totem and Stonechief Summon are summoning hits
(FightHitSummon with a SummonId): the creature appears on the cell the hit names relative
to the caster, or the nearest free one, and acts at once (SummonImmediateRound). Its stats are the
client's CalcSummonMonsterInheritProp: a fixed part from summon_monster_fix_prop on the
skill's level curve at the skill's rank (the Waterling's 76% max-HP factor, for instance), plus a share of the
caster's own props from summon_monster_add_prop times summon_rank_additive_factor at the
skill's rank (the Waterling inherits 19% of the caster's max HP, 25% attack, 50% defence, 80% speed and all of
the secondary stats; the Totem 16% / 0 / 50% / 105%; the Stonechief 18% / 70% / 80% / 70%). "Summons cannot
receive any stat boosts", so the caster's unbuffed sheet is the source. The creature takes its own turns on the
SPD clock, blocks its cell, is removed when killed (DestroyOnDie) and fades after five of its own
turns (its lifespan status ends the entity), never decides the result and never counts toward the round cap. Its
skills and passives are monster_group's, run by the same rules as a fighter's: the Waterling's
Dewdrop and Misty Vapor heal 6.5% and 4.8% of its max HP (PvP-scaled to a third) and dispel one debuff; the
Totem's Inspiration moves a random ally's next turn 20% closer (FightStatusRoundIntervalComponent)
and its Fighting Spirit is an aura that gives every ally within four cells an attack buff
(FightStatusMoveRangeComponent). Stealth follows the game's own words: a stealthed unit is
never the main target of an attack or a heal while a visible one can be, but it still sits under areas. A
summon's opening cooldowns follow the fighters' rule (this page's assumption) and its skill choice the same AI
lists, which for these skills carry no list of their own.
Chained hits. Lightning Chain is one strike plus eight links (FightHitChainedComponent,
its NextHitList): each link picks a random enemy within the skill's own reach of the last victim,
never one already struck and never straight back, and stops when nobody is in reach.
Repelling Wind. Its status watches a twelve-cell zone around the wearer
(FightStatusMoveNearComponent, TryAtEnterRange, which the client describes as "outside
→ inside") and rolls 75% when an enemy's move ends inside it from outside. The card says "when an enemy actively
enters", so only the enemy's own walk or leap counts, not a knockback or a pull.
How long a status lasts. The client's FightStatusComponent counts the rounds of the unit named by
RoundTarget — the holder, or for some statuses their caster — from StartRound, the
round that unit was on when the status landed, and checks it at RoundUpdateTiming, the start or the end of
that unit's rounds: left = CurDurationRound − (Round − StartRound), gone at 0. A
unit's round number goes up as its round starts, so a buff a fighter casts on itself is not ticked by the end of the
round it was cast in. A re-applied status re-bases on the new round, adding what was left when it is
IsAddDurationRound. Shadow Vengeance's Shadow Form follows its prefab: immune (IsImmunity),
never below 1 HP, not healed and not the main target of an attack, every Technique's cooldown 2 shorter, gone at the
end of its holder's next round or after four global rounds, and then the holder dies unless the fight is won.
Frost Guard and Holy Recuperation fire at the end of a round in which their wearer cast no Technique
(FightStatusRoundCheckSkillComponent). Frenzy and Fear follow the game's words: a frenzied fighter
treats "all targets except themselves as enemies" and picks its aim at random, a feared one "will not prioritize the
inflictor". An action delay is capped at 80% of a turn per turn.
Fantomon. Battlefield 910 does spawn each fighter's engaged Fantomon (its root carries
FightRolePetSpawnerComponent). The follower form rides its master's cell, is untargetable
(SafeAttacker), takes no turn (FollowMaster) and fires its support skill when the master
starts an Attack Technique (FightAIFollowMasterComponent), scaled by the pet's own attack; but the
follower's props are set by the server and nowhere in the client (pet_battle is dead config), so
pets are not run here until a recorded fight shows their numbers. The adult form is a different thing: its
Materialization skill says the pet "generates Fantasmia in battle. Once Fantasmia maxes out, it materializes behind
the caster before fighting alongside." The materialized entity (prefab 9301 and up) has a grid body, its own turns
and its own AI (FightRoleGridComponent, RoundDataDrive, FightAIComponent), is
summoned by a skill on the master (SummonId 9301, ReferenceType SourceMaster) and takes its
stats from the summon tables (summon_monster_fix_prop 9301+) the way Waterling does, so it blocks cells,
draws attacks and casts its own Techniques (Golden Feather and Golden Storm for Falko). That part is buildable from
the client; what is not in the client is how fast Fantasmia fills, so the adult form is not run here either.
Burning cells. Meteoric Flames is a summoning hit: it deals its Fire damage to the 3×3 and every
cell of it rolls 60% to spawn grid item 3320 with a Fire status whose MoveNear hook fires the Burn
skill at an enemy standing there when the cell appears (TryAtStart), at one arriving on it
(TryAtEnterRange) and at one starting its round on it (TryAtStandRound), for three of the
caster's rounds, or until the caster falls. The board marks such cells. A walk here is resolved at its
destination, so cells crossed mid-path do not fire; the client's step-by-step path is server-side.
Before round 1: the PlayStart phase. The fight has a PlayStart status before
Play, during which the AI is driven on a fixed interval (Battle.DrivePlayStartAIInterval),
and the skill table marks what fires then (skill.TryAtStartType: Heart of Challenge, Valor Surge,
Gale Dance, Void Blessing are "Casts once before battle starts"; the self-cast Charm effects such as Rapid Cast are
AutoSelfAtStart). The game's own note on this phase reads: "When multiple units on both sides are set
to cast skills before battle starts, they cast them from highest to lowest initial SPD. SPD changes during this
phase do not affect the order. If a character has multiple skills to cast before battle starts, Charms are cast
before Techniques. Skills of the same type are cast in loadout order, from top to bottom. Battle starts after all
such skills from both sides have been cast." This page orders by initial SPD and never re-sorts, as that says, and
adds one rule seen in real fights: every pre-battle buff (Valor Surge, Light Sword Array, Gale Dance, Void Blessing)
is cast first, by both sides, and only then the taunts, the faster tank first. Heart of Challenge is the only
pre-battle Technique aimed at enemies, so the buffs go in one pass and the taunts in a second, each pass fastest
fighter first and each fighter's skills in loadout order. It matters because Valor Surge dispels one ailment or debuff
from each ally it reaches: cast after a taunt, it would wipe it. "Charms are cast before Techniques": the eleven
Charms marked to cast before battle (Rapid Cast, Iron Fortress, Gale Shield, Soul Protection, Iron Solidarity and the
rest) fire their round-start effect in the first pass, just before their wearer's Techniques, and Charms that start
with a status have it from the first moment (Elemental Harmony one stack per element among the wearer's damaging
Techniques, Sacred Blessing one per Light one). When the phase ends, every fighter's first turn is timed from its
stats at that moment (FightRoundDriverComponent resets the clock on the change of game status), so SPD
cast before battle counts. The walk to a before-battle cast is not held to the 4-cell Movement, which the game gives
"per turn": in the same reported fight hami walked five cells to taunt Purr, Nocturne and Nai. That is an inference;
the shortest walk that reaches the most targets still wins. A taunt such as Heart of Challenge lands
Ridicule on every enemy within three cells. The game states what that does: "Taunted enemies target the
caster only, and approach the caster when using damaging Techniques. Summoning Techniques remain available, but
ally-targeting Techniques (grant buffs, healing, shields, etc.) are disabled while taunted." So a taunted fighter
here aims only at its taunter (a single-target skill must aim at the taunter itself, an area must cover it), cannot
cast a buff, heal or shield on itself or an ally until the taunt ends or the taunter falls (a skill flagged
ReleaseWhileRidicule, such as Light Sword Array, stays usable), and never uses the keep-distance ordering for a damaging Technique — it closes on the taunter
to break ties. Its skill's own priorities still come first, so it will step sideways to catch more targets; where
"approach" sits among those priorities is server-side, and this page puts it last. Every other skill with a
cooldown opens the fight on it unless it is a Zero
Initial CD skill. Control comes from the client's state_mutex table: Stun, Frozen and Phoenix Stasis
discard both move and skill, Restrict and Immobilize discard the move only.
Not modelled. Fantomon (above). Decoy Clone and Blast Spirit (a voodoo doll and a smart grid item,
equipped by nobody in the top 100). A tournament battle lasts at most 12 minutes, and the game's rule when time runs
out is "the team with more remaining members wins; if tied, the team with a higher average remaining HP wins"; this
page applies it at its round cap (average HP read as the share of max HP). The AI's scoring loop is
server-side: the criteria and each skill's ordering are the client's, their default ordering and the global
weights in BattleAISetting (preferred distance to teammates, bunching penalty) are not modelled.
The full rule-by-rule audit of this engine against the client is in
docs/ENGINE_AUDIT.md.