diff --git a/src/p_floor.c b/src/p_floor.c
index 0f1472810c39ba323b706c350c787ee0643df165..e787d1e13219f2b98409b5962fefc5c74d8ea29f 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -1047,40 +1047,37 @@ void T_MarioBlock(levelspecthink_t *block)
 #undef low
 }
 
-void T_FloatSector(levelspecthink_t *floater)
+void T_FloatSector(floatthink_t *floater)
 {
 	fixed_t cheeseheight;
+	fixed_t waterheight;
 	sector_t *actionsector;
 	INT32 secnum;
 
-	cheeseheight = (floater->sector->ceilingheight + floater->sector->floorheight)>>1;
-
 	// Just find the first sector with the tag.
 	// Doesn't work with multiple sectors that have different floor/ceiling heights.
-	secnum = P_FindSectorFromTag((INT16)floater->vars[0], -1);
+	secnum = P_FindSectorFromTag(floater->tag, -1);
+	if (secnum <= 0)
+		return;
+	actionsector = &sectors[secnum];
 
-	if (secnum > 0)
-		actionsector = &sectors[secnum];
-	else
-		actionsector = NULL;
+	cheeseheight = (floater->sector->ceilingheight + floater->sector->floorheight)>>1;
 
-	if (actionsector)
-	{
-		//boolean floatanyway = false; // Ignore the crumblestate setting.
-		fixed_t waterheight = P_SectorCheckWater(actionsector, floater->sector); // find the highest suitable water block around
-
-		if (waterheight == cheeseheight) // same height, no floating needed
-			;
-		else if (floater->sector->floorheight == actionsector->floorheight && waterheight < cheeseheight) // too low
-			;
-		else if (floater->sector->ceilingheight == actionsector->ceilingheight && waterheight > cheeseheight) // too high
-			;
-		// we have something to float in! Or we're for some reason above the ground, let's fall anyway
-		else if (floater->sector->crumblestate == CRUMBLE_NONE || floater->sector->crumblestate >= CRUMBLE_FALL/* || floatanyway*/)
-			EV_BounceSector(floater->sector, FRACUNIT, floater->sourceline);
-
-		P_RecalcPrecipInSector(actionsector);
-	}
+	//boolean floatanyway = false; // Ignore the crumblestate setting.
+	waterheight = P_SectorCheckWater(actionsector, floater->sector); // find the highest suitable water block around
+
+	if (waterheight == cheeseheight) // same height, no floating needed
+		return;
+
+	if (floater->sector->floorheight == actionsector->floorheight && waterheight < cheeseheight) // too low
+		return;
+
+	if (floater->sector->ceilingheight == actionsector->ceilingheight && waterheight > cheeseheight) // too high
+		return;
+
+	// we have something to float in! Or we're for some reason above the ground, let's fall anyway
+	if (floater->sector->crumblestate == CRUMBLE_NONE || floater->sector->crumblestate >= CRUMBLE_FALL/* || floatanyway*/)
+		EV_BounceSector(floater->sector, FRACUNIT, floater->sourceline);
 }
 
 static mobj_t *SearchMarioNode(msecnode_t *node)
diff --git a/src/p_saveg.c b/src/p_saveg.c
index c9d4bb5fb2021b818c4c9d6aef63808efeeb6111..443480813856494b76c23d185bde32ff87747457 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -1658,6 +1658,20 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
 	WRITEUINT32(save_p, SaveSector(ht->sector));
 }
 
+//
+// SaveFloatThinker
+//
+// Saves a floatthink_t thinker
+//
+static void SaveFloatThinker(const thinker_t *th, const UINT8 type)
+{
+	const floatthink_t *ht  = (const void *)th;
+	WRITEUINT8(save_p, type);
+	WRITEUINT32(save_p, SaveLine(ht->sourceline));
+	WRITEUINT32(save_p, SaveSector(ht->sector));
+	WRITEINT16(save_p, ht->tag);
+}
+
 // SaveEachTimeThinker
 //
 // Loads a eachtime_t from a save game
@@ -2317,7 +2331,7 @@ static void P_NetArchiveThinkers(void)
 			}
 			else if (th->function.acp1 == (actionf_p1)T_FloatSector)
 			{
-				SaveSpecialLevelThinker(th, tc_floatsector);
+				SaveFloatThinker(th, tc_floatsector);
 				continue;
 			}
 			else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
@@ -2800,6 +2814,20 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili
 	return &ht->thinker;
 }
 
+// LoadFloatThinker
+//
+// Loads a floatthink_t from a save game
+//
+static thinker_t* LoadFloatThinker(actionf_p1 thinker)
+{
+	floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
+	ht->thinker.function.acp1 = thinker;
+	ht->sourceline = LoadLine(READUINT32(save_p));
+	ht->sector = LoadSector(READUINT32(save_p));
+	ht->tag = READINT16(save_p);
+	return &ht->thinker;
+}
+
 // LoadEachTimeThinker
 //
 // Loads a eachtime_t from a save game
@@ -3542,7 +3570,7 @@ static void P_NetUnArchiveThinkers(void)
 					break;
 
 				case tc_floatsector:
-					th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0);
+					th = LoadFloatThinker((actionf_p1)T_FloatSector);
 					break;
 
 				case tc_laserflash:
diff --git a/src/p_spec.c b/src/p_spec.c
index 7d10a115232d4e1139fb635ab7725497d72801bd..54a6d88d656dd8c721bdddb57ba609b1b0007368 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -114,7 +114,7 @@ static void P_ResetColormapFader(sector_t *sector);
 static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
 	boolean ticbased, INT32 duration);
 static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
-static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline);
+static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline);
 //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
 static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers);
 static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
@@ -5927,9 +5927,9 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
   * \sa P_SpawnSpecials, T_FloatSector
   * \author SSNTails <http://www.ssntails.org>
   */
-static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
+static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline)
 {
-	levelspecthink_t *floater;
+	floatthink_t *floater;
 
 	// create and initialize new thinker
 	floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL);
@@ -5938,7 +5938,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
 	floater->thinker.function.acp1 = (actionf_p1)T_FloatSector;
 
 	floater->sector = sec;
-	floater->vars[0] = tag;
+	floater->tag = (INT16)tag;
 	floater->sourceline = sourceline;
 }
 
diff --git a/src/p_spec.h b/src/p_spec.h
index 79f6090fd1070a0002ad8b5f73e23f6f3b34743b..78cf817ea053087eb15036280e14489385a7632e 100644
--- a/src/p_spec.h
+++ b/src/p_spec.h
@@ -320,6 +320,14 @@ typedef struct
 	sector_t *sector;   // Sector the thinker is from
 } levelspecthink_t;
 
+typedef struct
+{
+	thinker_t thinker;
+	line_t *sourceline;
+	sector_t *sector;
+	INT16 tag;
+} floatthink_t;
+
 typedef struct
 {
 	thinker_t thinker;
@@ -381,7 +389,7 @@ void T_ContinuousFalling(levelspecthink_t *faller);
 void T_BounceCheese(levelspecthink_t *bouncer);
 void T_StartCrumble(elevator_t *elevator);
 void T_MarioBlock(levelspecthink_t *block);
-void T_FloatSector(levelspecthink_t *floater);
+void T_FloatSector(floatthink_t *floater);
 void T_MarioBlockChecker(levelspecthink_t *block);
 void T_ThwompSector(levelspecthink_t *thwomp);
 void T_NoEnemiesSector(levelspecthink_t *nobaddies);