diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg
index 92b072b4dd3c5b455c939d614b2404172b47e3e5..5dbfbd4e9141441c16271dfe710ee0819abda6da 100644
--- a/extras/conf/SRB2-22.cfg
+++ b/extras/conf/SRB2-22.cfg
@@ -2182,6 +2182,12 @@ linedeftypes
 			prefix = "(461)";
 			flags64text = "[6] Spawn inside a range";
 		}
+
+		462
+		{
+			title = "Stop timer/exit stage in Record Attack";
+			prefix = "(462)";
+		}
 	}
 
 	linedefexecmisc
diff --git a/src/m_menu.c b/src/m_menu.c
index 12e3f6b26f0904d58bb4d29e2801dff7e52d9f56..6a0a31bc1ae947e7ab8ed4828c8c173a94cf9b95 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -3280,12 +3280,14 @@ boolean M_Responder(event_t *ev)
 				 || (currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_SUBMENU)
                  && (currentMenu->menuitems[itemOn].status & IT_CALLTYPE))
 				{
+#ifndef DEVELOP
 					if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata)
 					{
 						S_StartSound(NULL, sfx_skid);
 						M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
 						return true;
 					}
+#endif
 				}
 				S_StartSound(NULL, sfx_menu1);
 				switch (currentMenu->menuitems[itemOn].status & IT_TYPE)
@@ -4636,10 +4638,12 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum)
 			/* FALLTHRU */
 		case LLM_RECORDATTACK:
 		case LLM_NIGHTSATTACK:
+#ifndef DEVELOP
 			if (mapvisited[mapnum] & MV_MAX)
 				return true;
 
 			if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED)
+#endif
 				return true;
 
 			return false;
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 27033acbcaaf1db1f52aeefb50f8c7201908da67..afb6462977e8ebfbf205103953a02816fad4083e 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -3912,10 +3912,16 @@ void A_BossDeath(mobj_t *mo)
 
 	// victory!
 	P_LinedefExecute(LE_ALLBOSSESDEAD, mo, NULL);
+	if (stoppedclock && modeattacking) // if you're just time attacking, skip making the capsule appear since you don't need to step on it anyways.
+		goto bossjustdie;
 	if (mo->flags2 & MF2_BOSSNOTRAP)
 	{
 		for (i = 0; i < MAXPLAYERS; i++)
+		{
+			if (!playeringame[i])
+				continue;
 			P_DoPlayerExit(&players[i]);
+		}
 	}
 	else
 	{
@@ -10557,7 +10563,11 @@ void A_ForceWin(mobj_t *actor)
 		return;
 
 	for (i = 0; i < MAXPLAYERS; i++)
+	{
+		if (!playeringame[i])
+			continue;
 		P_DoPlayerExit(&players[i]);
+	}
 }
 
 // Function: A_SpikeRetract
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 94fcc29879727f110205e10656bcb97f45a81472..e560a4a815c8a2cb7230478ede484490de468728 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -475,4 +475,5 @@ extern boolean runemeraldmanager;
 extern UINT16 emeraldspawndelay;
 extern INT32 numstarposts;
 extern UINT16 bossdisabled;
+extern boolean stoppedclock;
 #endif
