Menu

Damage Formula, Speed System & Stat Optimization Guide

Guide March 30, 2026 By Boring877

This guide breaks down how damage is calculated in Star Savior, how the turn speed system works, and how to optimize your stat investments. All formulas are verified from the game's decompiled source code (NKM.decompiled.cs, TurnSpeedCalculator.cs).

Damage Formula Overview

The damage calculation happens in multiple steps. Here is the simplified pipeline:

NKMUnitStatManager.cs - OBF_33238 (GetFinalDamage)
// Step 1: Raw Damage (from skill templet factors)
RawDamage = (ATK * AtkFactor% + HP * HpFactor% + DEF * DefFactor%)
            * SkillMultiplier / HitCount

// Step 2: Defense Reduction
DefReduction = DEF_target / (DEF_target + Constant)
EffectiveDefReduction = DefReduction * (1 - Penetration% + PenResist%)

// Step 3: Apply DEF to Raw Damage
PostDef = RawDamage * (1 - EffectiveDefReduction)

// Step 4: Damage Up/Down modifiers (additive)
DamageUp   = AttributeAdvantage + DamageUp% + SkillPhaseUp%
           + AttackTagUp% + BuffCountUp% + DebuffCountUp% + BreakUp%
DamageDown = AttributeDisadvantage + DamageReduce%
           + NonCritReduce% + RoleReduce% + ElementReduce%
           + BreakReduce% + AttackTagReduce%

// Step 5: Critical Hit (applied after modifiers)
if CriticalHit:
    CritDMG_applied = CritDamage% - CritDamageReduce%  (floor 0)
    PostDef += PostDef * CritDMG_applied

// Step 6: Random Variance (+/-5%)
FinalDamage = PostDef * Random.Range(0.95, 1.05)

// Step 7: Hard Caps
if FinalDamage > TargetHP * DamageLimitByHP%:
    FinalDamage = TargetHP * DamageLimitByHP%
if TotalReduction > DamageReduceTotalLimit:
    TotalReduction = DamageReduceTotalLimit

Attribute Advantage (Verified from Code)

NKMUnitStatManager.cs - OBF_16299
private static double CalcAttributeAdvantage(Unit attacker, Unit defender)
{
    double result = 0.0;
    if (attacker is BattleUnit unit)
    {
        // Check if attacker has advantage
        if (IsAttributeAdvantage(unit.Element, defender.Element))
        {
            result = 0.05;  // +5% base advantage
            result += unit.GetStat(RATE_DAMAGE_UP_ADJUST);  // + extra from buffs
        }
        // Check if attacker has disadvantage
        if (IsAttributeDisadvantage(unit.Element, defender.Element))
        {
            result = -0.05;  // -5% base disadvantage
        }
    }
    return result;
}

// Advantage relationships (OBF_11522):
// Sun > Star, Moon > Sun, Star > Moon
// Order > Chaos, Chaos > Order

Attribute advantage gives +5% damage and disadvantage gives -5% damage. This is a flat modifier applied during the damage up/down phase, not a multiplier on raw damage.

Defense Reduction Formula

NKMUnitStatManager.cs - OBF_10086 (CalcDefReduction)
private static double CalcDefReduction(BattleState host,
    Unit attacker, Unit defender, bool isDodge, DamageLog log)
{
    double defStat = defender.GetStat(NST_DEF);
    double hpGrownDefRate = defender.GetStat(RATE_HP_GROWN_DEF);
    hpGrownDefRate *= (1 - defender.GetBreakPercent());
    defStat += defStat * hpGrownDefRate;

    // Diminishing returns formula
    double defReduction = defStat / (defStat + Constant);
    // Constant differs between PVP and PVE modes

    // Apply penetration
    double penetration = attacker.GetStat(RATE_PENETRATE_DEF);
    double penResist = defender.GetStat(RATE_PENETRATE_DEF_RESIST);
    double effectivePen = penetration - penResist;
    defReduction -= defReduction * effectivePen;

    return Math.Max(defReduction, 0.0);
}

The defence constant is loaded at runtime from the game's const templet data. The actual values are:

  • PVE DefenceConst = 3,000 (from CLIENT_CONST_TEMPLET.json, field "DefenceConst")
  • PVP DefenceConst = 300 (from the same file, field "PvpDefenceConst")
CLIENT_CONST_TEMPLET.json
"DefenceConst": 3000,      // PVE defense constant
"PvpDefenceConst": 300,   // PVP defense constant (much lower)
"RATE_DAMAGE_REDUCE_TOTAL_LIMIT": 5000  // 50% cap on total damage reduction

Key takeaways about defense:

  • DEF has diminishing returns -- the formula is DEF / (DEF + 3000), so each additional point provides less reduction
  • The sweet spot is around 2,500-3,000 DEF -- at DEF = Constant you hit 50% reduction, past which returns drop sharply
  • DEF barely matters in PVP -- with a constant of only 300, even 1000 DEF gives 77% reduction, so PVP damage is mostly unmitigated
  • Penetration directly reduces the DEF reduction -- it's a percentage subtracted from the total reduction, not from the DEF stat itself
  • Penetration Resist on the defender counters the attacker's penetration
  • Total damage reduction is hard-capped at 50% (RATE_DAMAGE_REDUCE_TOTAL_LIMIT = 5000 basis points)

