diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp
index 1442f8505..c486ebbb6 100644
--- a/source/blood/src/blood.cpp
+++ b/source/blood/src/blood.cpp
@@ -129,10 +129,7 @@ void StartLevel(MapRecord* level)
 	memset(xsprite, 0, sizeof(xsprite));
 	memset(sprite, 0, kMaxSprites * sizeof(spritetype));
 	//drawLoadingScreen();
-	if (dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr))
-	{
-		I_Error("%s: Unable to load map", level->DisplayName());
-	}
+	dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr);
 	SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
 	STAT_NewLevel(currentLevel->fileName);
 	wsrand(dbReadMapCRC(currentLevel->LabelName()));
diff --git a/source/blood/src/db.cpp b/source/blood/src/db.cpp
index 15d14d4b5..13e9bad13 100644
--- a/source/blood/src/db.cpp
+++ b/source/blood/src/db.cpp
@@ -457,10 +457,41 @@ struct spritetypedisk
     int16_t hitag;
     int16_t extra;
 };
+
+struct sectortypedisk
+{
+    int16_t wallptr, wallnum;
+    int32_t ceilingz, floorz;
+    uint16_t ceilingstat, floorstat;
+    int16_t ceilingpicnum, ceilingheinum;
+    int8_t ceilingshade;
+    uint8_t ceilingpal, ceilingxpanning, ceilingypanning;
+    int16_t floorpicnum, floorheinum;
+    int8_t floorshade;
+    uint8_t floorpal, floorxpanning, floorypanning;
+    uint8_t visibility, fogpal;
+    int16_t type;
+    int16_t hitag;
+    int16_t extra;
+};
+
+struct walltypedisk
+{
+    int32_t x, y;
+    int16_t point2, nextwall, nextsector;
+    uint16_t cstat;
+    int16_t picnum, overpicnum;
+    int8_t shade;
+    uint8_t pal, xrepeat, yrepeat, xpanning, ypanning;
+    int16_t type;
+    int16_t hitag;
+    int16_t extra;
+};
+
 #pragma pack(pop)
 
 
-int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC) {
+void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC) {
     int16_t tpskyoff[256];
     ClearAutomap();
     #ifdef NOONE_EXTENSIONS
@@ -477,15 +508,13 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
 
     if (!fr.isOpen())
     {
-        Printf("Error opening map file %s", mapname.GetChars());
-        return -1;
+        I_Error("Error opening map file %s", mapname.GetChars());
     }
     MAPSIGNATURE header;
     fr.Read(&header, 6);
     if (memcmp(header.signature, "BLM\x1a", 4))
     {
-        Printf("%s: Map file corrupted", mapname.GetChars());
-        return -1;
+        I_Error("%s: Map file corrupted", mapname.GetChars());
     }
     byte_1A76C8 = 0;
     if ((LittleShort(header.version) & 0xff00) == 0x700) {
@@ -499,8 +528,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
         #endif
 
     } else {
-        Printf("%s: Map file is wrong version", mapname.GetChars());
-        return -1;
+        I_Error("%s: Map file is wrong version", mapname.GetChars());
     }
 
     MAPHEADER mapHeader;
@@ -542,14 +570,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
         }
         else
         {
-            Printf("%s: Corrupted Map file", mapname.GetChars());
-            return -1;
+            I_Error("%s: Corrupted Map file", mapname.GetChars());
         }
     }
     else if (mapHeader.at16)
     {
-        Printf("%s: Corrupted Map file", mapname.GetChars());
-        return -1;
+        I_Error("%s: Corrupted Map file", mapname.GetChars());
     }
     parallaxtype = mapHeader.at1a;
     gMapRev = mapHeader.at1b;
