← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/map_packet_loading into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/map_packet_loading into lp:widelands.

Commit message:
Map compatibility:
- No longer saving or loading unneeded packages in the editor.
- Removed compatibility code from MapBuildingPacket.


Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1531463 in widelands: "Do not load unneeded packages with map loading"
  https://bugs.launchpad.net/widelands/+bug/1531463

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/map_packet_loading/+merge/284470

Old maps now should load fine again, because the unneeded packets are omitted in the editor both when loading and saving.

I have used "Together We're Strong" and "The Green Plateau" from Build 18 as test cases.

-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/map_packet_loading into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2016-01-28 21:27:04 +0000
+++ src/editor/editorinteractive.cc	2016-01-29 15:16:47 +0000
@@ -42,6 +42,7 @@
 #include "logic/map_objects/world/resource_description.h"
 #include "logic/map_objects/world/world.h"
 #include "logic/player.h"
+#include "map_io/map_loader.h"
 #include "map_io/widelands_map_loader.h"
 #include "scripting/lua_interface.h"
 #include "scripting/lua_table.h"
@@ -223,7 +224,7 @@
 		egbase().add_player(p, 0, map.get_scenario_player_tribe(p), map.get_scenario_player_name(p));
 	}
 
-	ml->load_map_complete(egbase(), true);
+	ml->load_map_complete(egbase(), Widelands::MapLoader::LoadType::kEditor);
 	egbase().load_graphics(loader_ui);
 	map_changed(MapWas::kReplaced);
 }

=== modified file 'src/game_io/game_map_packet.cc'
--- src/game_io/game_map_packet.cc	2014-09-20 09:37:47 +0000
+++ src/game_io/game_map_packet.cc	2016-01-29 15:16:47 +0000
@@ -54,7 +54,7 @@
 
 
 void GameMapPacket::read_complete(Game & game) {
-	m_wml->load_map_complete(game, true);
+	m_wml->load_map_complete(game, MapLoader::LoadType::kScenario);
 	m_mol = m_wml->get_map_object_loader();
 }
 

=== modified file 'src/logic/game.cc'
--- src/logic/game.cc	2016-01-08 21:00:39 +0000
+++ src/logic/game.cc	2016-01-29 15:16:47 +0000
@@ -254,7 +254,7 @@
 		 	(*this, g_options.pull_section("global"), 1, false));
 
 	loaderUI.step(_("Loading map"));
-	maploader->load_map_complete(*this, true);
+	maploader->load_map_complete(*this, Widelands::MapLoader::LoadType::kScenario);
 	maploader.reset();
 
 	set_game_controller(new SinglePlayerGameController(*this, true, 1));
@@ -340,7 +340,10 @@
 
 	if (loaderUI)
 		loaderUI->step(_("Loading map"));
-	maploader->load_map_complete(*this, settings.scenario);
+	maploader->load_map_complete(*this,
+										  settings.scenario ?
+											  Widelands::MapLoader::LoadType::kScenario :
+											  Widelands::MapLoader::LoadType::kGame);
 
 	// Check for win_conditions
 	if (!settings.scenario) {

=== modified file 'src/logic/map_info.cc'
--- src/logic/map_info.cc	2016-01-24 12:43:26 +0000
+++ src/logic/map_info.cc	2016-01-29 15:16:47 +0000
@@ -85,7 +85,7 @@
 		}
 
 		ml->preload_map(true);
-		ml->load_map_complete(egbase, true);
+		ml->load_map_complete(egbase, Widelands::MapLoader::LoadType::kScenario);
 
 		std::unique_ptr<Texture> minimap(
 		   draw_minimap(egbase, nullptr, Point(0, 0), MiniMapLayer::Terrain));

