Attributes are the six numbers on a hero's Stats page that you raise with the points you earn from Leveling. Every combat stat on that page (Health, Attack, Defence, Stamina, resistances, crit chance and so on, see Character stats) is computed from them. A seventh, hidden attribute supplies the fixed stats that never change with level, such as Sanity, Rage and the stamina regeneration rate. This page gives the exact formula, the curves, and what one point is worth for each hero.
Overview#
- Each hero starts with a fixed set of attribute scores (table below).
- Every level gained at an altar gives 1 attribute point to spend on any attribute. At level 99 a hero has therefore spent or banked 98 points.
- A single attribute cannot go above 99.
- Each stat is the sum of "weight x curve" over the attributes. The curve (how much one score is worth) is the same for all six attributes. The weight (how much of that curve a hero gets from an attribute) differs per hero and per stat. This is the only thing that makes Benita a caster and Viola a glass-cannon duelist.
Starting attributes#
| Hero | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Sum | Hidden |
|---|---|---|---|---|---|---|---|---|
| Terrence | 15 | 9 | 14 | 8 | 13 | 12 | 71 | 1 |
| Viola | 9 | 15 | 13 | 11 | 10 | 14 | 72 | 1 |
| Benita | 11 | 12 | 14 | 15 | 10 | 9 | 71 | 1 |
| Norwood | 13 | 8 | 15 | 6 | 13 | 14 | 69 | 1 |
| Jerold | 10 | 8 | 14 | 12 | 12 | 14 | 70 | 1 |
| The First Messenger | 10 | 10 | 10 | 10 | 21 | 10 | 71 | 1 |
| Elena | 10 | 8 | 34 | 12 | 22 | 24 | 110 | 1 |
The hidden attribute is 1 for every hero. Elena, the Arcade hero, starts far above the others (sum 110, against 69 to 72 for the rest), mostly in Vigor, Vitality and Endurance. The First Messenger (10006) cannot be played (EnableHost is 0) but has a full attribute row and is used as a combat model.
Names of the attributes#
The game's scripts name the six slots Strength, Spirit, Brave, Dexterous, Tolerant and Generous. These internal names do not describe what the slots do, and the on-screen labels are stored in the Unity interface rather than in the game's data tables, so they cannot be read from the data. This wiki therefore labels the slots by what they actually drive (inferred):
| Slot | Script name | Wiki name | Main role |
|---|---|---|---|
| 1 | Strength | Strength | Attack for Terrence, Norwood and the First Messenger; a little Defence and resistance for everyone |
| 2 | Spirit | Dexterity | Crit rate and Crit damage for every hero; Viola's Attack |
| 3 | Brave | Vigor | Health and both shield capacities |
| 4 | Dexterous | Intellect | Elemental and Pierce resistance; Benita's Attack and Crit damage |
| 5 | Tolerant | Vitality | Physical Defence (main source) and Pierce resistance |
| 6 | Generous | Endurance | Stamina; Jerold's and Elena's Attack |
| 7 | Hidden | (hidden) | Fixed stats |
The formula#
For each of the 42 hero stats, the game does the following (FS_HeroData.GetPropertyAllByList):
stat = floor( sum over attributes a of weight[hero, stat, a] x curve[a, points, stat] / 1000 )
weightcomes from the HeroPropertyData table (Attribute_1toAttribute_7columns). It is in per mille: 850 means "85% of the curve".curvecomes from the HeroAttributeData table, indexed by attribute number, the score (1 to 99) and the stat (Property_1toProperty_42).- Only weights above 0 are used. A stat with no positive weight is 0.
- The sum is rounded down once, after all six attributes plus the hidden one have been added.
A reimplementation of this loop reproduces every starting-stat value listed under Starting stats below.
Worked example, Terrence at the start (Strength 15, Dexterity 9, Vigor 14):
- Health = 900 x Health curve(14) / 1000 = 900 x 944 / 1000 = 849.6, shown as 849.
- Attack = (850 x Attack curve(15) + 50 x Attack curve(9)) / 1000 = (850 x 68 + 50 x 43) / 1000 = 59.95, shown as 59.
What is shown on the Stats page for the hero (and used in battle) is that base value plus Trophies, Talents and difficulty effects. How those are layered on top is described on Character stats.
The curves#
All six visible attributes use the same table for every stat that playable heroes use: the curves of attributes 1 to 6 are identical at all 99 points. (The one exception is the four elemental attack stats, properties 19 to 22: only attribute 1 has a curve for them and attributes 2 to 6 are all 0. Only the First Messenger has weight on those stats, and only on attribute 1.) The curves fall into a few families, and several stats share one family:
| Family | Stats that use it |
|---|---|
| Attack-type | Physical Attack, and the Fire, Poison, Arcane and Dark attack stats |
| Defence-type | Physical Defence, the four elemental resistances, Pierce resistance |
| Crit damage | Crit damage |
| Crit rate | Crit rate |
| Health | Health |
| Stamina | Stamina |
| Shields | Trophy shield and Skill shield (nearly the Health curve) |
| Soul Dew | Soul Dew (property 7, internal name Mp), used only by the First Messenger |
| Points | Attack-type | Defence-type | Crit damage | Crit rate | Health | Stamina | Shields |
|---|---|---|---|---|---|---|---|
| 1 | 25 | 26 | 200 | 50 | 581 | 291 | 581 |
| 5 | 34 | 36 | 205 | 54 | 667 | 334 | 667 |
| 10 | 46 | 48 | 212 | 59 | 800 | 400 | 800 |
| 15 | 68 | 71 | 220 | 64 | 984 | 488 | 991 |
| 20 | 93 | 98 | 229 | 69 | 1186 | 573 | 1264 |
| 25 | 120 | 126 | 237 | 74 | 1379 | 637 | 1502 |
| 30 | 145 | 152 | 249 | 79 | 1524 | 688 | 1653 |
| 35 | 161 | 169 | 261 | 84 | 1607 | 725 | 1736 |
| 40 | 170 | 179 | 277 | 89 | 1680 | 750 | 1809 |
| 45 | 179 | 188 | 298 | 94 | 1735 | 773 | 1864 |
| 50 | 183 | 192 | 316 | 99 | 1776 | 793 | 1905 |
| 60 | 191 | 201 | 342 | 109 | 1821 | 815 | 1950 |
| 70 | 195 | 205 | 359 | 119 | 1837 | 823 | 1966 |
| 80 | 196 | 206 | 374 | 129 | 1850 | 830 | 1979 |
| 99 | 200 | 210 | 400 | 148 | 1871 | 840 | 2000 |
Points between the rows follow the table in HeroAttributeData. Key features:
- Attack, Defence, Health and Stamina rise fastest between about 10 and 30 points, then flatten hard. Attack gains about 5 per point from 20 to 30, 2.5 from 30 to 40, 1.3 from 40 to 50, 0.8 from 50 to 60 and only 0.2 per point beyond 60. Health gains about 34 per point from 20 to 30 and just 1.1 per point beyond 80.
- Their ceilings are exactly 200 (Attack), 210 (Defence), 1871 (Health), 840 (Stamina) and 2000 (Shields) at 99 points.
- Crit rate is perfectly linear: +1 per point (0.1 percent), from 50 at 1 point to 148 at 99.
- Crit damage keeps accelerating until about 50 points (up to +3.9 per point between 40 and 50), then slows. It reaches 400 at 99 points.
- Because the curve is the same for every attribute, for Attack, Defence, Health, Stamina and Shields a point is worth the most when the attribute is in the 10 to 30 range, whichever attribute it is. This is why spreading points over several attributes beats a single-attribute build for the first few dozen points.
What each attribute does, per hero#
Cell values are the weight: the share of the curve that the attribute gives to that stat. "Total weight" is the share you get with every contributing attribute at 99 (a stat with a total of 100% reaches the full ceiling above; Viola's 80% Health reaches 80% of 1871).
Terrence#
| Stat | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Total weight |
|---|---|---|---|---|---|---|---|
| Attack (physical) | 85% | 5% | - | - | - | - | 90% |
| Crit damage | 20% | 75% | - | - | - | - | 95% |
| Crit rate | - | 60% | - | - | - | - | 60% |
| Health | - | - | 90% | - | - | - | 90% |
| Defence | 25% | 5% | 10% | - | 60% | - | 100% |
| Stamina | - | - | - | - | - | 70% | 70% |
| Fire / Poison / Arcane / Dark resistance | 15% | 10% | 10% | 60% | 5% | - | 100% |
| Pierce resistance | - | - | - | 250% | 250% | - | 500% |
| Trophy shield and Skill shield | - | - | 90% | - | - | - | 90% |
Viola#
| Stat | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Total weight |
|---|---|---|---|---|---|---|---|
| Attack (physical) | 20% | 70% | - | - | - | - | 90% |
| Crit damage | 10% | 130% | - | - | - | - | 140% |
| Crit rate | - | 100% | - | - | - | - | 100% |
| Health | - | - | 80% | - | - | - | 80% |
| Defence | 25% | 5% | 5% | - | 45% | - | 80% |
| Stamina | - | - | - | - | - | 85% | 85% |
| Fire / Poison / Arcane / Dark resistance | 15% | 10% | 10% | 60% | 5% | - | 100% |
| Pierce resistance | - | - | - | 250% | 250% | - | 500% |
| Trophy shield and Skill shield | - | - | 80% | - | - | - | 80% |
Benita#
| Stat | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Total weight |
|---|---|---|---|---|---|---|---|
| Attack (physical) | 20% | 2.5% | 2.5% | 100% | - | - | 125% |
| Crit damage | 5% | 35% | - | 85% | - | - | 125% |
| Crit rate | - | 80% | - | - | - | - | 80% |
| Health | - | - | 90% | - | - | - | 90% |
| Defence | 25% | 5% | 5% | - | 50% | - | 85% |
| Stamina | - | - | - | - | - | 80% | 80% |
| Fire / Poison / Arcane / Dark resistance | 15% | 10% | 10% | 50% | 5% | - | 90% |
| Pierce resistance | - | - | - | 250% | 250% | - | 500% |
| Trophy shield and Skill shield | - | - | 95% | - | - | - | 95% |
Norwood#
| Stat | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Total weight |
|---|---|---|---|---|---|---|---|
| Attack (physical) | 100% | - | - | - | - | - | 100% |
| Crit damage | 10% | 60% | - | - | - | - | 70% |
| Crit rate | - | 40% | - | - | - | - | 40% |
| Health | - | - | 100% | - | - | - | 100% |
| Defence | 10% | 10% | 5% | - | 75% | - | 100% |
| Stamina | - | - | - | - | - | 75% | 75% |
| Fire / Poison / Arcane / Dark resistance | 10% | 10% | 5% | 40% | 5% | - | 70% |
| Pierce resistance | - | - | - | 250% | 250% | - | 500% |
| Trophy shield and Skill shield | - | - | 95% | - | - | - | 95% |
Jerold#
| Stat | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Total weight |
|---|---|---|---|---|---|---|---|
| Attack (physical) | 20% | - | - | - | - | 84% | 104% |
| Crit damage | 35% | 60% | - | - | - | 25% | 120% |
| Crit rate | - | 60% | - | - | - | 10% | 70% |
| Health | - | - | 87.5% | - | - | - | 87.5% |
| Defence | 20% | 10% | - | - | 67.5% | - | 97.5% |
| Stamina | - | - | - | - | - | 60% | 60% |
| Fire / Poison / Arcane / Dark resistance | 10% | 15% | - | 60% | - | 15% | 100% |
| Pierce resistance | - | - | - | 250% | 250% | - | 500% |
| Trophy shield and Skill shield | - | - | 95% | - | - | - | 95% |
Elena#
| Stat | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Total weight |
|---|---|---|---|---|---|---|---|
| Attack (physical) | 20% | - | - | - | - | 84% | 104% |
| Crit damage | 35% | 60% | - | - | - | 25% | 120% |
| Crit rate | - | 60% | - | - | - | 10% | 70% |
| Health | - | - | 87.5% | - | - | - | 87.5% |
| Defence | 20% | 10% | - | - | 67.5% | - | 97.5% |
| Stamina | - | - | - | - | - | 60% | 60% |
| Fire / Poison / Arcane / Dark resistance | 10% | 15% | - | 60% | - | 15% | 100% |
| Pierce resistance | - | - | - | 250% | 250% | - | 500% |
| Trophy shield and Skill shield | - | - | 95% | - | - | - | 95% |
Elena's weights are identical to Jerold's in all 42 stat rows; only her starting attributes and talent set differ.
The First Messenger (not playable) has Attack 280% Strength, Health 130% Vigor, Defence 130% Vitality, elemental resistance 150% Vitality, Pierce resistance 500% Intellect plus 500% Vitality and Stamina 100% Endurance. Its Crit rate is 0. It also has weight on the Fire, Poison, Arcane and Dark attack stats, which no playable hero has.
Stats every hero gets from the "hidden" attribute#
The hidden attribute is always 1 point. Its curve is a constant (1000 or 10000 depending on the stat), so the stat equals the hero's weight times that constant divided by 1000. The table shows the resulting stat values (for example Poise regen: weight 24 x 10000 / 1000 = 240). The regen and decay stats are applied each tick as value / 1000 of the matching maximum, so 240 means 24 percent of maximum per second and 400 stamina regen means 40 percent of maximum stamina per second (AnimalBase_Value:RecoveryEnergy, RecoveryToughness, DecrementRage).
| Fixed stat | Terrence | Viola | Benita | Norwood | Jerold | Elena |
|---|---|---|---|---|---|---|
| Stamina regen while guarding (per mille/s) | 100 | 100 | 100 | 100 | 100 | 100 |
| Sanity | 100 | 100 | 100 | 100 | 100 | 100 |
| Rage decay (per mille/s; only Norwood and Jerold ever apply it, see Rage#Decay) | 100 | 100 | 100 | 50 | 60 | 60 |
| Power | 100 | 100 | 100 | 100 | 100 | 100 |
| Poise regen (per mille/s) | 0 | 240 | 240 | 240 | 240 | 240 |
| Stamina regen (per mille/s) | 400 | 400 | 400 | 400 | 400 | 400 |
| Rage | 100 | 100 | 100 | 100 | 100 | 100 |
| Stamina exhaustion time value | 100 | 100 | 100 | 100 | 92 | 92 |
| Power regen (per mille/s) | 0 | 0 | 0 | 0 | 6 | 6 |
| Power decay (per mille/s) | 50 | 50 | 50 | 50 | 50 | 50 |
| Resilience (Weakness) | 10000 | 10000 | 10000 | 10000 | 10000 | 10000 |
| Resilience regen (per mille/s) | 100000 | 100000 | 100000 | 100000 | 100000 | 100000 |
Poise itself (property 13) has no attribute weight at all; see Hidden mechanics.
Starting stats#
| Stat at start | Terrence | Viola | Benita | Norwood | Jerold | Elena |
|---|---|---|---|---|---|---|
| Attack | 59 | 56 | 80 | 58 | 62 | 104 |
| Crit damage | 201 | 307 | 272 | 147 | 254 | 258 |
| Crit rate | 34 | 64 | 48 | 22 | 40 | 41 |
| Health | 849 | 724 | 849 | 984 | 826 | 1392 |
| Defence | 63 | 39 | 43 | 59 | 52 | 86 |
| Stamina | 303 | 398 | 308 | 351 | 281 | 375 |
| Elemental resistance | 50 | 54 | 58 | 32 | 55 | 63 |
| Pierce resistance | 260 | 252 | 297 | 247 | 285 | 412 |
| Shield capacity | 851 | 724 | 898 | 941 | 898 | 1634 |
What one attribute is worth#
These tables show the stat gain from putting 10 more points into one attribute, with all other attributes held steady. Stats that do not change are left out (Pierce resistance is also omitted; it moves only with Intellect and Vitality, at 250% weight each).
Abbreviations: Atk = Attack, CritDmg = Crit damage, CritRate = Crit rate (per mille), Def = Defence, Res = each elemental resistance, Stam = Stamina, Shield = both shield capacities.
From each hero's own starting score (a hero who starts higher in an attribute gains less from it, see Elena's Vigor 34):
| Attribute +10 | Terrence | Viola | Benita | Norwood | Jerold | Elena |
|---|---|---|---|---|---|---|
| Strength | Atk +45, CritDmg +3, Def +13, Res +8 | Atk +9, CritDmg +1, Def +12, Res +7 | Atk +10, CritDmg +1, Def +12, Res +7 | Atk +50, CritDmg +1, Def +5, Res +5 | Atk +9, CritDmg +6, Def +10, Res +5 | Atk +10, CritDmg +6, Def +10, Res +5 |
| Dexterity | Atk +3, CritDmg +13, CritRate +6, Def +2, Res +5 | Atk +36, CritDmg +22, CritRate +10, Def +3, Res +5 | Atk +2, CritDmg +6, CritRate +8, Def +2, Res +5 | CritDmg +9, CritRate +4, Def +5, Res +4 | CritDmg +9, CritRate +6, Def +4, Res +6 | CritDmg +9, CritRate +6, Def +5, Res +7 |
| Vigor | HP +358, Def +5, Res +6, Shield +462 | HP +319, Def +3, Res +5, Shield +406 | Atk +2, HP +358, Def +3, Res +5, Shield +488 | HP +395, Def +3, Res +2, Shield +485 | HP +348, Shield +488 | HP +118, Shield +128 |
| Intellect | Res +27 | Res +30 | Atk +52, CritDmg +15, Res +27 | Res +15 | Res +30 | Res +31 |
| Vitality | Def +31, Res +3 | Def +22, Res +2 | Def +25, Res +2 | Def +39, Res +2 | Def +34 | Def +36 |
| Endurance | Stam +117 | Stam +133 | Stam +138 | Stam +117 | Atk +42, CritDmg +4, CritRate +1, Stam +94, Res +8 | Atk +38, CritDmg +6, CritRate +1, Stam +56, Res +7 |
From 40 to 50 points (the same for every hero, to show the diminishing returns):
| Attribute +10 | Terrence | Viola | Benita | Norwood | Jerold | Elena |
|---|---|---|---|---|---|---|
| Strength | Atk +11, CritDmg +7, Def +3, Res +1 | Atk +2, CritDmg +4, Def +3, Res +1 | Atk +3, CritDmg +2, Def +3, Res +2 | Atk +13, CritDmg +4, Def +1, Res +1 | Atk +3, CritDmg +14, Def +3, Res +1 | Atk +3, CritDmg +14, Def +3, Res +1 |
| Dexterity | CritDmg +29, CritRate +6, Res +1 | Atk +9, CritDmg +51, CritRate +10, Res +1 | CritDmg +13, CritRate +8, Res +1 | CritDmg +24, CritRate +4, Def +1, Res +1 | CritDmg +23, CritRate +6, Def +1, Res +1 | CritDmg +23, CritRate +6, Def +1, Res +1 |
| Vigor | HP +86, Def +1, Res +1, Shield +86 | HP +76, Res +1, Shield +77 | HP +86, Res +1, Shield +91 | HP +96, Shield +91 | HP +84, Shield +91 | HP +84, Shield +91 |
| Intellect | Res +7 | Res +7 | Atk +13, CritDmg +33, Res +6 | Res +5 | Res +7 | Res +7 |
| Vitality | Def +7 | Def +6 | Def +6 | Def +9 | Def +9 | Def +9 |
| Endurance | Stam +30 | Stam +37 | Stam +34 | Stam +32 | Atk +11, CritDmg +10, CritRate +1, Stam +25, Res +1 | Atk +11, CritDmg +10, CritRate +1, Stam +25, Res +1 |
Reading the tables:
- Vigor is by far the best Health source for every hero at the start (+319 to +395 Health for 10 points for the five older heroes, +118 for Elena who starts at 34) but gives only +76 to +96 once you are past 40.
- Dexterity is the only way to raise Crit rate except for Jerold and Elena, whose Endurance also gives a sliver (+1).
- Intellect is nearly useless for Attack unless you are Benita (+52 Attack at the start).
- Endurance is a stamina stat for Terrence, Viola, Benita and Norwood but a damage stat for Jerold and Elena: 10 Endurance gives them +42 and +38 Attack at the start, more than Strength gives them.
Maximum values#
If one hero could have all six attributes at 99 (this takes about 520 points and a hero only ever has 98 spare points, so it is a ceiling, not a build), the stats would be:
| Hero | Attack | Crit damage | Crit rate | Health | Defence | Stamina | Elemental res. | Pierce res. | Shield |
|---|---|---|---|---|---|---|---|---|---|
| Terrence | 180 | 380 | 88 | 1683 | 210 | 588 | 210 | 1050 | 1800 |
| Viola | 180 | 560 | 148 | 1496 | 168 | 714 | 210 | 1050 | 1600 |
| Benita | 250 | 500 | 118 | 1683 | 178 | 672 | 189 | 1050 | 1900 |
| Norwood | 200 | 280 | 59 | 1871 | 210 | 630 | 147 | 1050 | 1900 |
| Jerold, Elena | 208 | 480 | 103 | 1637 | 204 | 504 | 210 | 1050 | 1900 |
| The First Messenger | 560 | 400 | 0 | 2432 | 273 | 840 | 315 | 2100 | 2000 |
Crit rate is in per mille (88 means an 8.8 percent chance; see Critical hits).
Spending points#
- Points are added on the Stats page, and only when it was opened at an altar (
playerinfoctrl.lua9272; Altars#What the altar menu offers). The page refuses to add a point once the attribute shows 99 (playerinfoctrl.lua1593, 1615) and only lets you take back points added in the current, unconfirmed session (1653). - The Stats page shows the new stat values live (
PlayerInfoCtrl.GetPropertyTemp, which calls the same formula) before you confirm. - When you confirm, any Health you add also heals you: the hero's current Health rises by the change in maximum Health (
AddHeroAttribute,playerinfoctrl.lua10615-10642). - Respec.
FS_HeroData:ResetAttributesets every spent point back to 0 and refundslevel - 1points. The only caller in the game scripts is the story-quest actionResetAttribute(StoryQuest row 1068, story 5), which resets every hero at once (ControllerStoryMode:ResetAllAttributePoints,FS_HeroList:RestAllHeroAttribute). In play it is the Gravedigger's dialog in Katib, which takes one Starry Honey Wine (Leveling has the wine prices). I found no other caller (inferred: there is no free respec in normal play; a "Reset Attributes" string exists in the text table, but the button lives in the Unity interface).
Preset builds in challenge modes#
Arcade mode and the story challenge (Obsession Challenge#Standard Mode (preset heroes)) replace a hero's attributes with a fixed build (FS_HeroList:ResetToChallenge, AddAttributeTo) at level 30, from the ArcadeHero (6 rows) and StoryChallengeHero (5 rows) tables. Each preset of the five original heroes spends 30 points above the hero's base, one more than the 29 a level-30 hero would normally have (Elena's is the exception, see below). Jerold's preset has +4, +6, +6, 0, +1, +13 over his base, and so on.
| Hero | Strength | Dexterity | Vigor | Intellect | Vitality | Endurance | Health | Attack | Defence |
|---|---|---|---|---|---|---|---|---|---|
| Terrence | 28 | 9 | 21 | 8 | 13 | 22 | 1102 | 116 | 84 |
| Viola | 9 | 34 | 18 | 11 | 10 | 20 | 884 | 119 | 45 |
| Benita | 14 | 15 | 20 | 20 | 12 | 20 | 1067 | 109 | 53 |
| Norwood | 30 | 8 | 22 | 6 | 15 | 18 | 1265 | 145 | 78 |
| Jerold | 14 | 14 | 20 | 12 | 13 | 27 | 1037 | 121 | 60 |
| Elena | 14 | 14 | 20 | 12 | 13 | 27 | 1037 | 121 | 60 |
Elena's row in ArcadeHero is the same build as Jerold's, which for her means 10 fewer total points than her natural start (her own base is Vigor 34, Vitality 22, Endurance 24). Because her weights equal Jerold's, her preset stats are Jerold's stats.
Enemies#
Enemies run through the same code with isHost = false (the full recipe is in Enemies#How enemy stats are built; the level comes from New Game Plus enemy scaling#How the level is chosen), which switches to the EnemyAttributeData table. An enemy's attributes are its HeroData base plus level - 1 on every one of the six visible slots (FS_HeroData.GetPropertyAll). The enemy curves match the hero curves for the first 22 or more points and then diverge (Health from point 23, Attack from 26, Crit rate from 52). Enemy attributes are also capped at 99. At 99 points:
| Stat at 99 points | Hero curve | Enemy curve |
|---|---|---|
| Attack | 200 | 456 |
| Health | 1871 | 4320 |
| Defence | 210 | 200 |
| Crit damage | 400 | 250 |
| Crit rate | 148 | 100 |
Enemy models also use different weights. Across the 67 enemy and boss rows, slot 1 feeds Attack, Crit damage and the four elemental attack stats, slot 2 feeds Crit resistance, slot 3 Health (and stamina recovery while guarding), slot 4 Soul Dew, Sanity, Pierce resistance and the four elemental resistances, slot 5 Pierce resistance, Defence, Rage decay and the four elemental resistances, and slot 6 Stamina and Power. The hidden slot supplies Crit resistance and Health on some rows, a share of Stamina, Poise, Poise regen, Resilience, the stamina delay value and the Human, Beast and Sendril type flags (properties 38 to 40). See Enemies for individual models.
Hidden mechanics#
- One curve, six attributes. The game never tells you that a point of Strength and a point of Vitality are worth exactly the same on the underlying curve; only the hero's weights decide. So when you want a raw stat (Health, Attack, Defence), the first points into the attribute with the largest weight are worth far more than the points after about 35; spreading across the attributes a hero has weight in is usually more efficient than stacking one.
- Steep up to about 30, flat after 60. The stats are built to reward a spread of roughly 20 to 40 points in each attribute you care about. Moving an attribute from 60 to 99 buys less Attack than 6 points from 20 to 26.
- Pierce resistance is 5 times the Defence curve. Intellect and Vitality each carry 250% weight, a total of 500% against 80% to 100% of the same curve for Defence, so at 99 points in both attributes Pierce resistance reaches 1,050 against a Defence ceiling of 210 for Terrence. Against each hero's own Defence the start ratio is 4.1 times (Terrence) to 6.9 times (Benita), because the Defence weights differ (Pierce 260 against Defence 63 for Terrence). Attacks whose defence type is Pierce are resisted by this stat instead of Defence (
animalbase_value.lua1826-1836), so Vitality and Intellect matter most against them. - Elemental resistances are always four identical stats. Fire, Poison, Arcane and Dark resistance have the same weights for every hero, so you cannot specialise.
- Endurance means damage for Jerold and Elena. Their Attack, Crit damage and Crit rate all draw on Endurance; their Strength is a minor source.
- Poise has no attribute source. Property 13 (Poise) is 0 for every hero at every attribute setting. No trophy stat is Poise (the trophy property tables only contain types 1, 2, 4, 5, 8, 10, 11, 15, 23 to 26 and 35 to 37), so base Poise is 0 and the stat only rises on Casual (+130, see Difficulty) and through run-time effects such as Norwood's +10 Abnormal bonus. The one trophy link to Poise is effect 110, which adds Poise to the Eat skills while drinking (Trophy effects#Movement, stamina and quality of life). Terrence's Poise Regen is also 0 while every other hero has 240 (24 percent of max Poise per second, from the hidden attribute): any Poise he gains from other sources does not regenerate by itself (inferred from the regen formula; see Poise and stagger).
- Values above 99 would break the stats. The attribute table has exactly 99 rows per attribute although the code declares a 200 maximum. A score of 100 or more finds no row and contributes 0 (inferred from
MS_HeroAttributeData.GetValue). The UI stops you at 99, and the preset builds stay under 35, so this never occurs in normal play. - Leveling cannot overspend. The 98-point total is a hard limit (Leveling):
attribPointsrises by exactly 1 per level-up (playerinfoctrl.lua10595) and nothing else adds attribute points in the scripts. - A leftover system. The BufferData table (12 rows, internal names for "Blessing" and "Source" buffs) carries numbers of 10, 20 or 40 in its attribute columns for six of its entries, the Life, Attack and Defence "Blessing" (rows 1 to 3) and "Source" (rows 7 to 9) buffs; their Chinese descriptions speak of raising a level by 1 or 2. The only reader is the guard-mode controller, and the function it calls (
EatBuffer) does not exist in the scripts, so this looks like cut content (inferred).
Sources#
TrophyPropertyandTrophyRandomPropertyPropertyType values (no 13);structdata/ms_trophyproperty.lua:30-60;logic/playervalue/animalbase_value.lua:202-221(only those properties are added) and:372(trophy effect 110).reference/lua_src/luascript/structdata/fs_herodata.lua: 142-150 (ResetAttribute), 328-340 (AddAttributeTo), 556-617 (GetPropertyAll, GetPropertyAllByList), GetAttributeAllByList just below.luascript/structdata/ms_herodata.lua: 6-14 (attribute names), 15-16 (AttributeMax7,AttributeValueMax99), 62 (PropertyMax42).luascript/structdata/ms_heroattributedata.lua: 6 (AttributePointMax200), 22-33 (the lookup that returns 0 for a missing row).luascript/logic/playervalue/hero10004_value.lua:15andhero10005_value.lua:15(the only callers ofDecrementRage, defined atanimalbase_value.lua:1586);hero10007_value.lua:19(Elena's Power decay).luascript/logic/playervalue/animalbase_value.lua: 1561-1625 (stamina delay(100 - value) / 10s, and the regen/decay ticks), 178 (enemy and unsaved-hero base stats), 2429 (Crit rate read).gamedata/playerdefine/animalbase_value_define.lua(outsideluascript/): 23 (CasualToughnessAdd130).luascript/structdata/fs_herolist.lua: 152-170 (reset and challenge presets);luascript/structdata/fs_userdata.lua: 80-106 (preset attribute list).luascript/ui/controller/playerinfoctrl.lua: 1593-1708 (add and remove point buttons), 3908-3916 (live preview), 10573-10595 (+1 attribute point per level), 10615-10642 (apply points, heal).luascript/controller/controllerstorymode.lua: 107, 5481, 9172 (ResetAttribute quest action).- Tables: HeroData rows 10001 to 10007 (
Attribute_1toAttribute_7); HeroAttributeData (693 rows, AttributeId 1 to 7, AttributePoint 1 to 99); HeroPropertyData (HeroId 10001 to 10007, PropertyId 1 to 42); EnemyAttributeData; ArcadeHero; StoryChallengeHero; StoryQuest row 1068 (ActionType 34, comment meaning "respec"); BufferData rows 1-3 and 7-9. - Pass check: HeroData rows 1-7 (starting attributes), ArcadeHero and StoryChallengeHero (levels 30, +30 over base for five heroes, Elena -10),
fs_herodata.lua:556-598(enemybase + level - 1, cap 99, one floor),fs_herolist.lua:151-155andcontrollerstorymode.lua:5481-5484(respec resets all heroes); Pierce/Defence start ratios re-derived from the starting-stat table. - Verification: independent reimplementation in
build/wiki/scripts/verify_attributes/w1.pytow8.py(weight tables, starting stats, +10 tables, maxima and presets all re-derived and matching). - Reimplementation and checks:
build/wiki/scripts/attributes/compute.py,snippets.py,marginal.py,presets.py(curve identity across attributes, 207-case comparison with the real Lua).