@@ -587,27 +613,37 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
     for (int i = 0; i < numsectors; i++)
     {
         sectortype *pSector = &sector[i];
-        fr.Read(pSector, sizeof(sectortype));
+        sectortypedisk load;
+        fr.Read(&load, sizeof(sectortypedisk));
         if (byte_1A76C8)
         {
-            dbCrypt((char*)pSector, sizeof(sectortype), gMapRev*sizeof(sectortype));
+            dbCrypt((char*)&load, sizeof(sectortypedisk), gMapRev*sizeof(sectortypedisk));
         }
-        pSector->wallptr = LittleShort(pSector->wallptr);
-        pSector->wallnum = LittleShort(pSector->wallnum);
-        pSector->ceilingz = LittleLong(pSector->ceilingz);
-        pSector->floorz = LittleLong(pSector->floorz);
-        pSector->ceilingstat = LittleShort(pSector->ceilingstat);
-        pSector->floorstat = LittleShort(pSector->floorstat);
-        pSector->ceilingpicnum = LittleShort(pSector->ceilingpicnum);
-        pSector->ceilingheinum = LittleShort(pSector->ceilingheinum);
-        pSector->floorpicnum = LittleShort(pSector->floorpicnum);
-        pSector->floorheinum = LittleShort(pSector->floorheinum);
-        pSector->type = LittleShort(pSector->type);
-        pSector->hitag = LittleShort(pSector->hitag);
-        pSector->extra = LittleShort(pSector->extra);
-
-        qsector_filler[i] = pSector->fogpal;
+        pSector->wallptr = LittleShort(load.wallptr);
+        pSector->wallnum = LittleShort(load.wallnum);
+        pSector->ceilingz = LittleLong(load.ceilingz);
+        pSector->floorz = LittleLong(load.floorz);
+        pSector->ceilingstat = LittleShort(load.ceilingstat);
+        pSector->floorstat = LittleShort(load.floorstat);
+        pSector->ceilingpicnum = LittleShort(load.ceilingpicnum);
+        pSector->ceilingheinum = LittleShort(load.ceilingheinum);
+        pSector->floorpicnum = LittleShort(load.floorpicnum);
+        pSector->floorheinum = LittleShort(load.floorheinum);
+        pSector->type = LittleShort(load.type);
+        pSector->hitag = LittleShort(load.hitag);
+        pSector->extra = LittleShort(load.extra);
+        pSector->ceilingshade = load.ceilingshade;
+        pSector->ceilingpal = load.ceilingpal;
+        pSector->ceilingxpanning = load.ceilingxpanning;
+        pSector->ceilingypanning = load.ceilingypanning;
+        pSector->floorshade = load.floorshade;
+        pSector->floorpal = load.floorpal;
+        pSector->floorxpanning = load.floorxpanning;
+        pSector->floorypanning = load.floorypanning;
+        pSector->visibility = load.visibility;
+        qsector_filler[i] = load.fogpal;
         pSector->fogpal = 0;
+
         if (sector[i].extra > 0)
         {
             char pBuffer[nXSectorSize];
@@ -711,22 +747,30 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
     for (int i = 0; i < numwalls; i++)
     {
         walltype *pWall = &wall[i];
-        fr.Read(pWall, sizeof(walltype));
+        walltypedisk load;
+        fr.Read(&load, sizeof(walltypedisk));
         if (byte_1A76C8)
         {
-            dbCrypt((char*)pWall, sizeof(walltype), (gMapRev*sizeof(sectortype)) | 0x7474614d);
+            dbCrypt((char*)&load, sizeof(walltypedisk), (gMapRev*sizeof(sectortypedisk)) | 0x7474614d);
         }
-        pWall->x = LittleLong(pWall->x);
-        pWall->y = LittleLong(pWall->y);
-        pWall->point2 = LittleShort(pWall->point2);
-        pWall->nextwall = LittleShort(pWall->nextwall);
-        pWall->nextsector = LittleShort(pWall->nextsector);
-        pWall->cstat = LittleShort(pWall->cstat);
-        pWall->picnum = LittleShort(pWall->picnum);
-        pWall->overpicnum = LittleShort(pWall->overpicnum);
-        pWall->type = LittleShort(pWall->type);
-        pWall->hitag = LittleShort(pWall->hitag);
-        pWall->extra = LittleShort(pWall->extra);
+        pWall->x = LittleLong(load.x);
+        pWall->y = LittleLong(load.y);
+        pWall->point2 = LittleShort(load.point2);
+        pWall->nextwall = LittleShort(load.nextwall);
+        pWall->nextsector = LittleShort(load.nextsector);
+        pWall->cstat = LittleShort(load.cstat);
+        pWall->picnum = LittleShort(load.picnum);
+        pWall->overpicnum = LittleShort(load.overpicnum);
+        pWall->type = LittleShort(load.type);
+        pWall->hitag = LittleShort(load.hitag);
+        pWall->extra = LittleShort(load.extra);
+        pWall->shade = load.shade;
+        pWall->pal = load.pal;
+        pWall->xrepeat = load.xrepeat;
+        pWall->xpanning = load.xpanning;
+        pWall->yrepeat = load.yrepeat;
+        pWall->ypanning = load.ypanning;
+
         if (wall[i].extra > 0)
         {
             char pBuffer[nXWallSize];
@@ -927,8 +971,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
 
     if (CalcCRC32(buffer.Data(), buffer.Size() -4) != nCRC)
     {
-        Printf("%s: Map File does not match CRC", mapname.GetChars());
-        return -1;
+        I_Error("%s: Map File does not match CRC", mapname.GetChars());
     }
     if (pCRC)
         *pCRC = nCRC;
@@ -945,14 +988,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
         }
         else
         {
-            Printf("%s: Corrupted Map file", mapname.GetChars());
-            return -1;
+            I_Error("%s: Corrupted Map file", mapname.GetChars());
         }
     }
     else if (gSongId != 0)
     {
-        Printf("%s: Corrupted Map file", mapname.GetChars());
-        return -1;
+        I_Error("%s: Corrupted Map file", mapname.GetChars());
     }
 
     if ((header.version & 0xff00) == 0x600)
@@ -1002,14 +1043,18 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
             
         }
     }
