diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp
index ebc5e57191f9314a23b3fad322efb0c65f2fb782..3867827cc96c17d7a6b894e3401accf74ba0b44b 100644
--- a/src/mapgen_v5.cpp
+++ b/src/mapgen_v5.cpp
@@ -451,23 +451,31 @@ void MapgenV5::generateBiomes() {
 				
 				if (c_below != CONTENT_AIR) {
 					if (nplaced < y0_top) {
-						// A hack to prevent dirt_with_grass from being
-						// placed below water.  TODO: fix later
-						content_t c_place = ((y < water_level) &&
-								(biome->c_top ==
-								c_dirt_with_grass)) ?
-								 c_dirt : biome->c_top;
-						
-						vm->m_data[i] = MapNode(c_place);
+						if(y < water_level)
+							vm->m_data[i] = MapNode(biome->c_filler);
+						else
+							vm->m_data[i] = MapNode(biome->c_top);
 						nplaced++;
 					} else if (nplaced < y0_filler && nplaced >= y0_top) {
 						vm->m_data[i] = MapNode(biome->c_filler);
 						nplaced++;
+					} else if (c == c_stone) {
+						have_air = false;
+						nplaced  = 0;
+						vm->m_data[i] = MapNode(biome->c_stone);
 					} else {
 						have_air = false;
 						nplaced  = 0;
 					}
+				} else if (c == c_stone) {
+					have_air = false;
+					nplaced = 0;
+					vm->m_data[i] = MapNode(biome->c_stone);
 				}
+			} else if (c == c_stone) {
+				have_air = false;
+				nplaced = 0;
+				vm->m_data[i] = MapNode(biome->c_stone);
 			} else if (c == c_water_source) {
 				have_air = true;
 				nplaced = 0;
diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp
index 8e345164e465781d449eafa3265450a9926bc8ae..bad01bc2a649091c9e9c30b3ba0b9671df8141a1 100644
--- a/src/mapgen_v7.cpp
+++ b/src/mapgen_v7.cpp
@@ -534,7 +534,7 @@ void MapgenV7::generateBiomes() {
 		Biome *biome  = (Biome *)bmgr->get(biomemap[index]);
 		s16 dfiller   = biome->depth_filler + noise_filler_depth->result[index];
 		s16 y0_top    = biome->depth_top;
-		s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
+		s16 y0_filler = biome->depth_top + dfiller;
 
 		s16 nplaced = 0;
 		u32 i = vm->m_area.index(x, node_max.Y, z);	
@@ -560,22 +560,31 @@ void MapgenV7::generateBiomes() {
 				
 				if (c_below != CONTENT_AIR) {
 					if (nplaced < y0_top) {
-						// A hack to prevent dirt_with_grass from being
-						// placed below water.  TODO: fix later
-						content_t c_place = ((y < water_level) &&
-								(biome->c_top == c_dirt_with_grass)) ?
-								 c_dirt : biome->c_top;
-						
-						vm->m_data[i] = MapNode(c_place);
+						if(y < water_level)
+							vm->m_data[i] = MapNode(biome->c_filler);
+						else
+							vm->m_data[i] = MapNode(biome->c_top);
 						nplaced++;
 					} else if (nplaced < y0_filler && nplaced >= y0_top) {
 						vm->m_data[i] = MapNode(biome->c_filler);
 						nplaced++;
+					} else if (c == c_stone) {
+						have_air = false;
+						nplaced  = 0;
+						vm->m_data[i] = MapNode(biome->c_stone);
 					} else {
 						have_air = false;
 						nplaced  = 0;
 					}
+				} else if (c == c_stone) {
+					have_air = false;
+					nplaced = 0;
+					vm->m_data[i] = MapNode(biome->c_stone);
 				}
+			} else if (c == c_stone) {
+				have_air = false;
+				nplaced = 0;
+				vm->m_data[i] = MapNode(biome->c_stone);
 			} else if (c == c_water_source) {
 				have_air = true;
 				nplaced = 0;
diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp
index 1746be25da118681829618509fbc54922329cb0b..9a986b3ded2b79c5973f9a4211d5350c61258ee6 100644
--- a/src/mg_biome.cpp
+++ b/src/mg_biome.cpp
@@ -58,6 +58,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef)
 
 	resolver->addNode("air",                 "", CONTENT_AIR, &b->c_top);
 	resolver->addNode("air",                 "", CONTENT_AIR, &b->c_filler);
+	resolver->addNode("mapgen_stone",        "", CONTENT_AIR, &b->c_stone);
 	resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_water);
 	resolver->addNode("air",                 "", CONTENT_AIR, &b->c_dust);
 	resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_dust_water);
@@ -112,3 +113,4 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
 	
 	return biome_closest ? biome_closest : (Biome *)m_elements[0];
 }
+
diff --git a/src/mg_biome.h b/src/mg_biome.h
index d6130ee3a2a601d6a7ab500b014cd3f08bef2db6..7a62998e31f1025c24d52420c7a0e1181a231944 100644
--- a/src/mg_biome.h
+++ b/src/mg_biome.h
@@ -42,6 +42,7 @@ class Biome : public GenElement {
 
 	content_t c_top;
 	content_t c_filler;
+	content_t c_stone;
 	content_t c_water;
 	content_t c_dust;
 	content_t c_dust_water;
@@ -77,3 +78,4 @@ class BiomeManager : public GenElementManager {
 };
 
 #endif
+
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 89bf8dadb17e9b7f80fe40f4df7c1964bec10112..bb76bb450b8ebd72b33a135d820b7d189535f4a8 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mg_ore.h"
 #include "mg_decoration.h"
 #include "mg_schematic.h"
+#include "mapgen_v5.h"
 #include "mapgen_v7.h"
 #include "settings.h"
 #include "main.h"
@@ -336,6 +337,8 @@ int ModApiMapgen::l_register_biome(lua_State *L)
 		 "mapgen_dirt_with_grass", CONTENT_AIR, &b->c_top);
 	resolver->addNode(getstringfield_default(L, index, "node_filler", ""),
 		"mapgen_dirt", CONTENT_AIR, &b->c_filler);
+	resolver->addNode(getstringfield_default(L, index, "node_stone", ""),
+		"mapgen_stone", CONTENT_AIR, &b->c_stone);
 	resolver->addNode(getstringfield_default(L, index, "node_water", ""),
 		"mapgen_water_source", CONTENT_AIR, &b->c_water);
 	resolver->addNode(getstringfield_default(L, index, "node_dust", ""),