=== modified file 'src/map_io/map_building_packet.cc'
--- src/map_io/map_building_packet.cc	2015-11-28 22:29:26 +0000
+++ src/map_io/map_building_packet.cc	2016-01-29 15:16:47 +0000
@@ -38,8 +38,6 @@
 namespace Widelands {
 
 constexpr uint16_t kCurrentPacketVersion = 3;
-constexpr uint16_t kLowestSupportedVersion = 1;
-constexpr uint16_t kPrioritiesIntroducedInVersion = 2;
 
 // constants to handle special building types
 constexpr uint8_t kTypeBuilding = 0;
@@ -57,7 +55,7 @@
 	InteractiveBase & ibase = *egbase.get_ibase();
 	try {
 		uint16_t const packet_version = fr.unsigned_16();
-		if (packet_version >= kLowestSupportedVersion && packet_version <= kCurrentPacketVersion) {
+		if (packet_version == kCurrentPacketVersion) {
 			Map & map = egbase.map();
 			uint16_t const width  = map.get_width ();
 			uint16_t const height = map.get_height();
@@ -98,10 +96,7 @@
 							}
 
 							mol.register_object<Building> (serial, *building);
-
-							if (packet_version >= kPrioritiesIntroducedInVersion) {
-								read_priorities (*building, fr);
-							}
+							read_priorities (*building, fr);
 
 							//  Reference the players tribe if in editor.
 							if (g_gr) // but not on dedicated servers ;)

=== modified file 'src/map_io/map_loader.h'
--- src/map_io/map_loader.h	2014-10-04 09:40:18 +0000
+++ src/map_io/map_loader.h	2016-01-29 15:16:47 +0000
@@ -36,12 +36,18 @@
 /// must be selected.
 class MapLoader {
 public:
+	enum class LoadType {
+		kGame,
+		kScenario,
+		kEditor
+	};
+
 	MapLoader(const std::string& filename, Map & M)
 		: m_map(M), m_s(STATE_INIT) {m_map.set_filename(filename);}
 	virtual ~MapLoader() {}
 
 	virtual int32_t preload_map(bool as_scenario) = 0;
-	virtual int32_t load_map_complete(EditorGameBase &, bool as_scenario) = 0;
+	virtual int32_t load_map_complete(EditorGameBase &, MapLoader::LoadType) = 0;
 
 	Map & map() {return m_map;}
 

=== modified file 'src/map_io/map_saver.cc'
--- src/map_io/map_saver.cc	2016-01-18 19:08:41 +0000
+++ src/map_io/map_saver.cc	2016-01-29 15:16:47 +0000
@@ -76,6 +76,8 @@
 	delete m_mos;
 	m_mos = new MapObjectSaver();
 
+	bool is_game = is_a(Game, &m_egbase);
+
 	// The binary data is saved in an own directory
 	// to keep it hidden from the poor debuggers
 	m_fs.ensure_directory_exists("binary");
@@ -109,12 +111,15 @@
 	{MapPlayerPositionPacket         p; p.write(m_fs, m_egbase, *m_mos);}
 	log("took %ums\n ", timer.ms_since_last_query());
 
-	//  This must come before anything that references messages, such as:
-	//    * command queue (PlayerMessageCommand, inherited by
-	//      Cmd_MessageSetStatusRead and Cmd_MessageSetStatusArchived)
-	log("Writing Player Message Data ... ");
-	{MapPlayersMessagesPacket        p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
+	// We don't save these when saving a map in the editor.
+	if (is_game) {
+		//  This must come before anything that references messages, such as:
+		//    * command queue (PlayerMessageCommand, inherited by
+		//      Cmd_MessageSetStatusRead and Cmd_MessageSetStatusArchived)
+		log("Writing Player Message Data ... ");
+		{MapPlayersMessagesPacket        p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+	}
 
 	log("Writing Resources Data ... ");
 	{MapResourcesPacket               p; p.write(m_fs, m_egbase);}
@@ -129,20 +134,19 @@
 	{MapVersionPacket               p; p.write(m_fs, m_egbase, *m_mos);}
 	log("took %ums\n ", timer.ms_since_last_query());
 
-
-	const Map & map = m_egbase.map();
-
-	PlayerNumber const nr_players = map.get_nrplayers();
-
-	//  allowed worker types
-	log("Writing Allowed Worker Types Data ... ");
-	{MapAllowedWorkerTypesPacket p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-    //  allowed building types
-    // Not saving this when in editor - it causes issues when changing tribe
-    // after next load in editor
-	if (is_a(Game, &m_egbase)) {
+	// We don't save these when saving a map in the editor.
+	if (is_game) {
+
+		const Map & map = m_egbase.map();
+
+		PlayerNumber const nr_players = map.get_nrplayers();
+
+		//  allowed worker types
+		log("Writing Allowed Worker Types Data ... ");
+		{MapAllowedWorkerTypesPacket p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		 //  allowed building types
 		iterate_players_existing_const(plnum, nr_players, m_egbase, player) {
 			for (DescriptionIndex i = 0; i < m_egbase.tribes().nrbuildings(); ++i) {
 				if (!player->is_building_type_allowed(i)) {
@@ -154,59 +158,64 @@
 				}
 			}
 		} end_find_a_forbidden_building_type_loop:;
+
+		// !!!!!!!!!! NOTE
+		// This packet must be written before any building or road packet. So do not
+		// change this order unless you know what you are doing
+		// EXISTING PACKETS
+		log("Writing Flag Data ... ");
+		{MapFlagPacket                   p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Writing Road Data ... ");
+		{MapRoadPacket                   p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Writing Building Data ... ");
+		{MapBuildingPacket               p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
 	}
 
-	// !!!!!!!!!! NOTE
-	// This packet must be before any building or road packet. So do not
-	// change this order without knowing what you do
-	// EXISTENT PACKETS
-	log("Writing Flag Data ... ");
-	{MapFlagPacket                   p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Writing Road Data ... ");
-	{MapRoadPacket                   p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Writing Building Data ... ");
-	{MapBuildingPacket               p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
+	// We do need to save this one in the editor!
 	log("Writing Map Objects ... ");
 	{MapObjectPacket                      p; p.write(m_fs, m_egbase, *m_mos);}
 	log("took %ums\n ", timer.ms_since_last_query());
 
-	// DATA PACKETS
-	if (m_mos->get_nr_flags()) {
-		log("Writing Flagdata Data ... ");
-		{MapFlagdataPacket            p; p.write(m_fs, m_egbase, *m_mos);}
-		log("took %ums\n ", timer.ms_since_last_query());
-	}
-
-	if (m_mos->get_nr_roads()) {
-		log("Writing Roaddata Data ... ");
-		{MapRoaddataPacket            p; p.write(m_fs, m_egbase, *m_mos);}
-		log("took %ums\n ", timer.ms_since_last_query());
-	}
-
-	if (m_mos->get_nr_buildings()) {
-		log("Writing Buildingdata Data ... ");
-		{MapBuildingdataPacket        p; p.write(m_fs, m_egbase, *m_mos);}
-		log("took %ums\n ", timer.ms_since_last_query());
-	}
-
-	log("Writing Node Ownership Data ... ");
-	{MapNodeOwnershipPacket         p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Writing Exploration Data ... ");
-	{MapExplorationPacket            p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Writing Players Unseen Data ... ");
-	{MapPlayersViewPacket           p; p.write(m_fs, m_egbase, *m_mos);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
+	if (is_game) {
+		// DATA PACKETS
+		if (m_mos->get_nr_flags()) {
+			log("Writing Flagdata Data ... ");
+			{MapFlagdataPacket            p; p.write(m_fs, m_egbase, *m_mos);}
+			log("took %ums\n ", timer.ms_since_last_query());
+		}
+
+		if (m_mos->get_nr_roads()) {
+			log("Writing Roaddata Data ... ");
+			{MapRoaddataPacket            p; p.write(m_fs, m_egbase, *m_mos);}
+			log("took %ums\n ", timer.ms_since_last_query());
+		}
+
+		if (m_mos->get_nr_buildings()) {
+			log("Writing Buildingdata Data ... ");
+			{MapBuildingdataPacket        p; p.write(m_fs, m_egbase, *m_mos);}
+			log("took %ums\n ", timer.ms_since_last_query());
+		}
+
+		log("Writing Node Ownership Data ... ");
+		{MapNodeOwnershipPacket         p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Writing Exploration Data ... ");
+		{MapExplorationPacket            p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Writing Players Unseen Data ... ");
+		{MapPlayersViewPacket           p; p.write(m_fs, m_egbase, *m_mos);}
+		log("took %ums\n ", timer.ms_since_last_query());
+	}
+
+	// We also want to write these in the editor.
 	log("Writing Scripting Data ... ");
 	{MapScriptingPacket              p; p.write(m_fs, m_egbase, *m_mos);}
 	log("took %ums\n ", timer.ms_since_last_query());
@@ -215,9 +224,11 @@
 	{MapObjectivePacket              p; p.write(m_fs, m_egbase, *m_mos);}
 	log("took %ums\n ", timer.ms_since_last_query());
 
-#ifndef NDEBUG
-	m_mos->detect_unsaved_objects();
-#endif
+	if (is_game) {
+		#ifndef NDEBUG
+			m_mos->detect_unsaved_objects();
+		#endif
+	}
 
 	// Write minimap
 	{

=== modified file 'src/map_io/s2map.cc'
--- src/map_io/s2map.cc	2016-01-17 20:04:07 +0000
+++ src/map_io/s2map.cc	2016-01-29 15:16:47 +0000
@@ -359,7 +359,7 @@
  * From now on the Map* can't be set to another one.
  */
 int32_t S2MapLoader::load_map_complete
-	(Widelands::EditorGameBase & egbase, bool)
+	(Widelands::EditorGameBase& egbase, MapLoader::LoadType)
 {
 	ScopedTimer timer("S2MapLoader::load_map_complete() took %ums");
 

=== modified file 'src/map_io/s2map.h'
--- src/map_io/s2map.h	2014-10-04 09:40:18 +0000
+++ src/map_io/s2map.h	2016-01-29 15:16:47 +0000
@@ -38,7 +38,7 @@
 
 	int32_t preload_map(bool) override;
 	virtual int32_t load_map_complete
-		(Widelands::EditorGameBase &, bool scenario) override;
+		(Widelands::EditorGameBase&, Widelands::MapLoader::LoadType) override;
 
 private:
 	const std::string m_filename;

=== modified file 'src/map_io/widelands_map_loader.cc'
--- src/map_io/widelands_map_loader.cc	2016-01-06 19:11:20 +0000
+++ src/map_io/widelands_map_loader.cc	2016-01-29 15:16:47 +0000
@@ -106,10 +106,12 @@
  * Load the complete map and make sure that it runs without problems
  */
 int32_t WidelandsMapLoader::load_map_complete
-	(EditorGameBase & egbase, bool const scenario)
+	(EditorGameBase & egbase, MapLoader::LoadType load_type)
 {
 	ScopedTimer timer("WidelandsMapLoader::load_map_complete() took %ums");
 
+	bool scenario = load_type != MapLoader::LoadType::kGame;
+
 	preload_map(scenario);
 	m_map.set_size(m_map.m_width, m_map.m_height);
 	m_mol.reset(new MapObjectLoader());
@@ -182,96 +184,99 @@
 	log("took %ums\n ", timer.ms_since_last_query());
 
 	//  NON MANDATORY PACKETS BELOW THIS POINT
-	log("Reading Map Extra Data ... ");
-	{MapExtradataPacket      p; p.read(*m_fs, !scenario);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Map Version Data ... ");
-	{MapVersionPacket      p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-
-	log("Reading Allowed Worker Types Data ... ");
-	{
-		MapAllowedWorkerTypesPacket p;
-		p.read(*m_fs, egbase, !scenario, *m_mol);
-	}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Allowed Building Types Data ... ");
-	{
-		MapAllowedBuildingTypesPacket p;
-		p.read(*m_fs, egbase, !scenario, *m_mol);
-	}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Node Ownership Data ... ");
-	{MapNodeOwnershipPacket p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Exploration Data ... ");
-	{MapExplorationPacket    p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	//  !!!!!!!!!! NOTE
-	//  This packet must be before any building or road packet. So do not change
-	//  this order without knowing what you do
-	//  EXISTENT PACKETS
-	log("Reading Flag Data ... ");
-	{MapFlagPacket           p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Road Data ... ");
-	{MapRoadPacket           p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Building Data ... ");
-	{MapBuildingPacket       p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	//  DATA PACKETS
-	log("Reading Flagdata Data ... ");
-	{MapFlagdataPacket       p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Roaddata Data ... ");
-	{MapRoaddataPacket       p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Reading Buildingdata Data ... ");
-	{MapBuildingdataPacket   p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	log("Second and third phase loading Map Objects ... ");
-	mapobjects.load_finish();
-	{
-		const Field & fields_end = map()[map().max_index()];
-		for (Field * field = &map()[0]; field < &fields_end; ++field)
-			if (BaseImmovable * const imm = field->get_immovable()) {
-				if (upcast(Building const, building, imm))
-					if (field != &map()[building->get_position()])
-						continue; //  not the building's main position
-				imm->load_finish(egbase);
-			}
-	}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	//  This should be at least after loading Soldiers (Bobs).
-	//  NOTE DO NOT CHANGE THE PLACE UNLESS YOU KNOW WHAT ARE YOU DOING
-	//  Must be loaded after every kind of object that can see.
-	log("Reading Players View Data ... ");
-	{MapPlayersViewPacket   p; p.read(*m_fs, egbase, !scenario, *m_mol);}
-	log("took %ums\n ", timer.ms_since_last_query());
-
-	//  This must come before anything that references messages, such as:
-	//    * command queue (PlayerMessageCommand, inherited by
-	//      Cmd_MessageSetStatusRead and Cmd_MessageSetStatusArchived)
-	log("Reading Player Message Data ... ");
-	{
-		MapPlayersMessagesPacket p;
-		p.read(*m_fs, egbase, !scenario, *m_mol);
-	}
-	log("took %ums\n ", timer.ms_since_last_query());
+	// Do not load unneeded packages in the editor
+	if (load_type != MapLoader::LoadType::kEditor) {
+		log("Reading Map Extra Data ... ");
+		{MapExtradataPacket      p; p.read(*m_fs, !scenario);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Map Version Data ... ");
+		{MapVersionPacket      p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+
+		log("Reading Allowed Worker Types Data ... ");
+		{
+			MapAllowedWorkerTypesPacket p;
+			p.read(*m_fs, egbase, !scenario, *m_mol);
+		}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Allowed Building Types Data ... ");
+		{
+			MapAllowedBuildingTypesPacket p;
+			p.read(*m_fs, egbase, !scenario, *m_mol);
+		}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Node Ownership Data ... ");
+		{MapNodeOwnershipPacket p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Exploration Data ... ");
+		{MapExplorationPacket    p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		//  !!!!!!!!!! NOTE
+		//  This packet must be before any building or road packet. So do not change
+		//  this order without knowing what you do
+		//  EXISTENT PACKETS
+		log("Reading Flag Data ... ");
+		{MapFlagPacket           p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Road Data ... ");
+		{MapRoadPacket           p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Building Data ... ");
+		{MapBuildingPacket       p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		//  DATA PACKETS
+		log("Reading Flagdata Data ... ");
+		{MapFlagdataPacket       p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Roaddata Data ... ");
+		{MapRoaddataPacket       p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Reading Buildingdata Data ... ");
+		{MapBuildingdataPacket   p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		log("Second and third phase loading Map Objects ... ");
+		mapobjects.load_finish();
+		{
+			const Field & fields_end = map()[map().max_index()];
+			for (Field * field = &map()[0]; field < &fields_end; ++field)
+				if (BaseImmovable * const imm = field->get_immovable()) {
+					if (upcast(Building const, building, imm))
+						if (field != &map()[building->get_position()])
+							continue; //  not the building's main position
+					imm->load_finish(egbase);
+				}
+		}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		//  This should be at least after loading Soldiers (Bobs).
+		//  NOTE DO NOT CHANGE THE PLACE UNLESS YOU KNOW WHAT ARE YOU DOING
+		//  Must be loaded after every kind of object that can see.
+		log("Reading Players View Data ... ");
+		{MapPlayersViewPacket   p; p.read(*m_fs, egbase, !scenario, *m_mol);}
+		log("took %ums\n ", timer.ms_since_last_query());
+
+		//  This must come before anything that references messages, such as:
+		//    * command queue (PlayerMessageCommand, inherited by
+		//      Cmd_MessageSetStatusRead and Cmd_MessageSetStatusArchived)
+		log("Reading Player Message Data ... ");
+		{
+			MapPlayersMessagesPacket p;
+			p.read(*m_fs, egbase, !scenario, *m_mol);
+		}
+		log("took %ums\n ", timer.ms_since_last_query());
+	} // load_type != MapLoader::LoadType::kEditor
 
 	//  Objectives
 	log("Reading Objective Data ... ");
@@ -282,11 +287,14 @@
 	{MapScriptingPacket      p; p.read(*m_fs, egbase, !scenario, *m_mol);}
 	log("took %ums\n ", timer.ms_since_last_query());
 
-	if (m_mol->get_nr_unloaded_objects())
-		log
-			("WARNING: There are %i unloaded objects. This is a bug, please "
-			 "consider committing!\n",
-			 m_mol->get_nr_unloaded_objects());
+	if (load_type != MapLoader::LoadType::kEditor) {
+		if (m_mol->get_nr_unloaded_objects()) {
+			log
+				("WARNING: There are %i unloaded objects. This is a bug, please "
+				 "consider committing!\n",
+				 m_mol->get_nr_unloaded_objects());
+		}
+	} // load_type != MapLoader::LoadType::kEditor
 
 	m_map.recalc_whole_map(egbase.world());
 

=== modified file 'src/map_io/widelands_map_loader.h'
--- src/map_io/widelands_map_loader.h	2015-01-27 20:43:52 +0000
+++ src/map_io/widelands_map_loader.h	2016-01-29 15:16:47 +0000
@@ -41,7 +41,7 @@
 	virtual ~WidelandsMapLoader();
 
 	int32_t preload_map(bool) override;
-	int32_t load_map_complete(EditorGameBase &, bool) override;
+	int32_t load_map_complete(EditorGameBase &, MapLoader::LoadType load_type) override;
 
 	MapObjectLoader * get_map_object_loader() {return m_mol.get();}
 


Follow ups