diff --git a/src/map.cpp b/src/map.cpp
index 3b775d79974b1555780a1c4c6909cdc3d8dfb540..0de9cf18ee6f87c2c0a5e989e4043f82e837ea44 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1969,7 +1969,7 @@ ServerMap::~ServerMap()
 #endif
 }
 
-void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
+void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
 {
 	/*dstream<<"initBlockMake(): ("<<blockpos.X<<","<<blockpos.Y<<","
 			<<blockpos.Z<<")"<<std::endl;*/
@@ -2022,18 +2022,19 @@ void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
 	v3s16 bigarea_blocks_min = blockpos - v3s16(1,1,1);
 	v3s16 bigarea_blocks_max = blockpos + v3s16(1,1,1);
 	
-	data->vmanip.setMap(this);
+	data->vmanip = new ManualMapVoxelManipulator(this);
+	//data->vmanip->setMap(this);
 
 	// Add the area
 	{
 		//TimeTaker timer("initBlockMake() initialEmerge");
-		data->vmanip.initialEmerge(bigarea_blocks_min, bigarea_blocks_max);
+		data->vmanip->initialEmerge(bigarea_blocks_min, bigarea_blocks_max);
 	}
 
 	// Data is ready now.
 }
 
-MapBlock* ServerMap::finishBlockMake(BlockMakeData *data,
+MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
 		core::map<v3s16, MapBlock*> &changed_blocks)
 {
 	v3s16 blockpos = data->blockpos;
@@ -2056,7 +2057,7 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data,
 	{
 		// 70ms @cs=8
 		//TimeTaker timer("finishBlockMake() blitBackAll");
-		data->vmanip.blitBackAll(&changed_blocks);
+		data->vmanip->blitBackAll(&changed_blocks);
 	}
 #if 1
 	dstream<<"finishBlockMake: changed_blocks.size()="
@@ -2248,7 +2249,7 @@ MapBlock * ServerMap::generateBlock(
 	/*
 		Create block make data
 	*/
-	BlockMakeData data;
+	mapgen::BlockMakeData data;
 	initBlockMake(&data, p);
 
 	/*
diff --git a/src/map.h b/src/map.h
index ada17cd7e499a039d2e555397a231d8de34bda90..86b6b6e182aed4c2cebc85b382b296f97dcc2abd 100644
--- a/src/map.h
+++ b/src/map.h
@@ -41,6 +41,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapchunk.h"
 #include "nodemetadata.h"
 
+namespace mapgen{
+	struct BlockMakeData;
+};
+
 /*
 	MapEditEvent
 */
@@ -333,10 +337,6 @@ class Map : public NodeContainer
 	This is the only map class that is able to generate map.
 */
 
-//struct ChunkMakeData;
-
-struct BlockMakeData;
-
 class ServerMap : public Map
 {
 public:
@@ -362,8 +362,8 @@ class ServerMap : public Map
 	/*
 		Blocks are generated by using these and makeBlock().
 	*/
-	void initBlockMake(BlockMakeData *data, v3s16 blockpos);
-	MapBlock* finishBlockMake(BlockMakeData *data,
+	void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
+	MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
 			core::map<v3s16, MapBlock*> &changed_blocks);
 	
 	// A non-threaded wrapper to the above
@@ -670,48 +670,5 @@ class ManualMapVoxelManipulator : public MapVoxelManipulator
 	bool m_create_area;
 };
 
-#if 0
-struct ChunkMakeData
-{
-	bool no_op;
-	ManualMapVoxelManipulator vmanip;
-	u64 seed;
-	v2s16 chunkpos;
-	s16 y_blocks_min;
-	s16 y_blocks_max;
-	v2s16 sectorpos_base;
-	s16 sectorpos_base_size;
-	v2s16 sectorpos_bigbase;
-	s16 sectorpos_bigbase_size;
-	s16 max_spread_amount;
-	UniqueQueue<v3s16> transforming_liquid;
-
-	ChunkMakeData():
-		no_op(false),
-		vmanip(NULL),
-		seed(0)
-	{}
-};
-
-void makeChunk(ChunkMakeData *data);
-#endif
-
-struct BlockMakeData
-{
-	bool no_op;
-	ManualMapVoxelManipulator vmanip;
-	u64 seed;
-	v3s16 blockpos;
-	UniqueQueue<v3s16> transforming_liquid;
-
-	BlockMakeData():
-		no_op(false),
-		vmanip(NULL),
-		seed(0)
-	{}
-};
-
-void makeBlock(BlockMakeData *data);
-
 #endif
 
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index a739ceaeb7034bf8aaef8cbab4417801a603e25c..801dd72b10650d5603a03dffd8874d90de96056e 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -903,6 +903,7 @@ bool is_cave(u64 seed, v3s16 p)
 
 	TODO: No perlin noises here, they should be outsourced
 	      and buffered
+		  NOTE: The speed of these actually isn't terrible
 */
 bool val_is_ground(double ground_noise1_val, v3s16 p, u64 seed)
 {
@@ -918,6 +919,8 @@ bool val_is_ground(double ground_noise1_val, v3s16 p, u64 seed)
 	double h = WATER_LEVEL + 10 * noise2d_perlin(
 			0.5+(float)p.X/250, 0.5+(float)p.Z/250,
 			seed+84174, 4, 0.5);
+	/*double f = 1;
+	double h = 0;*/
 	return ((double)p.Y - h < ground_noise1_val * f);
 }
 
@@ -1253,7 +1256,7 @@ void make_block(BlockMakeData *data)
 	/*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
 			<<blockpos.Z<<")"<<std::endl;*/
 
-	ManualMapVoxelManipulator &vmanip = data->vmanip;
+	ManualMapVoxelManipulator &vmanip = *(data->vmanip);
 	v3s16 blockpos_min = blockpos - v3s16(1,1,1);
 	v3s16 blockpos_max = blockpos + v3s16(1,1,1);
 	// Area of center block
@@ -1312,7 +1315,7 @@ void make_block(BlockMakeData *data)
 							vmanip.m_data[i] = MapNode(CONTENT_AIR);
 					}
 				
-					data->vmanip.m_area.add_y(em, i, 1);
+					data->vmanip->m_area.add_y(em, i, 1);
 				}
 			}
 		}
