diff --git a/src/doomstat.h b/src/doomstat.h
index 84939a8db7d7400edf1b51c5b6f2a9d330076fb3..877f5b50b72fda0b81838200562a88bea305c83e 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -435,7 +435,6 @@ typedef struct
 	tic_t time;   ///< Time in which the level was finished.
 	UINT32 score; ///< Score when the level was finished.
 	UINT16 rings; ///< Rings when the level was finished.
-	boolean gotperfect; ///< Got perfect bonus?
 } recorddata_t;
 
 /** Setup for one NiGHTS map.
diff --git a/src/g_game.c b/src/g_game.c
index 7084ce9b36de08e87c50e24059e58cf3c9328cb6..2fa70353edce5045b1dd8b91851be3efc75e73dd 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -540,11 +540,99 @@ void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare)
 		ntemprecords.nummares = mare;
 }
 
+//
+// G_UpdateRecordReplays
+//
+// Update replay files/data, etc. for Record Attack
+// See G_SetNightsRecords for NiGHTS Attack.
+//
+static void G_UpdateRecordReplays(void)
+{
+	const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
+	char *gpath;
+	char lastdemo[256], bestdemo[256];
+	UINT8 earnedEmblems;
+
+	// Record new best time
+	if (!mainrecords[gamemap-1])
+		G_AllocMainRecordData(gamemap-1);
+
+	if (players[consoleplayer].score > mainrecords[gamemap-1]->score)
+		mainrecords[gamemap-1]->score = players[consoleplayer].score;
+
+	if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time))
+		mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
+
+	if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings)
+		mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
+
+	// Save demo!
+	bestdemo[255] = '\0';
+	lastdemo[255] = '\0';
+	G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings));
+	G_CheckDemoStatus();
+
+	I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
+	I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755);
+
+	if ((gpath = malloc(glen)) == NULL)
+		I_Error("Out of memory for replay filepath\n");
+
+	sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
+	snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
+
+	if (FIL_FileExists(lastdemo))
+	{
+		UINT8 *buf;
+		size_t len = FIL_ReadFile(lastdemo, &buf);
+
+		snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
+		if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
+		{ // Better time, save this demo.
+			if (FIL_FileExists(bestdemo))
+				remove(bestdemo);
+			FIL_WriteFile(bestdemo, buf, len);
+			CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
+		}
+
+		snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
+		if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
+		{ // Better score, save this demo.
+			if (FIL_FileExists(bestdemo))
+				remove(bestdemo);
+			FIL_WriteFile(bestdemo, buf, len);
+			CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo);
+		}
+
+		snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
+		if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2)))
+		{ // Better rings, save this demo.
+			if (FIL_FileExists(bestdemo))
+				remove(bestdemo);
+			FIL_WriteFile(bestdemo, buf, len);
+			CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW MOST RINGS!"), M_GetText("Saved replay as"), bestdemo);
+		}
+
+		//CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo);
+
+		Z_Free(buf);
+	}
+	free(gpath);
+
+	// Check emblems when level data is updated
+	if ((earnedEmblems = M_CheckLevelEmblems()))
+		CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
+
+	// Update timeattack menu's replay availability.
+	Nextmap_OnChange();
+}
+
 void G_SetNightsRecords(void)
 {
 	INT32 i;
 	UINT32 totalscore = 0;
 	tic_t totaltime = 0;
+	UINT8 earnedEmblems;
 
 	const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
 	char *gpath;
@@ -644,6 +732,9 @@ void G_SetNightsRecords(void)
 	}
 	free(gpath);
 
+	if ((earnedEmblems = M_CheckLevelEmblems()))
+		CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
+
 	// If the mare count changed, this will update the score display
 	Nextmap_OnChange();
 }
@@ -3118,12 +3209,51 @@ static INT16 RandMap(INT16 tolflags, INT16 pprevmap)
 	return ix;
 }
 
+//
+// G_UpdateVisited
+//
+static void G_UpdateVisited(void)
+{
+	boolean spec = G_IsSpecialStage(gamemap);
+	// Update visitation flags?
+	if ((!modifiedgame || savemoddata) // Not modified
+		&& !multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode
+		&& !(spec && stagefailed)) // Not failed the special stage
+	{
+		UINT8 earnedEmblems;
+
+		// Update visitation flags
+		mapvisited[gamemap-1] |= MV_BEATEN;
+		// eh, what the hell
+		if (ultimatemode)
+			mapvisited[gamemap-1] |= MV_ULTIMATE;
+		// may seem incorrect but IS possible in what the main game uses as special stages, and nummaprings will be -1 in NiGHTS
+		if (nummaprings > 0 && players[consoleplayer].rings >= nummaprings)
+			mapvisited[gamemap-1] |= MV_PERFECT;
+		if (!spec)
+		{
+			// not available to special stages because they can only really be done in one order in an unmodified game, so impossible for first six and trivial for seventh
+			if (ALL7EMERALDS(emeralds))
+				mapvisited[gamemap-1] |= MV_ALLEMERALDS;
+		}
+
+		if (modeattacking == ATTACKING_RECORD)
+			G_UpdateRecordReplays();
+		else if (modeattacking == ATTACKING_NIGHTS)
+			G_SetNightsRecords();
+
+		if ((earnedEmblems = M_CompletionEmblems()))
+			CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
+	}
+}
+
 //
 // G_DoCompleted
 //
 static void G_DoCompleted(void)
 {
 	INT32 i;
+	boolean spec = G_IsSpecialStage(gamemap);
 
 	tokenlist = 0; // Reset the list
 
@@ -3156,14 +3286,14 @@ static void G_DoCompleted(void)
 		nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1);
 
 	// Remember last map for when you come out of the special stage.
-	if (!G_IsSpecialStage(gamemap))
+	if (!spec)
 		lastmap = nextmap;
 
 	// If nextmap is actually going to get used, make sure it points to
 	// a map of the proper gametype -- skip levels that don't support
 	// the current gametype. (Helps avoid playing boss levels in Race,
 	// for instance).
-	if (!token && !G_IsSpecialStage(gamemap)
+	if (!token && !spec
 		&& (nextmap >= 0 && nextmap < NUMMAPS))
 	{
 		register INT16 cm = nextmap;
@@ -3227,7 +3357,7 @@ static void G_DoCompleted(void)
 			gottoken = false;
 	}
 
-	if (G_IsSpecialStage(gamemap) && !gottoken)
+	if (spec && !gottoken)
 		nextmap = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001
 
 	automapactive = false;
@@ -3246,17 +3376,29 @@ static void G_DoCompleted(void)
 	if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
 		P_AllocMapHeader(nextmap);
 
-	if (skipstats && !modeattacking) // Don't skip stats if we're in record attack
+	if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed))
+	{
+		G_UpdateVisited();
 		G_AfterIntermission();
+	}
 	else
 	{
 		G_SetGamestate(GS_INTERMISSION);
 		Y_StartIntermission();
+		G_UpdateVisited();
 	}
 }
 
 void G_AfterIntermission(void)
 {
+	Y_CleanupScreenBuffer();
+
+	if (modeattacking)
+	{
+		M_EndModeAttackRun();
+		return;
+	}
+
 	HU_ClearCEcho();
 
 	if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene.
@@ -3423,7 +3565,6 @@ void G_LoadGameData(void)
 	UINT32 recscore;
 	tic_t  rectime;
 	UINT16 recrings;
-	boolean gotperf;
 
 	UINT8 recmares;
 	INT32 curmare;
@@ -3521,7 +3662,7 @@ void G_LoadGameData(void)
 		recscore = READUINT32(save_p);
 		rectime  = (tic_t)READUINT32(save_p);
 		recrings = READUINT16(save_p);
-		gotperf = (boolean)READUINT8(save_p);
+		save_p++; // compat
 
 		if (recrings > 10000 || recscore > MAXSCORE)
 			goto datacorrupt;
@@ -3533,9 +3674,6 @@ void G_LoadGameData(void)
 			mainrecords[i]->time = rectime;
 			mainrecords[i]->rings = recrings;
 		}
-
-		if (gotperf)
-			mainrecords[i]->gotperfect = gotperf;
 	}
 
 	// Nights records
@@ -3667,15 +3805,14 @@ void G_SaveGameData(void)
 			WRITEUINT32(save_p, mainrecords[i]->score);
 			WRITEUINT32(save_p, mainrecords[i]->time);
 			WRITEUINT16(save_p, mainrecords[i]->rings);
-			WRITEUINT8(save_p, mainrecords[i]->gotperfect);
 		}
 		else
 		{
 			WRITEUINT32(save_p, 0);
 			WRITEUINT32(save_p, 0);
 			WRITEUINT16(save_p, 0);
-			WRITEUINT8(save_p, 0);
 		}
+		WRITEUINT8(save_p, 0); // compat
 	}
 
 	// NiGHTS records
diff --git a/src/m_menu.c b/src/m_menu.c
index 9ffc1150cea886fd89a5eabf3996c7e73a350bd8..52ee6b4103d74be4dca1a1a2ca575e57ffca2c3c 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -9243,10 +9243,7 @@ void M_DrawTimeAttackMenu(void)
 
 		V_DrawString(104-72, 73+lsheadingheight/2, V_YELLOWMAP, "RINGS:");
 
-		if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->gotperfect)
-			V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE, beststr);
-		else
-			V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|V_YELLOWMAP, beststr);
+		V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|((mapvisited[cv_nextmap.value-1] & MV_PERFECT) ? V_YELLOWMAP : 0), beststr);
 
 		V_DrawRightAlignedString(104+72, 83+lsheadingheight/2, V_ALLOWLOWERCASE, reqrings);
 	}
diff --git a/src/y_inter.c b/src/y_inter.c
index 48d08a02e59532ebb1a3c04a489122a6f328bb41..32548d26369e7c7afe1509ef5b7213045c9dbaaa 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -166,13 +166,11 @@ static INT32 endtic = -1;
 intertype_t intertype = int_none;
 
 static void Y_RescaleScreenBuffer(void);
-static void Y_CleanupScreenBuffer(void);
 static void Y_AwardCoopBonuses(void);
 static void Y_AwardSpecialStageBonus(void);
 static void Y_CalculateCompetitionWinners(void);
 static void Y_CalculateTimeRaceWinners(void);
 static void Y_CalculateMatchWinners(void);
-static void Y_FollowIntermission(void);
 static void Y_UnloadData(void);
 
 // Stuff copy+pasted from st_stuff.c
@@ -293,7 +291,7 @@ static void Y_RescaleScreenBuffer(void)
 //
 // Free all related memory.
 //
-static void Y_CleanupScreenBuffer(void)
+void Y_CleanupScreenBuffer(void)
 {
 	// Who knows?
 	if (y_buffer == NULL)
@@ -819,7 +817,7 @@ void Y_IntermissionDrawer(void)
 			}
 		}
 	}
-	else if (intertype == int_classicrace)
+	else if (intertype == int_comp)
 	{
 		INT32 x = 4;
 		INT32 y = 48;
@@ -953,7 +951,7 @@ void Y_Ticker(void)
 		if (!--timer)
 		{
 			Y_EndIntermission();
-			Y_FollowIntermission();
+			G_AfterIntermission();
 			return;
 		}
 	}
@@ -961,7 +959,7 @@ void Y_Ticker(void)
 	else if (intertic == endtic)
 	{
 		Y_EndIntermission();
-		Y_FollowIntermission();
+		G_AfterIntermission();
 		return;
 	}
 
@@ -1145,7 +1143,7 @@ void Y_Ticker(void)
 		if (data.match.numplayers != D_NumPlayers())
 			Y_CalculateMatchWinners();
 	}
-	else if (intertype == int_race || intertype == int_classicrace) // race
+	else if (intertype == int_race || intertype == int_comp) // race
 	{
 		if (!intertic) // first time only
 			S_ChangeMusicInternal("_inter", true); // loop it
@@ -1154,96 +1152,6 @@ void Y_Ticker(void)
 	}
 }
 
-//
-// Y_UpdateRecordReplays
-//
-// Update replay files/data, etc. for Record Attack
-// See G_SetNightsRecords for NiGHTS Attack.
-//
-static void Y_UpdateRecordReplays(void)
-{
-	const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
-	char *gpath;
-	char lastdemo[256], bestdemo[256];
-	UINT8 earnedEmblems;
-
-	// Record new best time
-	if (!mainrecords[gamemap-1])
-		G_AllocMainRecordData(gamemap-1);
-
-	if (players[consoleplayer].score > mainrecords[gamemap-1]->score)
-		mainrecords[gamemap-1]->score = players[consoleplayer].score;
-
-	if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time))
-		mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
-
-	if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings)
-		mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
-
-	if (data.coop.gotperfbonus)
-		mainrecords[gamemap-1]->gotperfect = true;
-
-	// Save demo!
-	bestdemo[255] = '\0';
-	lastdemo[255] = '\0';
-	G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings));
-	G_CheckDemoStatus();
-
-	I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
-	I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755);
-
-	if ((gpath = malloc(glen)) == NULL)
-		I_Error("Out of memory for replay filepath\n");
-
-	sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
-	snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
-
-	if (FIL_FileExists(lastdemo))
-	{
-		UINT8 *buf;
-		size_t len = FIL_ReadFile(lastdemo, &buf);
-
-		snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
-		if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
-		{ // Better time, save this demo.
-			if (FIL_FileExists(bestdemo))
-				remove(bestdemo);
-			FIL_WriteFile(bestdemo, buf, len);
-			CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
-		}
-
-		snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
-		if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
-		{ // Better score, save this demo.
-			if (FIL_FileExists(bestdemo))
-				remove(bestdemo);
-			FIL_WriteFile(bestdemo, buf, len);
-			CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo);
-		}
-
-		snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
-		if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2)))
-		{ // Better rings, save this demo.
-			if (FIL_FileExists(bestdemo))
-				remove(bestdemo);
-			FIL_WriteFile(bestdemo, buf, len);
-			CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW MOST RINGS!"), M_GetText("Saved replay as"), bestdemo);
-		}
-
-		//CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo);
-
-		Z_Free(buf);
-	}
-	free(gpath);
-
-	// Check emblems when level data is updated
-	if ((earnedEmblems = M_CheckLevelEmblems()))
-		CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
-
-	// Update timeattack menu's replay availability.
-	Nextmap_OnChange();
-}
-
 //
 // Y_StartIntermission
 //
@@ -1252,7 +1160,6 @@ static void Y_UpdateRecordReplays(void)
 void Y_StartIntermission(void)
 {
 	INT32 i;
-	UINT8 completionEmblems = M_CompletionEmblems();
 
 	intertic = -1;
 
@@ -1265,10 +1172,7 @@ void Y_StartIntermission(void)
 	{
 		timer = 0;
 
-		if (G_IsSpecialStage(gamemap))
-			intertype = (maptol & TOL_NIGHTS) ? int_nightsspec : int_spec;
-		else
-			intertype = (maptol & TOL_NIGHTS) ? int_nights : int_coop;
+		intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
 	}
 	else
 	{
@@ -1283,14 +1187,7 @@ void Y_StartIntermission(void)
 		}
 
 		if (gametype == GT_COOP)
-		{
-			// Nights intermission is single player only
-			// Don't add it here
-			if (G_IsSpecialStage(gamemap))
-				intertype = int_spec;
-			else
-				intertype = int_coop;
-		}
+			intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
 		else if (gametype == GT_TEAMMATCH)
 			intertype = int_teammatch;
 		else if (gametype == GT_MATCH
@@ -1300,7 +1197,7 @@ void Y_StartIntermission(void)
 		else if (gametype == GT_RACE)
 			intertype = int_race;
 		else if (gametype == GT_COMPETITION)
-			intertype = int_classicrace;
+			intertype = int_comp;
 		else if (gametype == GT_CTF)
 			intertype = int_ctf;
 	}
@@ -1315,20 +1212,6 @@ void Y_StartIntermission(void)
 
 	switch (intertype)
 	{
-		case int_nights:
-			// Can't fail
-			G_SetNightsRecords();
-
-			// Check records
-			{
-				UINT8 earnedEmblems = M_CheckLevelEmblems();
-				if (earnedEmblems)
-					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
-			}
-
-			// fall back into the coop intermission for now
-			intertype = int_coop;
-			/* FALLTHRU */
 		case int_coop: // coop or single player, normal level
 		{
 			// award time and ring bonuses
@@ -1337,24 +1220,6 @@ void Y_StartIntermission(void)
 			// setup time data
 			data.coop.tics = players[consoleplayer].realtime;
 
-			if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback)
-			{
-				// Update visitation flags
-				mapvisited[gamemap-1] |= MV_BEATEN;
-				if (ALL7EMERALDS(emeralds))
-					mapvisited[gamemap-1] |= MV_ALLEMERALDS;
-				if (ultimatemode)
-					mapvisited[gamemap-1] |= MV_ULTIMATE;
-				if (data.coop.gotperfbonus)
-					mapvisited[gamemap-1] |= MV_PERFECT;
-
-				if (modeattacking == ATTACKING_RECORD)
-					Y_UpdateRecordReplays();
-
-				if (completionEmblems)
-					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
-			}
-
 			for (i = 0; i < 4; ++i)
 				data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC);
 			data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC);
