Add a Stat

In short

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

  1. 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)
  2. 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).
  3. Name. Add a case in StatInfo.DisplayName (shown in the build panel, the dev menu and modifier text).
  4. 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.
  5. 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.
  6. 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).