MapleStory Quest

Client formula audit

Formulas

Every calculation this site performs, with its source and status. If a number in the planner surprises you, it should be traceable to something on this page.
About this page

These are transcribed from the COT2 client formula audit published alongside the OSMS datamine. They are COT2 formulas, and several differ from both COT1 and older versions of the game, so applying remembered numbers from other versions will give wrong answers. The audit was made on Closed Online Test 2 and has not been redone for the Public Release, so until it is, these are the CoT2 formulas. The engine that implements them is covered by unit tests that assert these exact expressions.

Every formula18

Accuracy & Avoid

Read from the client
Common  = DEX × 1.2 + Level × 2 + LUK × 0.6

Beginner  Acc = Common / 2.5 + 5
Warrior   Acc = Common / 2.5 + 10
Magician  Acc = (INT × 1.2 + Level × 2 + LUK × 0.6) / 5.1 + 20
Bowman    Acc = Common / 4.8 + 20
Thief     Acc = Common / 4 + 15

Avoid = trunc(LUK / 3) + trunc(DEX / 6) + 5
  • Every stat is the total including equipment and buffs.
  • The magician branch reads INT where every other class reads DEX.
  • Below level 10 every character is a Beginner, whatever class the build is headed for, so the planner uses the Beginner line there and the class line from the first advancement on.

Hit test

Read from the client
BaseChance = Acc × 100 / ((max(0, LevelDiff) × 2 + 51) × 5)
Spread     = 0.15 + 0.2 / (1 + exp((BaseChance − Avoid) / 12))
Roll       = rand(1 − Spread, 1 + Spread)
DidHit     = Roll × BaseChance ≥ Avoid
  • Physical and magic share one hit-test routine.
  • Nine monster debuffs skip it and use their own success rate. No attack skill is exempt, Poison Mist included: its damage is gated by the hit test and then by its own success rate.
  • Roll is uniform, so MapleStory Quest reports the exact probability rather than sampling: P = clamp((1 + Spread − Avoid/BaseChance) / (2 × Spread), 0, 1).
  • This replaces the old Accuracy ÷ Avoid approximation, which is not what the client does.

Physical damage

Read from the client
StatDiv = 300 if Prone Stab, or Bow/Crossbow/Claw on Swing, Stab or Other
          100 otherwise
AtkDiv  = 150 if Prone Stab, or Bow/Crossbow/Claw on Swing or Other
           50 otherwise

MIN = SkillMult × (0.8 + (Primary × WepMult × Mastery + Secondary) / StatDiv + AttackPower / AtkDiv) × WeaponAttack
MAX = SkillMult × (1.0 + (Primary × WepMult + Secondary) / StatDiv + AttackPower / AtkDiv) × WeaponAttack
  • WeaponAttack is attack from the weapon and shield (5 barehanded), plus the throwing stars or arrows being fired. AttackPower is every other slot plus buffs.
  • The planner fires the first star or arrow in the build’s consumables that the weapon in hand can shoot (the Damage tab picks it), and adds it only on a shot: a Claw swung in melee throws nothing.
  • WepMult comes from the attack action, not the skill. Lucky Seven overrides it to 3.0.
  • A few skills never roll for swing or stab: Double Stab and Savage Blow always Stab, Avenger always Shoots, and Rush, Assaulter, Meso Explosion, Shout, Dragon Fury, Dragon Roar and Piercing Crusher always use Other. Every other physical skill is averaged over the weapon’s action list.
  • MIN and MAX are the corners of two independent rolls, so damage bunches toward the middle.

Magical damage

Read from the client
MAGIC = floor(Total INT / 2) + Magic Attack

MIN = (BasicAttack / 100) × MAGIC × (Total INT × Mastery / 100 + 1)
MAX = (BasicAttack / 100) × MAGIC × (Total INT / 100 + 1)
  • MAGIC and Magic Attack are different numbers. The planner shows both separately for exactly this reason.
  • The client seeds MAGIC with half the INT rounded down, so an odd INT adds nothing over the even one below it.
  • Magic reads mastery from the attacking skill itself, so a weapon mastery skill never affects magic.

Damage over time

Partly verified
TotalDamage   = (DoTBasicAttack / 100) × MAGIC × (Total INT / 125 + 1)
DamagePerTick = TotalDamage / DurationSeconds
  • MAGIC is the floored value above.
  • Note the 125 divisor, not the 100 used everywhere else.
  • DoT ignores all defence: the routine never reads the enemy’s weapon or magic defence.
  • DoT still takes the element modifier, the level penalty and the crit roll, but only ever the linear branch of the level penalty.
  • The client computes the total and never divides it; the per-tick line comes from the skill descriptions, which is why this is marked partial.

Bleed

Partly verified
TotalDamage   = (BleedPercent / 100) × ((2 × Primary + Secondary) / 100 + 1 + AttackPower / 50) × WeaponAttack
DamagePerTick = TotalDamage / DurationSeconds
  • The physical damage-over-time routine: Axe Mastery’s bleed, Coma’s and Inferno’s. It has its own base and is not a share of the hit that applied it, so it does not inherit the skill’s damage %, the weapon multiplier or the defence of the hit.
  • Like a magic DoT it ignores defence and takes the linear level penalty, the element and the crit roll.
  • The total is read from the client; the per-tick split is not, which is why this is marked partial.

Heal

Read from the client
HealAmount = ((INT × rand(0.8, 1.0) + LUK) / 200 + 3) × MAGIC × (RecoveryRate / 100) × (Targets × 0.1 + 1)
HealAmount = HealAmount × (HealBonus / 100 + 1)
UndeadDamage = trunc(HealAmount) / Targets × 0.5
  • MAGIC is the floored value above.
  • Targets is everyone the cast reaches: the monsters, the caster and the allies in range, and never fewer than 1, because the caster is always in range. The planner counts the caster alone unless an undead target is measured (then the caster and that monster), and takes a party size when one is given.
  • HealBonus is Bless’s bonus, 1% at level 1 rising to 10% at level 20, applied when Bless is switched on.

