Functions
This page documents functions used in the theorycrafting formula.
Cheatsheet
min(a, b) max(a, b) defense(level, reduction=0, ignore=0) # multiplied to the damage formula, usually defense(100) resist(r) # multiplied to the damage formula, usually resist(10) require(er, threshold) # multiplied to the maximizing value. e.g. require(er, 160) burn (em, bonus=0) superconduct (em, bonus=0) swirl (em, bonus=0) electrocharge(em, bonus=0) shatter (em, bonus=0) overload (em, bonus=0) bloom (em, bonus=0) burgeon (em, bonus=0) hyperbloom (em, bonus=0) # e.g. hyperbloom(em) * resist(10) vaporize_with_pyro (em, bonus=0) vaporize_with_hydro(em, bonus=0) melt_with_pyro (em, bonus=0) melt_with_cryo (em, bonus=0) # multiplied to the damage formula aggravate(em, bonus=0) spread (em, bonus=0) # e.g. (talent.Hit% * atk + spread(em)) * ... weapon_name.effect(v1, v2, v3, v4, v5) # returns 0 if the weapon is not equipped weapon_name.effect(v1, v5) # v2, v3, v4 are linearly interpolated weapon_name.effect(v1) # v5 is 2*v1
Basic Functions
min()Return the smallest argument value.
From 1 to 99 arguments are supported. Otherwise, it triggers a compiler error.
Example UsageMinimum_Value = min(10, 9, 17, 11) # returns 9 Furina_A4_Buff = min(28, hp/1000*0.7) * furina.a4max()
Return the largest argument value.
From 1 to 99 arguments are supported. Otherwise, it triggers a compiler error.
Example UsageMaximum_Value = max(10, 9, 17, 11) # returns 17 Rotation_Damage = max(N2C_Rotation_Damage, N3_Rotation_Damage)defense(level, reduction=0, ignore=0)
Return the opponent's defenses multiplier based on its level.
level
is the opponent's level.
Usually this is set to 100 for theorycrafting by
KQM standards.
reduction
is an optional argument for defense reduction (e.g. Lisa's A4 or Klee's C2).
It's in the unit of "%".
By default, it is set to 0.
ignore
is an optional argument for defense ignore (e.g. Raiden's C2 or Yae Miko's C6).
It's in the unit of "%".
By default, it is set to 0.
Damage = talent.Hit% * atk * (bonus%+pyro%+normal%) * (1+crit_rate%*crit_dmg%) Final_Damage = Damage * defense(100) * resist(10) Final_Damage_With_C2_Klee = Damage * defense(100, 23) * resist(10)resist(r)
Return the opponent's elemental resist multiplier.
r
is the opponent's elemental resistance in the unit of "%".
Typically, this is 10.
However in some cases this can be reduced (e.g. Viridescent Venerer's 4-piece effect)
and some enemies may have difference resistance.
# with 40% VV shred My_Damage = talent.Hit% * atk * (bonus%+hydro%+normal%) * (1+crit_rate%*crit_dmg%) * defense(100) * resist(10-40)require(er, threshold)
Return energy recharge requirement multiplier, based on given ER and threshold. Multiply this return value to the objective value you want to maximize.
er
is effective ER, which is ER after energy generation has been calculated in.
This effective ER calculation is done automatically by GAA.
So in most cases, simply pass in er
here as argument.
It's in the unit of "%" so typically the value should range within 100~300.
threshold
is the ER value we want to achieve
in order to have smooth rotation in a typical spiral abyss.
It's in the same unit as er
: "%".
The current implementation of this function in Javascript is:
function require(er, t) { return (er<t ? (er-t)/(t-50)+0.97 : 1-10/(er-(t-10))*0.03); }This a continuous piecewise function where it's a linear function with -0.03 at er=50 and 0.97 at er=t if er < t. Otherwise, it's a reciprocal function that approaches 1 as er gets larger. This function is not rigorously based on theory, but we arrived at it by adjusting over time to produce good result. This may further change in future GAA versions. Feel free to experiment by putting in your own energy recharge requirement formula. Example Usage
# 150 ER requirement, 20 second rotation with only one burst hit DPS = Rotation_Damage/20 * require(er, 150) Rotation_Damage = Burst_Damage Burst_Damage = talent.Burst% * atk * (bonus%+anemo%+burst%) * (1+crit_rate%*crit_dmg%) * defense(100) * resist(10)
Transformative Reaction Damage Functions
burn (em, bonus=0) superconduct (em, bonus=0) swirl (em, bonus=0) elecetrocharge(em, bonus=0) shatter (em, bonus=0) overload (em, bonus=0) bloom (em, bonus=0) burgeon (em, bonus=0) hyperbloom (em, bonus=0)Return the transformative damage. The returned value is dependent on character level.
em
is the elemental mastery of the character
that triggered the reaction (assumed to be the main character).
In most cases, just pass in em
here.
bonus
is an optional argument for reaction damage bonus
(e.g. Crimson Witch's 4-piece effect for burning,
Thundering Fury's 4-piece effect for superconduct, etc.).
It's in the unit of "%".
By default, this is 0.
Transformative reaction damage is not affected by crit (with one exception of Nahida C2), bonus damages not specific for the particular reaction, and enemy defense. To get the final damage number, you only need to multiply the output of this function with resistance.
Example Usage# transformative damage ignores defense and cannot crit Hyperbloom_Damage = hyperbloom(em) * resist(10)
Amplifying Reaction Damage Functions
vaporize_with_pyro (em, bonus=0) vaporize_with_hydro(em, bonus=0) melt_with_pyro (em, bonus=0) melt_with_cryo (em, bonus=0)Return the amplifying damage multiplier.
em
is the elemental mastery of the character
that triggered the reaction (assumed to be the main character).
In most cases, just pass in em
here.
bonus
is an optional argument for reaction damage bonus
(e.g. Mona's C1, Crimson Witch's 4-piece effect).
It's in the unit of "%".
By default, this is 0.
Amplifying reaction damage is calculated by simply multiplying the output of this function to the usual damage formula.
Example Usage# pyro vape with crimson witch Damage = talent.Hit% * atk * (bonus%+pyro%+normal%) * (1+crit_rate%*crit_dmg%) * defense(100) * resist(10) * vaporize_with_pyro(em, 15*crimson_witch_of_flames.piece_4)
Catalyze Damage Functions
aggravate(em, bonus=0) spread (em, bonus=0)Return the catalyze damage. The returned value is dependent on character level.
em
is the elemental mastery of the character.
In most cases, just pass in em
here.
bonus
is an optional argument for reaction damage bonus
(e.g. Baizhu's A4, Thundering Fury's 4-piece effect).
It's in the unit of "%".
By default, this is 0.
Catalyze reaction damage is flat addition to (the motion value multiplied by the scaling stat). Other values like crit, damage bonus, defense, resistance is multiplied after the sum.
Example Usage# aggravate with thundering fury Damage = (talent.Hit% * atk + aggravate(em, 20*thundering_fury.piece_4)) * (bonus%+electro%+normal%) * (1+crit_rate%*crit_dmg%) * defense(100) * resist(10)
Weapon Passive Effect Functions
weapon_name.effect(v1, v2, v3, v4, v5) weapon_name.effect(v1, v5) weapon_name.effect(v1)Returns 0 if the weapon is not equipped. Returns a value depending on the refinement of the weapon.
If five arguments are passed, N-th value is set as the return value for N refinements.
If two arguments are passed, the middle 3 values are inferred to be linearly interpolated
(i.e. v2 = 0.75*v1+0.25*v5
, v3 = 0.5*v1+0.5*v5
, v4 = 0.25*v1+0.75*v5
).
If one argument is passed, the last value is inferred to be double of the first value
(i.e. v5 = 2*v1
).
Any other number of arguments triggers a compiler error.
# evaluates to 0 if Slingshot is not equipped, 36 for R1 Slingshot, 42 for R2 Slingshot, ..., 60 for R5 Slingshot bonus += slingshot.effect(36, 60) # evaluates to 0 if Rust is not equipped, 40 for R1 Rust, 50 for R2 Rust, ..., 80 for R5 Rust normal += rust.effect(40)