Add a Final Boss

In short

Add the boss pitcher like any other (Add a Pitcher or Boss), then set the park’s finalBossId to its id. That pitcher then always pitches the last inning of runs on that park and never pitches anywhere else: every park’s finalBossId is kept out of the random boss innings on every park. All five run maps have one since #41.

Steps

  1. Create the boss in Assets/_Project/Scripts/Data/DefaultContent.cs with isBoss true and his trick, as in Add a Pitcher or Boss. The real example is The Phantom, Midnight Yard’s boss:
    var phantom = Pitcher("phantom", "BOSS: The Phantom", "Three balls leave his hand. Only one is real: watch the shadows.",
        true, 5, 1f, 0.8f, 1.15f, new Color(0.7f, 0.9f, 1f), (fastball, 2f), (changeup, 2f), (curve, 1f));
    phantom.decoys = 2;
    phantom.decoyChance = 1f / 4f;
    db.pitchers.Add(phantom);
    The other park bosses use minRound 8; it is never read for them, since they are placed, not drawn. A trick can be decoys (above), his own special ball (benny.balls.Add(Ball(BallEffect.Wiffle, 1f / 4f)), see Add a Special Ball) or batterModifiers. Farmer Fitz and The Alien have none yet.
  2. Point the park at it, after the park is created:
    midnight.finalBossId = "phantom";
    Every run map already has one (benny, farmer, gale, phantom, alien), so for an existing park you replace its boss; a new map (Add a Map) gets a new line.
  3. Done. RunMapGenerator.Generate looks the id up (FindPitcher) and puts that pitcher in the last inning. It also collects every park’s finalBossId and leaves all of them out of the random boss pool for innings 3 and 6, on every park.
  4. Cutscenes need nothing. The match intro only plays before inning 1, and the end scenes (MAP BEATEN! after inning 9, GAME OVER, BOSS DOWN! after innings 3 and 6) read the boss’s displayName from the inning (Intro/OutroCard). See Cutscenes. The INDEX lists him under BOSSES automatically (Index Screen).

What the player sees

The last inning’s cell on the map line score says FINAL BOSS, and the briefing pill says FINAL BOSS INNING (UI/RunMapView). The briefing and the HUD also list his own balls and decoys (”• His own …”, PitcherDefinition.DescribeBalls). Beating him ends the run with the MAP BEATEN! cutscene (unless CUTSCENES is off in Settings).

Check it works

  • Tools → Home Run Derby → Run Run Structure Test has ParkBossPitchesTheLastInning: it sets finalBossId = "knuckler" on the second park and checks it pitches inning 9 and not 3 or 6.
  • Tools → Home Run Derby → Run Ball Effect Test has EveryParkHasItsOwnBoss (a fixed park → boss table: add your pair there) and PhantomIsMidnightsFinalBoss.
  • Press Play, start a run on the park, F1 → JUMP TO INNING 9.

Gotchas

  • Make it isBoss = true. The regular-inning pool (!p.isBoss) does not exclude the park’s own boss, so a non-boss pitcher used as a final boss could also show up in ordinary innings.
  • If the last inning is not a multiple of bossEvery, a park with a final boss still makes it a boss inning (boss = ... || (last && own != null)).
  • Reusing a roaming boss shrinks every park’s pool. Setting a park’s finalBossId to The Ace or Knuckle Sandwich removes him from innings 3 and 6 everywhere, not just on that park. With no roaming boss left, the fallbacks reuse bosses and then allow park bosses away from home.
  • A boss can be the final boss of only one park in practice: the code allows two parks to share an id, and he then pitches inning 9 on both.
  • A wrong or unknown id is ignored silently (FindPitcher returns null) and inning 9 is a random boss.
  • The final boss counts as a boss inning for goals (x1.25) and coins (bossBonusCoins).