diff --git a/src/deh_lua.c b/src/deh_lua.c
index 4d3be4cbe3aa7016506c91769e43bb5d030b7020..6b758df2483965198efd91215faa9f710c5b13a9 100644
--- a/src/deh_lua.c
+++ b/src/deh_lua.c
@@ -133,15 +133,11 @@ static inline int lib_freeslot(lua_State *L)
 		}
 		else if (fastcmp(type, "TEAM"))
 		{
-			if (numteams == MAXTEAMS)
+			UINT8 i = G_AddTeam(word);
+			if (i == MAXTEAMS)
 				CONS_Alert(CONS_WARNING, "Ran out of free team slots!\n");
-			UINT8 i = numteams;
 			CONS_Printf("Team TEAM_%s allocated.\n",word);
-			teamnames[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
-			strcpy(teamnames[i],word);
 			lua_pushinteger(L, i);
-			G_InitTeam(i);
-			numteams++;
 			r++;
 			break;
 		}
@@ -578,7 +574,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
 		p = word+5;
 		for (i = 0; i < numteams; i++)
 		{
-			if (fastcmp(p, teamnames[i])) {
+			if (fastcmp(p, teamnames[i][0])) {
 				CacheAndPushConstant(L, word, i);
 				return 1;
 			}
diff --git a/src/deh_soc.c b/src/deh_soc.c
index 719420500c1f36caaecf13f9666c64e130137e0a..2fc09f0ad95ced54f98341fe19bf3ac6f41eedcd 100644
--- a/src/deh_soc.c
+++ b/src/deh_soc.c
@@ -475,13 +475,7 @@ void readfreeslots(MYFILE *f)
 			}
 			else if (fastcmp(type, "TEAM"))
 			{
-				if (numteams < MAXTEAMS)
-				{
-					teamnames[numteams] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
-					strcpy(teamnames[numteams],word);
-					G_InitTeam(numteams);
-					numteams++;
-				}
+				G_AddTeam(word);
 			}
 			else if (fastcmp(type, "SPR2"))
 			{
@@ -4363,7 +4357,7 @@ UINT8 get_team(const char *word)
 		word += 5; // take off the TEAM_
 	for (i = 0; i < numteams; i++)
 	{
-		if (fastcmp(word, teamnames[i]))
+		if (fastcmp(word, teamnames[i][0]))
 			return i;
 	}
 	deh_warning("Couldn't find team named 'TEAM_%s'",word);
diff --git a/src/doomstat.h b/src/doomstat.h
index 18a97c6703d7c36b16508fac545ea81c0cc1bd59..5f4d0beadfd9612b68d4179b24705fb5d57e0a2b 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -418,7 +418,7 @@ typedef struct
 extern team_t teams[MAXTEAMS];
 extern UINT8 numteams;
 
-extern char *teamnames[MAXTEAMS];
+extern char *teamnames[MAXTEAMS][2];
 
 #define NUMGAMETYPEFREESLOTS 128
 
diff --git a/src/g_game.c b/src/g_game.c
index 2822e8d62a63a5fc0e15aff2bc1792d4ba485586..112534b3040ccee4a64eb95bbdf7c9e9239eafd7 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -3531,7 +3531,19 @@ team_t teams[MAXTEAMS] = {
 	}
 };
 
-char *teamnames[MAXTEAMS];
+char *teamnames[MAXTEAMS][2];
+
+static void G_SetTeamName(UINT8 i, const char *name)
+{
+	Z_Free(teamnames[i][0]);
+	Z_Free(teamnames[i][1]);
+
+	teamnames[i][0] = Z_StrDup(name);
+	teamnames[i][1] = Z_StrDup(name);
+
+	strupr(teamnames[i][0]);
+	strlwr(teamnames[i][1]);
+}
 
 static void G_InitTeams(void)
 {
@@ -3540,7 +3552,6 @@ static void G_InitTeams(void)
 
 	teams[TEAM_NONE].name = Z_StrDup("None");
 	teams[TEAM_NONE].flag_name = Z_StrDup("Thingmabob");
-	teamnames[TEAM_NONE] = Z_StrDup("NONE");
 
 	teams[TEAM_RED].name = Z_StrDup("Red");
 	teams[TEAM_RED].flag_name = Z_StrDup("Red Flag");
@@ -3548,7 +3559,6 @@ static void G_InitTeams(void)
 	teams[TEAM_RED].icons[TEAM_ICON_FLAG] = Z_StrDup("RFLAGICO");
 	teams[TEAM_RED].icons[TEAM_ICON_GOT_FLAG] = Z_StrDup("GOTRFLAG");
 	teams[TEAM_RED].icons[TEAM_ICON_MISSING_FLAG] = Z_StrDup("NONICON2");
-	teamnames[TEAM_RED] = Z_StrDup("RED");
 
 	teams[TEAM_BLUE].name = Z_StrDup("Blue");
 	teams[TEAM_BLUE].flag_name = Z_StrDup("Blue Flag");
@@ -3556,7 +3566,10 @@ static void G_InitTeams(void)
 	teams[TEAM_BLUE].icons[TEAM_ICON_FLAG] = Z_StrDup("BFLAGICO");
 	teams[TEAM_BLUE].icons[TEAM_ICON_GOT_FLAG] = Z_StrDup("GOTBFLAG");
 	teams[TEAM_BLUE].icons[TEAM_ICON_MISSING_FLAG] = Z_StrDup("NONICON");
-	teamnames[TEAM_BLUE] = Z_StrDup("BLUE");
+
+	G_SetTeamName(TEAM_NONE, "NONE");
+	G_SetTeamName(TEAM_RED, "RED");
+	G_SetTeamName(TEAM_BLUE, "BLUE");
 
 	G_UpdateTeamSelection();
 }
@@ -3930,6 +3943,21 @@ void G_InitTeam(UINT8 team)
 	memset(&teams[team], 0, sizeof(team_t));
 }
 
+UINT8 G_AddTeam(const char *name)
+{
+	if (numteams == MAXTEAMS)
+		return MAXTEAMS;
+
+	UINT8 i = numteams;
+
+	G_InitTeam(i);
+	G_SetTeamName(i, name);
+
+	numteams++;
+
+	return i;
+}
+
 UINT8 G_GetGametypeTeam(UINT8 gtype, UINT8 team)
 {
 	if (team == TEAM_NONE || team >= gametypes[gtype].teams.num + 1)
diff --git a/src/g_game.h b/src/g_game.h
index 62fc7b50d5d4a3c97c27c3d8b512b8dbd24aaf17..8fd7d60d86e1f7ad24f334962d1e61c982067d9d 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -223,6 +223,7 @@ void G_AfterIntermission(void);
 void G_EndGame(void); // moved from y_inter.c/h and renamed
 
 void G_InitTeam(UINT8 team);
+UINT8 G_AddTeam(const char *name);
 UINT8 G_GetGametypeTeam(UINT8 gtype, UINT8 team);
 UINT8 G_GetTeam(UINT8 team);
 UINT8 G_GetTeamFromTeamFlag(UINT32 flag);
diff --git a/src/p_setup.c b/src/p_setup.c
index 92d22097ce19b58f0b468b14fd4c910763e1b806..8b58ae98fc88c79d63510504b60e131089ec2ee4 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1816,7 +1816,7 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
 
 		for (UINT8 j = 0; j < numteams; j++)
 		{
-			if (fastcmp(val, teamnames[j]))
+			if (fastcmp(val, teamnames[j][1]))
 			{
 				sectors[j].teambase = j;
 				break;
@@ -2737,12 +2737,7 @@ static void P_WriteTextmap(void)
 			// actual teams TEAM_RED and TEAM_BLUE.
 			UINT8 team = wsectors[i].teambase;
 			if (team != TEAM_NONE && team < numteams)
-			{
-				char *teambase = Z_StrDup(teamnames[team]);
-				strlwr(teambase);
-				fprintf(f, "teambase = \"%s\";\n", teambase);
-				Z_Free(teambase);
-			}
+				fprintf(f, "teambase = \"%s\";\n", teamnames[team][1]);
 			else
 				fprintf(f, "teambase = \"%s\";\n", "unknown");
 		}