From 5a34f40d80ea1a339b599bc11db549a6bd86912f Mon Sep 17 00:00:00 2001
From: kwolekr <kwolekr@minetest.net>
Date: Mon, 3 Feb 2014 22:42:10 -0500
Subject: [PATCH] Huge overhaul of the entire MapgenParams system

MapgenParams is no longer a polymorphic class, eliminating the need for messy and bug-prone reallocations.
Separation between the common and mapgen-specific parameters is now strongly defined.
Mapgen parameters objects are now properly encapsulated within the proper subsystems.
---
 src/biome.cpp                   |   6 +-
 src/cavegen.cpp                 |   3 +-
 src/defaultsettings.cpp         |  36 +------
 src/dungeongen.cpp              |   9 +-
 src/emerge.cpp                  | 168 +++++++++++---------------------
 src/emerge.h                    |  21 ++--
 src/map.cpp                     |  73 ++++----------
 src/map.h                       |  12 +--
 src/mapgen.cpp                  |  72 +-------------
 src/mapgen.h                    |  28 +++---
 src/mapgen_indev.cpp            |  96 ++++++++----------
 src/mapgen_indev.h              |  53 ++--------
 src/mapgen_math.cpp             |   8 +-
 src/mapgen_math.h               |  12 +--
 src/mapgen_singlenode.cpp       |   5 +-
 src/mapgen_singlenode.h         |  10 +-
 src/mapgen_v6.cpp               | 136 +++++++++++++++++---------
 src/mapgen_v6.h                 |  50 ++++------
 src/mapgen_v7.cpp               | 116 ++++++++++++++--------
 src/mapgen_v7.h                 |  43 +++-----
 src/noise.h                     |  13 +++
 src/script/lua_api/l_mapgen.cpp |  47 ++++-----
 src/script/lua_api/l_vmanip.cpp |   2 +-
 src/server.cpp                  |   8 +-
 24 files changed, 405 insertions(+), 622 deletions(-)

diff --git a/src/biome.cpp b/src/biome.cpp
index 7e3dcac77..1afad00a3 100644
--- a/src/biome.cpp
+++ b/src/biome.cpp
@@ -25,10 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "main.h"
 #include "util/mathconstants.h"
 
-NoiseParams nparams_biome_def_heat =
-	{50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70};
-NoiseParams nparams_biome_def_humidity =
-	{50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55};
+NoiseParams nparams_biome_def_heat(50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70);
+NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55);
 
 
 BiomeDefManager::BiomeDefManager() {
diff --git a/src/cavegen.cpp b/src/cavegen.cpp
index b32e140f8..d93911f27 100644
--- a/src/cavegen.cpp
+++ b/src/cavegen.cpp
@@ -24,8 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapgen_v7.h"
 #include "cavegen.h"
 
-NoiseParams nparams_caveliquids =
-	{0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6};
+NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6);
 
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index 053602833..cb7b0ef7a 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -250,41 +250,7 @@ void set_default_settings(Settings *settings)
 	settings->setDefault("mg_name", "v6");
 	settings->setDefault("water_level", "1");
 	settings->setDefault("chunksize", "5");
-	settings->setDefault("mg_flags", "trees, caves, v6_biome_blend");
-	settings->setDefault("mgv6_freq_desert", "0.45");
-	settings->setDefault("mgv6_freq_beach", "0.15");
-
-	settings->setDefault("mgv6_np_terrain_base",   "-4, 20, (250, 250, 250), 82341, 5, 0.6");
-	settings->setDefault("mgv6_np_terrain_higher", "20, 16, (500, 500, 500), 85039, 5, 0.6");
-	settings->setDefault("mgv6_np_steepness",      "0.85, 0.5, (125, 125, 125), -932, 5, 0.7");
-	settings->setDefault("mgv6_np_height_select",  "0.5, 1, (250, 250, 250), 4213, 5, 0.69");
-	settings->setDefault("mgv6_np_mud",            "4, 2, (200, 200, 200), 91013, 3, 0.55");
-	settings->setDefault("mgv6_np_beach",          "0, 1, (250, 250, 250), 59420, 3, 0.50");
-	settings->setDefault("mgv6_np_biome",          "0, 1, (250, 250, 250), 9130, 3, 0.50");
-	settings->setDefault("mgv6_np_cave",           "6, 6, (250, 250, 250), 34329, 3, 0.50");
-	settings->setDefault("mgv6_np_humidity",       "0.5, 0.5, (500, 500, 500), 72384, 4, 0.66");
-	settings->setDefault("mgv6_np_trees",          "0, 1, (125, 125, 125), 2, 4, 0.66");
-	settings->setDefault("mgv6_np_apple_trees",    "0, 1, (100, 100, 100), 342902, 3, 0.45");
-
-	settings->setDefault("mgv7_np_terrain_base",     "4, 70, (300, 300, 300), 82341, 6, 0.7");
-	settings->setDefault("mgv7_np_terrain_alt",      "4, 25, (600, 600, 600), 5934, 5, 0.6");
-	settings->setDefault("mgv7_np_terrain_persist",  "0.6, 0.1, (500, 500, 500), 539, 3, 0.6");
-	settings->setDefault("mgv7_np_height_select",    "-0.5, 1, (250, 250, 250), 4213, 5, 0.69");
-	settings->setDefault("mgv7_np_filler_depth",     "0, 1.2, (150, 150, 150), 261, 4, 0.7");
-	settings->setDefault("mgv7_np_mount_height",     "100, 30, (500, 500, 500), 72449, 4, 0.6");
-	settings->setDefault("mgv7_np_ridge_uwater",     "0, 1, (500, 500, 500), 85039, 4, 0.6");
-	settings->setDefault("mgv7_np_mountain",         "0, 1, (250, 350, 250), 5333, 5, 0.68");
-	settings->setDefault("mgv7_np_ridge",            "0, 1, (100, 120, 100), 6467, 4, 0.75");
-
-	settings->setDefault("mgindev_np_terrain_base",   "-4,   20,  (250, 250, 250), 82341, 5, 0.6,  10,  10");
-	settings->setDefault("mgindev_np_terrain_higher", "20,   16,  (500, 500, 500), 85039, 5, 0.6,  10,  10");
-	settings->setDefault("mgindev_np_steepness",      "0.85, 0.5, (125, 125, 125), -932,  5, 0.7,  2,   10");
-	settings->setDefault("mgindev_np_mud",            "4,    2,   (200, 200, 200), 91013, 3, 0.55, 1,   1");
-	settings->setDefault("mgindev_np_float_islands1", "0,    1,   (256, 256, 256), 3683,  6, 0.6,  1,   1.5");
-	settings->setDefault("mgindev_np_float_islands2", "0,    1,   (8,   8,   8  ), 9292,  2, 0.5,  1,   1.5");
-	settings->setDefault("mgindev_np_float_islands3", "0,    1,   (256, 256, 256), 6412,  2, 0.5,  1,   0.5");
-	settings->setDefault("mgindev_np_biome",          "0,    1,   (250, 250, 250), 9130,  3, 0.50, 1,   10");
-	settings->setDefault("mgindev_float_islands", "500");
+	settings->setDefault("mg_flags", "trees, caves");
 
 	settings->setDefault("mgmath_generator", "mandelbox");
 
diff --git a/src/dungeongen.cpp b/src/dungeongen.cpp
index ff0a39e9e..2027b7f13 100644
--- a/src/dungeongen.cpp
+++ b/src/dungeongen.cpp
@@ -31,12 +31,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 //#define DGEN_USE_TORCHES
 
-NoiseParams nparams_dungeon_rarity = 
-	{0.0, 1.0, v3f(500.0, 500.0, 500.0), 0, 2, 0.8};
-NoiseParams nparams_dungeon_wetness =
-	{0.0, 1.0, v3f(40.0, 40.0, 40.0), 32474, 4, 1.1};
-NoiseParams nparams_dungeon_density =
-	{0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4};
+NoiseParams nparams_dungeon_rarity(0.0, 1.0, v3f(500.0, 500.0, 500.0), 0, 2, 0.8);
+NoiseParams nparams_dungeon_wetness(0.0, 1.0, v3f(40.0, 40.0, 40.0), 32474, 4, 1.1);
+NoiseParams nparams_dungeon_density(0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4);
 
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/emerge.cpp b/src/emerge.cpp
index f63bc5dfe..42e533759 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -90,44 +90,42 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
 
 	this->ndef     = gamedef->getNodeDefManager();
 	this->biomedef = new BiomeDefManager();
-	this->params   = NULL;
+	this->gennotify = 0;
 
 	// Note that accesses to this variable are not synchronized.
 	// This is because the *only* thread ever starting or stopping
 	// EmergeThreads should be the ServerThread.
 	this->threads_active = false;
 
-	this->luaoverride_params          = NULL;
-	this->luaoverride_params_modified = 0;
-	this->luaoverride_flagmask        = 0;
-
-	this->gennotify = 0;
-
 	mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
 
-	int nthreads;
-	if (g_settings->get("num_emerge_threads").empty()) {
-		int nprocs = porting::getNumberOfProcessors();
-		// leave a proc for the main thread and one for some other misc threads
-		nthreads = (nprocs > 2) ? nprocs - 2 : 1;
-	} else {
-		nthreads = g_settings->getU16("num_emerge_threads");
-	}
+	// if unspecified, leave a proc for the main thread and one for
+	// some other misc thread
+	int nthreads = 0;
+	if (!g_settings->tryGetS16("num_emerge_threads", nthreads))
+		nthreads = porting::getNumberOfProcessors() - 2;
 	if (nthreads < 1)
 		nthreads = 1;
 
-	qlimit_total    = g_settings->getU16("emergequeue_limit_total");
-	qlimit_diskonly = g_settings->get("emergequeue_limit_diskonly").empty() ?
-		nthreads * 5 + 1 :
-		g_settings->getU16("emergequeue_limit_diskonly");
-	qlimit_generate = g_settings->get("emergequeue_limit_generate").empty() ?
-		nthreads + 1 :
-		g_settings->getU16("emergequeue_limit_generate");
+	qlimit_total = g_settings->getU16("emergequeue_limit_total");
+	if (!g_settings->tryGetU16("emergequeue_limit_diskonly", qlimit_diskonly))
+		qlimit_diskonly = nthreads * 5 + 1;
+	if (!g_settings->tryGetU16("emergequeue_limit_generate", qlimit_generate))
+		qlimit_generate = nthreads + 1;
 
 	for (int i = 0; i != nthreads; i++)
 		emergethread.push_back(new EmergeThread((Server *)gamedef, i));
 
 	infostream << "EmergeManager: using " << nthreads << " threads" << std::endl;