-    return 0;
-}
 
-int32_t qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum)
-{
-    // NUKE-TODO: implement flags, see mapedit.cpp
-    return dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, (short*)daang, (short*)dacursectnum, NULL);
+    memcpy(wallbackup, wall, sizeof(wallbackup));
+    memcpy(sectorbackup, sector, sizeof(sectorbackup));
+    // todo: back up xsector and xwall as well
 }
 
 
 END_BLD_NS
+
+// only used by the backup loader.
+void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum)
+{
+    Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, (short*)daang, (short*)dacursectnum, NULL);
+    Blood::dbInit();    // clean up immediately.
+}
diff --git a/source/blood/src/db.h b/source/blood/src/db.h
index 1cb0ae149..6f255bbce 100644
--- a/source/blood/src/db.h
+++ b/source/blood/src/db.h
@@ -356,6 +356,6 @@ unsigned short dbInsertXSector(int nSector);
 void dbInit(void);
 void PropagateMarkerReferences(void);
 unsigned int dbReadMapCRC(const char *pPath);
-int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC);
+void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC);
 
 END_BLD_NS
diff --git a/source/blood/src/replace.cpp b/source/blood/src/replace.cpp
index 2589d7cd3..fc74d7950 100644
--- a/source/blood/src/replace.cpp
+++ b/source/blood/src/replace.cpp
@@ -76,7 +76,6 @@ int32_t qinsertsprite(int16_t nSector, int16_t nStat);
 int32_t qdeletesprite(int16_t nSprite);
 int32_t qchangespritesect(int16_t nSprite, int16_t nSector);
 int32_t qchangespritestat(int16_t nSprite, int16_t nStatus);