Mastery

Read from the client
MasteryMult = (0.1 + MasteryLevel / 10) × 0.8

At mastery 10 → 0.88
With no mastery skill (level 0) → 0.08
Lucky Seven → fixed at 0.5
  • An unlearned mastery is level 0, not a zero multiplier: the primary stat still counts toward MIN at 0.08.
  • Lucky Seven ignores Claw Mastery and rolls its MIN at 0.5, the equivalent of mastery level 5.25.

Combo Attack & Elemental Charge

Read from the client
ComboBonus = 5 × Orbs × (Orbs − 1)   for Panic and Coma
ComboBonus = ComboDamage             for every other skill
SkillMult  = SkillMult × (ComboBonus / 100 + 1)

SkillMult  = SkillMult × (ChargeDamage / 100 + 1)
  • Both land on the Skill Damage % before the physical formula runs, so they scale the whole hit.
  • Combo Attack needs at least one orb. The planner assumes the skill’s own maximum orb count unless told otherwise, which is what a Crusader builds up to before Panic.
  • An active charge also gives the hit its element.

Shadow Partner

Partly verified
Damage = Damage × PartnerDamage / 100
  applied only to hits in the second half of the hit list
  • The partner repeats the hit list at its own share of the damage, 10% at level 1 rising to 40%.
  • The step is read from the client, but nothing in the code names the skill, so tying it to Shadow Partner is the audit’s inference.

Fixed damage

Partly verified
Damage = FixedDamage

Three Snails → 15 · 25 · 40
  • Three Snails states a flat number rather than a percentage, and the client’s own skill data carries the same numbers as its fixed damage.
  • The audit does not cover this step, so the planner takes defence, element, level and crit not to apply to it. Only the hit test does.

Defence

Read from the client
Def    = max(0, trunc(BaseDef × (Percent / 100 + 1)) + Flat)
Damage = Damage × 100 / (Def + 100)
  • Weapon defence applies to physical only, magic defence to magical only. Armor Crash zeroes weapon defence.

Elemental modifier

Read from the client
One element:   immune 0 · resistant 0.75 · neutral 1.0 · weak 1.25

Two elements:  0.25 × (Code(E1) + Code(E2))
               Code: immune 0 · resistant 1 · neutral 2 · weak 3
  • Element Composition is the two-element case: against a Fire-weak, Poison-immune target it lands at 0.25 × (3 + 0) = 0.75.

Level-difference penalty

Read from the client
LevelDiff = EnemyLevel − PlayerLevel

LevelDiff ≤ 0    no penalty
LevelDiff < 10   Damage / (LevelDiff² × 0.005 + 1)
LevelDiff ≥ 10   Damage / (LevelDiff × 0.05 + 1)

Critical hit

Read from the client
IsCrit = rand(0, 99) < CritRate
Damage = Damage × (100 + CritDamage) / 100
  • Base player values are 5% rate and 20% damage before gear and buffs.
  • The planner reports the expected value, 1 − rate + rate × (100 + CritDamage)/100, and shows the all-crit ceiling separately.

Element Amplification

Ambiguous, exposed as a choice
Damage = Damage × (ElementAmpDamage / 100 + 1)
  • The client audit found the amplification buff slot exists and drives the matching extra MP cost, but that no skill in this dataset sets it, so on current data the step never fires.
  • The skill tooltip meanwhile advertises Magic Attack Damage rising to 135%.
  • MapleStory Quest does not pick a side. Strict mode omits the multiplier; tooltip mode applies the advertised percentage. The planner defaults to strict and labels which mode a published build used.

Clamp

Read from the client
Damage = trunc(Damage)
Damage = clamp(Damage, 1, 99,999)

AP and SP

Partly verified
AP budget = 5 × Level + 20 − reserved     (620 at level 120)

Beginner SP = min(L, 10) − 1               from level 2    → 9 at Lv10
1st job SP = 1 + 3 × (min(L, 30) − 10)    from level 10   → 61 at Lv30
2nd job SP = 1 + 3 × (min(L, 70) − 30)    from level 30   → 121 at Lv70
3rd job SP = 1 + 3 × (min(L, 120) − 70)   from level 70   → 151 at Lv120
  • The client audit has no AP or SP section. The job pools are the project’s own model, written down in its handover notes; the Beginner’s is the site’s own reading, one point a level to nine at 10, which the nine ranks of the three Beginner skills bear out. Neither is the client’s, which is why this is marked partial.
  • Each pool pays only for skills of its own tier, and every class can spend the Beginner pool, since every character is a Beginner until level 10.

What is deliberately missing

  • Cast times and DPS. The audit does not establish frame-accurate cast delays, and Spell Booster’s speed stages have no verified conversion to milliseconds. The character’s own action frames are extracted from the client, but not yet turned into cast times, so the planner computes damage per cast exactly and turns it into DPS only for a cast time you supply.
  • Monster drop tables. Not present in the datamine. Item sources on this site come from quest rewards and crafting recipes only.
  • Potion stacking rules. The data states each consumable’s effect but not how overlapping categories interact, so consumable bonuses are entered as manual modifiers rather than stacked automatically.
  • Skill elements. Read from the client’s own skill data rather than from the tooltips: twenty-one skills carry an element there. The monster side is the datamine’s resistance table, and every value is overridable per target in the planner.
MapleStory Classic World damage & EXP formulas · MapleStory Quest