Index: binaries/data/mods/public/gui/common/functions_utility_loadsave.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility_loadsave.js	(révision 14624)
+++ binaries/data/mods/public/gui/common/functions_utility_loadsave.js	(copie de travail)
@@ -8,11 +8,48 @@
 	return n < 10 ? "0" + n : n;
 }
 
-function generateLabel(metadata)
+function generateLabel(metadata, engineInfo)
 {
 	var t = new Date(metadata.time*1000);
-
 	var date = t.getFullYear()+"-"+twoDigits(1+t.getMonth())+"-"+twoDigits(t.getDate());
 	var time = twoDigits(t.getHours())+":"+twoDigits(t.getMinutes())+":"+twoDigits(t.getSeconds());
-	return "["+date+" "+time+"] "+metadata.initAttributes.map+(metadata.description ? " - "+metadata.description : "");
+	var label = "["+date+" "+time+"] ";
+
+	if (engineInfo)
+	{
+		if (!hasSameVersion(metadata, engineInfo))
+			label = "[color=\"red\"]" + label + "[/color]";
+		else if (!hasSameMods(metadata, engineInfo))
+			label = "[color=\"orange\"]" + label + "[/color]";
+	}
+
+	label += metadata.initAttributes.map.replace("maps/","")
+		+ (metadata.description ? " - "+metadata.description : "");
+	return label;
 }
+
+/**
+ * Check the version compatibility between the saved game to be loaded and the engine
+ */
+function hasSameVersion(metadata, engineInfo)
+{
+	return (metadata.version_major == engineInfo.version_major);
+}
+
+/**
+ * Check the mod compatibility between the saved game to be loaded and the engine
+ */
+function hasSameMods(metadata, engineInfo)
+{
+	if (!metadata.mods)         // only here for backwards compatibility with previous saved games
+		var gameMods = [];
+	else
+		var gameMods = metadata.mods;
+
+	if (gameMods.length != engineInfo.mods.length)
+		return false;
+	for (var i = 0; i < gameMods.length; ++i)
+		if (gameMods[i] != engineInfo.mods[i])
+			return false;
+	return true;
+}
Index: binaries/data/mods/public/gui/savedgames/load.js
===================================================================
--- binaries/data/mods/public/gui/savedgames/load.js	(révision 14624)
+++ binaries/data/mods/public/gui/savedgames/load.js	(copie de travail)
@@ -1,3 +1,5 @@
+var gameMetadatas = [];
+
 function init()
 {
 	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
@@ -3,34 +5,68 @@
 
 	var savedGames = Engine.GetSavedGames();
-	if (savedGames.length == 0)
-	{
-		gameSelection.list = [ "No saved games found" ];
-		gameSelection.selected = 0;
-		Engine.GetGUIObjectByName("loadGameButton").enabled = false;
-		Engine.GetGUIObjectByName("deleteGameButton").enabled = false;
-		return;
-	}
 
+	// get current game version and loaded mods 
+	var engineInfo = Engine.GetEngineInfo();
+
 	savedGames.sort(sortDecreasingDate);
 
-	var gameListIDs = [ game.id for each (game in savedGames) ];
-	var gameListLabels = [ generateLabel(game.metadata) for each (game in savedGames) ];
+	var gameListIds = [ game.id for each (game in savedGames) ];
+	var gameListLabels = [ generateLabel(game.metadata, engineInfo) for each (game in savedGames) ];
+	gameMetadatas = [ game.metadata for each (game in savedGames) ];
 
 	gameSelection.list = gameListLabels;
-	gameSelection.list_data = gameListIDs;
-	gameSelection.selected = 0;
+	gameSelection.list_data = gameListIds;
+	if (gameSelection.selected == -1) 
+		gameSelection.selected = 0;
 }
 
 function loadGame()
 {
 	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
-	var gameID = gameSelection.list_data[gameSelection.selected];
+	var gameId = gameSelection.list_data[gameSelection.selected];
+	var gameLabel = gameSelection.list[gameSelection.selected];
+	var metadata = gameMetadatas[gameSelection.selected];
 
-	var metadata = Engine.StartSavedGame(gameID);
+	// check game compatibility before really loading it
+	var engineInfo = Engine.GetEngineInfo();
+	if (!hasSameVersion(metadata, engineInfo) || !hasSameMods(metadata, engineInfo))
+	{
+		// version not compatible ... ask for confirmation
+		var btCaptions = ["Yes", "No"];
+		var btCode = [function(){ reallyLoadGame(gameId); }, init];
+		var message = "This saved game may not be compatible:";
+		if (!hasSameVersion(metadata, engineInfo))
+			message += "\nIt needs 0AD version " + metadata.version_major
+				+ " while you are running version " + engineInfo.version_major + ".";
+
+		if (!hasSameMods(metadata, engineInfo))
+		{
+			if (!metadata.mods)         // only for backwards compatibility with previous saved games
+				metadata.mods = [];
+			if (metadata.mods.length == 0)
+				message += "\nIt does not need any mod"
+					+ " while you are running with \"" + engineInfo.mods.join() + "\".";
+			else if (engineInfo.mods.length == 0)
+				message += "\nIt needs the mod \"" + metadata.mods.join() + "\""
+					+ " while you are running without mod.";
+			else
+				message += "\nIt needs the mod \"" + metadata.mods.join() + "\""
+					+ " while you are running with \"" + engineInfo.mods.join() + "\".";
+		}
+		message += "\nDo you still want to proceed ?";
+		messageBox(500, 250, message, "Warning", 0, btCaptions, btCode);
+	}
+	else
+		reallyLoadGame(gameId);
+}
+
+function reallyLoadGame(gameId)
+{
+	var metadata = Engine.StartSavedGame(gameId);
 	if (!metadata)
 	{
 		// Probably the file wasn't found
 		// Show error and refresh saved game list
-		error("Could not load saved game '"+gameID+"'");
+		error("Could not load saved game '"+gameId+"'");
 		init();
 	}
Index: source/gui/scripting/ScriptFunctions.cpp
===================================================================
--- source/gui/scripting/ScriptFunctions.cpp	(révision 14624)
+++ source/gui/scripting/ScriptFunctions.cpp	(copie de travail)
@@ -194,6 +194,11 @@
 		g_Game->SetPlayerID(id);
 }
 
