diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp
index e91c18105..2c1ea2998 100644
--- a/source/blood/src/blood.cpp
+++ b/source/blood/src/blood.cpp
@@ -737,7 +737,6 @@ void GameInterface::app_init()
     WeaponInit();
     LoadSaveSetup();
     LoadSavedInfo();
-    timerInit(120);
 
     Printf(PRINT_NONOTIFY, "Initializing network users\n");
     netInitialize(true);
diff --git a/source/build/include/build.h b/source/build/include/build.h
index d8a20dee5..12857cb38 100644
--- a/source/build/include/build.h
+++ b/source/build/include/build.h
@@ -364,8 +364,6 @@ EXTERN struct validmode_t validmode[MAXVALIDMODES];
 EXTERN int32_t Numsprites;
 EXTERN int16_t numsectors, numwalls;
 EXTERN int32_t display_mirror;
-EXTERN ClockTicks totalclock;
-static inline int32_t BGetTime(void) { return (int32_t) totalclock; }
 
 EXTERN int32_t randomseed;
 EXTERN int16_t sintable[2048];
@@ -596,12 +594,9 @@ TILE VARIABLES:
         NUMTILES - the number of tiles found TILES.DAT.
 
 TIMING VARIABLES:
-        TOTALCLOCK - When the engine is initialized, TOTALCLOCK is set to zero.
-            From then on, it is incremented 120 times a second by 1.  That
-            means that the number of seconds elapsed is totalclock / 120.
         NUMFRAMES - The number of times the draw3dscreen function was called
             since the engine was initialized.  This helps to determine frame
-            rate.  (Frame rate = numframes * 120 / totalclock.)
+            rate.  (Frame rate = numframes * 120 / I_GetBuildTime().)
 
 OTHER VARIABLES:
 
diff --git a/source/build/include/timer.h b/source/build/include/timer.h
index bebe974ac..3d629abb4 100644
--- a/source/build/include/timer.h
+++ b/source/build/include/timer.h
@@ -8,8 +8,6 @@
 // for compatibility
 #define timerUninit()
 
-int      timerInit(int const tickspersecond);
-void     timerUpdateClock(void);
 double   timerGetHiTicks(void);
 uint32_t timerGetTicks(void);
 
diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp
index 380a9683f..b46d8a77f 100644
--- a/source/build/src/engine.cpp
+++ b/source/build/src/engine.cpp
@@ -1127,7 +1127,6 @@ int32_t engineInit(void)
 
     searchit = 0; searchstat = -1;
 
-    totalclock = 0;
     g_visibility = 512;
     parallaxvisibility = 512;
 
diff --git a/source/build/src/timer.cpp b/source/build/src/timer.cpp
index 6328f68e7..b6cb31446 100644
--- a/source/build/src/timer.cpp
+++ b/source/build/src/timer.cpp
@@ -20,25 +20,3 @@ uint32_t timerGetTicks(void)    { return duration_cast<milliseconds>(steady_cloc
 // Returns the time since an unspecified starting time in milliseconds.
 // (May be not monotonic for certain configurations.)
 double timerGetHiTicks(void) { return duration<double, nano>(steady_clock::now().time_since_epoch()).count() / 1000000.0; }
-
-int timerInit(int const tickspersecond)
-{
-    timerticspersec = tickspersecond;
-    timerlastsample = steady_clock::now();
-    return 0;
-}
-
-void timerUpdateClock(void)
-{
-    auto time = steady_clock::now();
-    auto elapsedTime = time - timerlastsample;
-
-    uint64_t numerator = (elapsedTime.count() * (uint64_t) timerticspersec * steady_clock::period::num);
-    uint64_t freq = steady_clock::period::den;
-    int n = numerator / freq;
-
-    if (n <= 0) return;
-
-    totalclock += n;
-    timerlastsample += n*nanoseconds(1000000000/timerticspersec);
-}
diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp
index 62b6bff0d..0ea0b6b4f 100644
--- a/source/core/gamecontrol.cpp
+++ b/source/core/gamecontrol.cpp
@@ -914,8 +914,6 @@ void app_loop()
 	{
 		try
 		{
-			timerUpdateClock();
-
 			TickSubsystems();
 			twod->SetSize(screen->GetWidth(), screen->GetHeight());
 			twodpsp.SetSize(screen->GetWidth(), screen->GetHeight());
diff --git a/source/core/raze_sound.cpp b/source/core/raze_sound.cpp
index 166fe7709..bb5ba4e63 100644
--- a/source/core/raze_sound.cpp
+++ b/source/core/raze_sound.cpp
@@ -242,8 +242,8 @@ void S_SerializeSounds(FSerializer& arc)
 			}
 			arc.EndArray();
 		}
-		// totalclock runs on 120 fps, we need to allow a small delay here.
-		soundEngine->SetRestartTime((int)totalclock + 6);
+		// Build runs at 120 fps, we need to allow a small delay here.
+		soundEngine->SetRestartTime(I_GetBuildTime() + 6);
 	}
 	GSnd->Sync(false);
 	GSnd->UpdateSounds();
diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp
index 6822bd7d2..3487d0a95 100644
--- a/source/exhumed/src/exhumed.cpp
+++ b/source/exhumed/src/exhumed.cpp
@@ -548,8 +548,6 @@ void ExitGame()
 void InitTimer()
 {
     htimer = 1;
-
-    timerInit(kTimerTicks);
 }
 
 static const char* actions[] =
diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp
index 33fbcb991..66e02cad2 100644
--- a/source/games/duke/src/sounds.cpp
+++ b/source/games/duke/src/sounds.cpp
@@ -353,7 +353,7 @@ void S_Update(void)
 	}
 	listener.ListenerObject = ud.camerasprite == -1 ? nullptr : &sprite[ud.camerasprite];
 	soundEngine->SetListener(listener);
-	soundEngine->UpdateSounds(totalclock);
+	soundEngine->UpdateSounds(gameclock);
 }
 
 
diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp
index ea71f9b3f..c88d33eaa 100644
--- a/source/sw/src/game.cpp
+++ b/source/sw/src/game.cpp
@@ -245,7 +245,6 @@ void GameInterface::app_init()
 
         paletteSetColorTable(DREALMSPAL, pal.Data(), true, true);
     }
-    timerInit(120);
     InitPalette();
     // sets numplayers, connecthead, connectpoint2, myconnectindex
 
diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp
index 09f266a63..fb0e2db9f 100644
--- a/source/sw/src/sounds.cpp
+++ b/source/sw/src/sounds.cpp
@@ -604,7 +604,7 @@ void DoUpdateSounds(void)
     soundEngine->SetListener(listener);
 
     UpdateAmbients();
-    soundEngine->UpdateSounds(totalclock);
+    soundEngine->UpdateSounds(I_GetBuildTime());
 }
 
 //==========================================================================