diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index e6fcdcf8324471ea18fc0e8d466183d45f4abb2b..36b97b2d1610b7790566d863bb5d2ee87957c8a2 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -644,15 +644,12 @@ int ModApiMainMenu::l_create_world(lua_State *L)
 			(gameidx < (int) games.size())) {
 
 		// Create world if it doesn't exist
-		if(!initializeWorld(path, games[gameidx].id)){
+		if (!loadGameConfAndInitWorld(path, games[gameidx])) {
 			lua_pushstring(L, "Failed to initialize world");
-
-		}
-		else {
-		lua_pushnil(L);
+		} else {
+			lua_pushnil(L);
 		}
-	}
-	else {
+	} else {
 		lua_pushstring(L, "Invalid game index");
 	}
 	return 1;
diff --git a/src/server.cpp b/src/server.cpp
index 235e802bbfab826cb2001c2af5077c68257a336b..52183980f6c9abff21e485980c607e6bf7c922b0 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -223,7 +223,7 @@ Server::Server(
 	infostream<<"- game:   "<<m_gamespec.path<<std::endl;
 
 	// Create world if it doesn't exist
-	if(!initializeWorld(m_path_world, m_gamespec.id))
+	if(!loadGameConfAndInitWorld(m_path_world, m_gamespec))
 		throw ServerError("Failed to initialize world");
 
 	// Create server thread
diff --git a/src/settings.cpp b/src/settings.cpp
index 594b8944dadf76939f461e89540a0bac4adce765..c1d70714fb75fb6e8011b0f75d54fb90c2e575bd 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -887,6 +887,11 @@ void Settings::clear()
 	clearNoLock();
 }
 
+void Settings::clearDefaults()
+{
+	JMutexAutoLock lock(m_mutex);
+	clearDefaultsNoLock();
+}
 
 void Settings::updateValue(const Settings &other, const std::string &name)
 {
@@ -958,11 +963,18 @@ void Settings::clearNoLock()
 		delete it->second.group;
 	m_settings.clear();
 
+	clearDefaultsNoLock();
+}
+
+void Settings::clearDefaultsNoLock()
+{
+	std::map<std::string, SettingsEntry>::const_iterator it;
 	for (it = m_defaults.begin(); it != m_defaults.end(); ++it)
 		delete it->second.group;
 	m_defaults.clear();
 }
 
+
 void Settings::registerChangedCallback(std::string name,
 	setting_changed_callback cbf, void *userdata)
 {
diff --git a/src/settings.h b/src/settings.h
index 1a7d9ab96aad4834d889f4bbd81a8b844e51c457..48708f6cc4602e95a2ccbc2eb061690ed21798a5 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -202,6 +202,7 @@ class Settings {
 	// remove a setting
 	bool remove(const std::string &name);
 	void clear();
+	void clearDefaults();
 	void updateValue(const Settings &other, const std::string &name);
 	void update(const Settings &other);
 	void registerChangedCallback(std::string name, setting_changed_callback cbf, void *userdata = NULL);
@@ -211,6 +212,7 @@ class Settings {
 
 	void updateNoLock(const Settings &other);
 	void clearNoLock();
+	void clearDefaultsNoLock();
 
 	void doCallbacks(std::string name);
 
diff --git a/src/subgame.cpp b/src/subgame.cpp
index a3edcda2eb294a08cc9c396891f6d5fd078663eb..864732876049c9206ebb4de7229e57cd8a075a1d 100644
--- a/src/subgame.cpp
+++ b/src/subgame.cpp
@@ -267,25 +267,31 @@ std::vector<WorldSpec> getAvailableWorlds()
 	return worlds;
 }
 
-bool initializeWorld(const std::string &path, const std::string &gameid)
+bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamespec)
 {
+	// Override defaults with those provided by the game.
+	// We clear and reload the defaults because the defaults
+	// might have been overridden by other subgame config
+	// files that were loaded before.
+	g_settings->clearDefaults();
+	set_default_settings(g_settings);
+	Settings game_defaults;
+	getGameMinetestConfig(gamespec.path, game_defaults);
+	override_default_settings(g_settings, &game_defaults);
+
 	infostream << "Initializing world at " << path << std::endl;
 
 	fs::CreateAllDirs(path);
 
-	// Initialize default settings and override defaults with those
-	// provided by the game
-	Settings game_defaults;
-	getGameMinetestConfig(path, game_defaults);
-	override_default_settings(g_settings, &game_defaults);
-
 	// Create world.mt if does not already exist
 	std::string worldmt_path = path + DIR_DELIM "world.mt";
 	if (!fs::PathExists(worldmt_path)) {
 		std::ostringstream ss(std::ios_base::binary);
-		ss << "gameid = " << gameid << "\nbackend = sqlite3\n"
-				<< "creative_mode = " << g_settings->get("creative_mode")
-				<< "\nenable_damage = " << g_settings->get("enable_damage") << "\n";
+		ss << "gameid = " << gamespec.id
+			<< "\nbackend = sqlite3"
+			<< "\ncreative_mode = " << g_settings->get("creative_mode")
+			<< "\nenable_damage = " << g_settings->get("enable_damage")
+			<< "\n";
 		if (!fs::safeWriteToFile(worldmt_path, ss.str()))
 			return false;
 
diff --git a/src/subgame.h b/src/subgame.h
index 4b15faa8d570546fe1c30ee0696b39271bf22fd3..f3633ce2f2695c7e36e6148bfb40b5f0e40aac52 100644
--- a/src/subgame.h
+++ b/src/subgame.h
@@ -98,8 +98,9 @@ struct WorldSpec
 
 std::vector<WorldSpec> getAvailableWorlds();
 
-// Create world directory and world.mt if they don't exist
-bool initializeWorld(const std::string &path, const std::string &gameid);
+// loads the subgame's config and creates world directory
+// and world.mt if they don't exist
+bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamespec);
 
 #endif