diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp
index a2f60b92dfebb791171178477e56603ac092c409..a8890ed2179e55a5f7a3de6f1e9c367803f68339 100644
--- a/src/g_gamedata.cpp
+++ b/src/g_gamedata.cpp
@@ -287,15 +287,28 @@ void srb2::save_ng_gamedata()
 
 	std::string gamedataname_s {gamedatafilename};
 	fs::path savepath {fmt::format("{}/{}", srb2home, gamedataname_s)};
-	int random_number = rand();
-	fs::path tmpsavepath {fmt::format("{}/{}_{}.tmp", srb2home, gamedataname_s, random_number)};
+	fs::path baksavepath {fmt::format("{}/{}.bak", srb2home, gamedataname_s)};
 
 	json ngdata_json = ng;
 
+
+	if (fs::exists(savepath))
+	{
+		try
+		{
+			fs::rename(savepath, baksavepath);
+		}
+		catch (const fs::filesystem_error& ex)
+		{
+			CONS_Alert(CONS_ERROR, "Failed to record backup save. Not attempting to save. %s\n", ex.what());
+			return;
+		}
+	}
+
 	try
 	{
-		std::string tmpsavepathstring = tmpsavepath.string();
-		srb2::io::FileStream file {tmpsavepathstring, srb2::io::FileStreamMode::kWrite};
+		std::string savepathstring = savepath.string();
+		srb2::io::FileStream file {savepathstring, srb2::io::FileStreamMode::kWrite};
 
 		// The header is necessary to validate during loading.
 		srb2::io::write(static_cast<uint32_t>(GD_VERSION_MAJOR), file); // major
@@ -308,21 +321,11 @@ void srb2::save_ng_gamedata()
 	}
 	catch (const std::exception& ex)
 	{
-		CONS_Alert(CONS_ERROR, "NG Gamedata save failed: %s\n", ex.what());
+		CONS_Alert(CONS_ERROR, "NG Gamedata save failed. Check directory for a ringdata.dat.bak. %s\n", ex.what());
 	}
 	catch (...)
 	{
-		CONS_Alert(CONS_ERROR, "NG Gamedata save failed\n");
-	}
-
-	try
-	{
-		// Now that the save is written successfully, move it over the old save
-		fs::rename(tmpsavepath, savepath);
-	}
-	catch (const fs::filesystem_error& ex)
-	{
-		CONS_Alert(CONS_ERROR, "NG Gamedata save succeeded but did not replace old save successfully: %s\n", ex.what());
+		CONS_Alert(CONS_ERROR, "NG Gamedata save failed. Check directory for a ringdata.dat.bak.\n");
 	}
 }
 
diff --git a/src/k_profiles.cpp b/src/k_profiles.cpp
index 3491d70fc2256da62b53fd1e7edf8d52cea44518..0b9425fcb6b33959e1821aa13cbdd1b2e727dd86 100644
--- a/src/k_profiles.cpp
+++ b/src/k_profiles.cpp
@@ -319,12 +319,24 @@ void PR_SaveProfiles(void)
 	std::vector<uint8_t> ubjson = json::to_ubjson(ng);
 
 	std::string realpath = fmt::format("{}/{}", srb2home, PROFILESFILE);
-	int random_number = rand();
-	std::string tmppath = fmt::format("{}_{}.tmp", realpath, random_number);
+	std::string bakpath = fmt::format("{}.bak", realpath);
+
+	if (fs::exists(realpath))
+	{
+		try
+		{
+			fs::rename(realpath, bakpath);
+		}
+		catch (const fs::filesystem_error& ex)
+		{
+			CONS_Alert(CONS_ERROR, "Failed to record profiles backup. Not attempting to save profiles. %s\n", ex.what());
+			return;
+		}
+	}
 
 	try
 	{
-		io::FileStream file {tmppath, io::FileStreamMode::kWrite};
+		io::FileStream file {realpath, io::FileStreamMode::kWrite};
 
 		io::write(static_cast<uint32_t>(0x52494E47), file, io::Endian::kBE); // "RING"
 		io::write(static_cast<uint32_t>(0x5052464C), file, io::Endian::kBE); // "PRFL"
@@ -334,16 +346,14 @@ void PR_SaveProfiles(void)
 		io::write(static_cast<uint8_t>(0), file); // reserved4
 		io::write_exact(file, tcb::as_bytes(tcb::make_span(ubjson)));
 		file.close();
-
-		fs::rename(tmppath, realpath);
 	}
 	catch (const std::exception& ex)
 	{
-		I_Error("Couldn't save profiles. Are you out of Disk space / playing in a protected folder?\n\nException: %s", ex.what());
+		I_Error("Couldn't save profiles. Are you out of Disk space / playing in a protected folder? Check directory for a ringprofiles.prf.bak if the profiles file is corrupt.\n\nException: %s", ex.what());
 	}
 	catch (...)
 	{
-		I_Error("Couldn't save profiles. Are you out of Disk space / playing in a protected folder?");
+		I_Error("Couldn't save profiles. Are you out of Disk space / playing in a protected folder? Check directory for a ringprofiles.prf.bak if the profiles file is corrupt.");
 	}
 }