diff --git a/src/command.c b/src/command.c
index 59f14e2f59927e1c9252b39e619d30a54b37b396..c8f1aeccc13756d6aaa903ef9d1073586a39dee7 100644
--- a/src/command.c
+++ b/src/command.c
@@ -1280,6 +1280,7 @@ void CV_RegisterVar(consvar_t *variable)
 		consvar_vars = variable;
 	}
 	variable->string = variable->zstring = NULL;
+	memset(&variable->revert, 0, sizeof variable->revert);
 	variable->changed = 0; // new variable has not been modified by the user
 
 #ifdef PARANOIA
@@ -1676,8 +1677,19 @@ static void CV_LoadVars(UINT8 **p,
 	serverloading = true;
 
 	for (cvar = consvar_vars; cvar; cvar = cvar->next)
+	{
 		if (cvar->flags & CV_NETVAR)
+		{
+			if (client && cvar->revert.v.string == NULL)
+			{
+				cvar->revert.v.const_munge = cvar->string;
+				cvar->revert.allocated = ( cvar->zstring != NULL );
+				cvar->zstring = NULL;/* don't free this */
+			}
+
 			Setvalue(cvar, cvar->defaultvalue, true);
+		}
+	}
 
 	count = READUINT16(*p);
 	while (count--)
@@ -1691,6 +1703,26 @@ static void CV_LoadVars(UINT8 **p,
 	serverloading = false;
 }
 
+void CV_RevertNetVars(void)
+{
+	consvar_t * cvar;
+
+	for (cvar = consvar_vars; cvar; cvar = cvar->next)
+	{
+		if (cvar->revert.v.string != NULL)
+		{
+			Setvalue(cvar, cvar->revert.v.string, false);
+
+			if (cvar->revert.allocated)
+			{
+				Z_Free(cvar->revert.v.string);
+			}
+
+			cvar->revert.v.string = NULL;
+		}
+	}
+}
+
 void CV_LoadNetVars(UINT8 **p)
 {
 	CV_LoadVars(p, ReadNetVar);
diff --git a/src/command.h b/src/command.h
index 8275d0fd1c122b3f4d82e3d69f470918688198ad..96813dc2c9f244291d82d666b7e66e0d99bc3c8b 100644
--- a/src/command.h
+++ b/src/command.h
@@ -138,6 +138,16 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
 	const char *string;   // value in string
 	char *zstring;        // Either NULL or same as string.
 	                      // If non-NULL, must be Z_Free'd later.
+	struct
+	{
+		char allocated; // whether to Z_Free
+		union
+		{
+			char       * string;
+			const char * const_munge;
+		} v;
+	} revert;             // value of netvar before joining netgame
+
 	UINT16 netid; // used internaly : netid for send end receive
 	                      // used only with CV_NETVAR
 	char changed;         // has variable been changed by the user? 0 = no, 1 = yes
@@ -146,7 +156,7 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
 
 /* name, defaultvalue, flags, PossibleValue, func */
 #define CVAR_INIT( ... ) \
-{ __VA_ARGS__, 0, NULL, NULL, 0U, (char)0, NULL }
+{ __VA_ARGS__, 0, NULL, NULL, {0}, 0U, (char)0, NULL }
 
 #ifdef OLD22DEMOCOMPAT
 typedef struct old_demo_var old_demo_var_t;
@@ -206,6 +216,9 @@ void CV_SaveVars(UINT8 **p, boolean in_demo);
 #define CV_SaveNetVars(p) CV_SaveVars(p, false)
 void CV_LoadNetVars(UINT8 **p);
 
+// then revert after leaving a netgame
+void CV_RevertNetVars(void);
+
 #define CV_SaveDemoVars(p) CV_SaveVars(p, true)
 void CV_LoadDemoVars(UINT8 **p);
 
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index c9490410b478041b66e4a37fe5c4c333bc54cf61..ceff769da3d71d4c224f7fff9d80e5516a2020db 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -3208,6 +3208,7 @@ void CL_Reset(void)
 	doomcom->numslots = 1;
 	SV_StopServer();
 	SV_ResetServer();
+	CV_RevertNetVars();
 
 	// make sure we don't leave any fileneeded gunk over from a failed join
 	fileneedednum = 0;