@@ -1421,40 +1286,8 @@ void Y_StartIntermission(void)
 			break;
 		}
 
-		case int_nightsspec:
-			if (modeattacking && stagefailed)
-			{
-				// Nuh-uh.  Get out of here.
-				Y_EndIntermission();
-				Y_FollowIntermission();
-				break;
-			}
-			if (!stagefailed)
-				G_SetNightsRecords();
-
-			// Check records
-			{
-				UINT8 earnedEmblems = M_CheckLevelEmblems();
-				if (earnedEmblems)
-					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
-			}
-
-			// fall back into the special stage intermission for now
-			intertype = int_spec;
-			/* FALLTHRU */
 		case int_spec: // coop or single player, special stage
 		{
-			// Update visitation flags?
-			if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback)
-			{
-				if (!stagefailed)
-					mapvisited[gamemap-1] |= MV_BEATEN;
-
-				// all emeralds/ultimate/perfect emblems won't be possible in ss, oh well?
-				if (completionEmblems)
-					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
-			}
-
 			// give out ring bonuses
 			Y_AwardSpecialStageBonus();
 
@@ -1640,7 +1473,7 @@ void Y_StartIntermission(void)
 			break;
 		}
 
-		case int_classicrace: // classic (full race)
+		case int_comp: // classic (full race)
 		{
 			// find out who won
 			Y_CalculateCompetitionWinners();
@@ -2195,23 +2028,6 @@ void Y_EndIntermission(void)
 	usebuffer = false;
 }
 
