diff --git a/src/baserunning.lua b/src/baserunning.lua
index c006c4f..c3812e1 100644
--- a/src/baserunning.lua
+++ b/src/baserunning.lua
@@ -14,11 +14,12 @@
 ---@field batter Runner | nil
 ---@field outs number
 ---@field announcer Announcer
+---@field onThirdOut fun()
 Baserunning = {}
 
 ---@param announcer any
 ---@return Baserunning
-function Baserunning.new(announcer)
+function Baserunning.new(announcer, onThirdOut)
     local o = setmetatable({
         runners = {},
         outRunners = {},
@@ -28,6 +29,7 @@ function Baserunning.new(announcer)
         --- it seems sensible to store the value here.
         outs = 0,
         announcer = announcer,
+        onThirdOut = onThirdOut,
     }, { __index = Baserunning })
 
     o.batter = o:newRunner()
@@ -37,7 +39,7 @@ end
 
 ---@param runner integer | Runner
 ---@param message string | nil
----@return boolean wasFinalOut
+---@return boolean wasThirdOut
 function Baserunning:outRunner(runner, message)
     self.outs = self.outs + 1
     if type(runner) ~= "number" then
@@ -59,6 +61,7 @@ function Baserunning:outRunner(runner, message)
     if self.outs < 3 then
         return false
     end
+    self.onThirdOut()
     self.outs = 0
 
     -- TODO: outRunners/scoredRunners split
@@ -69,6 +72,8 @@ function Baserunning:outRunner(runner, message)
     return true
 end
 
+---@param fielder Fielder
+---@return boolean outedSomeRunner
 function Baserunning:outEligibleRunners(fielder)
     local touchedBase = utils.isTouchingBase(fielder.x, fielder.y)
     local didOutRunner = false
@@ -82,8 +87,8 @@ function Baserunning:outEligibleRunners(fielder)
             -- Tag out
             or not runnerOnBase and utils.distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < C.TagDistance
         then
-            local wasFinalOut = self:outRunner(i)
-            if wasFinalOut then
+            local wasThirdOut = self:outRunner(i)
+            if wasThirdOut then
                 return true -- Don't keep running up self.outs after it's been reset
             end
             didOutRunner = true
@@ -171,6 +176,7 @@ function Baserunning:updateRunner(runner, runnerIndex, appliedSpeed, deltaSecond
     local nb = runner.nextBase
     local x, y, distance = utils.normalizeVector(runner.x, runner.y, nb.x, nb.y)
 
+    -- TODO: Do a better job drifting runners toward their bases when appliedSpeed is low/zero
     if distance < 2 then
         runner.nextBase = C.NextBaseMap[runner.nextBase]
         runner.forcedTo = nil
diff --git a/src/main.lua b/src/main.lua
index 9c1f863..2f8350f 100644
--- a/src/main.lua
+++ b/src/main.lua
@@ -40,9 +40,7 @@ import 'draw/fielder.lua'
 local gfx <const>, C <const> = playdate.graphics, C
 
 local announcer = Announcer.new()
-local baserunning = Baserunning.new(announcer)
 local fielding = Fielding.new()
-local npc = Npc.new(baserunning.runners, fielding.fielders)
 
 ---@alias SimpleAnimator { currentValue: fun(self): number; reset: fun(self, durationMs: number | nil) }
 
@@ -170,14 +168,8 @@ local function pitch(pitchFlyTimeMs, pitchTypeIndex)
     secondsSincePitchAllowed = 0
 end
 
----@param runner integer | Runner
----@param message string | nil
-local function outRunner(runner, message)
-    local wasFinalOut = baserunning:outRunner(runner, message)
-    if not wasFinalOut then
-        return
-    end
-
+local function nextHalfInning()
+    pitchTracker:reset()
     local currentlyFieldingTeam = battingTeam == teams.home and teams.away or teams.home
     local gameOver = inning == 9 and teams.away.score ~= teams.home.score
     if not gameOver then
@@ -202,6 +194,9 @@ local function outRunner(runner, message)
     end)
 end
 
+local baserunning = Baserunning.new(announcer, nextHalfInning)
+local npc = Npc.new(baserunning.runners, fielding.fielders)
+
 ---@param scoredRunCount number
 local function score(scoredRunCount)
     battingTeam.score = battingTeam.score + scoredRunCount
@@ -264,7 +259,7 @@ end
 local function strikeOut()
     local outBatter = baserunning.batter
     baserunning.batter = nil
-    outRunner(outBatter --[[@as Runner]], "Strike out!")
+    baserunning:outRunner(outBatter --[[@as Runner]], "Strike out!")
     nextBatter()
 end