Pascal's Wager Wiki

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#

HeroStrengthDexterityVigorIntellectVitalityEnduranceSumHidden
Terrence1591481312711
Viola91513111014721
Benita11121415109711
Norwood1381561314691
Jerold10814121214701
The First Messenger101010102110711
Elena108341222241101

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):

SlotScript nameWiki nameMain role
1StrengthStrengthAttack for Terrence, Norwood and the First Messenger; a little Defence and resistance for everyone
2SpiritDexterityCrit rate and Crit damage for every hero; Viola's Attack
3BraveVigorHealth and both shield capacities
4DexterousIntellectElemental and Pierce resistance; Benita's Attack and Crit damage
5TolerantVitalityPhysical Defence (main source) and Pierce resistance
6GenerousEnduranceStamina; Jerold's and Elena's Attack
7Hidden(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 )
  • weight comes from the HeroPropertyData table (Attribute_1 to Attribute_7 columns). It is in per mille: 850 means "85% of the curve".
  • curve comes from the HeroAttributeData table, indexed by attribute number, the score (1 to 99) and the stat (Property_1 to Property_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:

FamilyStats that use it
Attack-typePhysical Attack, and the Fire, Poison, Arcane and Dark attack stats
Defence-typePhysical Defence, the four elemental resistances, Pierce resistance
Crit damageCrit damage
Crit rateCrit rate
HealthHealth
StaminaStamina
ShieldsTrophy shield and Skill shield (nearly the Health curve)
Soul DewSoul Dew (property 7, internal name Mp), used only by the First Messenger
PointsAttack-typeDefence-typeCrit damageCrit rateHealthStaminaShields
1252620050581291581
5343620554667334667
10464821259800400800
15687122064984488991
2093982296911865731264
251201262377413796371502
301451522497915246881653
351611692618416077251736
401701792778916807501809
451791882989417357731864
501831923169917767931905
6019120134210918218151950
7019520535911918378231966
8019620637412918508301979
9920021040014818718402000

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#

StatStrengthDexterityVigorIntellectVitalityEnduranceTotal weight
Attack (physical)85%5%----90%
Crit damage20%75%----95%
Crit rate-60%----60%
Health--90%---90%
Defence25%5%10%-60%-100%
Stamina-----70%70%
Fire / Poison / Arcane / Dark resistance15%10%10%60%5%-100%
Pierce resistance---250%250%-500%
Trophy shield and Skill shield--90%---90%

Viola#

StatStrengthDexterityVigorIntellectVitalityEnduranceTotal weight
Attack (physical)20%70%----90%
Crit damage10%130%----140%
Crit rate-100%----100%
Health--80%---80%
Defence25%5%5%-45%-80%
Stamina-----85%85%
Fire / Poison / Arcane / Dark resistance15%10%10%60%5%-100%
Pierce resistance---250%250%-500%
Trophy shield and Skill shield--80%---80%

Benita#

StatStrengthDexterityVigorIntellectVitalityEnduranceTotal weight
Attack (physical)20%2.5%2.5%100%--125%
Crit damage5%35%-85%--125%
Crit rate-80%----80%
Health--90%---90%
Defence25%5%5%-50%-85%
Stamina-----80%80%
Fire / Poison / Arcane / Dark resistance15%10%10%50%5%-90%
Pierce resistance---250%250%-500%
Trophy shield and Skill shield--95%---95%

Norwood#

StatStrengthDexterityVigorIntellectVitalityEnduranceTotal weight
Attack (physical)100%-----100%
Crit damage10%60%----70%
Crit rate-40%----40%
Health--100%---100%
Defence10%10%5%-75%-100%
Stamina-----75%75%
Fire / Poison / Arcane / Dark resistance10%10%5%40%5%-70%
Pierce resistance---250%250%-500%
Trophy shield and Skill shield--95%---95%

Jerold#

StatStrengthDexterityVigorIntellectVitalityEnduranceTotal weight
Attack (physical)20%----84%104%
Crit damage35%60%---25%120%
Crit rate-60%---10%70%
Health--87.5%---87.5%
Defence20%10%--67.5%-97.5%
Stamina-----60%60%
Fire / Poison / Arcane / Dark resistance10%15%-60%-15%100%
Pierce resistance---250%250%-500%
Trophy shield and Skill shield--95%---95%

Elena#

StatStrengthDexterityVigorIntellectVitalityEnduranceTotal weight
Attack (physical)20%----84%104%
Crit damage35%60%---25%120%
Crit rate-60%---10%70%
Health--87.5%---87.5%
Defence20%10%--67.5%-97.5%
Stamina-----60%60%
Fire / Poison / Arcane / Dark resistance10%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 statTerrenceViolaBenitaNorwoodJeroldElena
Stamina regen while guarding (per mille/s)100100100100100100
Sanity100100100100100100
Rage decay (per mille/s; only Norwood and Jerold ever apply it, see Rage#Decay)100100100506060
Power100100100100100100
Poise regen (per mille/s)0240240240240240
Stamina regen (per mille/s)400400400400400400
Rage100100100100100100
Stamina exhaustion time value1001001001009292
Power regen (per mille/s)000066
Power decay (per mille/s)505050505050
Resilience (Weakness)100001000010000100001000010000
Resilience regen (per mille/s)100000100000100000100000100000100000

Poise itself (property 13) has no attribute weight at all; see Hidden mechanics.

Starting stats#

Stat at startTerrenceViolaBenitaNorwoodJeroldElena
Attack5956805862104
Crit damage201307272147254258
Crit rate346448224041
Health8497248499848261392
Defence633943595286
Stamina303398308351281375
Elemental resistance505458325563
Pierce resistance260252297247285412
Shield capacity8517248989418981634

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 +10TerrenceViolaBenitaNorwoodJeroldElena
StrengthAtk +45, CritDmg +3, Def +13, Res +8Atk +9, CritDmg +1, Def +12, Res +7Atk +10, CritDmg +1, Def +12, Res +7Atk +50, CritDmg +1, Def +5, Res +5Atk +9, CritDmg +6, Def +10, Res +5Atk +10, CritDmg +6, Def +10, Res +5
DexterityAtk +3, CritDmg +13, CritRate +6, Def +2, Res +5Atk +36, CritDmg +22, CritRate +10, Def +3, Res +5Atk +2, CritDmg +6, CritRate +8, Def +2, Res +5CritDmg +9, CritRate +4, Def +5, Res +4CritDmg +9, CritRate +6, Def +4, Res +6CritDmg +9, CritRate +6, Def +5, Res +7
VigorHP +358, Def +5, Res +6, Shield +462HP +319, Def +3, Res +5, Shield +406Atk +2, HP +358, Def +3, Res +5, Shield +488HP +395, Def +3, Res +2, Shield +485HP +348, Shield +488HP +118, Shield +128
IntellectRes +27Res +30Atk +52, CritDmg +15, Res +27Res +15Res +30Res +31
VitalityDef +31, Res +3Def +22, Res +2Def +25, Res +2Def +39, Res +2Def +34Def +36
EnduranceStam +117Stam +133Stam +138Stam +117Atk +42, CritDmg +4, CritRate +1, Stam +94, Res +8Atk +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 +10TerrenceViolaBenitaNorwoodJeroldElena
StrengthAtk +11, CritDmg +7, Def +3, Res +1Atk +2, CritDmg +4, Def +3, Res +1Atk +3, CritDmg +2, Def +3, Res +2Atk +13, CritDmg +4, Def +1, Res +1Atk +3, CritDmg +14, Def +3, Res +1Atk +3, CritDmg +14, Def +3, Res +1
DexterityCritDmg +29, CritRate +6, Res +1Atk +9, CritDmg +51, CritRate +10, Res +1CritDmg +13, CritRate +8, Res +1CritDmg +24, CritRate +4, Def +1, Res +1CritDmg +23, CritRate +6, Def +1, Res +1CritDmg +23, CritRate +6, Def +1, Res +1
VigorHP +86, Def +1, Res +1, Shield +86HP +76, Res +1, Shield +77HP +86, Res +1, Shield +91HP +96, Shield +91HP +84, Shield +91HP +84, Shield +91
IntellectRes +7Res +7Atk +13, CritDmg +33, Res +6Res +5Res +7Res +7
VitalityDef +7Def +6Def +6Def +9Def +9Def +9
EnduranceStam +30Stam +37Stam +34Stam +32Atk +11, CritDmg +10, CritRate +1, Stam +25, Res +1Atk +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:

HeroAttackCrit damageCrit rateHealthDefenceStaminaElemental res.Pierce res.Shield
Terrence18038088168321058821010501800
Viola180560148149616871421010501600
Benita250500118168317867218910501900
Norwood20028059187121063014710501900
Jerold, Elena208480103163720450421010501900
The First Messenger5604000243227384031521002000

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.lua 9272; Altars#What the altar menu offers). The page refuses to add a point once the attribute shows 99 (playerinfoctrl.lua 1593, 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.lua 10615-10642).
  • Respec. FS_HeroData:ResetAttribute sets every spent point back to 0 and refunds level - 1 points. The only caller in the game scripts is the story-quest action ResetAttribute (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.

HeroStrengthDexterityVigorIntellectVitalityEnduranceHealthAttackDefence
Terrence2892181322110211684
Viola9341811102088411945
Benita141520201220106710953
Norwood3082261518126514578
Jerold141420121327103712160
Elena141420121327103712160

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 pointsHero curveEnemy curve
Attack200456
Health18714320
Defence210200
Crit damage400250
Crit rate148100

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.lua 1826-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).
  • The hidden attribute decides class identity. Norwood's Rage decay value is half of Terrence's (50 against 100 per mille per second), and Jerold's and Elena's is 60. Only Norwood and Jerold use theirs: the game calls DecrementRage only for those two heroes, so Elena's Rage never drains (her Power decays instead) and the 100 of Terrence, Viola and Benita is never applied (Rage#Decay). Jerold and Elena also have a Stamina exhaustion value of 92 instead of 100, which adds a 0.8 second lock after the bar hits zero (Stamina). You cannot change any of these: the hidden attribute is not on the Stats page and the save always writes it as 0 added points.
  • 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): attribPoints rises by exactly 1 per level-up (playerinfoctrl.lua 10595) 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#

  • TrophyProperty and TrophyRandomProperty PropertyType 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 (AttributeMax 7, AttributeValueMax 99), 62 (PropertyMax 42).
  • luascript/structdata/ms_heroattributedata.lua: 6 (AttributePointMax 200), 22-33 (the lookup that returns 0 for a missing row).
  • luascript/logic/playervalue/hero10004_value.lua:15 and hero10005_value.lua:15 (the only callers of DecrementRage, defined at animalbase_value.lua:1586); hero10007_value.lua:19 (Elena's Power decay).
  • luascript/logic/playervalue/animalbase_value.lua: 1561-1625 (stamina delay (100 - value) / 10 s, and the regen/decay ticks), 178 (enemy and unsaved-hero base stats), 2429 (Crit rate read).
  • gamedata/playerdefine/animalbase_value_define.lua (outside luascript/): 23 (CasualToughnessAdd 130).
  • 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_1 to Attribute_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 (enemy base + level - 1, cap 99, one floor), fs_herolist.lua:151-155 and controllerstorymode.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.py to w8.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).