diff --git a/src/dehacked.c b/src/dehacked.c
index 09137112223711e292da453875a027b733c30005..63c4e790f8fb80c1237329048a1994fc8aca4af9 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -6015,6 +6015,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	"S_SIGNSTOP",
 	"S_SIGNBOARD",
 	"S_EGGMANSIGN",
+	"S_CLEARSIGN",
 
 	// Spike Ball
 	"S_SPIKEBALL1",
diff --git a/src/info.c b/src/info.c
index bd672af12999663066578c81cb45eb558420084b..de6ff475cc216651b3c9d1085f9a0f546314792f 100644
--- a/src/info.c
+++ b/src/info.c
@@ -1849,18 +1849,19 @@ state_t states[NUMSTATES] =
 	{SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4
 
 	// Level End Sign
-	{SPR_SIGN,                0, -1, {A_SignPlayer}, -3, 0, S_NULL},                // S_SIGN
-	{SPR_SIGN,                0,  1,   {A_SignSpin}, 30, 0, S_SIGNSPIN2},           // S_SIGNSPIN1
-	{SPR_SIGN,                0,  0,     {A_Repeat},  4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
-	{SPR_SIGN,                0,  0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4},           // S_SIGNSPIN3
-	{SPR_SIGN,                0,  1,   {A_SignSpin}, 30, 0, S_SIGNSPIN5},           // S_SIGNSPIN4
-	{SPR_SIGN,                0,  0,     {A_Repeat},  4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
-	{SPR_SIGN,                0,  0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1},           // S_SIGNSPIN6
-	{SPR_SIGN,                0,  1, {A_SignPlayer}, -1, 0, S_SIGNSLOW},            // S_SIGNPLAYER
-	{SPR_SIGN,                0,  1,   {A_SignSpin}, 30, 0, S_SIGNSLOW},            // S_SIGNSLOW
-	{SPR_SIGN,                0, -1,         {NULL},  0, 0, S_NULL},                // S_SIGNSTOP
-	{SPR_SIGN, FF_PAPERSPRITE|2, -1,         {NULL},  0, 0, S_NULL},                // S_SIGNBOARD
-	{SPR_SIGN, FF_PAPERSPRITE|1, -1,         {NULL},  0, 29, S_NULL},               // S_EGGMANSIGN
+	{SPR_SIGN,                 0, -1, {A_SignPlayer}, -3, 0, S_NULL},                // S_SIGN
+	{SPR_SIGN,                 0,  1,   {A_SignSpin}, 30, 0, S_SIGNSPIN2},           // S_SIGNSPIN1
+	{SPR_SIGN,                 0,  0,     {A_Repeat},  4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
+	{SPR_SIGN,                 0,  0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4},           // S_SIGNSPIN3
+	{SPR_SIGN,                 0,  1,   {A_SignSpin}, 30, 0, S_SIGNSPIN5},           // S_SIGNSPIN4
+	{SPR_SIGN,                 0,  0,     {A_Repeat},  4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
+	{SPR_SIGN,                 0,  0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1},           // S_SIGNSPIN6
+	{SPR_SIGN,                 0,  1, {A_SignPlayer}, -1, 0, S_SIGNSLOW},            // S_SIGNPLAYER
+	{SPR_SIGN,                 0,  1,   {A_SignSpin}, 30, 0, S_SIGNSLOW},            // S_SIGNSLOW
+	{SPR_SIGN,                 0, -1,         {NULL},  0, 0, S_NULL},                // S_SIGNSTOP
+	{SPR_SIGN, FF_PAPERSPRITE| 2, -1,         {NULL},  0, 0, S_NULL},                // S_SIGNBOARD
+	{SPR_SIGN, FF_PAPERSPRITE| 1, -1,         {NULL},  0, 29, S_NULL},               // S_EGGMANSIGN
+	{SPR_SIGN, FF_PAPERSPRITE|18, -1,         {NULL},  0, 29, S_NULL},               // S_CLEARSIGN
 
 	// Spike Ball
 	{SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1
@@ -7850,7 +7851,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		MT_SPARK,       // painchance
 		sfx_s3kb8,      // painsound
 		S_EGGMANSIGN,   // meleestate
-		S_NULL,         // missilestate
+		S_CLEARSIGN,    // missilestate
 		S_SIGNSTOP,     // deathstate
 		S_NULL,         // xdeathstate
 		sfx_s3k64,      // deathsound
diff --git a/src/info.h b/src/info.h
index 324795d457ef60f2552eac3e1c913a24c4235613..628335635da599b7f49766d693b2105bd831d08c 100644
--- a/src/info.h
+++ b/src/info.h
@@ -2021,6 +2021,7 @@ typedef enum state
 	S_SIGNSTOP,
 	S_SIGNBOARD,
 	S_EGGMANSIGN,
+	S_CLEARSIGN,
 
 	// Spike Ball
 	S_SPIKEBALL1,
diff --git a/src/p_enemy.c b/src/p_enemy.c
index bd7b81d40fd8c5ff305360b200bb07c6491e2e42..763146d81cdc8fd9c8fad6909e87fe5f6bcf7a38 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -5177,6 +5177,8 @@ void A_SignPlayer(mobj_t *actor)
 
 		if (signcolor)
 			;
+		else if (!skin->sprites[SPR2_SIGN].numframes)
+			signcolor = facecolor;
 		else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
 			signcolor = skin->prefoppositecolor;
 		else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
@@ -5187,33 +5189,25 @@ void A_SignPlayer(mobj_t *actor)
 	else if (locvar1 != -3) // set to a defined skin
 	{
 		// I turned this function into a fucking mess. I'm so sorry. -Lach
-		if (locvar1 == -2) // next skin
+		if (locvar1 == -2) // random skin
 		{
+#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0)
 			player_t *player = actor->target ? actor->target->player : NULL;
 			UINT8 skinnum;
-#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0)
-			if (ov->skin == NULL) // pick a random skin to start with!
+			UINT8 skincount = 0;
+			for (skincount = 0; skincount < numskins; skincount++)
+				if (!skincheck(skincount))
+					skincount++;
+			skinnum = P_RandomKey(skincount);
+			for (skincount = 0; skincount < numskins; skincount++)
 			{
-				UINT8 skincount = 0;
-				for (skincount = 0; skincount < numskins; skincount++)
-					if (!skincheck(skincount))
-						skincount++;
-				skinnum = P_RandomKey(skincount);
-				for (skincount = 0; skincount < numskins; skincount++)
-				{
-					if (skincount > skinnum)
-						break;
-					if (skincheck(skincount))
-						skinnum++;
-				}
-			}
-			else // otherwise, advance 1 skin
-			{
-				skinnum = (skin_t*)ov->skin-skins;
-				while ((skinnum = (skinnum + 1) % numskins) && skincheck(skinnum));
+				if (skincount > skinnum)
+					break;
+				if (skincheck(skincount))
+					skinnum++;
 			}
-#undef skincheck
 			skin = &skins[skinnum];
+#undef skincheck
 		}
 		else // specific skin
 			skin = &skins[locvar1];
@@ -5221,21 +5215,33 @@ void A_SignPlayer(mobj_t *actor)
 		facecolor = skin->prefcolor;
 		if (signcolor)
 			;
+		else if (!skin->sprites[SPR2_SIGN].numframes)
+			signcolor = facecolor;
 		else if (skin->prefoppositecolor)
 			signcolor = skin->prefoppositecolor;
 		else if (facecolor)
 			signcolor = Color_Opposite[facecolor - 1][0];
 	}
 
-	if (skin && skin->sprites[SPR2_SIGN].numframes) // player face
+	if (skin)
 	{
-		ov->color = facecolor;
-		ov->skin = skin;
-		P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
+		if (skin->sprites[SPR2_SIGN].numframes) // player face
+		{
+			ov->color = facecolor;
+			ov->skin = skin;
+			P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
+		}
+		else // CLEAR! sign
+		{
+			ov->color = SKINCOLOR_NONE;
+			ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters
+			P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN
+		}
 	}
 	else // Eggman face
 	{
 		ov->color = SKINCOLOR_NONE;
+		ov->skin = NULL;
 		P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
 		if (!signcolor)
 			signcolor = SKINCOLOR_CARBON;