Add a Ballpark Modifier

In short

A park changes play in two ways. Physics (wind, gravity) comes from BallparkDefinition.GetEnvironment(), which HitPhysics reads for every batted ball. Batter stats come from the park’s batterModifiers list, added to the batter’s stats for every at-bat there. If an existing stat or physics field covers it, no code is needed.

Steps

Using what exists (no code)

In Assets/_Project/Scripts/Data/DefaultContent.cs, set fields on the park:

windy.windMph = 12f;
windy.windDirectionDeg = -30f;   // the direction it blows TOWARD: 0 = out to center, -45 = out to left, 180 = straight in
moon.gravityScale = 0.75f;
midnight.isNight = true;
midnight.batterModifiers.Add(StatModifier.Percent(StatType.TimingWindow, -0.1f));

A new physics modifier

  1. Field. Add it under [Header("Modifiers")] in Assets/_Project/Scripts/Data/BallparkDefinition.cs, with a default that means “no change” (old parks keep playing the same).
  2. Environment. If the ball flight needs it, add a field to struct FlightEnvironment in Ballparks/BallparkMath.cs and fill it in BallparkDefinition.GetEnvironment().
  3. Use it in Batting/HitPhysics.cs (it calls park.GetEnvironment() in its simulation). Other readers of the environment: Ballparks/Scoreboard.cs (gravity for the smashed board’s pieces) and Ballparks/StadiumAmbience.cs (wind for flags and clouds).
  4. Describe it in BallparkDefinition.DescribeModifiers() so the map select card, the map screen briefing, the HUD line and the INDEX’s ballpark entry list it (they all call that method). The match intro card builds its own condition chips (Intro/MatchIntroCard: WIND, GRAVITY, NIGHT GAME and the batter modifiers); add a chip there for a new physics field. See Cutscenes.

A new stat-style modifier

Prefer batterModifiers. If no stat fits, add one (Add a Stat) and put a modifier for it in the park’s batterModifiers. They reach the batter in RunManager.PlayCurrentRound, CoopRun and BattingCage, and DescribeModifiers already lists them.

Check it works

  • Tools → Home Run Derby → Run Run Structure Test checks the dev insta-home-run clears every wall. A physics change that shortens flights (more gravity, wind blowing in) can break that check.
  • Tools → Home Run Derby → Run Scoreboard Smash Test checks normal home runs never reach the scoreboard; a change that lengthens flights can break it.
  • Press Play, use the batting cage on that park (Batting Cage) and F1 → ATTRIBUTES in a run to see stat changes.

Gotchas

  • isNight itself only changes looks (lit lamps, lower sky ambient, the “Night game” line). The night penalty to timing is the separate batterModifiers entry on Midnight Yard.
  • Pitches are not affected by park physics: the pitch path lives in PitchData and ignores wind and gravity. Park effects on pitches are special balls (Add a Special Ball); a park’s boss can add his own ball on top.
  • HitPhysics now also takes a per-hit sideways curve and a gravity scale from the swing (#46: curveAccel, gravityScale on the swing result), which act on top of the park’s wind and gravity. See Hit Physics.
  • Co-op: spectators re-run HitPhysics.Simulate on their own machine from the batter’s swing (AtBatController.Spectate.cs), so a physics change must be the same on every build in the lobby. Bump NetSession.Protocol when you add one (Protocol Versions).