diff --git a/src/p_saveg.c b/src/p_saveg.c
index fb2365bf0983e3de1cdb44b813ab9c333cc4bc48..470d3096ede6a7e01382d3d64515fb6a8fa1a982 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -3981,7 +3981,6 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
 
 static void P_NetArchiveMisc(void)
 {
-	UINT32 pig = 0;
 	INT32 i;
 
 	WRITEUINT32(save_p, ARCHIVEBLOCK_MISC);
@@ -3989,9 +3988,12 @@ static void P_NetArchiveMisc(void)
 	WRITEINT16(save_p, gamemap);
 	WRITEINT16(save_p, gamestate);
 
-	for (i = 0; i < MAXPLAYERS; i++)
-		pig |= (playeringame[i] != 0)<<i;
-	WRITEUINT32(save_p, pig);
+	{
+		UINT32 pig = 0;
+		for (i = 0; i < MAXPLAYERS; i++)
+			pig |= (playeringame[i] != 0)<<i;
+		WRITEUINT32(save_p, pig);
+	}
 
 	WRITEUINT32(save_p, P_GetRandSeed());
 
@@ -4003,7 +4005,14 @@ static void P_NetArchiveMisc(void)
 	WRITEUINT16(save_p, bossdisabled);
 
 	WRITEUINT16(save_p, emeralds);
-	WRITEUINT8(save_p, stagefailed);
+	{
+		UINT8 globools = 0;
+		if (stagefailed)
+			globools |= 1;
+		if (stoppedclock)
+			globools |= (1<<1);
+		WRITEUINT8(save_p, globools);
+	}
 
 	WRITEUINT32(save_p, token);
 	WRITEINT32(save_p, sstimer);
@@ -4042,7 +4051,6 @@ static void P_NetArchiveMisc(void)
 
 static inline boolean P_NetUnArchiveMisc(void)
 {
-	UINT32 pig;
 	INT32 i;
 
 	if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
@@ -4061,11 +4069,13 @@ static inline boolean P_NetUnArchiveMisc(void)
 
 	G_SetGamestate(READINT16(save_p));
 
-	pig = READUINT32(save_p);
-	for (i = 0; i < MAXPLAYERS; i++)
 	{
-		playeringame[i] = (pig & (1<<i)) != 0;
-		// playerstate is set in unarchiveplayers
+		UINT32 pig = READUINT32(save_p);
+		for (i = 0; i < MAXPLAYERS; i++)
+		{
+			playeringame[i] = (pig & (1<<i)) != 0;
+			// playerstate is set in unarchiveplayers
+		}
 	}
 
 	P_SetRandSeed(READUINT32(save_p));
@@ -4082,7 +4092,11 @@ static inline boolean P_NetUnArchiveMisc(void)
 	bossdisabled = READUINT16(save_p);
 
 	emeralds = READUINT16(save_p);
-	stagefailed = READUINT8(save_p);
+	{
+		UINT8 globools = READUINT8(save_p);
+		stagefailed = !!(globools & 1);
+		stoppedclock = !!(globools & (1<<1));
+	}
 
 	token = READUINT32(save_p);
 	sstimer = READINT32(save_p);
diff --git a/src/p_setup.c b/src/p_setup.c
index 79391c3e427298bdd977696c09069e6da5ac56fe..aff6c33d711bed5bb54ac2da8773f3f8f396be46 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -104,6 +104,7 @@ side_t *sides;
 mapthing_t *mapthings;
 INT32 numstarposts;
 UINT16 bossdisabled;
+boolean stoppedclock;
 boolean levelloading;
 UINT8 levelfadecol;
 
diff --git a/src/p_spec.c b/src/p_spec.c
index d6a8cb48e4979f2d14ecb29bbbe6b5549ad0e0f0..355f5e72851bc8802a1f2e9434c5aa23a0c97f36 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -3998,6 +3998,24 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 			}
 			break;
 
+		case 462: // Stop clock (and end level in record attack)
+			if (G_PlatformGametype())
+			{
+				stoppedclock = true;
+				CONS_Debug(DBG_GAMELOGIC, "Clock stopped!\n");
+				if (modeattacking)
+				{
+					UINT8 i;
+					for (i = 0; i < MAXPLAYERS; i++)
+					{
+						if (!playeringame[i])
+							continue;
+						P_DoPlayerExit(&players[i]);
+					}
+				}
+			}
+			break;
+
 #ifdef POLYOBJECTS
 		case 480: // Polyobj_DoorSlide
 		case 481: // Polyobj_DoorSwing
@@ -4521,7 +4539,11 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
 
 			// Mark all players with the time to exit thingy!
 			for (i = 0; i < MAXPLAYERS; i++)
+			{
+				if (!playeringame[i])
+					continue;
 				P_DoPlayerExit(&players[i]);
+			}
 			break;
 		}
 		case 10: // Special Stage Time/Rings
@@ -6395,6 +6417,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
 
 	// yep, we do this here - "bossdisabled" is considered an apparatus of specials.
 	bossdisabled = 0;
+	stoppedclock = false;
 
 	// Init special SECTORs.
 	sector = sectors;
diff --git a/src/p_tick.c b/src/p_tick.c
index 6b5c7980c86d7307a460e66111b70d0bad37a23e..e02b11f4907fd5d87bb722467485b0409f66a28e 100644
--- a/src/p_tick.c
+++ b/src/p_tick.c
@@ -678,7 +678,7 @@ void P_Ticker(boolean run)
 
 	if (run)
 	{
-		if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && --countdowntimer <= 0)
+		if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0)
 		{
 			countdowntimer = 0;
 			countdowntimeup = true;
diff --git a/src/p_user.c b/src/p_user.c
index 6a67e329cc09072ec74d5c926ae3c2f6446d8e91..37e3f356883a04d50de7374749c07089780cf489 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -9397,7 +9397,7 @@ static void P_DeathThink(player_t *player)
 	if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame)))
 	{
 		// Keep time rolling in race mode
-		if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER))
+		if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock)
 		{
 			if (gametype == GT_RACE || gametype == GT_COMPETITION)
 			{
@@ -11389,7 +11389,7 @@ void P_PlayerThink(player_t *player)
 	}
 
 	// Synchronizes the "real" amount of time spent in the level.
-	if (!player->exiting)
+	if (!player->exiting && !stoppedclock)
 	{
 		if (gametype == GT_RACE || gametype == GT_COMPETITION)
 		{
diff --git a/src/st_stuff.c b/src/st_stuff.c
index 139303fbbd41b0e07ca5006aa6a60c5a19edfbf4..3fbee27e468ca31501186970bc9cf8f11019f292 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -707,7 +707,7 @@ static void ST_drawTime(void)
 			{
 				if (timelimitintics >= stplyr->realtime)
 				{
-					tics = (timelimitintics - stplyr->realtime);
+					tics = (timelimitintics + (TICRATE-1) - stplyr->realtime);
 					if (tics < 3*TICRATE)
 						ST_drawRaceNum(tics);
 				}
@@ -740,10 +740,12 @@ static void ST_drawTime(void)
 	if (F_GetPromptHideHud(hudinfo[HUD_TIME].y))
 		return;
 
+	downwards = (downwards && (tics < 30*TICRATE) && (leveltime/5 & 1) && !stoppedclock); // overtime?
+
 	// TIME:
-	ST_DrawPatchFromHud(HUD_TIME, ((downwards && (tics < 30*TICRATE) && (leveltime/5 & 1)) ? sboredtime : sbotime), V_HUDTRANS);
+	ST_DrawPatchFromHud(HUD_TIME, (downwards ? sboredtime : sbotime), V_HUDTRANS);
 
-	if (!tics && downwards && (leveltime/5 & 1)) // overtime!
+	if (downwards) // overtime!
 		return;
 
 	if (cv_timetic.value == 3) // Tics only -- how simple is this?