Defense Reduction Examples (PVE)

DEF Reduction Curve (PVE)
DEF / (DEF + 3000) -- Diminishing Returns
1,000 DEF
25%
75% dmg
2,000 DEF
40%
60% dmg
2,500 DEF
45.5%
54.5% dmg
3,000 DEF
50%
50% dmg
4,000 DEF
57.1%
42.9% dmg
5,000 DEF
62.5%
37.5% dmg
Sweet spot: 2,500 - 3,000 DEF
Marginal Value of +1,000 DEF
Extra reduction gained per 1,000 DEF at each tier
0 to 1k
+25.0%
1k to 2k
+15.0%
2k to 3k
+10.0%
3k to 4k
+7.1%
4k to 5k
+5.4%

Critical Hit System

NKMUnitStatManager.cs - OBF_6758
private static double CalcCritDamageModifier(HitType hitType,
    ref DamageContext ctx)
{
    if (hitType != HitType.CriticalHit)
        return 0.0;

    // Crit DMG = attacker's CritDamage - defender's CritDamageReduce
    int critDMG = (attacker.GetStat(RATE_CRITICAL_DAMAGE)
                   - defender.GetStat(RATE_CRITICAL_DAMAGE_REDUCE));
    if (critDMG < 0) critDMG = 0;

    double result = critDMG / 10000.0;  // basis points to decimal
    return result;
}

Important details:

  • Crit Damage is applied after defense reduction and damage up/down modifiers
  • Crit Damage Reduce (on the defender) can partially or fully negate the attacker's Crit Damage bonus
  • Non-critical hits can have additional NST_RATE_NONCRITICAL_DAMAGE_REDUCE applied to the defender
  • Effect RES triggers +50% damage reduction on the attacker's output (half damage on evade)

Random Variance

NKMUnitStatManager.cs (line 17438)
// Final damage has +/-5% random variance
double variance = RandomGenerator.Range(9500, 10500) / 10000.0;
finalDamage *= variance;

Every hit has a +/-5% random variance applied at the very end. This means even identical attacks will deal slightly different damage each time. Over many hits this averages out, but on any single attack the damage can vary by up to 10% (from 95% to 105% of the calculated value).

Turn Speed System

Star Savior uses an action gauge system (similar to Final Fantasy X). Every unit has a gauge that fills up over time, and whoever reaches 10000 first gets to act.

TurnSpeedCalculator.cs - OBF_21085 constructor
// Action gauge calculation
double speed = unit.GetStat(NST_TURN_SPEED);

// Apply +/-5% random variance to speed (in certain battle modes)
if (applyRandomVariance)
{
    double variance = RandomGenerator.Range(9500, 10500) / 10000.0;
    speed *= variance;
}

// Slow debuff cuts speed to 30%
if (isSlowed)
{
    speed *= 0.3;
}

// Ticks until this unit acts:
// ticksRemaining = (10000 - currentGauge) / speed

How it works:

  • Each "tick", every unit's gauge fills by their speed value
  • The unit whose gauge reaches 10,000 first gets the next turn
  • After acting, the gauge resets (but retains leftover fill)
  • Speed has +/-5% random variance per tick, making close speed values unreliable
  • The slow debuff (IsLowTurnSpeed) reduces speed to 30%

Speed and Turns

Turns per 1000 Ticks by Speed
More speed = more turns = more total damage over a fight
10
100
12
120
14
140
17
170
20
200

Speed and Enemy Turn Denial

In a battle that ends after 7 of your turns, your speed determines how many times the enemy acts:

Your SPDEnemy Turns (120 SPD enemy)Enemy Turns (140 SPD enemy)
1207 (equal)8
14067 (equal)
17056
20045

Stat Optimization Guide

Expected Damage Formula

The expected damage per hit (accounting for crit probability) is:

Expected Damage = ATK * [1 + CritRate * CritDamage]

This means Crit Rate and Crit Damage multiply each other. If one is zero, the other does nothing. They must be built together.

ATK vs Crit Damage -- The Breakeven

Given typical endgame values (ATK ~6000, base Crit Damage 50-68% bonus):

Your Crit Rate+200 ATK Damage+10% CD Damage+12% CD DamageWinner
5%+219+86+104ATK (2.5x)
20%+230+360+432CD
30%+234+540+648CD (2.8x)
45%+240+810+972CD (4x)
50%+242+900+1,080CD (4.5x)

The breakeven point: +200 ATK = +10% CD at ~42% Crit Rate, and +200 ATK = +12% CD at ~33% Crit Rate.

+200 ATK vs +10% CD Damage Bonus
ATK 6000, base CD 50%. Where each stat gives more damage.
5% CR
+219
+86
ATK wins
20% CR
+230
+360
CD wins
30% CR
+234
+540
CD 2.3x
45% CR
+240
+810
CD 3.4x
50% CR
+242
+900
CD 3.7x
+200 ATK
+10% CD

