diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp
index 6fcf6e135d5e27c7b2aeb3dab3c7ef7bd21eadc2..e4a2b6b7ae4a57b3dd092e99285327814f7a64f5 100644
--- a/src/g_gamedata.cpp
+++ b/src/g_gamedata.cpp
@@ -28,6 +28,9 @@
 namespace fs = std::filesystem;
 using json = nlohmann::json;
 
+#define GD_VERSION_MAJOR (0xBA5ED321)
+#define GD_VERSION_MINOR (1)
+
 void srb2::save_ng_gamedata()
 {
 	if (gamedata == NULL || !gamedata->loaded)
@@ -294,8 +297,8 @@ void srb2::save_ng_gamedata()
 		srb2::io::BufferedOutputStream<srb2::io::FileStream> bos {std::move(file)};
 
 		// The header is necessary to validate during loading.
-		srb2::io::write(static_cast<uint32_t>(0xBA5ED321), bos); // major
-		srb2::io::write(static_cast<uint8_t>(0), bos); // minor/flags
+		srb2::io::write(static_cast<uint32_t>(GD_VERSION_MAJOR), bos); // major
+		srb2::io::write(static_cast<uint8_t>(GD_VERSION_MINOR), bos); // minor/flags
 		srb2::io::write(static_cast<uint8_t>(gamedata->evercrashed), bos); // dirty (crash recovery)
 
 		std::vector<uint8_t> ubjson = json::to_ubjson(ng);
@@ -414,7 +417,7 @@ void srb2::load_ng_gamedata()
 		return;
 	}
 
-	if (majorversion != 0xBA5ED321)
+	if (majorversion != GD_VERSION_MAJOR)
 	{
 		const char* gdfolder = G_GameDataFolder();
 		I_Error("Game data is not for Ring Racers v2.0.\nDelete %s (maybe in %s) and try again.", gamedatafilename, gdfolder);
@@ -829,7 +832,42 @@ void srb2::load_ng_gamedata()
 		}
 	}
 
+	bool converted = false;
+	UINT32 chao_key_rounds = GDCONVERT_ROUNDSTOKEY;
+	UINT32 start_keys = GDINIT_CHAOKEYS;
+
+	if (minorversion == 0)
+	{
+		chao_key_rounds = 14;
+		start_keys = 3;
+	}
+
+	if (chao_key_rounds != GDCONVERT_ROUNDSTOKEY)
+	{
+		// Chao key rounds changed.
+		// Just reset all round progress, because there is a dumbass
+		// bug that can cause infinite chao keys from loading.
+		gamedata->pendingkeyrounds = 0;
+		gamedata->pendingkeyroundoffset = 0;
+		gamedata->keyspending = 0;
+		converted = true;
+	}
+
+	if (GDINIT_CHAOKEYS > start_keys)
+	{
+		// Chao key starting amount changed.
+		// Give some free keys!
+		gamedata->chaokeys += GDINIT_CHAOKEYS - start_keys;
+		converted = true;
+	}
+
 	M_FinaliseGameData();
+
+	if (converted)
+	{
+		CONS_Printf("Gamedata was converted from version %d to version %d\n",
+			minorversion, GD_VERSION_MINOR);
+	}
 }
 
 // G_LoadGameData
diff --git a/src/m_cond.h b/src/m_cond.h
index 88905fda528b2f6de63dc76662c37489e6114409..b9197f3f036179c7a1d19b26d22c03748f42a8db 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -299,9 +299,9 @@ typedef enum {
 #define GDMAX_CHAOKEYS 9999
 #define GDMAX_SEALEDSWAPS 7
 
-#define GDCONVERT_ROUNDSTOKEY 14
+#define GDCONVERT_ROUNDSTOKEY 5
 
-#define GDINIT_CHAOKEYS 3 // Start with 3 Chao Keys !!
+#define GDINIT_CHAOKEYS 10 // Start with 10 Chao Keys !!
 #define GDINIT_PRISONSTOPRIZE 30 // 30 Prison Eggs to your [Wild Prize] !!
 
 typedef enum {