-//
-// Y_FollowIntermission
-//
-static void Y_FollowIntermission(void)
-{
-	if (modeattacking)
-	{
-		M_EndModeAttackRun();
-		return;
-	}
-
-	// This handles whether to play a post-level cutscene, end the game,
-	// or simply go to the next level.
-	// No need to duplicate the code here!
-	G_AfterIntermission();
-}
-
 #define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
 
 //
@@ -2224,8 +2040,6 @@ static void Y_UnloadData(void)
 	if (rendermode != render_soft)
 		return;
 
-	Y_CleanupScreenBuffer();
-
 	// unload the background patches
 	UNLOAD(bgpatch);
 	UNLOAD(widebgpatch);
@@ -2261,7 +2075,7 @@ static void Y_UnloadData(void)
 			break;
 		default:
 			//without this default,
-			//int_none, int_tag, int_chaos, and int_classicrace
+			//int_none, int_tag, int_chaos, and int_comp
 			//are not handled
 			break;
 	}
diff --git a/src/y_inter.h b/src/y_inter.h
index ccb48dbd4c3ed5cd43273a3971724bb9b6c897b7..b47f3b157e8d3eb0b03ca408c0818aa873b97a81 100644
--- a/src/y_inter.h
+++ b/src/y_inter.h
@@ -16,6 +16,7 @@ void Y_Ticker(void);
 void Y_StartIntermission(void);
 void Y_EndIntermission(void);
 void Y_ConsiderScreenBuffer(void);
+void Y_CleanupScreenBuffer(void);
 
 typedef enum
 {
@@ -26,9 +27,7 @@ typedef enum
 //	int_tag,      // Tag
 	int_ctf,      // CTF
 	int_spec,     // Special Stage
-	int_nights,   // NiGHTS into Dreams
-	int_nightsspec,// NiGHTS special stage
 	int_race,     // Race
-	int_classicrace, // Competition
+	int_comp,     // Competition
 } intertype_t;
 extern intertype_t intertype;