diff --git a/src/g_game.c b/src/g_game.c
index faaed13c732929d643908ea1f2e3f495ce3b940a..11ad1862dcd8677409a4a06205592f5f7976e419 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2978,7 +2978,7 @@ void G_AddPlayer(INT32 playernum)
 	if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP))
 		p->lives = cv_startinglives.value;
 
-	if (countplayers && !notexiting)
+	if ((countplayers && !notexiting) || G_IsSpecialStage(gamemap))
 		P_DoPlayerExit(p);
 }
 
diff --git a/src/p_mobj.c b/src/p_mobj.c
index f2dd1a734f07a77b0180a2c0e2d610d49798d9a7..b5af077b57066ddaf8ad758dd314f509398c4c7a 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -11294,7 +11294,7 @@ void P_SpawnPlayer(INT32 playernum)
 	mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale);
 	mobj->height = P_GetPlayerHeight(p);
 
-	if (!leveltime && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage
+	if (!leveltime && !p->spectator && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage
 	{
 		if (maptol & TOL_NIGHTS)
 		{
diff --git a/src/p_tick.c b/src/p_tick.c
index e02b11f4907fd5d87bb722467485b0409f66a28e..60a776cbc508c619f023faea966e57c62758af54 100644
--- a/src/p_tick.c
+++ b/src/p_tick.c
@@ -476,7 +476,7 @@ static inline void P_DoSpecialStageStuff(void)
 		// Count up the rings of all the players and see if
 		// they've collected the required amount.
 		for (i = 0; i < MAXPLAYERS; i++)
-			if (playeringame[i])
+			if (playeringame[i] && players[i].nightstime)
 			{
 				tic_t oldnightstime = players[i].nightstime;
 				countspheres += players[i].spheres;
@@ -506,12 +506,11 @@ static inline void P_DoSpecialStageStuff(void)
 			{
 				// Halt all the players
 				for (i = 0; i < MAXPLAYERS; i++)
-					if (playeringame[i])
+					if (playeringame[i] && !players[i].exiting)
 					{
 						players[i].mo->momx = players[i].mo->momy = 0;
 						players[i].exiting = (14*TICRATE)/5 + 1;
 					}
-
 				sstimer = 0;
 				P_GiveEmerald(true);
 				P_RestoreMusic(&players[consoleplayer]);
diff --git a/src/p_user.c b/src/p_user.c
index cdfc073c62d0ed4cd1a3aa2f26070299403a4cd7..0983963e93f68347bea8f0a72dde041188a814b4 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -343,13 +343,15 @@ void P_GiveEmerald(boolean spawnObj)
 				continue;
 
 			emmo = P_SpawnMobjFromMobj(players[i].mo, 0, 0, players[i].mo->height, MT_GOTEMERALD);
+			if (!emmo)
+				continue;
 			P_SetTarget(&emmo->target, players[i].mo);
 			P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
 			P_SetTarget(&players[i].mo->tracer, emmo);
 
 			if (pnum == 255)
 			{
-				i = pnum;
+				pnum = i;
 				continue;
 			}