All heroes share the same six base attributes but have different minimum and maximum limits based on their classes and different primary and secondary stats.
All classes will share the same attribute rarity system, where heroes whose total attributes add up to 0 ~ 299 will be common, 300 ~ 375 will be epic, and 376+ will be legendary.
Class
Primary Stat
Secondary Stat
Warrior
Strength
Vitality
Assassin
Agility
Strength
Mage
Intelligence
Will
Ranger
Strength
Agility
Berserker
Vitality
Endurance
Ninja
Agility
Vitality
Spiritualist
Intelligence
Endurance
Machinist
Intelligence
Agility
Strength
Strength affects the hero's physical damage dealt through attacks and skills in combat.
Agility
Agility affects the hero's turn order and critical rate % in combat.
Vitality
Vitality affects the hero's maximum HP in combat.
Endurance
Endurance affects the hero's physical defense in combat.
Intelligence
Intelligence affects the hero's magical damage dealt through attacks and skills in combat.
Will
Will affects the hero's magical defense in combat.
Combat Attributes
This section contains our formulas for calculating your heroes' combat attributes.
Level 1-10 has only 9 levels while every other tier has 10. To maintain the same combat stats as before, heroes under level 10 will have a 1-level penalty when applying the formula.
Health Points (HP)
// Get the raw max HP based on all sources of VIT.constrawMaxHp=5*VIT* (1.5+ (LEVEL/100) *15);// Get the raw equipment boosts ('HP %', 'HP')constrawEquipmentHpBoost= ((rawMaxHp /100) *HP%+HP); // Get the total equipment boosts ('Equipment HP% Bonus')consttotalEquipmentHpBoost= (rawEquipmentHpBoost /100) * (100+EQP.HP%);// Get the total HP (including combat boosts)constbaseMaxHp=Math.round((rawMaxHp + totalEquipmentHpBoost) *BOOSTS.HP%);
The hero's HP resets for every quest. You lose when your HP reaches 0.
Attack (P.ATK / M.ATK)
// Get the raw magic attack based on all sources of INT.constbaseMagicAttack= intelligence * (1.5+ (combatStatLevel /100) *15);// Get the total M. ATK after applying raw and total equipment boosts.constmagicAttack=Math.round( baseMagicAttack + (((baseMagicAttack /100) *M.ATK%+M.ATK) /100) * (100+EQP.ATK%) );// Same for physicalAttack. Replace M.ATK with P.ATK.
Basic attacks will deal damage based on your class's attribute.
STR is used for Physical Attack, INT is used for Magic Attack.
Physical Defense/Magic Resistance (DEF/RES)
// Get the raw defense based on all sources of ENDconstbaseDefense=END* (1.5+ (LEVEL/100) *15);// Get the total DEF after raw/total equipment and combat boosts.// The flow is the same as in the HP formula, just substitute the values.constdefense=Math.round( (baseDefense + (((baseDefense /100) *DEF%+DEF) /100) * (100+EQP.DEF%)) *BOOSTS.DEF% );
DEF reduces the amount of physical damage received.
RES reduces the amount of magic damage received.
Other Formulas
The provided formulas below is pseudo-code for players to be able to follow the logic for analytics/calculations.
DISCLAIMER: Correct as of 29th November 2023, all subject to change.
// Crit Rateconsta=6.26415119;constb=46.6345086;constc=0.58114342;constd=0.16064906;conste=86.56111256;constcritRate= a + b / (c +Math.exp(-d * (agi - e)));
Critical Damage/Resistance is applied after Final Attack!
See Base Damage Formula for where exactly it's applied.
// Return without deducting SP if dazed.// Deduct SP cost of skill if necessary.// If the skill can be shut down and the corresponding shutdown// type matching the skill type is in effect, return.// Start with our attack stat calculated from the hero + eqp + boosts.constbaseAttack= userPhysicalAttack || userMagicAttack;// Roll for accuracy.constaccuracyRoll=RandomBetween(0,100);// Check for accuracy. The attack misses if:// The user has no 'lock on' effect// and skill is not guaranteed to hit// and accuracyRoll > skillAccuracy%// Check for crit. hasCritOnEffect is a status effect belonging to the user..constcritRoll=RandomBetween(0,100);constisCrit= hasCritOnEffect || critRoll < userCriticalRate;// Track the actual damage dealt for recoil.let actualDealtDamage =0;// For all targets... (including self if applicable, such as in status effect)for (allTargets) {// Check for requirements.// etc. Check for requireBleed. Fail if target is not bleeding. // etc. Check for requirePoison. Fail if target is not poisoned. // etc. Check for requireDebuff. Fail if target is not debuffed.// Calculated Defense = DEF/RES (based on skillProperty) * F.DEF%.constcalcDefense= (targetDefense || targetResistance) /100) * (100+ targetFinalDefense%);// Calculate total attack stat. getBaseAttack is used on skills with custom damage logic and overrides the attack stat// etc. Berserk (based on HP%), Devour (*2), StatusEffects-only skills (0)constcalcAttack= ((isFunction(skill.getBaseAttack)?skill.getBaseAttack(): baseAttack) /100) * (100+ userFinalAttack%);// Apply defense reduction to attack stat.constinitialDamage= (calcAttack *RandomBetween(70,130)) / (calcDefense +100);// If this is a healing skill, apply heal instead and return.if (isHealingSkill) {// Calculate HP to recover/necro.constextraHpToRecover= (initialDamage /100) * targetLifeGain%;consthpToRecover= initialDamage + extraHpToRecover;// If target is necro-ed, this will deal damage instead of heal.return; }constextraSkillDamage= isSkill? (initialDamage /100) *Math.max(0, userSkillDamage%):0;// Calculate extra revenge damage (30% damage increase if user below X% HP)constuserHpPerc= userHp / userMaxHp *100;constextraRevengeDamage= userHpPerc < userRevengeThreshold%? initialDamage *0.3:0;// Calculate skill damage reduction if skill.constskillDefendedDamage= isSkill ?Math.max(0, ((initialDamage + extraSkillDamage + extraRevengeDamage) /100) * targetSkillDefense% ):0;// Finally, we get the hit damage. Return if this is <= 0.constbaseHitDamage= initialDamage + extraSkillDamage + extraRevengeDamage - skillDefendedDamage;// Check for dodgeconstdodgeRoll=RandomBetween(0,100);// Check for target dodge. The attack is dodged if:// The user has no 'lock on' effect// and skill is not guaranteed to hit// and dodgeRoll < targetDodgeRate%// If target has protect status and skill can be protected against,// Negate damage and return.// Check for effects to apply on hit damage.// Check for Lethal (+X% damage increase if target HP below 50%).consttargetHpPerc=target.hp /target.maxHp;constextraLethalDamage= targetHpPerc <0.5? (baseHitDamage /100) * userLethal%:0;// Calculate base damage after hit effects.constbaseDamage=Math.round(baseHitDamage + extraLethalDamage);// Calculate critical damage bonus.constrawCrit= (baseHitDamage /100) *Math.max(0, userCriticalDamage%);constrawCritRes=100-Math.min(100, targetCriticalResistance%);constcriticalDamage= isCrit ? (rawCrit /100) * rawCritRes :0;// Get damage factoring armor.constdamageToReceive= baseDamage + criticalDamage - targetFlatDamageReduce;// Apply modifiers to the damage itself, and generates status efects.// etc. Aimed Shot, Convert X% HP into damage, attack for min. % HPconst { statusEffects,correctedDamage } = getFunctionCodeResponse[skill.functionCode]({...});if (correctedDamage >0) {constroundedDamage=Math.round(correctedDamage);// Track the actual dealt damage. actualDealtDamage += roundedDamage;// Apply Damage Reflectif (targetReflectHitRate%>0) {constreflectedDamage=Math.round((correctedDamage /100) * targetReflectHitRate%); }// Apply Life Drainif (userLifeDrainRate%>0) {constdrainDamage=Math.round( (correctedDamage /100) * userLifeDrainRate% ); }// Apply Backlash Damageif (userBacklashRate%>0) {constbacklashDamage=Math.round( (correctedDamage /100) * userBacklashRate ); } } }// Handle Effects here.// Handle Recoil.if (skillHasRecoil) {constrecoilDamage=Math.round(actualDealtDamage * skillRecoil%);if (recoilDamage >0) {// Apply Recoil Damage. }// END, continue to next user.
Attributes and Effects Glossary
Accuracy - % Chance for an attack/skill to succeed.
Critical Hit - Roll for critical hit based on Critical Rate % (unless the skill has special conditions). Deal additional damage based on Critical Damage %, reduced by the target's Critical Resistance %.
Require Bleed/Poison/Debuff/etc... - Attack/Skill will fail if target is not bleeding/poisoned/debuffed/etc...
Final Defense - A bonus applied on top of base Defense/Resistance depending on the incoming attack/skill type.
Final Attack - A bonus applied on top of the attack/skill base attack calculated
Necro - All sources of healing effects will deal damage instead
Skill Damage - Skills will deal an additional % damage. For players, skills are everything other than 'Attack'. For monsters, skills are everything except the monster's basic attack (which can have varying names and effects)
Revenge - Deal an extra fixed 30% damage if the user is below a % HP depending on the revenge threshold.
Skill Defense - Receive a % damage reduction against an incoming skill (revenge damage included). (Already applied DoTs do not count)
Dodge - % to avoid an attack/skill if the skill is not guaranteed to hit.
Protect - Negates all damage by an incoming attack/skill within the same turn.
Lethal - Deal extra % damage based on user's lethal threshold if target HP is below 50%.
Armor (flat damage reduce) - Reduces a FLAT amount of damage after all other effects are calculated.
Damage Reflect - User reflects % of true direct damage received to the attack/skill's user.
Life Drain - User drains % of true direct damage received. (affected by Necro)
Backlash - User receives a % of direct damage dealt as recoil.
Recoil Damage - User receives fixed damage based on a % of damage dealt.
The glossary is accurate as of v1.106.6 and may be changed further down as skills are implemented and balanced.