20% ATK Set vs 40% CD Set

// 20% ATK set: always +20% damage
// 40% CD set:  only works on crits

// Effective bonus per hit:
// ATK set:  +20% guaranteed
// CD set:   CR * 40% average (and RNG-dependent)

// CD set only wins when Crit Rate > 76%
// Example at 45% CR:
//   ATK set: 1.20 * multiplier
//   CD set:  1 + 0.45 * 0.40 = 1.18 * multiplier  (ATK wins)

Result: 20% ATK set always beats 40% CD set unless you have unrealistically high Crit Rate (76%+). The ATK set gives more average damage AND perfect consistency.

30 SPD vs 12% ATK

// In a battle lasting 1000 ticks:
// 120 SPD: 12 turns * 1.00 = 12.0x damage
// 150 SPD: 15 turns * 1.00 = 15.0x damage  (+25%)
// vs
// 120 SPD: 12 turns * 1.12 = 13.44x damage  (+12%)

30 SPD wins in any battle lasting 3+ turns. In a 7-10 turn fight, 30 SPD also denies 1-2 enemy turns, which is often more valuable than the raw damage difference.

Build Recommendations

For character-specific gear and stat recommendations, see the Character Builds page.

General Priority

  1. Speed first -- get to 140-170 SPD to outspeed enemies and deny turns (check the Equipment Database for SPD gear options)
  2. ATK as foundation -- maximize ATK through affection, tactics, resonance, and gear main stats (these are "free" and don't compete with substats)
  3. Crit Rate to 40-50% -- this is the minimum threshold where CD investment becomes worthwhile
  4. Crit Damage as high as possible -- at 40%+ CR, CD is the highest-value stat per point
  5. Effect Hit -- essential for debuff-reliant characters

Set Bonus Recommendations

4-Piece Set Bonus Damage Comparison
ATK 6000, 45% CR, 50% base CD -- which set gives the most?
Attack Set
8,640
+20% ATK
Destruction
9,420
+40% CD
Insight
8,856
+30% CR
Annihilation
9,060
+20% CD+Hit
Speed Set
7,200 + turns
+15 SPD
No Set
7,200
baseline
Playstyle4-Piece SetWhy
General / SafeAttack Set (+20% ATK)Always works, no RNG, beats CD set at realistic crit rates
Crit Build (40%+ CR)Destruction Set (+40% CD)Best ceiling damage if you can maintain high CR
Speed ControlSpeed Set (+15 SPD)Turn denial is extremely valuable in 7-10 turn fights
DebufferHit Set (+20% Effect Hit)Essential for landing debuffs consistently

The Golden Rule

ATK is your foundation, CD is your multiplier. You need a strong foundation before the multiplier matters. Get ATK high from free sources (affection, tactics, resonance), then decide: if your Crit Rate is below 30%, prioritize ATK substats. If it's 40%+ from buffs and gear, stack CD as your primary substat investment.

Battle Power Formula

The game uses a Battle Power score for unit ranking. This is separate from actual combat damage:

NKMUnitStatManager.cs - OBF_26687 (CalcBattleScore)
double atkFactor = ATK / 10.0 * ATK_WEIGHT * (
    (1 - critRate) + critRate * (1 + critDamage) );
double hpFactor  = HP / 55.0 * HP_WEIGHT;
double defFactor = DEF / 5.0 * DEF_WEIGHT;
double spdFactor = (100 + (SPD - 100) / SPD_NORMALIZE) / 100.0;
double potenFactor = 1.0 + totalPotentialPoints * POTEN_SCALE;
double hitFactor  = max(1.0,
    1 + (effectHit - 10000 + effectEvade) / 10.0);

double rawScore = (atkFactor + hpFactor + defFactor)
    * spdFactor * hitFactor;

double bonusFromLB = limitBreakGrade * 0.02;
double bonusFromSkills = totalSkillLevels * 0.01;
double multiplier = 1.0 + bonusFromLB + bonusFromSkills;

int battlePower = (int)(rawScore * multiplier);

Key points about Battle Power:

  • ATK has the highest weight (divided by 10 vs HP/55 and DEF/5)
  • Crit interactions are baked into the ATK factor
  • Limit Break grades add 2% per grade
  • Total skill levels add 1% per level
  • Potential points add a small bonus per point

Source Code References

All formulas in this guide are extracted from the game's decompiled C# source code. The key files are:

  • NKM.decompiled.cs -- Game model/logic (UnitStatManager, damage calculation, stat builder)
  • NKC.decompiled.cs -- Client UI code (stat display, tooltips)
  • Star.Templets.decompiled.cs -- Damage templet data structures (AtkFactor, HpFactor, DefFactor fields)

The decompiled and deobfuscated source code is publicly available at github.com/boring877/star-savior-decompiled.

Tags
advancedcombatdamagespeedstatsoptimizationtheorycraft