diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c
index 0ab8ad9c348a14de25bb8cfc0fd2ad809bab15ee..9b3fd2ea086d761e1a0eff0f202162923c52958e 100644
--- a/src/lua_consolelib.c
+++ b/src/lua_consolelib.c
@@ -374,6 +374,9 @@ static int lib_cvRegisterVar(lua_State *L)
 				size_t count = 0;
 				CV_PossibleValue_t *cvpv;
 
+				const char * const MINMAX[2] = {"MIN", "MAX"};
+				int minmax_unset = 3;
+
 				lua_pushnil(L);
 				while (lua_next(L, 4))
 				{
@@ -392,16 +395,45 @@ static int lib_cvRegisterVar(lua_State *L)
 				lua_pushnil(L);
 				while (lua_next(L, 4))
 				{
+					INT32 n;
+					const char * strval;
+
 					// stack: [...] PossibleValue table, index, value
 					//                       4             5      6
 					if (lua_type(L, 5) != LUA_TSTRING
 					|| lua_type(L, 6) != LUA_TNUMBER)
 						FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}");
-					cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5));
-					cvpv[i].value = (INT32)lua_tonumber(L, 6);
-					i++;
+
+					strval = lua_tostring(L, 5);
+
+					if (
+							stricmp(strval, MINMAX[n=0]) == 0 ||
+							stricmp(strval, MINMAX[n=1]) == 0
+					){
+						/* need to shift forward */
+						if (minmax_unset == 3)
+						{
+							memmove(&cvpv[2], &cvpv[0],
+									i * sizeof *cvpv);
+							i += 2;
+						}
+						cvpv[n].strvalue = MINMAX[n];
+						minmax_unset &= ~(1 << n);
+					}
+					else
+					{
+						n = i++;
+						cvpv[n].strvalue = Z_StrDup(strval);
+					}
+
+					cvpv[n].value = (INT32)lua_tonumber(L, 6);
+
 					lua_pop(L, 1);
 				}
+
+				if (minmax_unset && minmax_unset != 3)
+					FIELDERROR("PossibleValue", "custom PossibleValue table requires requires both MIN and MAX keys if one is present");
+
 				cvpv[i].value = 0;
 				cvpv[i].strvalue = NULL;
 				cvar->PossibleValue = cvpv;