+
+	loadParamsFromSettings(g_settings);
+
+	if (g_settings->get("fixed_map_seed").empty()) {
+		params.seed = (((u64)(myrand() & 0xffff) << 0)
+					 | ((u64)(myrand() & 0xffff) << 16)
+					 | ((u64)(myrand() & 0xffff) << 32)
+					 | ((u64)(myrand() & 0xffff) << 48));
+	}
 }
 
 
@@ -162,9 +160,7 @@ EmergeManager::~EmergeManager() {
 }
 
 
-void EmergeManager::initMapgens(MapgenParams *mgparams) {
-	Mapgen *mg;
-
+void EmergeManager::initMapgens() {
 	if (mapgen.size())
 		return;
 
@@ -178,77 +174,25 @@ void EmergeManager::initMapgens(MapgenParams *mgparams) {
 	for (size_t i = 0; i != decorations.size(); i++)
 		decorations[i]->resolveNodeNames(ndef);
 
-	// Apply mapgen parameter overrides from Lua
-	if (luaoverride_params) {
-		if (luaoverride_params_modified & MGPARAMS_SET_MGNAME) {
-			MapgenParams *mgp = setMapgenType(mgparams, luaoverride_params->mg_name);
-			if (!mgp) {
-				errorstream << "EmergeManager: Failed to set new mapgen name"
-							<< std::endl;
-			} else {
-				mgparams = mgp;
-			}
-		}
-
-		if (luaoverride_params_modified & MGPARAMS_SET_SEED)
-			mgparams->seed = luaoverride_params->seed;
-
-		if (luaoverride_params_modified & MGPARAMS_SET_WATER_LEVEL)
-			mgparams->water_level = luaoverride_params->water_level;
-
-		if (luaoverride_params_modified & MGPARAMS_SET_FLAGS) {
-			mgparams->flags &= ~luaoverride_flagmask;
-			mgparams->flags |= luaoverride_params->flags;
+	if (!params.sparams) {
+		params.sparams = createMapgenParams(params.mg_name);
+		if (!params.sparams) {
+			params.mg_name = DEFAULT_MAPGEN;
+			params.sparams = createMapgenParams(params.mg_name);
+			assert(params.sparams);
 		}
-
-		delete luaoverride_params;
-		luaoverride_params = NULL;
+		params.sparams->readParams(g_settings);
 	}
 
 	// Create the mapgens
-	this->params = mgparams;
 	for (size_t i = 0; i != emergethread.size(); i++) {
-		mg = createMapgen(params->mg_name, i, params);
-		if (!mg) {
-			infostream << "EmergeManager: Falling back to Mapgen V6" << std::endl;
-
-			params = setMapgenType(params, "v6");
-			mg = createMapgen(params->mg_name, i, params);
-			if (!mg) {
-				errorstream << "EmergeManager: CRITICAL ERROR: Failed to fall"
-					"back to Mapgen V6, not generating map" << std::endl;
-			}
-		}
+		Mapgen *mg = createMapgen(params.mg_name, i, &params);
+		assert(mg);
 		mapgen.push_back(mg);
 	}
 }
 
 
-MapgenParams *EmergeManager::setMapgenType(MapgenParams *mgparams,
-	std::string newname) {
-	MapgenParams *newparams = createMapgenParams(newname);
-	if (!newparams) {
-		errorstream << "EmergeManager: Mapgen override failed" << std::endl;
-		return NULL;
-	}
-
-	newparams->mg_name     = newname;
-	newparams->seed        = mgparams->seed;
-	newparams->water_level = mgparams->water_level;
-	newparams->chunksize   = mgparams->chunksize;
-	newparams->flags       = mgparams->flags;
-
-	if (!newparams->readParams(g_settings)) {
-		errorstream << "EmergeManager: Mapgen override failed" << std::endl;
-		delete newparams;
-		return NULL;
-	}
-
-	delete mgparams;
-	return newparams;
-}
-
-
 Mapgen *EmergeManager::getCurrentMapgen() {
 	for (unsigned int i = 0; i != emergethread.size(); i++) {
 		if (emergethread[i]->IsSameThread())
@@ -363,12 +307,12 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos) {
 
 	//yuck, but then again, should i bother being accurate?
 	//the height of the nodes in a single block is quite variable
-	return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params->water_level;
+	return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level;
 }
 
 
 u32 EmergeManager::getBlockSeed(v3s16 p) {
-	return (u32)(params->seed & 0xFFFFFFFF) +
+	return (u32)(params.seed & 0xFFFFFFFF) +
 		p.Z * 38134234 +
 		p.Y * 42123 +
 		p.X * 23;
@@ -390,7 +334,7 @@ Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid,
 }
 
 
-MapgenParams *EmergeManager::createMapgenParams(std::string mgname) {
+MapgenSpecificParams *EmergeManager::createMapgenParams(std::string mgname) {
 	std::map<std::string, MapgenFactory *>::const_iterator iter;
 	iter = mglist.find(mgname);
 	if (iter == mglist.end()) {
@@ -404,37 +348,35 @@ MapgenParams *EmergeManager::createMapgenParams(std::string mgname) {
 }
 
 
-MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) {
-	std::string mg_name = settings->get("mg_name");
-	MapgenParams *mgparams = createMapgenParams(mg_name);
-	if (!mgparams)
-		return NULL;
+void EmergeManager::loadParamsFromSettings(Settings *settings) {
+	std::string seed_str;
+	const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed";
 
-	std::string seedstr = settings->get(settings == g_settings ?
-									"fixed_map_seed" : "seed");
+	if (settings->tryGet(setname, seed_str))
+		params.seed = read_seed(seed_str.c_str());
 
-	mgparams->mg_name     = mg_name;
-	mgparams->seed        = read_seed(seedstr.c_str());
-	mgparams->water_level = settings->getS16("water_level");
-	mgparams->chunksize   = settings->getS16("chunksize");
-	mgparams->flags       = settings->getFlagStr("mg_flags", flagdesc_mapgen);
+	settings->tryGet("mg_name",         params.mg_name);
+	settings->tryGetS16("water_level",  params.water_level);
+	settings->tryGetS16("chunksize",    params.chunksize);
+	settings->tryGetFlagStr("mg_flags", params.flags, flagdesc_mapgen);
+
+	delete params.sparams;
+	params.sparams = createMapgenParams(params.mg_name);
+	if (params.sparams)
+		params.sparams->readParams(settings);
 
-	if (!mgparams->readParams(settings)) {
-		delete mgparams;
-		return NULL;
-	}
-	return mgparams;
 }
 
 
-void EmergeManager::setParamsToSettings(Settings *settings) {
-	settings->set("mg_name",         params->mg_name);
-	settings->setU64("seed",         params->seed);
-	settings->setS16("water_level",  params->water_level);
-	settings->setS16("chunksize",    params->chunksize);
-	settings->setFlagStr("mg_flags", params->flags, flagdesc_mapgen);
+void EmergeManager::saveParamsToSettings(Settings *settings) {
+	settings->set("mg_name",         params.mg_name);
+	settings->setU64("seed",         params.seed);
+	settings->setS16("water_level",  params.water_level);
+	settings->setS16("chunksize",    params.chunksize);
+	settings->setFlagStr("mg_flags", params.flags, flagdesc_mapgen);
 
-	params->writeParams(settings);
+	if (params.sparams)
+		params.sparams->writeParams(settings);
 }
 
 
diff --git a/src/emerge.h b/src/emerge.h
index 17097327b..14a2728ba 100644
--- a/src/emerge.h
+++ b/src/emerge.h
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irr_v3d.h"
 #include "util/container.h"
 #include "map.h" // for ManualMapVoxelManipulator
+#include "mapgen.h" // for MapgenParams
 
 #define MGPARAMS_SET_MGNAME      1
 #define MGPARAMS_SET_SEED        2
@@ -37,9 +38,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 	infostream << "EmergeThread: " x << std::endl; }
 
 class EmergeThread;
-class Mapgen;
-struct MapgenParams;
-struct MapgenFactory;
+//class Mapgen;
+//struct MapgenFactory;
 class Biome;
 class BiomeDefManager;
 class Decoration;
@@ -90,7 +90,7 @@ class EmergeManager : public IBackgroundBlockEmerger {
 	bool threads_active;
 
 	//settings
-	MapgenParams *params;
+	MapgenParams params;
 	bool mapgen_debug_info;
 	u16 qlimit_total;
 	u16 qlimit_diskonly;
@@ -98,10 +98,6 @@ class EmergeManager : public IBackgroundBlockEmerger {
 
 	u32 gennotify;
 
-	MapgenParams *luaoverride_params;
-	u32 luaoverride_params_modified;
-	u32 luaoverride_flagmask;
-
 	//block emerge queue data structures
 	JMutex queuemutex;
 	std::map<v3s16, BlockEmergeData *> blocks_enqueued;
@@ -115,19 +111,18 @@ class EmergeManager : public IBackgroundBlockEmerger {
 	EmergeManager(IGameDef *gamedef);
 	~EmergeManager();
 
-	void initMapgens(MapgenParams *mgparams);
-	MapgenParams *setMapgenType(MapgenParams *mgparams, std::string newname);
+	void initMapgens();
 	Mapgen *getCurrentMapgen();
 	Mapgen *createMapgen(std::string mgname, int mgid,
 						MapgenParams *mgparams);
-	MapgenParams *createMapgenParams(std::string mgname);
+	MapgenSpecificParams *createMapgenParams(std::string mgname);
 	void startThreads();
 	void stopThreads();
 	bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate);
 
 	void registerMapgen(std::string name, MapgenFactory *mgfactory);
-	MapgenParams *getParamsFromSettings(Settings *settings);
-	void setParamsToSettings(Settings *settings);
+	void loadParamsFromSettings(Settings *settings);
+	void saveParamsToSettings(Settings *settings);
 
 	//mapgen helper methods
 	Biome *getBiomeAtPoint(v3s16 p);
diff --git a/src/map.cpp b/src/map.cpp
index 4d32ecdfe..075649f94 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -2407,34 +2407,11 @@ s16 Map::getHumidity(v3s16 p)
 */
 ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge):
 	Map(dout_server, gamedef),
-	m_seed(0),
+	m_emerge(emerge),
 	m_map_metadata_changed(true)
 {
 	verbosestream<<__FUNCTION_NAME<<std::endl;
 
-	m_emerge = emerge;
-	m_mgparams = m_emerge->getParamsFromSettings(g_settings);
-	if (!m_mgparams)
-		m_mgparams = new MapgenV6Params();
-
-	m_seed = m_mgparams->seed;
-
-	if (g_settings->get("fixed_map_seed").empty())
-	{
-		m_seed = (((u64)(myrand() & 0xffff) << 0)
-				| ((u64)(myrand() & 0xffff) << 16)
-				| ((u64)(myrand() & 0xffff) << 32)
-				| ((u64)(myrand() & 0xffff) << 48));
-		m_mgparams->seed = m_seed;
-	}
-
-	/*
-		Experimental and debug stuff
-	*/
-
-	{
-	}
-
 	/*
 		Try to load map; if not found, create a new one.
 	*/
@@ -2496,7 +2473,7 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer
 				infostream<<"ServerMap: Successfully loaded map "
 						<<"metadata from "<<savedir
 						<<", assuming valid save directory."
-						<<" seed="<<m_seed<<"."
+						<<" seed="<< m_emerge->params.seed <<"."
 						<<std::endl;
 
 				m_map_saving_enabled = true;
@@ -2552,7 +2529,7 @@ ServerMap::~ServerMap()
 	/*
 		Close database if it was opened
 	*/
-	delete(dbase);
+	delete dbase;
 
 #if 0
 	/*
@@ -2565,8 +2542,16 @@ ServerMap::~ServerMap()
 		delete chunk;
 	}
 #endif
+}
+
+u64 ServerMap::getSeed()
+{
+	return m_emerge->params.seed;
+}
 
-	delete m_mgparams;
+s16 ServerMap::getWaterLevel()
+{
+	return m_emerge->params.water_level;
 }
 
 bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
@@ -2574,7 +2559,7 @@ bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
 	bool enable_mapgen_debug_info = m_emerge->mapgen_debug_info;
 	EMERGE_DBG_OUT("initBlockMake(): " PP(blockpos) " - " PP(blockpos));
 
-	s16 chunksize = m_mgparams->chunksize;
+	s16 chunksize = m_emerge->params.chunksize;
 	s16 coffset = -chunksize / 2;
 	v3s16 chunk_offset(coffset, coffset, coffset);
 	v3s16 blockpos_div = getContainerPos(blockpos - chunk_offset, chunksize);
@@ -2590,7 +2575,7 @@ bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
 		blockpos_over_limit(blockpos_max + extra_borders))
 		return false;
 
-	data->seed = m_seed;
+	data->seed = m_emerge->params.seed;
 	data->blockpos_min = blockpos_min;
 	data->blockpos_max = blockpos_max;
 	data->blockpos_requested = blockpos;
@@ -3451,7 +3436,7 @@ void ServerMap::saveMapMeta()
 
 	Settings params;
 
-	m_emerge->setParamsToSettings(&params);
+	m_emerge->saveParamsToSettings(&params);
 	params.writeLines(ss);
 
 	ss<<"[end_of_params]\n";
@@ -3497,28 +3482,10 @@ void ServerMap::loadMapMeta()
 		params.parseConfigLine(line);
 	}
 	
-	MapgenParams *mgparams;
-	try {
-		mgparams = m_emerge->getParamsFromSettings(&params);
-	} catch (SettingNotFoundException &e) {
-		infostream << "Couldn't get a setting from map_meta.txt: "
-				   << e.what() << std::endl;
-		mgparams = NULL;
-	}
-	
-	if (mgparams) {
-		if (m_mgparams)
-			delete m_mgparams;
-		m_mgparams = mgparams;
-		m_seed = mgparams->seed;
-	} else {
-		if (params.exists("seed")) {
-			m_seed = read_seed(params.get("seed").c_str());
-			m_mgparams->seed = m_seed;
-		}
-	}
+	m_emerge->loadParamsFromSettings(&params);
 
-	verbosestream<<"ServerMap::loadMapMeta(): "<<"seed="<<m_seed<<std::endl;
+	verbosestream<<"ServerMap::loadMapMeta(): seed="
+		<< m_emerge->params.seed<<std::endl;
 }
 
 void ServerMap::saveSectorMeta(ServerMapSector *sector)
@@ -3940,7 +3907,7 @@ s16 ServerMap::updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
 		block = getBlockNoCreateNoEx(getNodeBlockPos(p));
 	}
 
-	f32 heat = m_emerge->biomedef->calcBlockHeat(p, m_seed,
+	f32 heat = m_emerge->biomedef->calcBlockHeat(p, getSeed(),
 			env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
 
 	if(block) {
@@ -3961,7 +3928,7 @@ s16 ServerMap::updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *bl
 		block = getBlockNoCreateNoEx(getNodeBlockPos(p));
 	}
 
-	f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, m_seed,
+	f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, getSeed(),
 			env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
 			
 	if(block) {
diff --git a/src/map.h b/src/map.h
index 5ec1a0b9d..54d8fe9ea 100644
--- a/src/map.h
+++ b/src/map.h
@@ -493,21 +493,13 @@ class ServerMap : public Map
 
 	bool isSavingEnabled(){ return m_map_saving_enabled; }
 
-	u64 getSeed(){ return m_seed; }
-
-	MapgenParams *getMapgenParams(){ return m_mgparams; }
-	void setMapgenParams(MapgenParams *mgparams){ m_mgparams = mgparams; }
-
-	// Parameters fed to the Mapgen
-	MapgenParams *m_mgparams;
+	u64 getSeed();
+	s16 getWaterLevel();
 
 	virtual s16 updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
 	virtual s16 updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
 
 private:
-	// Seed used for all kinds of randomness in generation
-	u64 m_seed;
-	
 	// Emerge manager
 	EmergeManager *m_emerge;
 
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index a07f24db5..d97c3e609 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -39,15 +39,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/serialize.h"
 #include "filesys.h"
 
+
 FlagDesc flagdesc_mapgen[] = {
 	{"trees",          MG_TREES},
 	{"caves",          MG_CAVES},
 	{"dungeons",       MG_DUNGEONS},
-	{"v6_jungles",     MGV6_JUNGLES},
-	{"v6_biome_blend", MGV6_BIOME_BLEND},
 	{"flat",           MG_FLAT},
 	{"nolight",        MG_NOLIGHT},
-	{"v6_nomudflow",   MGV6_NOMUDFLOW},
 	{NULL,             0}
 };
 
@@ -1124,71 +1122,3 @@ void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) {
 		vm->spreadLight(bank, light_sources, ndef);
 	}
 }
-
-
-//////////////////////// Mapgen V6 parameter read/write
-
-bool MapgenV6Params::readParams(Settings *settings) {
-	freq_desert = settings->getFloat("mgv6_freq_desert");
-	freq_beach  = settings->getFloat("mgv6_freq_beach");
-
-	bool success =
-		settings->getNoiseParams("mgv6_np_terrain_base",   np_terrain_base)   &&
-		settings->getNoiseParams("mgv6_np_terrain_higher", np_terrain_higher) &&
-		settings->getNoiseParams("mgv6_np_steepness",      np_steepness)      &&
-		settings->getNoiseParams("mgv6_np_height_select",  np_height_select)  &&
-		settings->getNoiseParams("mgv6_np_mud",            np_mud)            &&
-		settings->getNoiseParams("mgv6_np_beach",          np_beach)          &&
-		settings->getNoiseParams("mgv6_np_biome",          np_biome)          &&
-		settings->getNoiseParams("mgv6_np_cave",           np_cave)           &&
-		settings->getNoiseParams("mgv6_np_humidity",       np_humidity)       &&
-		settings->getNoiseParams("mgv6_np_trees",          np_trees)          &&
-		settings->getNoiseParams("mgv6_np_apple_trees",    np_apple_trees);
-	return success;
-}
-
-
-void MapgenV6Params::writeParams(Settings *settings) {
-	settings->setFloat("mgv6_freq_desert", freq_desert);
-	settings->setFloat("mgv6_freq_beach",  freq_beach);
-
-	settings->setNoiseParams("mgv6_np_terrain_base",   np_terrain_base);
-	settings->setNoiseParams("mgv6_np_terrain_higher", np_terrain_higher);
-	settings->setNoiseParams("mgv6_np_steepness",      np_steepness);
-	settings->setNoiseParams("mgv6_np_height_select",  np_height_select);
-	settings->setNoiseParams("mgv6_np_mud",            np_mud);
-	settings->setNoiseParams("mgv6_np_beach",          np_beach);
-	settings->setNoiseParams("mgv6_np_biome",          np_biome);
-	settings->setNoiseParams("mgv6_np_cave",           np_cave);
-	settings->setNoiseParams("mgv6_np_humidity",       np_humidity);
-	settings->setNoiseParams("mgv6_np_trees",          np_trees);
-	settings->setNoiseParams("mgv6_np_apple_trees",    np_apple_trees);
-}
-
-
-bool MapgenV7Params::readParams(Settings *settings) {
-	bool success =
-		settings->getNoiseParams("mgv7_np_terrain_base",    np_terrain_base)    &&
-		settings->getNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt)     &&
-		settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist) &&
-		settings->getNoiseParams("mgv7_np_height_select",   np_height_select)   &&
-		settings->getNoiseParams("mgv7_np_filler_depth",    np_filler_depth)    &&
-		settings->getNoiseParams("mgv7_np_mount_height",    np_mount_height)    &&
-		settings->getNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater)    &&
-		settings->getNoiseParams("mgv7_np_mountain",        np_mountain)        &&
-		settings->getNoiseParams("mgv7_np_ridge",           np_ridge);
-	return success;
-}
-
-
-void MapgenV7Params::writeParams(Settings *settings) {
-	settings->setNoiseParams("mgv7_np_terrain_base",    np_terrain_base);
-	settings->setNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt);
-	settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist);
-	settings->setNoiseParams("mgv7_np_height_select",   np_height_select);
-	settings->setNoiseParams("mgv7_np_filler_depth",    np_filler_depth);
-	settings->setNoiseParams("mgv7_np_mount_height",    np_mount_height);
-	settings->setNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater);
-	settings->setNoiseParams("mgv7_np_mountain",        np_mountain);
-	settings->setNoiseParams("mgv7_np_ridge",           np_ridge);
-}
diff --git a/src/mapgen.h b/src/mapgen.h
index aa66982c3..4cee3c2aa 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -28,17 +28,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "noise.h"
 #include "settings.h"
 
+#define DEFAULT_MAPGEN "v6"
+
 /////////////////// Mapgen flags
 #define MG_TREES         0x01
 #define MG_CAVES         0x02
 #define MG_DUNGEONS      0x04
-#define MGV6_JUNGLES     0x08
-#define MGV6_BIOME_BLEND 0x10
-#define MG_FLAT          0x20
-#define MG_NOLIGHT       0x40
-#define MGV7_MOUNTAINS   0x80
-#define MGV7_RIDGES      0x100
-#define MGV6_NOMUDFLOW   0x200
+#define MG_FLAT          0x08
+#define MG_NOLIGHT       0x10
 
 /////////////////// Ore generation flags
 // Use absolute value of height to determine ore placement
@@ -101,6 +98,12 @@ enum OreType {
 };
 
 
+struct MapgenSpecificParams {
+	virtual void readParams(Settings *settings) = 0;
+	virtual void writeParams(Settings *settings) = 0;
+	virtual ~MapgenSpecificParams() {}
+};
+
 struct MapgenParams {
 	std::string mg_name;
 	int chunksize;
@@ -108,17 +111,16 @@ struct MapgenParams {
 	int water_level;
 	u32 flags;
 
+	MapgenSpecificParams *sparams;
+
 	MapgenParams() {
 		mg_name     = "v6";
 		seed        = 0;
 		water_level = 1;
 		chunksize   = 5;
-		flags       = MG_TREES | MG_CAVES | MGV6_BIOME_BLEND;
+		flags       = MG_TREES | MG_CAVES;
+		sparams     = NULL;
 	}
-
-	virtual bool readParams(Settings *settings) { return true; }
-	virtual void writeParams(Settings *settings) {}
-	virtual ~MapgenParams() {}
 };
 
 class Mapgen {
@@ -156,7 +158,7 @@ class Mapgen {
 struct MapgenFactory {
 	virtual Mapgen *createMapgen(int mgid, MapgenParams *params,
 								 EmergeManager *emerge) = 0;
-	virtual MapgenParams *createMapgenParams() = 0;
+	virtual MapgenSpecificParams *createMapgenParams() = 0;
 	virtual ~MapgenFactory() {}
 };
 
diff --git a/src/mapgen_indev.cpp b/src/mapgen_indev.cpp
index a22e2522f..67535b0b4 100644
--- a/src/mapgen_indev.cpp
+++ b/src/mapgen_indev.cpp
@@ -24,24 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 #include "log.h"
 
-/////////////////// Mapgen Indev perlin noise (default values - not used, from config or defaultsettings)
-
-NoiseIndevParams nparams_indev_def;
-
-/*
-NoiseIndevParams nparams_indev_def_terrain_base;
-//	(-AVERAGE_MUD_AMOUNT, 20.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6, 1);
-NoiseIndevParams nparams_indev_def_terrain_higher;
-//	(20.0, 16.0, v3f(500.0, 500.0, 500.0), 85039, 5, 0.6, 1);
-NoiseIndevParams nparams_indev_def_steepness;
-//	(0.85, 0.5, v3f(125.0, 125.0, 125.0), -932, 5, 0.7, 1);
-NoiseIndevParams nparams_indev_def_mud;
-//	(AVERAGE_MUD_AMOUNT, 2.0, v3f(200.0, 200.0, 200.0), 91013, 3, 0.55, 1);
-NoiseIndevParams nparams_indev_def_float_islands;
-//	(1, 10.0, v3f(500.0, 500.0, 500.0), 32451, 5, 0.6, 1);
-NoiseIndevParams nparams_indev_def_biome;
-*/
-
 ///////////////////////////////////////////////////////////////////////////////
 
 void NoiseIndev::init(NoiseIndevParams *np, int seed, int sx, int sy, int sz) {
@@ -81,27 +63,28 @@ void NoiseIndev::transformNoiseMapFarScale(float xx, float yy, float zz) {
         }
 }
 
-MapgenIndev::MapgenIndev(int mapgenid, MapgenIndevParams *params, EmergeManager *emerge) 
+MapgenIndev::MapgenIndev(int mapgenid, MapgenParams *params, EmergeManager *emerge) 
 	: MapgenV6(mapgenid, params, emerge)
 {
-	noiseindev_terrain_base    = new NoiseIndev(&params->npindev_terrain_base,   seed, csize.X, csize.Z);
-	noiseindev_terrain_higher  = new NoiseIndev(&params->npindev_terrain_higher, seed, csize.X, csize.Z);
-	noiseindev_steepness       = new NoiseIndev(&params->npindev_steepness,      seed, csize.X, csize.Z);
-	noiseindev_mud             = new NoiseIndev(&params->npindev_mud,            seed, csize.X, csize.Z);
-	noiseindev_float_islands1  = new NoiseIndev(&params->npindev_float_islands1, seed, csize.X, csize.Y, csize.Z);
-	noiseindev_float_islands2  = new NoiseIndev(&params->npindev_float_islands2, seed, csize.X, csize.Y, csize.Z);
-	noiseindev_float_islands3  = new NoiseIndev(&params->npindev_float_islands3, seed, csize.X, csize.Z);
-	noiseindev_biome           = new NoiseIndev(&params->npindev_biome,          seed, csize.X, csize.Z);
+	MapgenIndevParams *sp = (MapgenIndevParams *)params->sparams;
+
+	float_islands = sp->float_islands;
+
+	noiseindev_terrain_base    = new NoiseIndev(&sp->npindev_terrain_base,   seed, csize.X, csize.Z);
+	noiseindev_terrain_higher  = new NoiseIndev(&sp->npindev_terrain_higher, seed, csize.X, csize.Z);
+	noiseindev_steepness       = new NoiseIndev(&sp->npindev_steepness,      seed, csize.X, csize.Z);
+	noiseindev_mud             = new NoiseIndev(&sp->npindev_mud,            seed, csize.X, csize.Z);
+	noiseindev_float_islands1  = new NoiseIndev(&sp->npindev_float_islands1, seed, csize.X, csize.Y, csize.Z);
+	noiseindev_float_islands2  = new NoiseIndev(&sp->npindev_float_islands2, seed, csize.X, csize.Y, csize.Z);
+	noiseindev_float_islands3  = new NoiseIndev(&sp->npindev_float_islands3, seed, csize.X, csize.Z);
+	noiseindev_biome           = new NoiseIndev(&sp->npindev_biome,          seed, csize.X, csize.Z);
 }
 
 MapgenIndev::~MapgenIndev() {
 	delete noiseindev_terrain_base;
 	delete noiseindev_terrain_higher;
 	delete noiseindev_steepness;
-	//delete noise_height_select;
-	//delete noise_trees;
 	delete noiseindev_mud;
-	//delete noise_beach;
 	delete noiseindev_float_islands1;
 	delete noiseindev_float_islands2;
 	delete noiseindev_float_islands3;
@@ -166,39 +149,43 @@ void MapgenIndev::calculateNoise() {
 		z + 0.2 * noiseindev_biome->npindev->spread.Z * farscale(noiseindev_biome->npindev->farspread, x, z));
 }
 
-bool MapgenIndevParams::readParams(Settings *settings) {
-	freq_desert = settings->getFloat("mgv6_freq_desert");
-	freq_beach  = settings->getFloat("mgv6_freq_beach");
-
-	bool success = 
-		settings->getNoiseIndevParams("mgindev_np_terrain_base",   npindev_terrain_base)   &&
-		settings->getNoiseIndevParams("mgindev_np_terrain_higher", npindev_terrain_higher) &&
-		settings->getNoiseIndevParams("mgindev_np_steepness",      npindev_steepness)      &&
-		settings->getNoiseParams("mgv6_np_height_select",          np_height_select)       &&
-		settings->getNoiseParams("mgv6_np_trees",                  np_trees)               &&
-		settings->getNoiseIndevParams("mgindev_np_mud",            npindev_mud)            &&
-		settings->getNoiseParams("mgv6_np_beach",                  np_beach)               &&
-		settings->getNoiseIndevParams("mgindev_np_biome",          npindev_biome)          &&
-		settings->getNoiseParams("mgv6_np_cave",                   np_cave)                &&
-		settings->getNoiseIndevParams("mgindev_np_float_islands1", npindev_float_islands1) &&
-		settings->getNoiseIndevParams("mgindev_np_float_islands2", npindev_float_islands2) &&
-		settings->getNoiseIndevParams("mgindev_np_float_islands3", npindev_float_islands3);
-	return success;
+MapgenIndevParams::MapgenIndevParams() {
+	float_islands = 500;
+	npindev_terrain_base    = NoiseIndevParams(-4,   20,  v3f(250, 250, 250), 82341, 5, 0.6,  10,  10);
+	npindev_terrain_higher  = NoiseIndevParams(20,   16,  v3f(500, 500, 500), 85039, 5, 0.6,  10,  10);
+	npindev_steepness       = NoiseIndevParams(0.85, 0.5, v3f(125, 125, 125), -932,  5, 0.7,  2,   10);
+	npindev_mud             = NoiseIndevParams(4,    2,   v3f(200, 200, 200), 91013, 3, 0.55, 1,   1);
+	npindev_biome           = NoiseIndevParams(0,    1,   v3f(250, 250, 250), 9130,  3, 0.50, 1,   10);
+	npindev_float_islands1  = NoiseIndevParams(0,    1,   v3f(256, 256, 256), 3683,  6, 0.6,  1,   1.5);
+	npindev_float_islands2  = NoiseIndevParams(0,    1,   v3f(8,   8,   8  ), 9292,  2, 0.5,  1,   1.5);
+	npindev_float_islands3  = NoiseIndevParams(0,    1,   v3f(256, 256, 256), 6412,  2, 0.5,  1,   0.5);
+}
+
+void MapgenIndevParams::readParams(Settings *settings) {
+	MapgenV6Params::readParams(settings);
+
+	settings->tryGetS16("mgindev_float_islands", float_islands);
+
+	settings->getNoiseIndevParams("mgindev_np_terrain_base",   npindev_terrain_base);
+	settings->getNoiseIndevParams("mgindev_np_terrain_higher", npindev_terrain_higher);
+	settings->getNoiseIndevParams("mgindev_np_steepness",      npindev_steepness);
+	settings->getNoiseIndevParams("mgindev_np_mud",            npindev_mud);
+	settings->getNoiseIndevParams("mgindev_np_biome",          npindev_biome);
+	settings->getNoiseIndevParams("mgindev_np_float_islands1", npindev_float_islands1);
+	settings->getNoiseIndevParams("mgindev_np_float_islands2", npindev_float_islands2);
+	settings->getNoiseIndevParams("mgindev_np_float_islands3", npindev_float_islands3);
 }
 
 void MapgenIndevParams::writeParams(Settings *settings) {
-	settings->setFloat("mgv6_freq_desert", freq_desert);
-	settings->setFloat("mgv6_freq_beach",  freq_beach);
+	MapgenV6Params::writeParams(settings);
+
+	settings->setS16("mgindev_float_islands", float_islands);
 
 	settings->setNoiseIndevParams("mgindev_np_terrain_base",   npindev_terrain_base);
 	settings->setNoiseIndevParams("mgindev_np_terrain_higher", npindev_terrain_higher);
 	settings->setNoiseIndevParams("mgindev_np_steepness",      npindev_steepness);
-	settings->setNoiseParams("mgv6_np_height_select",          np_height_select);
-	settings->setNoiseParams("mgv6_np_trees",                  np_trees);
 	settings->setNoiseIndevParams("mgindev_np_mud",            npindev_mud);
-	settings->setNoiseParams("mgv6_np_beach",                  np_beach);
 	settings->setNoiseIndevParams("mgindev_np_biome",          npindev_biome);
-	settings->setNoiseParams("mgv6_np_cave",                   np_cave);
 	settings->setNoiseIndevParams("mgindev_np_float_islands1", npindev_float_islands1);
 	settings->setNoiseIndevParams("mgindev_np_float_islands2", npindev_float_islands2);
 	settings->setNoiseIndevParams("mgindev_np_float_islands3", npindev_float_islands3);
@@ -391,7 +378,6 @@ void MapgenIndev::generateFloatIslands(int min_y) {
 }
 
 void MapgenIndev::generateExperimental() {
-	int float_islands = g_settings->getS16("mgindev_float_islands");
 	if (float_islands)
 		generateFloatIslands(float_islands);
 }
diff --git a/src/mapgen_indev.h b/src/mapgen_indev.h
index cfef59041..a5b0a6678 100644
--- a/src/mapgen_indev.h
+++ b/src/mapgen_indev.h
@@ -65,72 +65,38 @@ class NoiseIndev : public Noise {
 	void transformNoiseMapFarScale(float xx = 0, float yy = 0, float zz = 0);
 };
 
-extern NoiseIndevParams nparams_indev_def;
-/*
-extern NoiseIndevParams nparams_indev_def_terrain_base;
-extern NoiseIndevParams nparams_indev_def_terrain_higher;
-extern NoiseIndevParams nparams_indev_def_steepness;
-//extern NoiseIndevParams nparams_indev_def_height_select;
-//extern NoiseIndevParams nparams_indev_def_trees;
-extern NoiseIndevParams nparams_indev_def_mud;
-//extern NoiseIndevParams nparams_indev_def_beach;
-extern NoiseIndevParams nparams_indev_def_biome;
-//extern NoiseIndevParams nparams_indev_def_cave;
-extern NoiseIndevParams nparams_indev_def_float_islands;
-*/
 
 struct MapgenIndevParams : public MapgenV6Params {
+	s16 float_islands;
 	NoiseIndevParams npindev_terrain_base;
 	NoiseIndevParams npindev_terrain_higher;
 	NoiseIndevParams npindev_steepness;
-	//NoiseParams *np_height_select;
-	//NoiseParams *np_trees;
 	NoiseIndevParams npindev_mud;
-	//NoiseParams *np_beach;
 	NoiseIndevParams npindev_biome;
-	//NoiseParams *np_cave;
 	NoiseIndevParams npindev_float_islands1;
 	NoiseIndevParams npindev_float_islands2;
 	NoiseIndevParams npindev_float_islands3;
 
-	MapgenIndevParams() {
-		//freq_desert       = 0.45;
-		//freq_beach        = 0.15;
-		npindev_terrain_base   = nparams_indev_def; //&nparams_indev_def_terrain_base;
-		npindev_terrain_higher = nparams_indev_def; //&nparams_indev_def_terrain_higher;
-		npindev_steepness      = nparams_indev_def; //&nparams_indev_def_steepness;
-		//np_height_select  = &nparams_v6_def_height_select;
-		//np_trees          = &nparams_v6_def_trees;
-		npindev_mud            = nparams_indev_def; //&nparams_indev_def_mud;
-		//np_beach          = &nparams_v6_def_beach;
-		npindev_biome          = nparams_indev_def; //&nparams_indev_def_biome;
-		//np_cave           = &nparams_v6_def_cave;
-		npindev_float_islands1  = nparams_indev_def; //&nparams_indev_def_float_islands;
-		npindev_float_islands2  = nparams_indev_def; //&nparams_indev_def_float_islands;
-		npindev_float_islands3  = nparams_indev_def; //&nparams_indev_def_float_islands;
+	MapgenIndevParams();
+	~MapgenIndevParams() {}
 
-	}
-
-	bool readParams(Settings *settings);
+	void readParams(Settings *settings);
 	void writeParams(Settings *settings);
 };
 
 class MapgenIndev : public MapgenV6 {
-    public:
+public:
 	NoiseIndev *noiseindev_terrain_base;
 	NoiseIndev *noiseindev_terrain_higher;
 	NoiseIndev *noiseindev_steepness;
-	//NoiseIndev *noise_height_select;
-	//NoiseIndev *noise_trees;
 	NoiseIndev *noiseindev_mud;
-	//NoiseIndev *noise_beach;
 	NoiseIndev *noiseindev_biome;
-	//NoiseIndevParams *np_cave;
 	NoiseIndev *noiseindev_float_islands1;
 	NoiseIndev *noiseindev_float_islands2;
 	NoiseIndev *noiseindev_float_islands3;
+	s16 float_islands;
 
-	MapgenIndev(int mapgenid, MapgenIndevParams *params, EmergeManager *emerge);
+	MapgenIndev(int mapgenid, MapgenParams *params, EmergeManager *emerge);
 	~MapgenIndev();
 	void calculateNoise();
 
@@ -138,7 +104,6 @@ class MapgenIndev : public MapgenV6 {
 	float baseTerrainLevelFromMap(int index);
 	float getMudAmount(int index);
 	void generateCaves(int max_stone_y);
-	//void defineCave(Cave & cave, PseudoRandom ps, v3s16 node_min, bool large_cave);
 	void generateExperimental();
 	
 	void generateFloatIslands(int min_y);
@@ -146,10 +111,10 @@ class MapgenIndev : public MapgenV6 {
 
 struct MapgenFactoryIndev : public MapgenFactoryV6 {
 	Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
-		return new MapgenIndev(mgid, (MapgenIndevParams *)params, emerge);
+		return new MapgenIndev(mgid, params, emerge);
 	};
 
-	MapgenParams *createMapgenParams() {
+	MapgenSpecificParams *createMapgenParams() {
 		return new MapgenIndevParams();
 	};
 };
diff --git a/src/mapgen_math.cpp b/src/mapgen_math.cpp
index 7748895b5..aee2b0d2a 100644
--- a/src/mapgen_math.cpp
+++ b/src/mapgen_math.cpp
@@ -147,7 +147,7 @@ double sphere(double x, double y, double z, double d, int ITR = 1) {
 
 //////////////////////// Mapgen Math parameter read/write
 
-bool MapgenMathParams::readParams(Settings *settings) {
+void MapgenMathParams::readParams(Settings *settings) {
 	//params = settings->getJson("mg_math");
 	// can be counfigured from here.
 	std::string value = "{}";
@@ -157,8 +157,6 @@ bool MapgenMathParams::readParams(Settings *settings) {
 	}
 
 	if (params["generator"].empty()) params["generator"] = settings->get("mgmath_generator");
-
-	return true;
 }
 
 
@@ -169,8 +167,8 @@ void MapgenMathParams::writeParams(Settings *settings) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-MapgenMath::MapgenMath(int mapgenid, MapgenMathParams *params_, EmergeManager *emerge) : MapgenV7(mapgenid, params_, emerge) {
-	mg_params = params_;
+MapgenMath::MapgenMath(int mapgenid, MapgenParams *params_, EmergeManager *emerge) : MapgenV7(mapgenid, params_, emerge) {
+	mg_params = (MapgenMathParams *)params_;
 	this->flags |= MG_NOLIGHT;
 
 	Json::Value & params = mg_params->params;
diff --git a/src/mapgen_math.h b/src/mapgen_math.h
index 1bc404641..304a337c4 100644
--- a/src/mapgen_math.h
+++ b/src/mapgen_math.h
@@ -26,12 +26,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 struct MapgenMathParams : public MapgenV7Params {
 
-	MapgenMathParams() {
-	}
+	MapgenMathParams() {}
+	~MapgenMathParams() {}
 
 	Json::Value params;
 
-	bool readParams(Settings *settings);
+	void readParams(Settings *settings);
 	void writeParams(Settings *settings);
 };
 
@@ -39,7 +39,7 @@ class MapgenMath : public MapgenV7 {
 	public:
 		MapgenMathParams * mg_params;
 
-		MapgenMath(int mapgenid, MapgenMathParams *mg_params, EmergeManager *emerge);
+		MapgenMath(int mapgenid, MapgenParams *mg_params, EmergeManager *emerge);
 		~MapgenMath();
 
 		int generateTerrain();
@@ -57,10 +57,10 @@ class MapgenMath : public MapgenV7 {
 
 struct MapgenFactoryMath : public MapgenFactory {
 	Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
-		return new MapgenMath(mgid, (MapgenMathParams *)params, emerge);
+		return new MapgenMath(mgid, params, emerge);
 	};
 
-	MapgenParams *createMapgenParams() {
+	MapgenSpecificParams *createMapgenParams() {
 		return new MapgenMathParams();
 	};
 };
diff --git a/src/mapgen_singlenode.cpp b/src/mapgen_singlenode.cpp
index fd443995c..5288a1f08 100644
--- a/src/mapgen_singlenode.cpp
+++ b/src/mapgen_singlenode.cpp
@@ -29,8 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 //////////////////////// Mapgen Singlenode parameter read/write
 
-bool MapgenSinglenodeParams::readParams(Settings *settings) {
-	return true;
+void MapgenSinglenodeParams::readParams(Settings *settings) {
 }
 
 
@@ -39,7 +38,7 @@ void MapgenSinglenodeParams::writeParams(Settings *settings) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-MapgenSinglenode::MapgenSinglenode(int mapgenid, MapgenSinglenodeParams *params) {
+MapgenSinglenode::MapgenSinglenode(int mapgenid, MapgenParams *params) {
 	flags = params->flags;
 }
 
diff --git a/src/mapgen_singlenode.h b/src/mapgen_singlenode.h
index e2eb1bb90..eba85e7ce 100644
--- a/src/mapgen_singlenode.h
+++ b/src/mapgen_singlenode.h
@@ -22,12 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "mapgen.h"
 
-struct MapgenSinglenodeParams : public MapgenParams {
+struct MapgenSinglenodeParams : public MapgenSpecificParams {
 	
 	MapgenSinglenodeParams() {}
 	~MapgenSinglenodeParams() {}
 	
-	bool readParams(Settings *settings);
+	void readParams(Settings *settings);
 	void writeParams(Settings *settings);
 };
 
@@ -35,7 +35,7 @@ class MapgenSinglenode : public Mapgen {
 public:
 	u32 flags;
 
-	MapgenSinglenode(int mapgenid, MapgenSinglenodeParams *params);
+	MapgenSinglenode(int mapgenid, MapgenParams *params);
 	~MapgenSinglenode();
 	
 	void makeChunk(BlockMakeData *data);
@@ -44,10 +44,10 @@ class MapgenSinglenode : public Mapgen {
 
 struct MapgenFactorySinglenode : public MapgenFactory {
 	Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
-		return new MapgenSinglenode(mgid, (MapgenSinglenodeParams *)params);
+		return new MapgenSinglenode(mgid, params);
 	};
 	
-	MapgenParams *createMapgenParams() {
+	MapgenSpecificParams *createMapgenParams() {
 		return new MapgenSinglenodeParams();
 	};
 };
diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp
index a27ca2e0a..526d4af2e 100644
--- a/src/mapgen_v6.cpp
+++ b/src/mapgen_v6.cpp
@@ -37,62 +37,47 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h"
 #include "mapgen_v6.h"
 
-/////////////////// Mapgen V6 perlin noise default values
-NoiseParams nparams_v6_def_terrain_base =
-	{-AVERAGE_MUD_AMOUNT, 20.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6};
-NoiseParams nparams_v6_def_terrain_higher =
-	{20.0, 16.0, v3f(500.0, 500.0, 500.0), 85039, 5, 0.6};
-NoiseParams nparams_v6_def_steepness =
-	{0.85, 0.5, v3f(125.0, 125.0, 125.0), -932, 5, 0.7};
-NoiseParams nparams_v6_def_height_select =
-	{0.5, 1.0, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69};
-NoiseParams nparams_v6_def_mud =
-	{AVERAGE_MUD_AMOUNT, 2.0, v3f(200.0, 200.0, 200.0), 91013, 3, 0.55};
-NoiseParams nparams_v6_def_beach =
-	{0.0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50};
-NoiseParams nparams_v6_def_biome =
-	{0.0, 1.0, v3f(250.0, 250.0, 250.0), 9130, 3, 0.50};
-NoiseParams nparams_v6_def_cave =
-	{6.0, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50};
-NoiseParams nparams_v6_def_humidity =
-	{0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 4, 0.66};
-NoiseParams nparams_v6_def_trees =
-	{0.0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66};
-NoiseParams nparams_v6_def_apple_trees =
-	{0.0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45};
-
+FlagDesc flagdesc_mapgen_v6[] = {
+	{"v6_jungles",     MGV6_JUNGLES},
+	{"v6_biome_blend", MGV6_BIOME_BLEND},
+	{"v6_nomudflow",   MGV6_NOMUDFLOW},
+	{NULL,             0}
+};
 
 ///////////////////////////////////////////////////////////////////////////////
 
 
-MapgenV6::MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge) {
+MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
 	this->generating  = false;
 	this->id       = mapgenid;
 	this->emerge   = emerge;
 
-	this->seed     = (int)params->seed;
+	this->seed        = (int)params->seed;
 	this->water_level = params->water_level;
-	this->flags   = params->flags;
-	this->csize   = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
-	this->gennotify = emerge->gennotify;
-
-	this->freq_desert = params->freq_desert;
-	this->freq_beach  = params->freq_beach;
+	this->flags       = params->flags;
+	this->csize       = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
+	this->gennotify   = emerge->gennotify;
 
 	this->ystride = csize.X; //////fix this
 	
-	np_cave        = &params->np_cave;
-	np_humidity    = &params->np_humidity;
-	np_trees       = &params->np_trees;
-	np_apple_trees = &params->np_apple_trees;
-
-	noise_terrain_base   = new Noise(&params->np_terrain_base,   seed, csize.X, csize.Y);
-	noise_terrain_higher = new Noise(&params->np_terrain_higher, seed, csize.X, csize.Y);
-	noise_steepness      = new Noise(&params->np_steepness,      seed, csize.X, csize.Y);
-	noise_height_select  = new Noise(&params->np_height_select,  seed, csize.X, csize.Y);
-	noise_mud            = new Noise(&params->np_mud,            seed, csize.X, csize.Y);
-	noise_beach          = new Noise(&params->np_beach,          seed, csize.X, csize.Y);
-	noise_biome          = new Noise(&params->np_biome,          seed, csize.X, csize.Y);
+	MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
+
+	this->spflags     = sp->spflags;
+	this->freq_desert = sp->freq_desert;
+	this->freq_beach  = sp->freq_beach;
+
+	np_cave        = &sp->np_cave;
+	np_humidity    = &sp->np_humidity;
+	np_trees       = &sp->np_trees;
+	np_apple_trees = &sp->np_apple_trees;
+
+	noise_terrain_base   = new Noise(&sp->np_terrain_base,   seed, csize.X, csize.Y);
+	noise_terrain_higher = new Noise(&sp->np_terrain_higher, seed, csize.X, csize.Y);
+	noise_steepness      = new Noise(&sp->np_steepness,      seed, csize.X, csize.Y);
+	noise_height_select  = new Noise(&sp->np_height_select,  seed, csize.X, csize.Y);
+	noise_mud            = new Noise(&sp->np_mud,            seed, csize.X, csize.Y);
+	noise_beach          = new Noise(&sp->np_beach,          seed, csize.X, csize.Y);
+	noise_biome          = new Noise(&sp->np_biome,          seed, csize.X, csize.Y);
 }
 
 
@@ -107,6 +92,63 @@ MapgenV6::~MapgenV6() {
 }
 
 
+MapgenV6Params::MapgenV6Params() {
+	spflags     = MGV6_BIOME_BLEND;
+	freq_desert = 0.45;
+	freq_beach  = 0.15;
+
+	np_terrain_base   = NoiseParams(-4,  20.0, v3f(250.0, 250.0, 250.0), 82341,  5, 0.6);
+	np_terrain_higher = NoiseParams(20,  16.0, v3f(500.0, 500.0, 500.0), 85039,  5, 0.6);
+	np_steepness      = NoiseParams(0.85,0.5,  v3f(125.0, 125.0, 125.0), -932,   5, 0.7);
+	np_height_select  = NoiseParams(0.5, 1.0,  v3f(250.0, 250.0, 250.0), 4213,   5, 0.69);
+	np_mud            = NoiseParams(4,   2.0,  v3f(200.0, 200.0, 200.0), 91013,  3, 0.55);
+	np_beach          = NoiseParams(0,   1.0,  v3f(250.0, 250.0, 250.0), 59420,  3, 0.50);
+	np_biome          = NoiseParams(0,   1.0,  v3f(250.0, 250.0, 250.0), 9130,   3, 0.50);
+	np_cave           = NoiseParams(6,   6.0,  v3f(250.0, 250.0, 250.0), 34329,  3, 0.50);
+	np_humidity       = NoiseParams(0.5, 0.5,  v3f(500.0, 500.0, 500.0), 72384,  4, 0.66);
+	np_trees          = NoiseParams(0,   1.0,  v3f(125.0, 125.0, 125.0), 2,      4, 0.66);
+	np_apple_trees    = NoiseParams(0,   1.0,  v3f(100.0, 100.0, 100.0), 342902, 3, 0.45);
+}
+
+
+void MapgenV6Params::readParams(Settings *settings) {
+	settings->tryGetFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6);
+	settings->tryGetFloat("mgv6_freq_desert", freq_desert);
+	settings->tryGetFloat("mgv6_freq_beach",  freq_beach);
+
+	settings->getNoiseParams("mgv6_np_terrain_base",   np_terrain_base);
+	settings->getNoiseParams("mgv6_np_terrain_higher", np_terrain_higher);
+	settings->getNoiseParams("mgv6_np_steepness",      np_steepness);
+	settings->getNoiseParams("mgv6_np_height_select",  np_height_select);
+	settings->getNoiseParams("mgv6_np_mud",            np_mud);
+	settings->getNoiseParams("mgv6_np_beach",          np_beach);
+	settings->getNoiseParams("mgv6_np_biome",          np_biome);
+	settings->getNoiseParams("mgv6_np_cave",           np_cave);
+	settings->getNoiseParams("mgv6_np_humidity",       np_humidity);
+	settings->getNoiseParams("mgv6_np_trees",          np_trees);
+	settings->getNoiseParams("mgv6_np_apple_trees",    np_apple_trees);
+}
+
+
+void MapgenV6Params::writeParams(Settings *settings) {
+	settings->setFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6);
+	settings->setFloat("mgv6_freq_desert", freq_desert);
+	settings->setFloat("mgv6_freq_beach",  freq_beach);
+
+	settings->setNoiseParams("mgv6_np_terrain_base",   np_terrain_base);
+	settings->setNoiseParams("mgv6_np_terrain_higher", np_terrain_higher);
+	settings->setNoiseParams("mgv6_np_steepness",      np_steepness);
+	settings->setNoiseParams("mgv6_np_height_select",  np_height_select);
+	settings->setNoiseParams("mgv6_np_mud",            np_mud);
+	settings->setNoiseParams("mgv6_np_beach",          np_beach);
+	settings->setNoiseParams("mgv6_np_biome",          np_biome);
+	settings->setNoiseParams("mgv6_np_cave",           np_cave);
+	settings->setNoiseParams("mgv6_np_humidity",       np_humidity);
+	settings->setNoiseParams("mgv6_np_trees",          np_trees);
+	settings->setNoiseParams("mgv6_np_apple_trees",    np_apple_trees);
+}
+
+
 //////////////////////// Some helper functions for the map generator
 
 
@@ -323,7 +365,7 @@ BiomeType MapgenV6::getBiome(int index, v2s16 p)
 	if (d > freq_desert)
 		return BT_DESERT;
 		
-	if ((flags & MGV6_BIOME_BLEND) &&
+	if ((spflags & MGV6_BIOME_BLEND) &&
 		(d > freq_desert - 0.10) &&
 		((noise2d(p.X, p.Y, seed) + 1.0) > (freq_desert - d) * 20.0))
 		return BT_DESERT;
@@ -439,7 +481,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
 		addDirtGravelBlobs();
 
 		// Flow mud away from steep edges
-		if (!(flags & MGV6_NOMUDFLOW))
+		if (!(spflags & MGV6_NOMUDFLOW))
 			flowMud(mudflow_minpos, mudflow_maxpos);
 
 	}
@@ -866,7 +908,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
 		
 		float humidity;
 		bool is_jungle = false;
-		if (flags & MGV6_JUNGLES) {
+		if (spflags & MGV6_JUNGLES) {
 			humidity = getHumidity(p2d_center);
 			if (humidity > 0.75) {
 				is_jungle = true;
diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h
index eec5e4677..07d79f6a6 100644
--- a/src/mapgen_v6.h
+++ b/src/mapgen_v6.h
@@ -24,25 +24,23 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #define AVERAGE_MUD_AMOUNT 4
 
+/////////////////// Mapgen V6 flags
+#define MGV6_JUNGLES     0x01
+#define MGV6_BIOME_BLEND 0x02
+#define MGV6_NOMUDFLOW   0x04
+
+
+extern FlagDesc flagdesc_mapgen_v6[];
+
+
 enum BiomeType
 {
 	BT_NORMAL,
 	BT_DESERT
 };
 
-extern NoiseParams nparams_v6_def_terrain_base;
-extern NoiseParams nparams_v6_def_terrain_higher;
-extern NoiseParams nparams_v6_def_steepness;
-extern NoiseParams nparams_v6_def_height_select;
-extern NoiseParams nparams_v6_def_mud;
-extern NoiseParams nparams_v6_def_beach;
-extern NoiseParams nparams_v6_def_biome;
-extern NoiseParams nparams_v6_def_cave;
-extern NoiseParams nparams_v6_def_humidity;
-extern NoiseParams nparams_v6_def_trees;
-extern NoiseParams nparams_v6_def_apple_trees;
-
-struct MapgenV6Params : public MapgenParams {
+struct MapgenV6Params : public MapgenSpecificParams {
+	u32 spflags;
 	float freq_desert;
 	float freq_beach;
 	NoiseParams np_terrain_base;
@@ -57,25 +55,10 @@ struct MapgenV6Params : public MapgenParams {
 	NoiseParams np_trees;
 	NoiseParams np_apple_trees;
 	
-	MapgenV6Params() {
-		freq_desert       = 0.45;
-		freq_beach        = 0.15;
-		np_terrain_base   = nparams_v6_def_terrain_base;
-		np_terrain_higher = nparams_v6_def_terrain_higher;
-		np_steepness      = nparams_v6_def_steepness;
-		np_height_select  = nparams_v6_def_height_select;
-		np_mud            = nparams_v6_def_mud;
-		np_beach          = nparams_v6_def_beach;
-		np_biome          = nparams_v6_def_biome;
-		np_cave           = nparams_v6_def_cave;
-		np_humidity       = nparams_v6_def_humidity;
-		np_trees          = nparams_v6_def_trees;
-		np_apple_trees    = nparams_v6_def_apple_trees;
-	}
-	
+	MapgenV6Params();
 	~MapgenV6Params() {}
 	
-	bool readParams(Settings *settings);
+	void readParams(Settings *settings);
 	void writeParams(Settings *settings);
 };
 
@@ -85,6 +68,7 @@ class MapgenV6 : public Mapgen {
 
 	int ystride;
 	u32 flags;
+	u32 spflags;
 
 	u32 blockseed;
 	v3s16 node_min;
@@ -124,7 +108,7 @@ class MapgenV6 : public Mapgen {
 	content_t c_stair_cobble;
 	content_t c_stair_sandstone;
 
-	MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge);
+	MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge);
 	~MapgenV6();
 	
 	void makeChunk(BlockMakeData *data);
@@ -165,10 +149,10 @@ class MapgenV6 : public Mapgen {
 
 struct MapgenFactoryV6 : public MapgenFactory {
 	Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
-		return new MapgenV6(mgid, (MapgenV6Params *)params, emerge);
+		return new MapgenV6(mgid, params, emerge);
 	};
 	
-	MapgenParams *createMapgenParams() {
+	MapgenSpecificParams *createMapgenParams() {
 		return new MapgenV6Params();
 	};
 };
diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp
index 6d5c04900..77e25a672 100644
--- a/src/mapgen_v7.cpp
+++ b/src/mapgen_v7.cpp
@@ -38,33 +38,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapgen_v7.h"
 
 
-/////////////////// Mapgen V7 perlin noise default values
-NoiseParams nparams_v7_def_terrain_base =
-	{4, 70, v3f(300, 300, 300), 82341, 6, 0.7};
-NoiseParams nparams_v7_def_terrain_alt =
-	{4, 25, v3f(600, 600, 600), 5934, 5, 0.6};
-NoiseParams nparams_v7_def_terrain_persist =
-	{0.6, 0.1, v3f(500, 500, 500), 539, 3, 0.6};
-NoiseParams nparams_v7_def_height_select =
-	{-0.5, 1, v3f(250, 250, 250), 4213, 5, 0.69};
-	
-NoiseParams nparams_v7_def_filler_depth =
-	{0, 1.2, v3f(150, 150, 150), 261, 4, 0.7};
-
-NoiseParams nparams_v7_def_mount_height =
-	{100, 30, v3f(500, 500, 500), 72449, 4, 0.6};	
-NoiseParams nparams_v7_def_ridge_uwater =
-	{0, 1, v3f(500, 500, 500), 85039, 4, 0.6};
-NoiseParams nparams_v7_def_mountain =
-	{0, 1, v3f(250, 350, 250), 5333, 5, 0.68};
-NoiseParams nparams_v7_def_ridge =
-	{0, 1, v3f(100, 100, 100), 6467, 4, 0.75};
-
+FlagDesc flagdesc_mapgen_v7[] = {
+	{"v7_mountains", MGV7_MOUNTAINS},
+	{"v7_ridges",    MGV7_RIDGES},
+	{NULL,           0}
+};
 
 ///////////////////////////////////////////////////////////////////////////////
 
 
-MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge) {
+MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
 	this->generating  = false;
 	this->id     = mapgenid;
 	this->emerge = emerge;
@@ -86,19 +69,21 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
 	this->heightmap = new s16[csize.X * csize.Z];
 	this->ridge_heightmap = new s16[csize.X * csize.Z];
 
+	MapgenV7Params *sp = (MapgenV7Params *)params->sparams;
+
 	// Terrain noise
-	noise_terrain_base    = new Noise(&params->np_terrain_base,    seed, csize.X, csize.Z);
-	noise_terrain_alt     = new Noise(&params->np_terrain_alt,     seed, csize.X, csize.Z);
-	noise_terrain_persist = new Noise(&params->np_terrain_persist, seed, csize.X, csize.Z);
-	noise_height_select   = new Noise(&params->np_height_select,   seed, csize.X, csize.Z);
-	noise_filler_depth    = new Noise(&params->np_filler_depth,    seed, csize.X, csize.Z);
-	noise_mount_height    = new Noise(&params->np_mount_height,    seed, csize.X, csize.Z);
-	noise_ridge_uwater    = new Noise(&params->np_ridge_uwater,    seed, csize.X, csize.Z);
-	
+	noise_terrain_base    = new Noise(&sp->np_terrain_base,    seed, csize.X, csize.Z);
+	noise_terrain_alt     = new Noise(&sp->np_terrain_alt,     seed, csize.X, csize.Z);
+	noise_terrain_persist = new Noise(&sp->np_terrain_persist, seed, csize.X, csize.Z);
+	noise_height_select   = new Noise(&sp->np_height_select,   seed, csize.X, csize.Z);
+	noise_filler_depth    = new Noise(&sp->np_filler_depth,    seed, csize.X, csize.Z);
+	noise_mount_height    = new Noise(&sp->np_mount_height,    seed, csize.X, csize.Z);
+	noise_ridge_uwater    = new Noise(&sp->np_ridge_uwater,    seed, csize.X, csize.Z);
+
 	// 3d terrain noise
-	noise_mountain = new Noise(&params->np_mountain, seed, csize.X, csize.Y, csize.Z);
-	noise_ridge    = new Noise(&params->np_ridge,    seed, csize.X, csize.Y, csize.Z);
-	
+	noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y, csize.Z);
+	noise_ridge    = new Noise(&sp->np_ridge,    seed, csize.X, csize.Y, csize.Z);
+
 	// Biome noise
 	noise_heat     = new Noise(bmgr->np_heat,     seed, csize.X, csize.Z);
 	noise_humidity = new Noise(bmgr->np_humidity, seed, csize.X, csize.Z);	
@@ -125,6 +110,54 @@ MapgenV7::~MapgenV7() {
 }
 
 
+MapgenV7Params::MapgenV7Params() {
+	spflags = MGV7_MOUNTAINS | MGV7_RIDGES;
+
+	np_terrain_base    = NoiseParams(4,    70,  v3f(300, 300, 300), 82341, 6, 0.7);
+	np_terrain_alt     = NoiseParams(4,    25,  v3f(600, 600, 600), 5934,  5, 0.6);
+	np_terrain_persist = NoiseParams(0.6,  0.1, v3f(500, 500, 500), 539,   3, 0.6);
+	np_height_select   = NoiseParams(-0.5, 1,   v3f(250, 250, 250), 4213,  5, 0.69);
+	np_filler_depth    = NoiseParams(0,    1.2, v3f(150, 150, 150), 261,   4, 0.7);
+	np_mount_height    = NoiseParams(100,  30,  v3f(500, 500, 500), 72449, 4, 0.6);
+	np_ridge_uwater    = NoiseParams(0,    1,   v3f(500, 500, 500), 85039, 4, 0.6);
+	np_mountain        = NoiseParams(0,    1,   v3f(250, 350, 250), 5333,  5, 0.68);
+	np_ridge           = NoiseParams(0,    1,   v3f(100, 100, 100), 6467,  4, 0.75);
+}
+
+
+void MapgenV7Params::readParams(Settings *settings) {
+	settings->tryGetFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7);
+
+	settings->getNoiseParams("mgv7_np_terrain_base",    np_terrain_base);
+	settings->getNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt);
+	settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist);
+	settings->getNoiseParams("mgv7_np_height_select",   np_height_select);
+	settings->getNoiseParams("mgv7_np_filler_depth",    np_filler_depth);
+	settings->getNoiseParams("mgv7_np_mount_height",    np_mount_height);
+	settings->getNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater);
+	settings->getNoiseParams("mgv7_np_mountain",        np_mountain);
+	settings->getNoiseParams("mgv7_np_ridge",           np_ridge);
+}
+
+
+void MapgenV7Params::writeParams(Settings *settings) {
+	settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7);
+
+	settings->setNoiseParams("mgv7_np_terrain_base",    np_terrain_base);
+	settings->setNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt);
+	settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist);
+	settings->setNoiseParams("mgv7_np_height_select",   np_height_select);
+	settings->setNoiseParams("mgv7_np_filler_depth",    np_filler_depth);
+	settings->setNoiseParams("mgv7_np_mount_height",    np_mount_height);
+	settings->setNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater);
+	settings->setNoiseParams("mgv7_np_mountain",        np_mountain);
+	settings->setNoiseParams("mgv7_np_ridge",           np_ridge);
+}
+
+
+///////////////////////////////////////
+
+
 int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
 	// Base terrain calculation
 	s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
@@ -262,13 +295,13 @@ void MapgenV7::calculateNoise() {
 	
 	noise_filler_depth->perlinMap2D(x, z);
 	
-	if (flags & MGV7_MOUNTAINS) {
+	if (spflags & MGV7_MOUNTAINS) {
 		noise_mountain->perlinMap3D(x, y, z);
 		noise_mount_height->perlinMap2D(x, z);
 		noise_mount_height->transformNoiseMap();
 	}
 
-	if (flags & MGV7_RIDGES) {
+	if (spflags & MGV7_RIDGES) {
 		noise_ridge->perlinMap3D(x, y, z);
 		noise_ridge_uwater->perlinMap2D(x, z);
 	}
@@ -375,10 +408,10 @@ void MapgenV7::carveRivers() {
 int MapgenV7::generateTerrain() {
 	int ymax = generateBaseTerrain();
 
-	if (flags & MGV7_MOUNTAINS)
+	if (spflags & MGV7_MOUNTAINS)
 		generateMountainTerrain();
 
-	if (flags & MGV7_RIDGES)
+	if (spflags & MGV7_RIDGES)
 		generateRidgeTerrain();
 		
 	return ymax;
@@ -695,14 +728,15 @@ void MapgenV7::addTopNodes() {
 #endif
 
 
-#include "mapgen_v6.h"
+NoiseParams nparams_v7_def_cave(6, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50);
+
 void MapgenV7::generateCaves(int max_stone_y) {
 	PseudoRandom ps(blockseed + 21343);
 
 	int volume_nodes = (node_max.X - node_min.X + 1) *
 					   (node_max.Y - node_min.Y + 1) *
 					   (node_max.Z - node_min.Z + 1);
-	float cave_amount = NoisePerlin2D(&nparams_v6_def_cave,
+	float cave_amount = NoisePerlin2D(&nparams_v7_def_cave,
 								node_min.X, node_min.Y, seed);
 
 	u32 caves_count = MYMAX(0.0, cave_amount) * volume_nodes / 250000;
@@ -715,5 +749,5 @@ void MapgenV7::generateCaves(int max_stone_y) {
 	for (u32 i = 0; i < bruises_count; i++) {
 		CaveV7 cave(this, &ps, true);
 		cave.makeCave(node_min, node_max, max_stone_y);
-	}	
+	}
 }
diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h
index e7a72e464..a7c80928f 100644
--- a/src/mapgen_v7.h
+++ b/src/mapgen_v7.h
@@ -22,17 +22,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "mapgen.h"
 
-extern NoiseParams nparams_v7_def_terrain_base;
-extern NoiseParams nparams_v7_def_terrain_alt;
-extern NoiseParams nparams_v7_def_terrain_persist;
-extern NoiseParams nparams_v7_def_height_select;
-extern NoiseParams nparams_v7_def_filler_depth;
-extern NoiseParams nparams_v7_def_mount_height;
-extern NoiseParams nparams_v7_def_ridge_uwater;
-extern NoiseParams nparams_v7_def_mountain;
-extern NoiseParams nparams_v7_def_ridge;
-
-struct MapgenV7Params : public MapgenParams {
+/////////////////// Mapgen V7 flags
+#define MGV7_MOUNTAINS   0x01
+#define MGV7_RIDGES      0x02
+
+
+extern FlagDesc flagdesc_mapgen_v7[];
+
+
+struct MapgenV7Params : public MapgenSpecificParams {
+	u32 spflags;
 	NoiseParams np_terrain_base;
 	NoiseParams np_terrain_alt;
 	NoiseParams np_terrain_persist;
@@ -43,21 +42,10 @@ struct MapgenV7Params : public MapgenParams {
 	NoiseParams np_mountain;
 	NoiseParams np_ridge;
 	
-	MapgenV7Params() {
-		np_terrain_base    = nparams_v7_def_terrain_base;
-		np_terrain_alt     = nparams_v7_def_terrain_alt;
-		np_terrain_persist = nparams_v7_def_terrain_persist;
-		np_height_select   = nparams_v7_def_height_select;
-		np_filler_depth    = nparams_v7_def_filler_depth;
-		np_mount_height    = nparams_v7_def_mount_height;
-		np_ridge_uwater    = nparams_v7_def_ridge_uwater;
-		np_mountain        = nparams_v7_def_mountain;
-		np_ridge           = nparams_v7_def_ridge;
-	}
-	
+	MapgenV7Params();
 	~MapgenV7Params() {}
 	
-	bool readParams(Settings *settings);
+	void readParams(Settings *settings);
 	void writeParams(Settings *settings);
 };
 
@@ -69,6 +57,7 @@ class MapgenV7 : public Mapgen {
 	int ystride;
 	int zstride;
 	u32 flags;
+	u32 spflags;
 
 	u32 blockseed;
 	v3s16 node_min;
@@ -103,7 +92,7 @@ class MapgenV7 : public Mapgen {
 	content_t c_desert_sand;
 	content_t c_desert_stone;
 
-	MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge);
+	MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge);
 	~MapgenV7();
 	
 	virtual void makeChunk(BlockMakeData *data);
@@ -132,10 +121,10 @@ class MapgenV7 : public Mapgen {
 
 struct MapgenFactoryV7 : public MapgenFactory {
 	Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
-		return new MapgenV7(mgid, (MapgenV7Params *)params, emerge);
+		return new MapgenV7(mgid, params, emerge);
 	};
 	
-	MapgenParams *createMapgenParams() {
+	MapgenSpecificParams *createMapgenParams() {
 		return new MapgenV7Params();
 	};
 };
diff --git a/src/noise.h b/src/noise.h
index 0bf1a2f13..074bedb92 100644
--- a/src/noise.h
+++ b/src/noise.h
@@ -68,6 +68,19 @@ struct NoiseParams {
 	int seed;
 	int octaves;
 	float persist;
+
+	NoiseParams() {}
+
+	NoiseParams(float offset_, float scale_, v3f spread_,
+		int seed_, int octaves_, float persist_)
+	{
+		offset  = offset_;
+		scale   = scale_;
+		spread  = spread_;
+		seed    = seed_;
+		octaves = octaves_;
+		persist = persist_;
+	}
 };
 
 
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 5489531b6..709c7de35 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -137,7 +137,7 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
 			return 1; }
 		case MGOBJ_HEATMAP: { // Mapgen V7 specific objects
 		case MGOBJ_HUMIDMAP:
-			if (strcmp(emerge->params->mg_name.c_str(), "v7"))
+			if (strcmp(emerge->params.mg_name.c_str(), "v7"))
 				return 0;
 
 			MapgenV7 *mgv7 = (MapgenV7 *)mg;
@@ -188,50 +188,37 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
 		return 0;
 
 	EmergeManager *emerge = getServer(L)->getEmergeManager();
-	if (!emerge || emerge->mapgen.size())
-		return 0;
+	ASSERT(emerge);
 
-	MapgenParams *oparams = new MapgenParams;
-	u32 paramsmodified = 0;
-	u32 flagmask = 0;
+	std::string flagstr;
 
 	lua_getfield(L, 1, "mgname");
 	if (lua_isstring(L, -1)) {
-		oparams->mg_name = std::string(lua_tostring(L, -1));
-		paramsmodified |= MGPARAMS_SET_MGNAME;
+		emerge->params.mg_name = std::string(lua_tostring(L, -1));
+		delete emerge->params.sparams;
+		emerge->params.sparams = NULL;
 	}
 
 	lua_getfield(L, 1, "seed");
-	if (lua_isnumber(L, -1)) {
-		oparams->seed = lua_tointeger(L, -1);
-		paramsmodified |= MGPARAMS_SET_SEED;
-	}
+	if (lua_isnumber(L, -1))
+		emerge->params.seed = lua_tointeger(L, -1);
 
 	lua_getfield(L, 1, "water_level");
-	if (lua_isnumber(L, -1)) {
-		oparams->water_level = lua_tointeger(L, -1);
-		paramsmodified |= MGPARAMS_SET_WATER_LEVEL;
+	if (lua_isnumber(L, -1))
+		emerge->params.water_level = lua_tointeger(L, -1);
+
+	lua_getfield(L, 1, "flagmask");
+	if (lua_isstring(L, -1)) {
+		flagstr = lua_tostring(L, -1);
+		emerge->params.flags &= ~readFlagString(flagstr, flagdesc_mapgen);
 	}
 
 	lua_getfield(L, 1, "flags");
 	if (lua_isstring(L, -1)) {
-		std::string flagstr = std::string(lua_tostring(L, -1));
-		oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
-		paramsmodified |= MGPARAMS_SET_FLAGS;
-
-		lua_getfield(L, 1, "flagmask");
-		if (lua_isstring(L, -1)) {
-			flagstr = std::string(lua_tostring(L, -1));
-			flagmask = readFlagString(flagstr, flagdesc_mapgen);
-		}
+		flagstr = lua_tostring(L, -1);
+		emerge->params.flags |= readFlagString(flagstr, flagdesc_mapgen);
 	}
 
-	delete emerge->luaoverride_params;
-
-	emerge->luaoverride_params          = oparams;
-	emerge->luaoverride_params_modified = paramsmodified;
-	emerge->luaoverride_flagmask        = flagmask;
-
 	return 0;
 }
 
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index 4c9047bd9..b48b3a8f1 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -149,7 +149,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
 	Mapgen mg;
 	mg.vm          = vm;
 	mg.ndef        = ndef;
-	mg.water_level = emerge->params->water_level;
+	mg.water_level = emerge->params.water_level;
 	
 	mg.calcLighting(p1, p2);
 
diff --git a/src/server.cpp b/src/server.cpp
index 5dde78e60..00db9128d 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -348,12 +348,10 @@ Server::Server(
 	m_clients.setEnv(m_env);
 
 	// Run some callbacks after the MG params have been set up but before activation
-	MapgenParams *mgparams = servermap->getMapgenParams();
-	m_script->environment_OnMapgenInit(mgparams);
+	m_script->environment_OnMapgenInit(&m_emerge->params);
 
 	// Initialize mapgens
-	m_emerge->initMapgens(mgparams);
-	servermap->setMapgenParams(m_emerge->params);
+	m_emerge->initMapgens();
 
 	// Give environment reference to scripting api
 	m_script->initializeEnvironment(m_env);
@@ -4779,7 +4777,7 @@ v3f findSpawnPos(ServerMap &map)
 #endif
 
 #if 1
-	s16 water_level = map.m_mgparams->water_level;
+	s16 water_level = map.getWaterLevel();
 
 	// Try to find a good place a few times
 	for(s32 i=0; i<1000; i++)
-- 
GitLab