diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 95927710a3cda2f281b27f0c03dc0f0d6c7313a1..53a2fb2357d8cb57ad10ce2c0e2cc3c7988b7123 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -3576,6 +3576,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
 
 	if (pnum == consoleplayer)
 	{
+		if (Playing())
+			LUAh_GameQuit();
 #ifdef DUMPCONSISTENCY
 		if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
 #endif
@@ -4244,6 +4246,8 @@ static void HandleConnect(SINT8 node)
 static void HandleShutdown(SINT8 node)
 {
 	(void)node;
+	if (Playing())
+		LUAh_GameQuit();
 	D_QuitNetGame();
 	CL_Reset();
 	D_StartTitle();
@@ -4258,6 +4262,8 @@ static void HandleShutdown(SINT8 node)
 static void HandleTimeout(SINT8 node)
 {
 	(void)node;
+	if (Playing())
+		LUAh_GameQuit();
 	D_QuitNetGame();
 	CL_Reset();
 	D_StartTitle();
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 3efb66dd55a0531ab97b61e68addeeade22ec2cc..b5ebad6d6be39f84b1157f56fb925b48b938c53b 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -3570,6 +3570,8 @@ static void Command_Playintro_f(void)
   */
 FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
 {
+	if (Playing())
+		LUAh_GameQuit();
 	I_Quit();
 }
 
@@ -4231,6 +4233,9 @@ void Command_ExitGame_f(void)
 {
 	INT32 i;
 
+	if (Playing())
+		LUAh_GameQuit();
+
 	D_QuitNetGame();
 	CL_Reset();
 	CV_ClearChangedFlags();
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 315c35cdf3e3b00c2c96759056a1db201b220a46..48f6cab32c51ceb695d325b47196341033d0a6a7 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -58,6 +58,7 @@ enum hook {
 	hook_SeenPlayer,
 	hook_PlayerThink,
 	hook_ShouldJingleContinue,
+	hook_GameQuit,
 
 	hook_MAX // last hook
 };
@@ -112,3 +113,4 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_
 #endif
 #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
 boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
+void LUAh_GameQuit(void); // Hook for game quitting
\ No newline at end of file
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index b3390eb95279a6bc27a586d035f8432e1fcdaf03..5cfd1bd3d461f49e774593dd87f0daac77ee08e1 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -70,6 +70,7 @@ const char *const hookNames[hook_MAX+1] = {
 	"SeenPlayer",
 	"PlayerThink",
 	"ShouldJingleContinue",
+	"GameQuit",
 	NULL
 };
 
@@ -1769,3 +1770,29 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
 
 	return keepplaying;
 }
+
+// Hook for game quitting
+void LUAh_GameQuit(void)
+{
+	hook_p hookp;
+	if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8))))
+		return;
+
+	lua_pushcfunction(gL, LUA_GetErrorMessage);
+
+	for (hookp = roothook; hookp; hookp = hookp->next)
+	{
+		if (hookp->type != hook_GameQuit)
+			continue;
+
+		PushHook(gL, hookp);
+		if (lua_pcall(gL, 0, 0, 1)) {
+			if (!hookp->error || cv_debug & DBG_LUA)
+				CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+			lua_pop(gL, 1);
+			hookp->error = true;
+		}
+	}
+	
+	lua_pop(gL, 1); // Pop error handler
+}
diff --git a/src/m_menu.c b/src/m_menu.c
index 61b41d75b89293f08f6697adb39d657e7d5c054f..f684354a5aec05a8995a5eca275c9d38cf9de63e 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -44,6 +44,7 @@
 #include "p_local.h"
 #include "p_setup.h"
 #include "f_finale.h"
+#include "lua_hook.h"
 
 #ifdef HWRENDER
 #include "hardware/hw_main.h"
@@ -6918,6 +6919,8 @@ static void M_SelectableClearMenus(INT32 choice)
 static void M_UltimateCheat(INT32 choice)
 {
 	(void)choice;
+	if (Playing())
+		LUAh_GameQuit();
 	I_Quit();
 }
 
@@ -13196,6 +13199,8 @@ void M_QuitResponse(INT32 ch)
 
 	if (ch != 'y' && ch != KEY_ENTER)
 		return;
+	if (Playing())
+		LUAh_GameQuit();
 	if (!(netgame || cv_debug))
 	{
 		S_ResetCaptions();
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 0a6e9c01c196ac226cd0ba0e33bb15937118781d..01194a02fa00e1ecb4bb2af51e078fa1d6e0980b 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -73,6 +73,7 @@
 #include "../console.h"
 #include "../command.h"
 #include "../r_main.h"
+#include "../lua_hook.h"
 #include "sdlmain.h"
 #ifdef HWRENDER
 #include "../hardware/hw_main.h"
@@ -1057,8 +1058,9 @@ void I_GetEvent(void)
 					M_SetupJoystickMenu(0);
 			 	break;
 			case SDL_QUIT:
+				if (Playing())
+					LUAh_GameQuit();
 				I_Quit();
-				M_QuitResponse('y');
 				break;
 		}
 	}