diff --git a/src/console.c b/src/console.c
index 6d273f62076b0b544b27acf1b22bf313009fc8b6..119079464c50fd22682306b040d7d439b1f389ac 100644
--- a/src/console.c
+++ b/src/console.c
@@ -1889,7 +1889,7 @@ void CON_Drawer(void)
 		CON_DrawConsole();
 	else if (gamestate == GS_LEVEL
 	|| gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE
-	|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
+	|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS)
 		CON_DrawHudlines();
 
 	Unlock_state();
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 210619164020fcc9cf07f95982d58dacf76c0b9b..9b3187cbb7d9cbe4da74cc5643edbeefebc2ad37 100755
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -2600,6 +2600,8 @@ static void CL_ConnectToServer(void)
 	}
 	while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
 
+	if (netgame)
+		F_StartWaitingPlayers();
 	DEBFILE(va("Synchronisation Finished\n"));
 
 	displayplayer = consoleplayer;
diff --git a/src/d_main.c b/src/d_main.c
index 5861f988655c62e9b812b13d48832c940f66ebc2..2db4002580151c622395e2ed78756793221457b6 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -458,6 +458,13 @@ static void D_Display(void)
 
 		case GS_WAITINGPLAYERS:
 			// The clientconnect drawer is independent...
+			if (netgame)
+			{
+				// I don't think HOM from nothing drawing is independent...
+				F_WaitingPlayersDrawer();
+				HU_Erase();
+				HU_Drawer();
+			}
 		case GS_DEDICATEDSERVER:
 		case GS_NULL:
 			break;
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index b23aaa5a0adb1aab4fa46b510525c74c9f6002ef..2cdf70843bffa1c6b50642bb9e91284de6d7bcd0 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -2174,7 +2174,7 @@ static void Command_Pause(void)
 
 	if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
 	{
-		if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) || (marathonmode && gamestate == GS_INTERMISSION))
+		if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_WAITINGPLAYERS) || (marathonmode && gamestate == GS_INTERMISSION))
 		{
 			CONS_Printf(M_GetText("You can't pause here.\n"));
 			return;
diff --git a/src/f_finale.c b/src/f_finale.c
index 299a6a054c0ae42e590226b85de0b078826bcbd3..529244b5a6153ed2ec177ee80392b29b0113519e 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -4660,3 +4660,36 @@ void F_TextPromptTicker(void)
 			animtimer--;
 	}
 }
+
+// ================
+//  WAITINGPLAYERS
+// ================
+
+void F_StartWaitingPlayers(void)
+{
+	wipegamestate = GS_TITLESCREEN; // technically wiping from title screen
+	finalecount = 0;
+}
+
+void F_WaitingPlayersTicker(void)
+{
+	if (paused)
+		return;
+
+	finalecount++;
+
+	// dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music
+	if (finalecount == 2)
+		S_ChangeMusicInternal("_CHSEL", true);
+}
+
+void F_WaitingPlayersDrawer(void)
+{
+	const char *waittext1 = "You will join";
+	const char *waittext2 = "next level...";
+
+	V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
+
+	V_DrawCreditString((160 - (V_CreditStringWidth(waittext1)>>1))<<FRACBITS, 48<<FRACBITS, 0, waittext1);
+	V_DrawCreditString((160 - (V_CreditStringWidth(waittext2)>>1))<<FRACBITS, 64<<FRACBITS, 0, waittext2);
+}
diff --git a/src/f_finale.h b/src/f_finale.h
index 7f53bfbad59b18814693db553eb7d25815a082bd..cb71775d05fc109aa4c3468c19cfe381eff72635 100644
--- a/src/f_finale.h
+++ b/src/f_finale.h
@@ -74,6 +74,10 @@ void F_StartContinue(void);
 void F_ContinueTicker(void);
 void F_ContinueDrawer(void);
 
+void F_StartWaitingPlayers(void);
+void F_WaitingPlayersTicker(void);
+void F_WaitingPlayersDrawer(void);
+
 extern INT32 finalecount;
 extern INT32 titlescrollxspeed;
 extern INT32 titlescrollyspeed;
diff --git a/src/g_game.c b/src/g_game.c
index 47e670bfecebef38e74d96c20993be11a9f6f5ef..bcfe6910513c30b342e8ee302aa1c22d49b7f246 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2437,14 +2437,17 @@ void G_Ticker(boolean run)
 		case GS_TITLESCREEN:
 			if (titlemapinaction)
 				P_Ticker(run);
-				// then intentionally fall through
-			/* FALLTHRU */
-		case GS_WAITINGPLAYERS:
 			if (run)
 				F_MenuPresTicker();
 			F_TitleScreenTicker(run);
 			break;
 
+		case GS_WAITINGPLAYERS:
+			if (netgame)
+				F_WaitingPlayersTicker();
+			HU_Ticker();
+			break;
+
 		case GS_DEDICATEDSERVER:
 		case GS_NULL:
 			break; // do nothing
diff --git a/src/p_saveg.c b/src/p_saveg.c
index 40fd656386077dccae3506f76fb4b4ec82ca33db..62aa624fc17d7a36f6604b31af3840405bc597c7 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -4279,7 +4279,11 @@ static void P_NetArchiveMisc(boolean resending)
 	if (resending)
 		WRITEUINT32(save_p, gametic);
 	WRITEINT16(save_p, gamemap);
-	WRITEINT16(save_p, gamestate);
+
+	if (gamestate != GS_LEVEL)
+		WRITEINT16(save_p, GS_WAITINGPLAYERS); // nice hack to put people back into waitingplayers
+	else
+		WRITEINT16(save_p, gamestate);
 	WRITEINT16(save_p, gametype);
 
 	{