@@ -1428,7 +1431,7 @@ void make_block(BlockMakeData *data)
 						vmanip.m_data[i] = MapNode(CONTENT_STONE);
 				}
 			
-				data->vmanip.m_area.add_y(em, i, 1);
+				data->vmanip->m_area.add_y(em, i, 1);
 			}
 		}
 	}
@@ -1597,7 +1600,7 @@ void make_block(BlockMakeData *data)
 					}
 				}
 
-				data->vmanip.m_area.add_y(em, i, -1);
+				data->vmanip->m_area.add_y(em, i, -1);
 			}
 		}
 	}
@@ -1617,7 +1620,7 @@ void make_block(BlockMakeData *data)
 			&& node_min.Y < approx_groundlevel)
 	{
 		// Dungeon generator doesn't modify places which have this set
-		data->vmanip.clearFlag(VMANIP_FLAG_DUNGEON_INSIDE
+		data->vmanip->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE
 				| VMANIP_FLAG_DUNGEON_PRESERVE);
 		
 		// Set all air and water to be untouchable to make dungeons open
@@ -1637,7 +1640,7 @@ void make_block(BlockMakeData *data)
 						vmanip.m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
 					else if(vmanip.m_data[i].d == CONTENT_WATERSOURCE)
 						vmanip.m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
-					data->vmanip.m_area.add_y(em, i, -1);
+					data->vmanip->m_area.add_y(em, i, -1);
 				}
 			}
 		}
@@ -1645,7 +1648,7 @@ void make_block(BlockMakeData *data)
 		PseudoRandom random(blockseed+2);
 
 		// Add it
-		make_dungeon1(data->vmanip, random);
+		make_dungeon1(vmanip, random);
 		
 		// Convert some cobble to mossy cobble
 		for(s16 x=full_node_min.X; x<=full_node_max.X; x++)
@@ -1678,7 +1681,7 @@ void make_block(BlockMakeData *data)
 						if(wetness > 1.2)
 							vmanip.m_data[i].d = CONTENT_MUD;
 					}*/