+CScriptValRooted GetEngineInfo(ScriptInterface::CxPrivate* pCxPrivate)
+{
+	return SavedGames::GetEngineInfo(*(pCxPrivate->pScriptInterface));
+}
+
 void StartNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	ENSURE(g_NetServer);
@@ -822,6 +827,7 @@
 	scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer");
 	scriptInterface.RegisterFunction<void, std::wstring, &SendNetworkChat>("SendNetworkChat");
 	scriptInterface.RegisterFunction<std::vector<CScriptValRooted>, &GetAIs>("GetAIs");
+	scriptInterface.RegisterFunction<CScriptValRooted, &GetEngineInfo>("GetEngineInfo");
 
 	// Saved games
 	scriptInterface.RegisterFunction<CScriptVal, std::wstring, &StartSavedGame>("StartSavedGame");
Index: source/ps/GameSetup/Config.cpp
===================================================================
--- source/ps/GameSetup/Config.cpp	(révision 14624)
+++ source/ps/GameSetup/Config.cpp	(copie de travail)
@@ -76,6 +76,7 @@
 // If non-empty, specified map will be automatically loaded
 CStr g_AutostartMap = "";
 
+std::vector<std::string> g_modsLoaded;
 
 //----------------------------------------------------------------------------
 // config
Index: source/ps/GameSetup/Config.h
===================================================================
--- source/ps/GameSetup/Config.h	(révision 14624)
+++ source/ps/GameSetup/Config.h	(copie de travail)
@@ -90,6 +90,9 @@
 
 extern CStrW g_CursorName;
 
+// list of mods currently loaded
+extern std::vector<std::string> g_modsLoaded;
+
 class CmdLineArgs;
 extern void CONFIG_Init(const CmdLineArgs& args);
 
Index: source/ps/GameSetup/GameSetup.cpp
===================================================================
--- source/ps/GameSetup/GameSetup.cpp	(révision 14624)
+++ source/ps/GameSetup/GameSetup.cpp	(copie de travail)
@@ -391,6 +391,10 @@
 static std::vector<CStr> GetMods(const CmdLineArgs& args, bool dev)
 {
 	std::vector<CStr> mods = args.GetMultiple("mod");
+	// List of the mods, to be used by the Gui
+	g_modsLoaded.clear();
+	for (size_t i = 0; i < mods.size(); ++i)
+		g_modsLoaded.push_back((std::string)mods[i]);
 	// TODO: It would be nice to remove this hard-coding
 	mods.insert(mods.begin(), "public");
 
Index: source/ps/SavedGame.cpp
===================================================================
--- source/ps/SavedGame.cpp	(révision 14624)
+++ source/ps/SavedGame.cpp	(copie de travail)
@@ -24,6 +24,7 @@
 #include "lib/file/archive/archive_zip.h"
 #include "ps/CLogger.h"
 #include "ps/Filesystem.h"
+#include "ps/GameSetup/Config.h"
 #include "scriptinterface/ScriptInterface.h"
 #include "simulation2/Simulation2.h"
 
@@ -76,6 +77,7 @@
 	simulation.GetScriptInterface().Eval("({})", metadata);
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "version_major", SAVED_GAME_VERSION_MAJOR);
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "version_minor", SAVED_GAME_VERSION_MINOR);
+	simulation.GetScriptInterface().SetProperty(metadata.get(), "mods", g_modsLoaded);
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "time", (double)now);
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "player", playerID);
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "initAttributes", simulation.GetInitAttributes());
@@ -241,3 +243,14 @@
 	// Successfully deleted file
 	return true;
 }
+
+CScriptValRooted SavedGames::GetEngineInfo(ScriptInterface& scriptInterface) 
+{ 
+	CScriptValRooted metainfo; 
+	scriptInterface.Eval("({})", metainfo); 
+	scriptInterface.SetProperty(metainfo.get(), "version_major", SAVED_GAME_VERSION_MAJOR); 
+	scriptInterface.SetProperty(metainfo.get(), "version_minor", SAVED_GAME_VERSION_MINOR); 
+	scriptInterface.SetProperty(metainfo.get(), "mods"         , g_modsLoaded);
+	return metainfo; 
+}
+
Index: source/ps/SavedGame.h
===================================================================
--- source/ps/SavedGame.h	(révision 14624)
+++ source/ps/SavedGame.h	(copie de travail)
@@ -92,6 +92,14 @@
  */
 bool DeleteSavedGame(const std::wstring& name);
 
+/**
+ * Gets info (version and mods loaded) on the running engine
+ *
+ * @param scriptInterface the ScriptInterface in which to create the return data.
+ * @return list of objects containing saved game data
+ */
+CScriptValRooted GetEngineInfo(ScriptInterface& scriptInterface);
+
 }
 
 #endif // INCLUDED_SAVEDGAME
