Stats are the numbers on the batter that everything else changes (batters, upgrades, synergies, parks, bosses all
give StatModifiers). A new stat is a StatType value, a base value and a name in StatInfo, and one place in the
game code that reads it with stats.Get(StatType.X). Without that last step the stat does nothing.
Steps
Enum value. Add it at the end of enum StatType in Assets/_Project/Scripts/Stats/StatType.cs, with a
comment saying what it does:
GreenStreakBonus // extra home run score per green in a row before this one (0.1 = +10% each)
Base value. Add a case in StatInfo.BaseValue if it is not 0 (Power, Contact and HR Multiplier start at 1,
Timing Window at 0.11, Green HR Score at 0.25).
Name. Add a case in StatInfo.DisplayName (shown in the build panel, the dev menu and modifier text).
Format. Add a case in StatInfo.Format if x1.00 is the wrong look (ms, degrees, whole numbers, %). If a
modifier for it should read differently too, add a line in StatModifier.Describe.
Read it where it matters, from the PlayerStats of the at-bat:
int perHomeRun = config.coinsPerHomeRun + run.Stats.GetInt(StatType.CoinBonus); // RunManager.InningCoins
Today’s readers: SwingResolver (Power, Contact, TimingWindow, LaunchBonus), ScoreCalculator (HomeRunMultiplier,
GreenBonus, GreenStreakBonus), Batting/HitTally (HomeRunMultiplier, for the hit counter), RunManager
(ExtraOuts, CoinBonus), CoopRun (ExtraOuts), ShopService (RerollDiscount). What each one does now that batting
works Mario Superstar Baseball style (#46) is in Stats and Batting Explained.
Give it to something: an upgrade, synergy, batter, park or boss modifier
(StatModifier.Add(StatType.X, 1f) or StatModifier.Percent(StatType.X, 0.1f)).
Numbers
PlayerStats.Get: final = (BaseValue + sum of Adds) x max(0, 1 + sum of Percents). GetInt rounds that.
Check it works
Press Play, start a run, F1 → ATTRIBUTES lists every stat (StatInfo.All) and turns it yellow when it
differs from the base. GIVE AN UPGRADE that carries it to see it move.
The STATS list in the build panel (map and shop screens) shows it automatically.
Gotchas
Append, never insert or reorder.StatModifier.stat is stored as a number in exported assets; inserting a value
shifts every stat after it.
Percent modifiers on a stat with base 0 do nothing unless something adds to it first (0 x anything = 0).
The main menu batter card only draws bars for Power, Contact and Timing (MainMenuView), so a new stat doesn’t
appear there unless you add it.
The match intro’s player card (Intro/MatchIntroCard) shows Power, Contact, Timing Window and HR Multiplier always,
and Launch Angle, Extra Outs, Coins per HR, Green HR Score and Green Streak Score only when they differ from base. Add
a new stat to ShownWhenChanged (or AlwaysShown) to list it there.
Co-op: stats are computed on each player’s own machine. If the stat changes a co-op rule (like ExtraOuts does
through CoopRules.OutsForTurn), bump NetSession.Protocol (Protocol Versions).