diff --git a/src/command.c b/src/command.c
index a34d9694a1c4f5026225780bca1d2e1d47b77c25..b03d2d8c1c90afd4c2a632389097eee1323a497c 100644
--- a/src/command.c
+++ b/src/command.c
@@ -76,6 +76,7 @@ CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
 CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
 CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
 CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
+CV_PossibleValue_t CV_TrueFalse[] = {{0, "False"}, {1, "True"}, {0, NULL}};
 
 // Filter consvars by EXECVERSION
 // First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
@@ -863,9 +864,11 @@ static void COM_Help_f(void)
 			{
 				CONS_Printf(" Possible values:\n");
 				if (cvar->PossibleValue == CV_YesNo)
-					CONS_Printf("  Yes or No (On or Off, 1 or 0)\n");
+					CONS_Printf("  Yes or No (On or Off, True or False, 1 or 0)\n");
 				else if (cvar->PossibleValue == CV_OnOff)
-					CONS_Printf("  On or Off (Yes or No, 1 or 0)\n");
+					CONS_Printf("  On or Off (Yes or No, True or False, 1 or 0)\n");
+				else if (cvar->PossibleValue == CV_TrueFalse)
+					CONS_Printf("  True or False (On or Off, Yes or No, 1 or 0)\n");
 				else if (cvar->PossibleValue == Color_cons_t)
 				{
 					for (i = 1; i < numskincolors; ++i)
@@ -1016,7 +1019,7 @@ static void COM_Toggle_f(void)
 	if (CV_Immutable(cvar))
 		return;
 
-	if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff))
+	if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff || cvar->PossibleValue == CV_TrueFalse))
 	{
 		CONS_Alert(CONS_NOTICE, M_GetText("%s is not a boolean value\n"), COM_Argv(1));
 		return;
@@ -1507,12 +1510,12 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
 						goto found;
 			}
 			// Not found ... but wait, there's hope!
-			if (var->PossibleValue == CV_OnOff || var->PossibleValue == CV_YesNo)
+			if (var->PossibleValue == CV_OnOff || var->PossibleValue == CV_YesNo || var->PossibleValue == CV_TrueFalse)
 			{
 				overrideval = -1;
-				if (!stricmp(valstr, "on") || !stricmp(valstr, "yes"))
+				if (!stricmp(valstr, "on") || !stricmp(valstr, "yes") || !stricmp(valstr, "true"))
 					overrideval = 1;
-				else if (!stricmp(valstr, "off") || !stricmp(valstr, "no"))
+				else if (!stricmp(valstr, "off") || !stricmp(valstr, "no") || !stricmp(valstr, "false"))
 					overrideval = 0;
 
 				if (overrideval != -1)
diff --git a/src/command.h b/src/command.h
index 69d1890d34d068ac67eb48c10e5c0ec5b8764b7f..619d8c1dcab07a7ab5dfbe20e98cae409c77fb9d 100644
--- a/src/command.h
+++ b/src/command.h
@@ -177,6 +177,7 @@ extern CV_PossibleValue_t CV_OnOff[];
 extern CV_PossibleValue_t CV_YesNo[];
 extern CV_PossibleValue_t CV_Unsigned[];
 extern CV_PossibleValue_t CV_Natural[];
+extern CV_PossibleValue_t CV_TrueFalse[];
 
 // Filter consvars by version
 extern consvar_t cv_execversion;
diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c
index 1d15b3b145c5e5d0f2bccdd055ff1dcde60056b0..9e5d1e2ee03dfe94144c1eec79757fb2d3a2f064 100644
--- a/src/lua_consolelib.c
+++ b/src/lua_consolelib.c
@@ -357,7 +357,7 @@ static int lib_cvRegisterVar(lua_State *L)
 			if (lua_islightuserdata(L, 4))
 			{
 				CV_PossibleValue_t *pv = lua_touserdata(L, 4);
-				if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural)
+				if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural || pv == CV_TrueFalse)
 					cvar->PossibleValue = pv;
 				else
 					FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer")
@@ -652,6 +652,8 @@ int LUA_ConsoleLib(lua_State *L)
 	lua_setglobal(L, "CV_Unsigned");
 	lua_pushlightuserdata(L, CV_Natural);
 	lua_setglobal(L, "CV_Natural");
+	lua_pushlightuserdata(L, CV_TrueFalse);
+	lua_setglobal(L, "CV_TrueFalse");
 
 	// Set global functions
 	lua_pushvalue(L, LUA_GLOBALSINDEX);