-int32_t qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum);
 
 void HookReplaceFunctions(void)
 {
diff --git a/source/build/include/build.h b/source/build/include/build.h
index 952f7a954..001372cff 100644
--- a/source/build/include/build.h
+++ b/source/build/include/build.h
@@ -248,7 +248,6 @@ struct usermaphack_t
 
 extern usermaphack_t g_loadedMapHack;
 
-#if !defined DEBUG_MAIN_ARRAYS
 EXTERN spriteext_t *spriteext;
 EXTERN spritesmooth_t *spritesmooth;
 
@@ -256,31 +255,16 @@ EXTERN sectortype *sector;
 EXTERN walltype *wall;
 EXTERN spritetype *sprite;
 EXTERN tspriteptr_t tsprite;
-#else
-#endif
+
+extern sectortype sectorbackup[MAXSECTORS];
+extern walltype wallbackup[MAXWALLS];
 
 
 static inline tspriteptr_t renderMakeTSpriteFromSprite(tspriteptr_t const tspr, uint16_t const spritenum)
 {
     auto const spr = &sprite[spritenum];
 
-    tspr->pos = spr->pos;
-    tspr->cstat = spr->cstat;
-    tspr->picnum = spr->picnum;
-    tspr->shade = spr->shade;
-    tspr->pal = spr->pal;
-    tspr->blend = spr->blend;
-    tspr->xrepeat = spr->xrepeat;
-    tspr->yrepeat = spr->yrepeat;
-    tspr->xoffset = spr->xoffset;
-    tspr->yoffset = spr->yoffset;
-    tspr->sectnum = spr->sectnum;
-    tspr->statnum = spr->statnum;
-    tspr->ang = spr->ang;
-    tspr->vel = spr->vel;
-    tspr->lotag = spr->lotag;
-    tspr->hitag = spr->hitag;
-    tspr->extra = spr->extra;
+    *tspr = *spr;
 
     tspr->clipdist = 0;
     tspr->owner = spritenum;
@@ -561,9 +545,8 @@ void   engineUnInit(void);
 void   initspritelists(void);
 
 void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
-int32_t   engineLoadMHK(const char *filename);
+void loadMapBackup(const char* filename);
 void G_LoadMapHack(const char* filename);
-int32_t   saveboard(const char *filename, const vec3_t *dapos, int16_t daang, int16_t dacursectnum);
 
 int32_t   qloadkvx(int32_t voxindex, const char *filename);
 void vox_undefine(int32_t const);
diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp
index ebbff0f41..d1955707a 100644
--- a/source/core/maploader.cpp
+++ b/source/core/maploader.cpp
@@ -40,6 +40,7 @@
 #include "printf.h"
 #include "inputstate.h"
 #include "md4.h"
+#include "gamecontrol.h"
 
 
 static void ReadSectorV7(FileReader& fr, sectortype& sect)
@@ -63,7 +64,7 @@ static void ReadSectorV7(FileReader& fr, sectortype& sect)
 	sect.floorxpanning = fr.ReadUInt8();
 	sect.floorypanning = fr.ReadUInt8();
 	sect.visibility = fr.ReadUInt8();
-	sect.fogpal = fr.ReadUInt8(); // note: currently unused.
+	sect.fogpal = fr.ReadUInt8(); // note: currently unused, except for Blood.
 	sect.lotag = fr.ReadInt16();
 	sect.hitag = fr.ReadInt16();
 	sect.extra = fr.ReadInt16();
@@ -440,4 +441,27 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
 	guniqhudid = 0;
 	G_LoadMapHack(filename);
 
+	memcpy(wallbackup, wall, sizeof(wallbackup));
+	memcpy(sectorbackup, sector, sizeof(sectorbackup));
 }
+
+
+void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum);
+
+
+// loads a map into the backup buffer.
+void loadMapBackup(const char* filename)
+{
+	vec3_t pos;
+	int16_t scratch;
+
+	if (g_gameType & GAMEFLAG_BLOOD)
+	{
+		qloadboard(filename, 0, &pos, &scratch, &scratch);
+	}
+	else
+	{
+		engineLoadBoard(filename, 0, &pos, &scratch, &scratch);
+		initspritelists();
+	}
+}
\ No newline at end of file
diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp
index 34e25e077..e93023b4e 100644
--- a/source/core/savegamehelp.cpp
+++ b/source/core/savegamehelp.cpp
@@ -56,6 +56,10 @@
 #include "gamestate.h"
 #include "razemenu.h"
 
+
+sectortype sectorbackup[MAXSECTORS];
+walltype wallbackup[MAXWALLS];
+
 static CompositeSavegameWriter savewriter;
 static FResourceFile *savereader;
 void LoadEngineState();
@@ -135,6 +139,7 @@ bool OpenSaveGameForRead(const char *name)
 		info->Unlock();
 
 		// Load system-side data from savegames.
+		loadMapBackup(currentLevel->fileName);
 		LoadEngineState();
 		SerializeSession(arc); // must be AFTER LoadEngineState because it needs info from it.
 		gi->SerializeGameState(arc);
@@ -468,8 +473,6 @@ static walltype zwal;
 
 FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectortype *def)
 {
-	def = &zsec;
-	if (arc.isReading()) c = {};
 	if (arc.BeginObject(key))
 	{
 		arc("wallptr", c.wallptr, def->wallptr)
@@ -502,8 +505,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectort
 
 FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype *def)
 {
-	def = &zwal;
-	if (arc.isReading()) c = {};
 	if (arc.BeginObject(key))
 	{
 		arc("x", c.x, def->x)
@@ -533,9 +534,9 @@ void SerializeMap(FSerializer& arc)
 	if (arc.BeginObject("engine"))
 	{
 		arc ("numsectors", numsectors)
-			.Array("sectors", sector, numsectors)
+			.Array("sectors", sector, sectorbackup, numsectors)
 			("numwalls", numwalls)
-			.Array("walls", wall, numwalls)
+			.Array("walls", wall, wallbackup, numwalls)
 			.EndObject();
 	}