diff --git a/src/map.cpp b/src/map.cpp
index 1bd4f299f05f6eb75884641e30170151a930a825..93c4d50529dca1059cbd9dd5566d9415aa5c9302 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -570,6 +570,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
 	Starting point gets sunlight.
 
 	Returns the lowest y value of where the sunlight went.
+
+	Mud is turned into grass in where the sunlight stops.
 */
 s16 Map::propagateSunlight(v3s16 start,
 		core::map<v3s16, MapBlock*> & modified_blocks)
@@ -599,7 +601,17 @@ s16 Map::propagateSunlight(v3s16 start,
 
 			modified_blocks.insert(blockpos, block);
 		}
-		else{
+		else
+		{
+			// Turn mud into grass
+			if(n.d == CONTENT_MUD)
+			{
+				n.d = CONTENT_GRASS;
+				block->setNode(relpos, n);
+				modified_blocks.insert(blockpos, block);
+			}
+
+			// Sunlight goes no further
 			break;
 		}
 	}
@@ -1912,10 +1924,6 @@ MapBlock * ServerMap::emergeBlock(
 		}
 	}
 	
-	// This is the basic material of what the visible flat ground
-	// will consist of
-	u8 material = CONTENT_GRASS;
-
 	u8 water_material = CONTENT_WATER;
 	if(g_settings.getBool("endless_water"))
 		water_material = CONTENT_OCEAN;
@@ -1981,7 +1989,66 @@ MapBlock * ServerMap::emergeBlock(
 				Calculate material
 			*/
 
-			if(real_y <= surface_y - surface_depth)
+			// If node is over heightmap y, it's air or water
+			if(real_y > surface_y)
+			{
+				// If under water level, it's water
+				if(real_y < WATER_LEVEL)
+				{
+					n.d = water_material;
+					n.setLight(LIGHTBANK_DAY,
+							diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
+				}
+				// else air
+				else
+					n.d = CONTENT_AIR;
+			}
+			// Else it's ground or dungeons (air)
+			else
+			{
+				// Create dungeons
+				if(underground_emptiness[
+						ued*ued*(z0*ued/MAP_BLOCKSIZE)
+						+ued*(y0*ued/MAP_BLOCKSIZE)
+						+(x0*ued/MAP_BLOCKSIZE)])
+				{
+					n.d = CONTENT_AIR;
+				}
+				else
+				{
+					// If it's surface_depth under ground, it's stone
+					if(real_y <= surface_y - surface_depth)
+					{
+						n.d = CONTENT_STONE;
+					}
+					else
+					{
+						// It is mud if it is under the first ground
+						// level or under water
+						if(real_y < WATER_LEVEL || real_y <= surface_y - 1)
+						{
+							n.d = CONTENT_MUD;
+						}
+						else
+						{
+							n.d = CONTENT_GRASS;
+						}
+
+						//n.d = CONTENT_MUD;
+						
+						/*// If under water level, it's mud
+						if(real_y < WATER_LEVEL)
+							n.d = CONTENT_MUD;
+						// Only the topmost node is grass
+						else if(real_y <= surface_y - 1)
+							n.d = CONTENT_MUD;
+						else
+							n.d = CONTENT_GRASS;*/
+					}
+				}
+			}
+#if 0
+			else if(real_y <= surface_y - surface_depth)
 			{
 				// Create dungeons
 				if(underground_emptiness[
@@ -2009,19 +2076,7 @@ MapBlock * ServerMap::emergeBlock(
 				else
 					n.d = material;
 			}
-			// If node is over heightmap y
-			else{
-				// If under water level, it's water
-				if(real_y < WATER_LEVEL)
-				{
-					n.d = water_material;
-					n.setLight(LIGHTBANK_DAY,
-							diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
-				}
-				// else air
-				else
-					n.d = CONTENT_AIR;
-			}
+#endif
 			block->setNode(v3s16(x0,y0,z0), n);
 		}
 	}
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 60efa2fcfa1f015728fb3966d2df9d413b0d622b..20287732253d2a4f9fb17426187338ace1c78fc6 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -860,7 +860,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
 	is_underground is set.
 
 	At the moment, all sunlighted nodes are added to light_sources.
-	TODO: This could be optimized.
+	- SUGG: This could be optimized
+
+	Turns sunglighted mud into grass.
 */
 bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
 {
@@ -880,10 +882,6 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
 				MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
 				if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
 				{
-					/*if(is_underground)
-					{
-						no_sunlight = true;
-					}*/
 					no_sunlight = true;
 				}
 			}
@@ -891,15 +889,14 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
 			{
 				no_top_block = true;
 				
-				// TODO: This makes over-ground roofed places sunlighted
+				// NOTE: This makes over-ground roofed places sunlighted
 				// Assume sunlight, unless is_underground==true
 				if(is_underground)
 				{
 					no_sunlight = true;
 				}
 				
-				// TODO: There has to be some way to allow this behaviour
-				// As of now, it just makes everything dark.
+				// NOTE: As of now, it just would make everything dark.
 				// No sunlight here
 				//no_sunlight = true;
 			}
@@ -928,7 +925,15 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
 
 						light_sources.insert(pos_relative + pos, true);
 					}
-					else{
+					else
+					{
+						// Turn mud into grass
+						if(n.d == CONTENT_MUD)
+						{
+							n.d = CONTENT_GRASS;
+						}
+
+						// Sunlight goes no further
 						break;
 					}
 				}
diff --git a/src/mapblock.h b/src/mapblock.h
index 586c10228f1f36e0880bc49c297b776b899be6d9..743dad9276fdd647f6bf82ea10bce6b0f7b9a462 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -310,7 +310,8 @@ class MapBlock : public NodeContainer
 	// Updates all DAYNIGHT_CACHE_COUNT meshes
 	void updateMeshes(s32 first_i=0);*/
 #endif // !SERVER
-
+	
+	// See comments in mapblock.cpp
 	bool propagateSunlight(core::map<v3s16, bool> & light_sources);
 	
 	// Copies data to VoxelManipulator to getPosRelative()