-					data->vmanip.m_area.add_y(em, i, -1);
+					data->vmanip->m_area.add_y(em, i, -1);
 				}
 			}
 		}
@@ -1722,7 +1725,7 @@ void make_block(BlockMakeData *data)
 					}
 				}
 
-				data->vmanip.m_area.add_y(em, i, -1);
+				data->vmanip->m_area.add_y(em, i, -1);
 			}
 		}
 	}
@@ -1800,7 +1803,7 @@ void make_block(BlockMakeData *data)
 					else if(current_depth != 0)
 						break;
 
-					data->vmanip.m_area.add_y(em, i, -1);
+					data->vmanip->m_area.add_y(em, i, -1);
 				}
 			}
 		}
@@ -1833,8 +1836,8 @@ void make_block(BlockMakeData *data)
 			bool found = false;
 			for(; p.Y >= y-6; p.Y--)
 			{
-				u32 i = data->vmanip.m_area.index(p);
-				MapNode *n = &data->vmanip.m_data[i];
+				u32 i = data->vmanip->m_area.index(p);
+				MapNode *n = &data->vmanip->m_data[i];
 				if(n->d != CONTENT_AIR && n->d != CONTENT_IGNORE)
 				{
 					found = true;
@@ -1848,15 +1851,15 @@ void make_block(BlockMakeData *data)
 				Trees grow only on mud and grass
 			*/
 			{
-				u32 i = data->vmanip.m_area.index(p);
-				MapNode *n = &data->vmanip.m_data[i];
+				u32 i = data->vmanip->m_area.index(p);
+				MapNode *n = &data->vmanip->m_data[i];
 				if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
 					continue;
 			}
 			// Tree will be placed one higher
 			p.Y++;
 			// Make a tree
-			make_tree(data->vmanip, p);
+			make_tree(vmanip, p);
 		}
 
 #if 0
@@ -1881,8 +1884,8 @@ void make_block(BlockMakeData *data)
 			v3s16 p(x,y,z);
 			// Filter placement
 			/*{
-				u32 i = data->vmanip.m_area.index(v3s16(p));
-				MapNode *n = &data->vmanip.m_data[i];
+				u32 i = data->vmanip->m_area.index(v3s16(p));
+				MapNode *n = &data->vmanip->m_data[i];
 				if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
 					continue;
 			}*/
@@ -1916,8 +1919,8 @@ void make_block(BlockMakeData *data)
 			v3s16 p(x,y,z);
 			// Filter placement
 			/*{
-				u32 i = data->vmanip.m_area.index(v3s16(p));
-				MapNode *n = &data->vmanip.m_data[i];
+				u32 i = data->vmanip->m_area.index(v3s16(p));
+				MapNode *n = &data->vmanip->m_data[i];
 				if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
 					continue;
 			}*/
@@ -1931,6 +1934,17 @@ void make_block(BlockMakeData *data)
 
 }
 
+BlockMakeData::BlockMakeData():
+	no_op(false),
+	vmanip(NULL),
+	seed(0)
+{}
+
+BlockMakeData::~BlockMakeData()
+{
+	delete vmanip;
+}
+
 }; // namespace mapgen
 
 
diff --git a/src/mapgen.h b/src/mapgen.h
index 5aa0282faecda91fd62ce072277fcf6fe873bfda..57d0ee8a01d06de3b9707cc450fad4c59695b1e9 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -21,9 +21,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MAPGEN_HEADER
 
 #include "common_irrlicht.h"
+#include "utility.h" // UniqueQueue
 
 struct BlockMakeData;
 class MapBlock;
+class ManualMapVoxelManipulator;
 
 namespace mapgen
 {
@@ -44,6 +46,19 @@ namespace mapgen
 	*/
 	bool get_have_sand(u64 seed, v2s16 p2d);
 	double tree_amount_2d(u64 seed, v2s16 p);
+	
+
+	struct BlockMakeData
+	{
+		bool no_op;
+		ManualMapVoxelManipulator *vmanip;
+		u64 seed;
+		v3s16 blockpos;
+		UniqueQueue<v3s16> transforming_liquid;
+
+		BlockMakeData();
+		~BlockMakeData();
+	};
 
 }; // namespace mapgen