diff --git a/game_api.txt b/game_api.txt
index 887f394e28f4f0e84ed6687e6c191f990d30db11..d5d09e92d6af8b1cc4258dca1046ddc7e52ef833 100644
--- a/game_api.txt
+++ b/game_api.txt
@@ -155,7 +155,8 @@ The doors mod allows modders to register custom doors and trapdoors.
 ### Fence gate definition
 
 	description = "Wooden Fence Gate",
-	texture = "default_wood.png",
+	texture = "default_wood.png", -- `backface_culling` will automatically be
+	                              -- set to `true` if not specified.
 	material = "default:wood",
 	groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
 	sounds = default.node_sound_wood_defaults(), -- optional
@@ -591,6 +592,48 @@ Default constants
 
 `default.LIGHT_MAX`  The maximum light level (see [Node definition] light_source)
 
+
+GUI and formspecs
+-----------------
+
+`default.get_hotbar_bg(x, y)`
+
+ * Get the hotbar background as string, containing the formspec elements
+ * x: Horizontal position in the formspec
+ * y: Vertical position in the formspec
+
+`default.gui_bg`
+
+ * Background color formspec element
+
+`default.gui_bg_img`
+
+ * Image overlay formspec element for the background to use in formspecs
+
+`default.gui_slots`
+
+ * `listcolors` formspec element that is used to format the slots in formspecs
+
+`default.gui_survival_form`
+
+ * Entire formspec for the survival inventory
+
+`default.get_chest_formspec(pos)`
+
+ * Get the chest formspec using the defined GUI elements
+ * pos: Location of the node
+
+`default.get_furnace_active_formspec(fuel_percent, item_percent)`
+
+ * Get the active furnace formspec using the defined GUI elements
+ * fuel_percent: Percent of how much the fuel is used
+ * item_percent: Percent of how much the item is cooked
+
+`default.get_furnace_inactive_formspec()`
+
+ * Get the inactive furnace formspec using the defined GUI elements
+
+
 Player API
 ----------
 
diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua
index 896844e5a480cda772a4188a994744b3e6a0c3a2..78df9a1816b925c1c406b4e71b34781ed3050862 100644
--- a/mods/beds/functions.lua
+++ b/mods/beds/functions.lua
@@ -1,7 +1,7 @@
 local pi = math.pi
 local player_in_bed = 0
 local is_sp = minetest.is_singleplayer()
-local enable_respawn = minetest.setting_getbool("enable_bed_respawn")
+local enable_respawn = minetest.settings:get_bool("enable_bed_respawn")
 if enable_respawn == nil then
 	enable_respawn = true
 end
@@ -22,7 +22,7 @@ local function get_look_yaw(pos)
 end
 
 local function is_night_skip_enabled()
-	local enable_night_skip = minetest.setting_getbool("enable_bed_night_skip")
+	local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip")
 	if enable_night_skip == nil then
 		enable_night_skip = true
 	end
diff --git a/mods/bones/init.lua b/mods/bones/init.lua
index 0026588c4d497f3561ca281855495834387bc483..2efed395a7bc110247f071a5c788a4f9f8a88e75 100644
--- a/mods/bones/init.lua
+++ b/mods/bones/init.lua
@@ -21,8 +21,8 @@ local bones_formspec =
 	"listring[current_player;main]" ..
 	default.get_hotbar_bg(0,4.85)
 
-local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 1200
-local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early")) or share_bones_time / 4
+local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200
+local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4
 
 minetest.register_node("bones:bones", {
 	description = "Bones",
@@ -161,7 +161,7 @@ end
 
 minetest.register_on_dieplayer(function(player)
 
-	local bones_mode = minetest.setting_get("bones_mode") or "bones"
+	local bones_mode = minetest.settings:get("bones_mode") or "bones"
 	if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then
 		bones_mode = "bones"
 	end
diff --git a/mods/carts/cart_entity.lua b/mods/carts/cart_entity.lua
index a19da64833d5a482561b46ad979db806d54f3397..8f73374602e102c240d2cfe3be1b6bf0b79a0ca4 100644
--- a/mods/carts/cart_entity.lua
+++ b/mods/carts/cart_entity.lua
@@ -58,7 +58,8 @@ end
 
 function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
 	local pos = self.object:getpos()
-	if not self.railtype then
+	local vel = self.object:getvelocity()
+	if not self.railtype or vector.equals(vel, {x=0, y=0, z=0}) then
 		local node = minetest.get_node(pos).name
 		self.railtype = minetest.get_item_group(node, "connect_to_raillike")
 	end
@@ -105,7 +106,6 @@ function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities,
 		return
 	end
 	-- Player punches cart to alter velocity
-	local vel = self.object:getvelocity()
 	if puncher:get_player_name() == self.driver then
 		if math.abs(vel.x + vel.z) > carts.punch_speed_max then
 			return
diff --git a/mods/carts/functions.lua b/mods/carts/functions.lua
index a47171948a8dbabedca691e005a9eee2dfc4db32..96a12d2b50eefe852b0d8bce624494014066215c 100644
--- a/mods/carts/functions.lua
+++ b/mods/carts/functions.lua
@@ -211,7 +211,12 @@ end
 
 function carts:get_rail_groups(additional_groups)
 	-- Get the default rail groups and add more when a table is given
-	local groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1}
+	local groups = {
+		dig_immediate = 2,
+		attached_node = 1,
+		rail = 1,
+		connect_to_raillike = minetest.raillike_group("rail")
+	}
 	if type(additional_groups) == "table" then
 		for k, v in pairs(additional_groups) do
 			groups[k] = v
diff --git a/mods/carts/rails.lua b/mods/carts/rails.lua
index 066779d17683d0b23d81b2d5ce8df4ff67135827..a5fff8a4db3629d17f878fa8353e6eec9f1371e7 100644
--- a/mods/carts/rails.lua
+++ b/mods/carts/rails.lua
@@ -22,7 +22,7 @@ minetest.register_alias("default:rail", "carts:rail")
 
 
 carts:register_rail("carts:powerrail", {
-	description = "Powered rail",
+	description = "Powered Rail",
 	tiles = {
 		"carts_rail_straight_pwr.png", "carts_rail_curved_pwr.png",
 		"carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"
@@ -41,7 +41,7 @@ minetest.register_craft({
 
 
 carts:register_rail("carts:brakerail", {
-	description = "Brake rail",
+	description = "Brake Rail",
 	tiles = {
 		"carts_rail_straight_brk.png", "carts_rail_curved_brk.png",
 		"carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png"
diff --git a/mods/creative/init.lua b/mods/creative/init.lua
index bba9b34eea1aafeea6aa0dc8973f18b84ffe5ead..7b842eda65047ede361e7efc9de1108889911e49 100644
--- a/mods/creative/init.lua
+++ b/mods/creative/init.lua
@@ -1,9 +1,15 @@
 creative = {}
 
-local creative_mode_cache = minetest.setting_getbool("creative_mode")
+minetest.register_privilege("creative", {
+	description = "Allow player to use creative inventory",
+	give_to_singleplayer = false
+})
+
+local creative_mode_cache = minetest.settings:get_bool("creative_mode")
 
 function creative.is_enabled_for(name)
-	return creative_mode_cache
+	return creative_mode_cache or
+		minetest.check_player_privs(name, {creative = true})
 end
 
 dofile(minetest.get_modpath("creative") .. "/inventory.lua")
diff --git a/mods/creative/inventory.lua b/mods/creative/inventory.lua
index 0e1d813eafc81313f7661e47a1a8ee4bd36d78b4..00b2aa550dbd54ffa9a560e63a27f95e087230c7 100644
--- a/mods/creative/inventory.lua
+++ b/mods/creative/inventory.lua
@@ -10,22 +10,25 @@ function creative.init_creative_inventory(player)
 
 	minetest.create_detached_inventory("creative_" .. player_name, {
 		allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
-			if not to_list == "main" then
-				return count
-			else
+			local name = player2 and player2:get_player_name() or ""
+			if not creative.is_enabled_for(name) or
+					to_list == "main" then
 				return 0
 			end
+			return count
 		end,
 		allow_put = function(inv, listname, index, stack, player2)
 			return 0
 		end,
 		allow_take = function(inv, listname, index, stack, player2)
+			local name = player2 and player2:get_player_name() or ""
+			if not creative.is_enabled_for(name) then
+				return 0
+			end
 			return -1
 		end,
 		on_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
 		end,
-		on_put = function(inv, listname, index, stack, player2)
-		end,
 		on_take = function(inv, listname, index, stack, player2)
 			if stack and stack:get_count() > 0 then
 				minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory")
diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua
index 50ffb1ae890eb06ccac2ddc966aee3a21d5adae6..dce630da845c83f594e3545facd713ce15797c01 100644
--- a/mods/default/crafting.lua
+++ b/mods/default/crafting.lua
@@ -190,6 +190,9 @@ minetest.register_craft({
 	}
 })
 
+-- Axes
+-- Recipes face left to match appearence in textures and inventory
+
 minetest.register_craft({
 	output = 'default:axe_wood',
 	recipe = {
@@ -244,60 +247,6 @@ minetest.register_craft({
 	}
 })
 
-minetest.register_craft({
-	output = 'default:axe_wood',
-	recipe = {
-		{'group:wood', 'group:wood'},
-		{'group:stick', 'group:wood'},
-		{'group:stick',''},
-	}
-})
-
-minetest.register_craft({
-	output = 'default:axe_stone',
-	recipe = {
-		{'group:stone', 'group:stone'},
-		{'group:stick', 'group:stone'},
-		{'group:stick', ''},
-	}
-})
-
-minetest.register_craft({
-	output = 'default:axe_steel',
-	recipe = {
-		{'default:steel_ingot', 'default:steel_ingot'},
-		{'group:stick', 'default:steel_ingot'},
-		{'group:stick', ''},
-	}
-})
-
-minetest.register_craft({
-	output = 'default:axe_bronze',
-	recipe = {
-		{'default:bronze_ingot', 'default:bronze_ingot'},
-		{'group:stick', 'default:bronze_ingot'},
-		{'group:stick', ''},
-	}
-})
-
-minetest.register_craft({
-	output = 'default:axe_mese',
-	recipe = {
-		{'default:mese_crystal', 'default:mese_crystal'},
-		{'group:stick', 'default:mese_crystal'},
-		{'group:stick', ''},
-	}
-})
-
-minetest.register_craft({
-	output = 'default:axe_diamond',
-	recipe = {
-		{'default:diamond', 'default:diamond'},
-		{'group:stick', 'default:diamond'},
-		{'group:stick', ''},
-	}
-})
-
 minetest.register_craft({
 	output = 'default:sword_wood',
 	recipe = {
diff --git a/mods/default/craftitems.lua b/mods/default/craftitems.lua
index 33cdd5f664eb4d8e59f75f6d89c0b6cadbbc7b60..e4a93ae58d8833997fbb538b0122f3f9d9c4affc 100644
--- a/mods/default/craftitems.lua
+++ b/mods/default/craftitems.lua
@@ -75,12 +75,16 @@ local function book_on_use(itemstack, user)
 	return itemstack
 end
 
+local max_text_size = 10000
+local max_title_size = 80
+local short_title_size = 35
 minetest.register_on_player_receive_fields(function(player, formname, fields)
 	if formname ~= "default:book" then return end
 	local inv = player:get_inventory()
 	local stack = player:get_wielded_item()
 
-	if fields.save and fields.title ~= "" and fields.text ~= "" then
+	if fields.save and fields.title and fields.text
+			and fields.title ~= "" and fields.text ~= "" then
 		local new_stack, data
 		if stack:get_name() ~= "default:book_written" then
 			local count = stack:get_count()
@@ -99,11 +103,15 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 		end
 
 		if not data then data = {} end
-		data.title = fields.title
+		data.title = fields.title:sub(1, max_title_size)
 		data.owner = player:get_player_name()
-		data.description = "\""..fields.title.."\" by "..data.owner
-		data.text = fields.text
-		data.text_len = #data.text
+		local short_title = data.title
+		-- Don't bother triming the title if the trailing dots would make it longer
+		if #short_title > short_title_size + 3 then
+			short_title = short_title:sub(1, short_title_size) .. "..."
+		end
+		data.description = "\""..short_title.."\" by "..data.owner
+		data.text = fields.text:sub(1, max_text_size)
 		data.page = 1
 		data.page_max = math.ceil((#data.text:gsub("[^\n]", "") + 1) / lpp)
 
diff --git a/mods/default/functions.lua b/mods/default/functions.lua
index a067f4033528e706d996a8a3fe4da27b2957289c..e6db391cea6335add12bff05af88753a0de53979 100644
--- a/mods/default/functions.lua
+++ b/mods/default/functions.lua
@@ -140,7 +140,7 @@ default.cool_lava = function(pos, node)
 		{pos = pos, max_hear_distance = 16, gain = 0.25})
 end
 
-if minetest.setting_getbool("enable_lavacooling") ~= false then
+if minetest.settings:get_bool("enable_lavacooling") ~= false then
 	minetest.register_abm({
 		label = "Lava cooling",
 		nodenames = {"default:lava_source", "default:lava_flowing"},
@@ -148,7 +148,9 @@ if minetest.setting_getbool("enable_lavacooling") ~= false then
 		interval = 1,
 		chance = 2,
 		catch_up = false,
-		action = default.cool_lava,
+		action = function(...)
+			default.cool_lava(...)
+		end,
 	})
 end
 
@@ -231,7 +233,9 @@ minetest.register_abm({
 	neighbors = {"group:sand"},
 	interval = 12,
 	chance = 83,
-	action = default.grow_cactus
+	action = function(...)
+		default.grow_cactus(...)
+	end
 })
 
 minetest.register_abm({
@@ -240,7 +244,9 @@ minetest.register_abm({
 	neighbors = {"default:dirt", "default:dirt_with_grass"},
 	interval = 14,
 	chance = 71,
-	action = default.grow_papyrus
+	action = function(...)
+		default.grow_papyrus(...)
+	end
 })
 
 
diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua
index 4b82205825ece9ff25223960bc19bea59fa24839..1643d427cb8573ffe3fcf6165b826cc1650544ad 100644
--- a/mods/default/furnace.lua
+++ b/mods/default/furnace.lua
@@ -3,50 +3,49 @@
 -- Formspecs
 --
 
-local function active_formspec(fuel_percent, item_percent)
-	local formspec =
-		"size[8,8.5]"..
+function default.get_furnace_active_formspec(fuel_percent, item_percent)
+	return "size[8,8.5]"..
 		default.gui_bg..
 		default.gui_bg_img..
 		default.gui_slots..
-		"list[current_name;src;2.75,0.5;1,1;]"..
-		"list[current_name;fuel;2.75,2.5;1,1;]"..
+		"list[context;src;2.75,0.5;1,1;]"..
+		"list[context;fuel;2.75,2.5;1,1;]"..
 		"image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
 		(100-fuel_percent)..":default_furnace_fire_fg.png]"..
 		"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
 		(item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
-		"list[current_name;dst;4.75,0.96;2,2;]"..
+		"list[context;dst;4.75,0.96;2,2;]"..
 		"list[current_player;main;0,4.25;8,1;]"..
 		"list[current_player;main;0,5.5;8,3;8]"..
-		"listring[current_name;dst]"..
+		"listring[context;dst]"..
 		"listring[current_player;main]"..
-		"listring[current_name;src]"..
+		"listring[context;src]"..
 		"listring[current_player;main]"..
-		"listring[current_name;fuel]"..
+		"listring[context;fuel]"..
 		"listring[current_player;main]"..
 		default.get_hotbar_bg(0, 4.25)
-	return formspec
 end
 
-local inactive_formspec =
-	"size[8,8.5]"..
-	default.gui_bg..
-	default.gui_bg_img..
-	default.gui_slots..
-	"list[current_name;src;2.75,0.5;1,1;]"..
-	"list[current_name;fuel;2.75,2.5;1,1;]"..
-	"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
-	"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
-	"list[current_name;dst;4.75,0.96;2,2;]"..
-	"list[current_player;main;0,4.25;8,1;]"..
-	"list[current_player;main;0,5.5;8,3;8]"..
-	"listring[current_name;dst]"..
-	"listring[current_player;main]"..
-	"listring[current_name;src]"..
-	"listring[current_player;main]"..
-	"listring[current_name;fuel]"..
-	"listring[current_player;main]"..
-	default.get_hotbar_bg(0, 4.25)
+function default.get_furnace_inactive_formspec()
+	return "size[8,8.5]"..
+		default.gui_bg..
+		default.gui_bg_img..
+		default.gui_slots..
+		"list[context;src;2.75,0.5;1,1;]"..
+		"list[context;fuel;2.75,2.5;1,1;]"..
+		"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
+		"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
+		"list[context;dst;4.75,0.96;2,2;]"..
+		"list[current_player;main;0,4.25;8,1;]"..
+		"list[current_player;main;0,5.5;8,3;8]"..
+		"listring[context;dst]"..
+		"listring[current_player;main]"..
+		"listring[context;src]"..
+		"listring[current_player;main]"..
+		"listring[context;fuel]"..
+		"listring[current_player;main]"..
+		default.get_hotbar_bg(0, 4.25)
+end
 
 --
 -- Node callback functions that are the same for active and inactive furnace
@@ -190,7 +189,7 @@ local function furnace_node_timer(pos, elapsed)
 	--
 	-- Update formspec, infotext and node
 	--
-	local formspec = inactive_formspec
+	local formspec
 	local item_state
 	local item_percent = 0
 	if cookable then
@@ -216,7 +215,7 @@ local function furnace_node_timer(pos, elapsed)
 		active = "active "
 		local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
 		fuel_state = fuel_percent .. "%"
-		formspec = active_formspec(fuel_percent, item_percent)
+		formspec = default.get_furnace_active_formspec(fuel_percent, item_percent)
 		swap_node(pos, "default:furnace_active")
 		-- make sure timer restarts automatically
 		result = true
@@ -224,12 +223,14 @@ local function furnace_node_timer(pos, elapsed)
 		if not fuellist[1]:is_empty() then
 			fuel_state = "0%"
 		end
+		formspec = default.get_furnace_inactive_formspec()
 		swap_node(pos, "default:furnace")
 		-- stop timer on the inactive furnace
 		minetest.get_node_timer(pos):stop()
 	end
 
-	local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
+	local infotext = "Furnace " .. active .. "(Item: " .. item_state ..
+		"; Fuel: " .. fuel_state .. ")"
 
 	--
 	-- Set meta values
@@ -266,7 +267,7 @@ minetest.register_node("default:furnace", {
 
 	on_construct = function(pos)
 		local meta = minetest.get_meta(pos)
-		meta:set_string("formspec", inactive_formspec)
+		meta:set_string("formspec", default.get_furnace_inactive_formspec())
 		local inv = meta:get_inventory()
 		inv:set_size('src', 1)
 		inv:set_size('fuel', 1)
@@ -327,4 +328,3 @@ minetest.register_node("default:furnace_active", {
 	allow_metadata_inventory_move = allow_metadata_inventory_move,
 	allow_metadata_inventory_take = allow_metadata_inventory_take,
 })
-
diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua
index d7e23250c2fcdbcd2f75382876ec17a47bb734a5..3e80ce33ea455fb935feab26c9b2e8227dd524b7 100644
--- a/mods/default/mapgen.lua
+++ b/mods/default/mapgen.lua
@@ -43,12 +43,12 @@ minetest.register_alias("mapgen_stair_sandstone_block", "stairs:stair_sandstone_
 -- Register ores
 --
 
--- Blob ores
--- These first to avoid other ores in blobs
-
 -- Mgv6
 
-function default.register_mgv6_blob_ores()
+function default.register_mgv6_ores()
+
+	-- Blob ore
+	-- These first to avoid other ores in blobs
 
 	-- Clay
 	-- This first to avoid clay in sand blobs
@@ -134,14 +134,289 @@ function default.register_mgv6_blob_ores()
 			persist = 0.0
 		},
 	})
+
+	-- Scatter ores
+
+	-- Coal
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_coal",
+		wherein        = "default:stone",
+		clust_scarcity = 8 * 8 * 8,
+		clust_num_ores = 9,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_coal",
+		wherein        = "default:stone",
+		clust_scarcity = 8 * 8 * 8,
+		clust_num_ores = 8,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = 64,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_coal",
+		wherein        = "default:stone",
+		clust_scarcity = 24 * 24 * 24,
+		clust_num_ores = 27,
+		clust_size     = 6,
+		y_min          = -31000,
+		y_max          = 0,
+	})
+
+	-- Iron
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_iron",
+		wherein        = "default:stone",
+		clust_scarcity = 9 * 9 * 9,
+		clust_num_ores = 12,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_iron",
+		wherein        = "default:stone",
+		clust_scarcity = 7 * 7 * 7,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = 0,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_iron",
+		wherein        = "default:stone",
+		clust_scarcity = 24 * 24 * 24,
+		clust_num_ores = 27,
+		clust_size     = 6,
+		y_min          = -31000,
+		y_max          = -64,
+	})
+
+	-- Copper
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_copper",
+		wherein        = "default:stone",
+		clust_scarcity = 9 * 9 * 9,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_copper",
+		wherein        = "default:stone",
+		clust_scarcity = 12 * 12 * 12,
+		clust_num_ores = 4,
+		clust_size     = 3,
+		y_min          = -63,
+		y_max          = -16,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_copper",
+		wherein        = "default:stone",
+		clust_scarcity = 9 * 9 * 9,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = -64,
+	})
+
+	-- Tin
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_tin",
+		wherein        = "default:stone",
+		clust_scarcity = 10 * 10 * 10,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_tin",
+		wherein        = "default:stone",
+		clust_scarcity = 13 * 13 * 13,
+		clust_num_ores = 4,
+		clust_size     = 3,
+		y_min          = -127,
+		y_max          = -32,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_tin",
+		wherein        = "default:stone",
+		clust_scarcity = 10 * 10 * 10,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = -128,
+	})
+
+	-- Gold
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_gold",
+		wherein        = "default:stone",
+		clust_scarcity = 13 * 13 * 13,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_gold",
+		wherein        = "default:stone",
+		clust_scarcity = 15 * 15 * 15,
+		clust_num_ores = 3,
+		clust_size     = 2,
+		y_min          = -255,
+		y_max          = -64,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_gold",
+		wherein        = "default:stone",
+		clust_scarcity = 13 * 13 * 13,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = -256,
+	})
+
+	-- Mese crystal
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_mese",
+		wherein        = "default:stone",
+		clust_scarcity = 14 * 14 * 14,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_mese",
+		wherein        = "default:stone",
+		clust_scarcity = 18 * 18 * 18,
+		clust_num_ores = 3,
+		clust_size     = 2,
+		y_min          = -255,
+		y_max          = -64,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_mese",
+		wherein        = "default:stone",
+		clust_scarcity = 14 * 14 * 14,
+		clust_num_ores = 5,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = -256,
+	})
+
+	-- Diamond
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_diamond",
+		wherein        = "default:stone",
+		clust_scarcity = 15 * 15 * 15,
+		clust_num_ores = 4,
+		clust_size     = 3,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_diamond",
+		wherein        = "default:stone",
+		clust_scarcity = 17 * 17 * 17,
+		clust_num_ores = 4,
+		clust_size     = 3,
+		y_min          = -255,
+		y_max          = -128,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:stone_with_diamond",
+		wherein        = "default:stone",
+		clust_scarcity = 15 * 15 * 15,
+		clust_num_ores = 4,
+		clust_size     = 3,
+		y_min          = -31000,
+		y_max          = -256,
+	})
+
+	-- Mese block
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:mese",
+		wherein        = "default:stone",
+		clust_scarcity = 36 * 36 * 36,
+		clust_num_ores = 3,
+		clust_size     = 2,
+		y_min          = 1025,
+		y_max          = 31000,
+	})
+
+	minetest.register_ore({
+		ore_type       = "scatter",
+		ore            = "default:mese",
+		wherein        = "default:stone",
+		clust_scarcity = 36 * 36 * 36,
+		clust_num_ores = 3,
+		clust_size     = 2,
+		y_min          = -31000,
+		y_max          = -1024,
+	})
 end
 
 
 -- All mapgens except mgv6
 
-function default.register_blob_ores()
+function default.register_ores()
+
+	-- Blob ore
+	-- These first to avoid other ores in blobs
 
 	-- Clay
+	-- This first to avoid clay in sand blobs
 
 	minetest.register_ore({
 		ore_type        = "blob",
@@ -188,7 +463,7 @@ function default.register_blob_ores()
 			"deciduous_forest_shore", "deciduous_forest_ocean", "cold_desert",
 			"cold_desert_ocean", "savanna", "savanna_shore", "savanna_ocean",
 			"rainforest", "rainforest_swamp", "rainforest_ocean", "underground",
-			"floatland_ocean", "floatland_grassland", "floatland_coniferous_forest"}
+			"floatland_coniferous_forest", "floatland_coniferous_forest_ocean"}
 	})
 
 	-- Dirt
@@ -212,8 +487,7 @@ function default.register_blob_ores()
 		},
 		biomes = {"taiga", "snowy_grassland", "grassland", "coniferous_forest",
 			"deciduous_forest", "deciduous_forest_shore", "savanna", "savanna_shore",
-			"rainforest", "rainforest_swamp", "floatland_grassland",
-			"floatland_coniferous_forest"}
+			"rainforest", "rainforest_swamp", "floatland_coniferous_forest"}
 	})
 
 	-- Gravel
@@ -242,15 +516,10 @@ function default.register_blob_ores()
 			"deciduous_forest_shore", "deciduous_forest_ocean", "cold_desert",
 			"cold_desert_ocean", "savanna", "savanna_shore", "savanna_ocean",
 			"rainforest", "rainforest_swamp", "rainforest_ocean", "underground",
-			"floatland_ocean", "floatland_grassland", "floatland_coniferous_forest"}
+			"floatland_coniferous_forest", "floatland_coniferous_forest_ocean"}
 	})
-end
-
 
--- Scatter ores
--- All mapgens
-
-function default.register_ores()
+	-- Scatter ores
 
 	-- Coal
 
@@ -1176,6 +1445,8 @@ end
 
 
 -- Biomes for floatlands
+-- Used when mgv7 'biomerepeat' flag is false
+-- TODO Temporary simple biomes to be developed later
 
 function default.register_floatland_biomes(floatland_level, shadow_limit)
 
@@ -1195,60 +1466,16 @@ function default.register_floatland_biomes(floatland_level, shadow_limit)
 		--node_river_water = "",
 		--node_riverbed = "",
 		--depth_riverbed = ,
-		y_min = floatland_level + 2,
-		y_max = 31000,
-		heat_point = 50,
-		humidity_point = 70,
-	})
-
-	-- Grassland
-
-	minetest.register_biome({
-		name = "floatland_grassland",
-		--node_dust = "",
-		node_top = "default:dirt_with_grass",
-		depth_top = 1,
-		node_filler = "default:dirt",
-		depth_filler = 1,
-		--node_stone = "",
-		--node_water_top = "",
-		--depth_water_top = ,
-		--node_water = "",
-		--node_river_water = "",
-		--node_riverbed = "",
-		--depth_riverbed = ,
-		y_min = floatland_level + 2,
-		y_max = 31000,
-		heat_point = 50,
-		humidity_point = 35,
-	})
-
-	-- Sandstone desert
-
-	minetest.register_biome({
-		name = "floatland_sandstone_desert",
-		--node_dust = "",
-		node_top = "default:sand",
-		depth_top = 1,
-		node_filler = "default:sand",
-		depth_filler = 1,
-		node_stone = "default:sandstone",
-		--node_water_top = "",
-		--depth_water_top = ,
-		--node_water = "",
-		--node_river_water = "",
-		--node_riverbed = "",
-		--depth_riverbed = ,
-		y_min = floatland_level + 2,
+		y_min = floatland_level + 4,
 		y_max = 31000,
 		heat_point = 50,
-		humidity_point = 0,
+		humidity_point = 50,
 	})
 
-	-- Floatland ocean / underground
+	-- Coniferous forest ocean
 
 	minetest.register_biome({
-		name = "floatland_ocean",
+		name = "floatland_coniferous_forest_ocean",
 		--node_dust = "",
 		node_top = "default:sand",
 		depth_top = 1,
@@ -1262,7 +1489,7 @@ function default.register_floatland_biomes(floatland_level, shadow_limit)
 		--node_riverbed = "",
 		--depth_riverbed = ,
 		y_min = shadow_limit,
-		y_max = floatland_level + 1,
+		y_max = floatland_level + 3,
 		heat_point = 50,
 		humidity_point = 50,
 	})
@@ -1794,33 +2021,41 @@ end
 
 -- Get setting or default
 local mgv7_spflags = minetest.get_mapgen_setting("mgv7_spflags") or
-	"mountains, ridges, nofloatlands"
+	"mountains, ridges, nofloatlands, caverns, biomerepeat"
 local captures_float = string.match(mgv7_spflags, "floatlands")
 local captures_nofloat = string.match(mgv7_spflags, "nofloatlands")
+local captures_nobiorep = string.match(mgv7_spflags, "nobiomerepeat")
 
-local mgv7_floatland_level = minetest.get_mapgen_setting("mgv7_floatland_level") or 1280
-local mgv7_shadow_limit = minetest.get_mapgen_setting("mgv7_shadow_limit") or 1024
+-- Get setting or default
+-- Make global for mods to use to register floatland biomes
+default.mgv7_floatland_level =
+	minetest.get_mapgen_setting("mgv7_floatland_level") or 1280
+default.mgv7_shadow_limit =
+	minetest.get_mapgen_setting("mgv7_shadow_limit") or 1024
 
 minetest.clear_registered_biomes()
 minetest.clear_registered_ores()
 minetest.clear_registered_decorations()
 
 local mg_name = minetest.get_mapgen_setting("mg_name")
+
 if mg_name == "v6" then
-	default.register_mgv6_blob_ores()
-	default.register_ores()
+	default.register_mgv6_ores()
 	default.register_mgv6_decorations()
-elseif mg_name == "v7" and captures_float == "floatlands" and
-		captures_nofloat ~= "nofloatlands" then
-	-- Mgv7 with floatlands
-	default.register_biomes(mgv7_shadow_limit - 1)
-	default.register_floatland_biomes(mgv7_floatland_level, mgv7_shadow_limit)
-	default.register_blob_ores()
+elseif mg_name == "v7" and
+		captures_float == "floatlands" and
+		-- Need to check for 'nofloatlands' because that contains
+		-- 'floatlands' which makes the second condition true.
+		captures_nofloat ~= "nofloatlands" and
+		captures_nobiorep == "nobiomerepeat" then
+	-- Mgv7 with floatlands and floatland biomes
+	default.register_biomes(default.mgv7_shadow_limit - 1)
+	default.register_floatland_biomes(
+		default.mgv7_floatland_level, default.mgv7_shadow_limit)
 	default.register_ores()
 	default.register_decorations()
 else
 	default.register_biomes(31000)
-	default.register_blob_ores()
 	default.register_ores()
 	default.register_decorations()
 end
diff --git a/mods/default/models/character.b3d b/mods/default/models/character.b3d
index 9ab454366bee8fb6c9e45e64ac0d77808d5ea66f..fb693bc595084c289d5ecb9a2ea8e281142a3be2 100644
Binary files a/mods/default/models/character.b3d and b/mods/default/models/character.b3d differ
diff --git a/mods/default/models/character.blend b/mods/default/models/character.blend
index fca9f6597fe998d1aebcac4abe126b13099a5788..be40608628f870b8374d8739136d5cf68cf67c1b 100644
Binary files a/mods/default/models/character.blend and b/mods/default/models/character.blend differ
diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua
index aad08b31e7765452aec41826b40dd02c63cf0f3e..d0a2d18cb4e1b341710c75a38378f8c1551ef30c 100644
--- a/mods/default/nodes.lua
+++ b/mods/default/nodes.lua
@@ -592,7 +592,7 @@ minetest.register_node("default:ice", {
 --
 
 minetest.register_node("default:tree", {
-	description = "Tree",
+	description = "Apple Tree",
 	tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
 	paramtype2 = "facedir",
 	is_ground_content = false,
@@ -603,7 +603,7 @@ minetest.register_node("default:tree", {
 })
 
 minetest.register_node("default:wood", {
-	description = "Wooden Planks",
+	description = "Apple Wood Planks",
 	paramtype2 = "facedir",
 	place_param2 = 0,
 	tiles = {"default_wood.png"},
@@ -613,7 +613,7 @@ minetest.register_node("default:wood", {
 })
 
 minetest.register_node("default:sapling", {
-	description = "Sapling",
+	description = "Apple Tree Sapling",
 	drawtype = "plantlike",
 	tiles = {"default_sapling.png"},
 	inventory_image = "default_sapling.png",
@@ -631,7 +631,7 @@ minetest.register_node("default:sapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(2400,4800))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -649,7 +649,7 @@ minetest.register_node("default:sapling", {
 })
 
 minetest.register_node("default:leaves", {
-	description = "Leaves",
+	description = "Apple Tree Leaves",
 	drawtype = "allfaces_optional",
 	waving = 1,
 	tiles = {"default_leaves.png"},
@@ -716,7 +716,7 @@ minetest.register_node("default:jungletree", {
 })
 
 minetest.register_node("default:junglewood", {
-	description = "Junglewood Planks",
+	description = "Jungle Wood Planks",
 	paramtype2 = "facedir",
 	place_param2 = 0,
 	tiles = {"default_junglewood.png"},
@@ -726,7 +726,7 @@ minetest.register_node("default:junglewood", {
 })
 
 minetest.register_node("default:jungleleaves", {
-	description = "Jungle Leaves",
+	description = "Jungle Tree Leaves",
 	drawtype = "allfaces_optional",
 	waving = 1,
 	tiles = {"default_jungleleaves.png"},
@@ -747,7 +747,7 @@ minetest.register_node("default:jungleleaves", {
 })
 
 minetest.register_node("default:junglesapling", {
-	description = "Jungle Sapling",
+	description = "Jungle Tree Sapling",
 	drawtype = "plantlike",
 	tiles = {"default_junglesapling.png"},
 	inventory_image = "default_junglesapling.png",
@@ -765,7 +765,7 @@ minetest.register_node("default:junglesapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(2400,4800))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -826,7 +826,7 @@ minetest.register_node("default:pine_needles",{
 })
 
 minetest.register_node("default:pine_sapling", {
-	description = "Pine Sapling",
+	description = "Pine Tree Sapling",
 	drawtype = "plantlike",
 	tiles = {"default_pine_sapling.png"},
 	inventory_image = "default_pine_sapling.png",
@@ -844,7 +844,7 @@ minetest.register_node("default:pine_sapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(2400,4800))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -885,7 +885,7 @@ minetest.register_node("default:acacia_wood", {
 })
 
 minetest.register_node("default:acacia_leaves", {
-	description = "Acacia Leaves",
+	description = "Acacia Tree Leaves",
 	drawtype = "allfaces_optional",
 	tiles = {"default_acacia_leaves.png"},
 	special_tiles = {"default_acacia_leaves_simple.png"},
@@ -924,7 +924,7 @@ minetest.register_node("default:acacia_sapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(2400,4800))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -964,7 +964,7 @@ minetest.register_node("default:aspen_wood", {
 })
 
 minetest.register_node("default:aspen_leaves", {
-	description = "Aspen Leaves",
+	description = "Aspen Tree Leaves",
 	drawtype = "allfaces_optional",
 	tiles = {"default_aspen_leaves.png"},
 	waving = 1,
@@ -1002,7 +1002,7 @@ minetest.register_node("default:aspen_sapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(2400,4800))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -1394,7 +1394,7 @@ minetest.register_node("default:bush_sapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(1200, 2400))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -1465,7 +1465,7 @@ minetest.register_node("default:acacia_bush_sapling", {
 	sounds = default.node_sound_leaves_defaults(),
 
 	on_construct = function(pos)
-		minetest.get_node_timer(pos):start(math.random(1200, 2400))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end,
 
 	on_place = function(itemstack, placer, pointed_thing)
@@ -1798,7 +1798,7 @@ minetest.register_node("default:lava_flowing", {
 -- Tools / "Advanced" crafting / Non-"natural"
 --
 
-local function get_chest_formspec(pos)
+function default.get_chest_formspec(pos)
 	local spos = pos.x .. "," .. pos.y .. "," .. pos.z
 	local formspec =
 		"size[8,9]" ..
@@ -1815,13 +1815,14 @@ local function get_chest_formspec(pos)
 end
 
 local function chest_lid_obstructed(pos)
-	local above = { x = pos.x, y = pos.y + 1, z = pos.z }
+	local above = {x = pos.x, y = pos.y + 1, z = pos.z}
 	local def = minetest.registered_nodes[minetest.get_node(above).name]
 	-- allow ladders, signs, wallmounted things and torches to not obstruct
-	if def.drawtype == "airlike" or
+	if def and
+			(def.drawtype == "airlike" or
 			def.drawtype == "signlike" or
 			def.drawtype == "torchlike" or
-			(def.drawtype == "nodebox" and def.paramtype2 == "wallmounted") then
+			(def.drawtype == "nodebox" and def.paramtype2 == "wallmounted")) then
 		return false
 	end
 	return true
@@ -1921,7 +1922,7 @@ function default.register_chest(name, d)
 			end
 			minetest.after(0.2, minetest.show_formspec,
 					clicker:get_player_name(),
-					"default:chest", get_chest_formspec(pos))
+					"default:chest", default.get_chest_formspec(pos))
 			open_chests[clicker:get_player_name()] = { pos = pos,
 					sound = def.sound_close, swap = name }
 		end
@@ -1943,7 +1944,7 @@ function default.register_chest(name, d)
 			minetest.show_formspec(
 				player:get_player_name(),
 				"default:chest_locked",
-				get_chest_formspec(pos)
+				default.get_chest_formspec(pos)
 			)
 		end
 		def.on_skeleton_key_use = function(pos, player, newsecret)
@@ -1988,7 +1989,7 @@ function default.register_chest(name, d)
 			end
 			minetest.after(0.2, minetest.show_formspec,
 					clicker:get_player_name(),
-					"default:chest", get_chest_formspec(pos))
+					"default:chest", default.get_chest_formspec(pos))
 			open_chests[clicker:get_player_name()] = { pos = pos,
 					sound = def.sound_close, swap = name }
 		end
@@ -2021,12 +2022,19 @@ function default.register_chest(name, d)
 	local def_closed = table.copy(def)
 
 	def_opened.mesh = "chest_open.obj"
+	for i = 1, #def_opened.tiles do
+		if type(def_opened.tiles[i]) == "string" then
+			def_opened.tiles[i] = {name = def_opened.tiles[i], backface_culling = true}
+		elseif def_opened.tiles[i].backface_culling == nil then
+			def_opened.tiles[i].backface_culling = true
+		end
+	end
 	def_opened.drop = "default:" .. name
 	def_opened.groups.not_in_creative_inventory = 1
 	def_opened.selection_box = {
 		type = "fixed",
 		fixed = { -1/2, -1/2, -1/2, 1/2, 3/16, 1/2 },
-		}
+	}
 	def_opened.can_dig = function()
 		return false
 	end
@@ -2276,7 +2284,7 @@ minetest.register_node("default:ladder_steel", {
 })
 
 default.register_fence("default:fence_wood", {
-	description = "Wooden Fence",
+	description = "Apple Wood Fence",
 	texture = "default_fence_wood.png",
 	inventory_image = "default_fence_overlay.png^default_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
 	wield_image = "default_fence_overlay.png^default_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
@@ -2286,7 +2294,7 @@ default.register_fence("default:fence_wood", {
 })
 
 default.register_fence("default:fence_acacia_wood", {
-	description = "Acacia Fence",
+	description = "Acacia Wood Fence",
 	texture = "default_fence_acacia_wood.png",
 	inventory_image = "default_fence_overlay.png^default_acacia_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
 	wield_image = "default_fence_overlay.png^default_acacia_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
@@ -2296,7 +2304,7 @@ default.register_fence("default:fence_acacia_wood", {
 })
 
 default.register_fence("default:fence_junglewood", {
-	description = "Junglewood Fence",
+	description = "Jungle Wood Fence",
 	texture = "default_fence_junglewood.png",
 	inventory_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126",
 	wield_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126",
@@ -2306,7 +2314,7 @@ default.register_fence("default:fence_junglewood", {
 })
 
 default.register_fence("default:fence_pine_wood", {
-	description = "Pine Fence",
+	description = "Pine Wood Fence",
 	texture = "default_fence_pine_wood.png",
 	inventory_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
 	wield_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
@@ -2316,7 +2324,7 @@ default.register_fence("default:fence_pine_wood", {
 })
 
 default.register_fence("default:fence_aspen_wood", {
-	description = "Aspen Fence",
+	description = "Aspen Wood Fence",
 	texture = "default_fence_aspen_wood.png",
 	inventory_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
 	wield_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126",
diff --git a/mods/default/textures/default_book.png b/mods/default/textures/default_book.png
index 15af2b699894ac23e1f8121870a879bd44128b7d..448a7df0287088582d9e12eaa1189052ace175e2 100644
Binary files a/mods/default/textures/default_book.png and b/mods/default/textures/default_book.png differ
diff --git a/mods/default/textures/default_book_written.png b/mods/default/textures/default_book_written.png
index d843e5f6d7c7cc0a7a0740aed086390f33713d7e..9196ac64764e2ada74ef8d7c3684716b680239ff 100644
Binary files a/mods/default/textures/default_book_written.png and b/mods/default/textures/default_book_written.png differ
diff --git a/mods/default/textures/default_bookshelf_slot.png b/mods/default/textures/default_bookshelf_slot.png
index 31c4eb5e6e25b208782e7ec11c8b527a125ebb02..715a3dce79d22d9e3d73db7cb18d1ab4dd435a29 100644
Binary files a/mods/default/textures/default_bookshelf_slot.png and b/mods/default/textures/default_bookshelf_slot.png differ
diff --git a/mods/default/textures/default_clay_brick.png b/mods/default/textures/default_clay_brick.png
index dc7a4317e398abf00487242ed6fbd4f5971e803b..b288ef0b25b092a58df1aae4a6e5e3a267beb2c6 100644
Binary files a/mods/default/textures/default_clay_brick.png and b/mods/default/textures/default_clay_brick.png differ
diff --git a/mods/default/textures/default_mese_post_light_top.png b/mods/default/textures/default_mese_post_light_top.png
index 6834bd369e1daa8d372f80d3cfefa84303684d2e..365c1a785466fc0b70465dddab984801a09f53d4 100644
Binary files a/mods/default/textures/default_mese_post_light_top.png and b/mods/default/textures/default_mese_post_light_top.png differ
diff --git a/mods/default/tools.lua b/mods/default/tools.lua
index d6602a660a4e1089e2827568b7e4a3b3e9682fa2..c2cf6e6ba97a72c533f0e810985613c9eae1393b 100644
--- a/mods/default/tools.lua
+++ b/mods/default/tools.lua
@@ -283,7 +283,7 @@ minetest.register_tool("default:axe_diamond", {
 		full_punch_interval = 0.9,
 		max_drop_level=1,
 		groupcaps={
-			choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=30, maxlevel=2},
+			choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=30, maxlevel=3},
 		},
 		damage_groups = {fleshy=7},
 	},
diff --git a/mods/default/trees.lua b/mods/default/trees.lua
index 81c9831e63bf9c8a3422c4960b8563ba680fd960..d00a6b5e8caeec956f6c2f0e59f0a7bb8b9b2b82 100644
--- a/mods/default/trees.lua
+++ b/mods/default/trees.lua
@@ -31,12 +31,12 @@ local function is_snow_nearby(pos)
 end
 
 
--- Sapling ABM
+-- Grow sapling
 
 function default.grow_sapling(pos)
 	if not default.can_grow(pos) then
-		-- try a bit later again
-		minetest.get_node_timer(pos):start(math.random(240, 600))
+		-- try again 5 min later
+		minetest.get_node_timer(pos):start(300)
 		return
 	end
 
@@ -94,7 +94,7 @@ minetest.register_lbm({
 			"default:pine_sapling", "default:acacia_sapling",
 			"default:aspen_sapling"},
 	action = function(pos)
-		minetest.get_node_timer(pos):start(math.random(1200, 2400))
+		minetest.get_node_timer(pos):start(math.random(300, 1500))
 	end
 })
 
diff --git a/mods/doors/init.lua b/mods/doors/init.lua
index 1a44394b12ffb275bb68f0e1a4e41ca4517c1b5c..b5515f109afa3b0a370b85f9bde0aac49ed222fc 100644
--- a/mods/doors/init.lua
+++ b/mods/doors/init.lua
@@ -667,7 +667,7 @@ function doors.register_trapdoor(name, def)
 end
 
 doors.register_trapdoor("doors:trapdoor", {
-	description = "Trapdoor",
+	description = "Wooden Trapdoor",
 	inventory_image = "doors_trapdoor.png",
 	wield_image = "doors_trapdoor.png",
 	tile_front = "doors_trapdoor.png",
@@ -712,7 +712,7 @@ function doors.register_fencegate(name, def)
 	local fence = {
 		description = def.description,
 		drawtype = "mesh",
-		tiles = {def.texture},
+		tiles = {},
 		paramtype = "light",
 		paramtype2 = "facedir",
 		sunlight_propagates = true,
@@ -734,6 +734,16 @@ function doors.register_fencegate(name, def)
 		},
 	}
 
+
+	if type(def.texture) == "string" then
+		fence.tiles[1] = {name = def.texture, backface_culling = true}
+	elseif def.texture.backface_culling == nil then
+		fence.tiles[1] = table.copy(def.texture)
+		fence.tiles[1].backface_culling = true
+	else
+		fence.tiles[1] = def.texture
+	end
+
 	if not fence.sounds then
 		fence.sounds = default.node_sound_wood_defaults()
 	end
@@ -773,35 +783,35 @@ function doors.register_fencegate(name, def)
 end
 
 doors.register_fencegate("doors:gate_wood", {
-	description = "Wooden Fence Gate",
+	description = "Apple Wood Fence Gate",
 	texture = "default_wood.png",
 	material = "default:wood",
 	groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}
 })
 
 doors.register_fencegate("doors:gate_acacia_wood", {
-	description = "Acacia Fence Gate",
+	description = "Acacia Wood Fence Gate",
 	texture = "default_acacia_wood.png",
 	material = "default:acacia_wood",
 	groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}
 })
 
 doors.register_fencegate("doors:gate_junglewood", {
-	description = "Junglewood Fence Gate",
+	description = "Jungle Wood Fence Gate",
 	texture = "default_junglewood.png",
 	material = "default:junglewood",
 	groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}
 })
 
 doors.register_fencegate("doors:gate_pine_wood", {
-	description = "Pine Fence Gate",
+	description = "Pine Wood Fence Gate",
 	texture = "default_pine_wood.png",
 	material = "default:pine_wood",
 	groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}
 })
 
 doors.register_fencegate("doors:gate_aspen_wood", {
-	description = "Aspen Fence Gate",
+	description = "Aspen Wood Fence Gate",
 	texture = "default_aspen_wood.png",
 	material = "default:aspen_wood",
 	groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}
diff --git a/mods/doors/textures/doors_trapdoor_side.png b/mods/doors/textures/doors_trapdoor_side.png
index c45d870d90c4b50e495c4cc48911eb4e62717bc2..4a8b99f2836e47737f494f2c1959486337994e6e 100644
Binary files a/mods/doors/textures/doors_trapdoor_side.png and b/mods/doors/textures/doors_trapdoor_side.png differ
diff --git a/mods/dye/init.lua b/mods/dye/init.lua
index 8028457627779f1b8b479c010fe2a6a00e047be9..8f26fed42b66723c859fdc1b50026f5159b29a85 100644
--- a/mods/dye/init.lua
+++ b/mods/dye/init.lua
@@ -28,21 +28,21 @@ dye.dyes = {
 -- This collection of colors is partly a historic thing, partly something else
 
 local dyes = {
-	{"white",      "White dye",      {dye=1, basecolor_white=1,   excolor_white=1,      unicolor_white=1}},
-	{"grey",       "Grey dye",       {dye=1, basecolor_grey=1,    excolor_grey=1,       unicolor_grey=1}},
-	{"dark_grey",  "Dark grey dye",  {dye=1, basecolor_grey=1,    excolor_darkgrey=1,   unicolor_darkgrey=1}},
-	{"black",      "Black dye",      {dye=1, basecolor_black=1,   excolor_black=1,      unicolor_black=1}},
-	{"violet",     "Violet dye",     {dye=1, basecolor_magenta=1, excolor_violet=1,     unicolor_violet=1}},
-	{"blue",       "Blue dye",       {dye=1, basecolor_blue=1,    excolor_blue=1,       unicolor_blue=1}},
-	{"cyan",       "Cyan dye",       {dye=1, basecolor_cyan=1,    excolor_cyan=1,       unicolor_cyan=1}},
-	{"dark_green", "Dark green dye", {dye=1, basecolor_green=1,   excolor_green=1,      unicolor_dark_green=1}},
-	{"green",      "Green dye",      {dye=1, basecolor_green=1,   excolor_green=1,      unicolor_green=1}},
-	{"yellow",     "Yellow dye",     {dye=1, basecolor_yellow=1,  excolor_yellow=1,     unicolor_yellow=1}},
-	{"brown",      "Brown dye",      {dye=1, basecolor_brown=1,   excolor_orange=1,     unicolor_dark_orange=1}},
-	{"orange",     "Orange dye",     {dye=1, basecolor_orange=1,  excolor_orange=1,     unicolor_orange=1}},
-	{"red",        "Red dye",        {dye=1, basecolor_red=1,     excolor_red=1,        unicolor_red=1}},
-	{"magenta",    "Magenta dye",    {dye=1, basecolor_magenta=1, excolor_red_violet=1, unicolor_red_violet=1}},
-	{"pink",       "Pink dye",       {dye=1, basecolor_red=1,     excolor_red=1,        unicolor_light_red=1}},
+	{"white",      "White Dye",      {dye=1, basecolor_white=1,   excolor_white=1,      unicolor_white=1}},
+	{"grey",       "Grey Dye",       {dye=1, basecolor_grey=1,    excolor_grey=1,       unicolor_grey=1}},
+	{"dark_grey",  "Dark Grey Dye",  {dye=1, basecolor_grey=1,    excolor_darkgrey=1,   unicolor_darkgrey=1}},
+	{"black",      "Black Dye",      {dye=1, basecolor_black=1,   excolor_black=1,      unicolor_black=1}},
+	{"violet",     "Violet Dye",     {dye=1, basecolor_magenta=1, excolor_violet=1,     unicolor_violet=1}},
+	{"blue",       "Blue Dye",       {dye=1, basecolor_blue=1,    excolor_blue=1,       unicolor_blue=1}},
+	{"cyan",       "Cyan Dye",       {dye=1, basecolor_cyan=1,    excolor_cyan=1,       unicolor_cyan=1}},
+	{"dark_green", "Dark Green Dye", {dye=1, basecolor_green=1,   excolor_green=1,      unicolor_dark_green=1}},
+	{"green",      "Green Dye",      {dye=1, basecolor_green=1,   excolor_green=1,      unicolor_green=1}},
+	{"yellow",     "Yellow Dye",     {dye=1, basecolor_yellow=1,  excolor_yellow=1,     unicolor_yellow=1}},
+	{"brown",      "Brown Dye",      {dye=1, basecolor_brown=1,   excolor_orange=1,     unicolor_dark_orange=1}},
+	{"orange",     "Orange Dye",     {dye=1, basecolor_orange=1,  excolor_orange=1,     unicolor_orange=1}},
+	{"red",        "Red Dye",        {dye=1, basecolor_red=1,     excolor_red=1,        unicolor_red=1}},
+	{"magenta",    "Magenta Dye",    {dye=1, basecolor_magenta=1, excolor_red_violet=1, unicolor_red_violet=1}},
+	{"pink",       "Pink Dye",       {dye=1, basecolor_red=1,     excolor_red=1,        unicolor_light_red=1}},
 }
 
 -- Define items
diff --git a/mods/farming/api.lua b/mods/farming/api.lua
index 35a77e9fcac3d0dc592219c6f441815c117fc22d..150301ad5b0064bfb8ff73ba55cd1a8f6fd687ea 100644
--- a/mods/farming/api.lua
+++ b/mods/farming/api.lua
@@ -118,15 +118,6 @@ farming.register_hoe = function(name, def)
 				{"", "group:stick", ""}
 			}
 		})
-		-- Reverse Recipe
-		minetest.register_craft({
-			output = name:sub(2),
-			recipe = {
-				{"", def.material, def.material},
-				{"", "group:stick", ""},
-				{"", "group:stick", ""}
-			}
-		})
 	end
 end
 
diff --git a/mods/farming/depends.txt b/mods/farming/depends.txt
index 470ec30b9bd5379cd6d90edc29d7e36b8b17d2cb..301d9719929bafbb3ee6063ba89a77a9437f59ea 100644
--- a/mods/farming/depends.txt
+++ b/mods/farming/depends.txt
@@ -1,2 +1,3 @@
 default
 wool
+stairs
diff --git a/mods/farming/init.lua b/mods/farming/init.lua
index 97dc9b4aaea8c90477c135c8ff0326a74d55a1fb..667a66851827b7d5cc26cf0a037f7deff4032333 100644
--- a/mods/farming/init.lua
+++ b/mods/farming/init.lua
@@ -9,7 +9,7 @@ dofile(farming.path .. "/hoes.lua")
 
 -- WHEAT
 farming.register_plant("farming:wheat", {
-	description = "Wheat seed",
+	description = "Wheat Seed",
 	paramtype2 = "meshoptions",
 	inventory_image = "farming_wheat_seed.png",
 	steps = 8,
@@ -47,7 +47,7 @@ minetest.register_craft({
 
 -- Cotton
 farming.register_plant("farming:cotton", {
-	description = "Cotton seed",
+	description = "Cotton Seed",
 	inventory_image = "farming_cotton_seed.png",
 	steps = 8,
 	minlight = 13,
diff --git a/mods/farming/nodes.lua b/mods/farming/nodes.lua
index c969d31be04a72e860bacb620908eb43ad172736..1e746ecd43bc23db136da2876bdddab43d38b2f3 100644
--- a/mods/farming/nodes.lua
+++ b/mods/farming/nodes.lua
@@ -98,6 +98,16 @@ minetest.register_node("farming:straw", {
 	sounds = default.node_sound_leaves_defaults(),
 })
 
+stairs.register_stair_and_slab(
+	"straw",
+	"farming:straw",
+	{snappy = 3, flammable = 4},
+	{"farming_straw.png"},
+	"Straw Stair",
+	"Straw Slab",
+	default.node_sound_leaves_defaults()
+)
+
 minetest.register_abm({
 	label = "Farming soil",
 	nodenames = {"group:field"},
diff --git a/mods/fire/init.lua b/mods/fire/init.lua
index 2dbf5dfd3febe7ce4804c15281644a431e84145a..f97636b5bd090d022909e5b5ff16f6d22fb1b65f 100644
--- a/mods/fire/init.lua
+++ b/mods/fire/init.lua
@@ -148,7 +148,7 @@ minetest.override_item("default:coalblock", {
 -- Sound
 --
 
-local flame_sound = minetest.setting_getbool("flame_sound")
+local flame_sound = minetest.settings:get_bool("flame_sound")
 if flame_sound == nil then
 	-- Enable if no setting present
 	flame_sound = true
@@ -290,10 +290,10 @@ minetest.register_abm({
 
 -- Enable the following ABMs according to 'enable fire' setting
 
-local fire_enabled = minetest.setting_getbool("enable_fire")
+local fire_enabled = minetest.settings:get_bool("enable_fire")
 if fire_enabled == nil then
 	-- enable_fire setting not specified, check for disable_fire
-	local fire_disabled = minetest.setting_getbool("disable_fire")
+	local fire_disabled = minetest.settings:get_bool("disable_fire")
 	if fire_disabled == nil then
 		-- Neither setting specified, check whether singleplayer
 		fire_enabled = minetest.is_singleplayer()
diff --git a/mods/flowers/README.txt b/mods/flowers/README.txt
index 2a5e4de3a9c5c3190d88f44d4a823dd70432294d..6fd309423ae0c9efde08dea6bebac16b700d5ff0 100644
--- a/mods/flowers/README.txt
+++ b/mods/flowers/README.txt
@@ -11,7 +11,6 @@ Authors of media (textures)
 ---------------------------
 RHRhino (CC BY-SA 3.0):
   flowers_dandelion_white.png
-  flowers_dandelion_yellow.png
   flowers_geranium.png
   flowers_rose.png
   flowers_tulip.png
@@ -23,4 +22,7 @@ Gambit (CC BY-SA 3.0):
   flowers_waterlily.png
 
 yyt16384 (CC BY-SA 3.0):
-  flowers_waterlily_bottom.png, derived from Gambit's texture
+  flowers_waterlily_bottom.png -- Derived from Gambit's texture
+
+paramat (CC BY-SA 3.0):
+  flowers_dandelion_yellow.png -- Derived from RHRhino's texture
diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua
index 6ebc85f66d2417129456f95ebe4efd24169f1743..529d225871277425ed06cb6cf3eb257bcb5d1e5b 100644
--- a/mods/flowers/init.lua
+++ b/mods/flowers/init.lua
@@ -59,7 +59,7 @@ end
 flowers.datas = {
 	{
 		"rose",
-		"Rose",
+		"Red Rose",
 		{-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16},
 		{color_red = 1, flammable = 1}
 	},
@@ -72,7 +72,7 @@ flowers.datas = {
 	{
 		"dandelion_yellow",
 		"Yellow Dandelion",
-		{-2 / 16, -0.5, -2 / 16, 2 / 16, 4 / 16, 2 / 16},
+		{-4 / 16, -0.5, -4 / 16, 4 / 16, -2 / 16, 4 / 16},
 		{color_yellow = 1, flammable = 1}
 	},
 	{
@@ -89,7 +89,7 @@ flowers.datas = {
 	},
 	{
 		"dandelion_white",
-		"White dandelion",
+		"White Dandelion",
 		{-5 / 16, -0.5, -5 / 16, 5 / 16, -2 / 16, 5 / 16},
 		{color_white = 1, flammable = 1}
 	},
diff --git a/mods/flowers/license.txt b/mods/flowers/license.txt
index d30116227d78a49bfc0692103bd14fc6e019923e..419ebe5a72e578c03fafa57560d073cb8b194a63 100644
--- a/mods/flowers/license.txt
+++ b/mods/flowers/license.txt
@@ -32,6 +32,7 @@ Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
 Copyright (C) 2014-2016 RHRhino
 Copyright (C) 2015-2016 Gambit
 Copyright (C) 2016 yyt16384
+Copyright (C) 2017 paramat
 
 You are free to:
 Share — copy and redistribute the material in any medium or format.
diff --git a/mods/flowers/mapgen.lua b/mods/flowers/mapgen.lua
index 1bf6f5a5c04670e7d25818095fa3d2e43d692609..582797a9108e8f30bc221ab7738e2b99ee07c570 100644
--- a/mods/flowers/mapgen.lua
+++ b/mods/flowers/mapgen.lua
@@ -87,15 +87,15 @@ local function register_flower(seed, name)
 		place_on = {"default:dirt_with_grass"},
 		sidelen = 16,
 		noise_params = {
-			offset = -0.015,
-			scale = 0.025,
+			offset = -0.02,
+			scale = 0.04,
 			spread = {x = 200, y = 200, z = 200},
 			seed = seed,
 			octaves = 3,
 			persist = 0.6
 		},
 		biomes = {"grassland", "deciduous_forest", "coniferous_forest",
-			"floatland_grassland", "floatland_coniferous_forest"},
+			"floatland_coniferous_forest"},
 		y_min = 1,
 		y_max = 31000,
 		decoration = "flowers:"..name,
diff --git a/mods/flowers/textures/flowers_dandelion_yellow.png b/mods/flowers/textures/flowers_dandelion_yellow.png
index ec11c1c80990a5e142f3cb9bc3d7da59b6bcce63..544f60c151aa0183c560c4650fb9466e6651e42d 100644
Binary files a/mods/flowers/textures/flowers_dandelion_yellow.png and b/mods/flowers/textures/flowers_dandelion_yellow.png differ
diff --git a/mods/give_initial_stuff/init.lua b/mods/give_initial_stuff/init.lua
index 6e01be6871e9cb15325a0d770fc032b38660fc18..f2477b4db93436cbfe9c178c943322ab6e23b203 100644
--- a/mods/give_initial_stuff/init.lua
+++ b/mods/give_initial_stuff/init.lua
@@ -1,8 +1,44 @@
-minetest.register_on_newplayer(function(player)
-        --print("on_newplayer")
-        if minetest.setting_getbool("give_initial_stuff") then
-                minetest.log("action", "Giving initial stuff to player "..player:get_player_name())
-                player:get_inventory():add_item('main', 'illuna:noobcoin 42')
-                player:get_inventory():add_item('main', 'magical_potion:fly_small 2')
-        end
-end)
+local stuff_string = minetest.settings:get("initial_stuff") or
+		"illuna:noobcoin 42" ..
+		"magical_potion:fly_small 2"
+
+give_initial_stuff = {
+	items = {}
+}
+
+function give_initial_stuff.give(player)
+	minetest.log("action",
+			"Giving initial stuff to player " .. player:get_player_name())
+	local inv = player:get_inventory()
+	for _, stack in ipairs(give_initial_stuff.items) do
+		inv:add_item("main", stack)
+	end
+end
+
+function give_initial_stuff.add(stack)
+	give_initial_stuff.items[#give_initial_stuff.items + 1] = ItemStack(stack)
+end
+
+function give_initial_stuff.clear()
+	give_initial_stuff.items = {}
+end
+
+function give_initial_stuff.add_from_csv(str)
+	local items = str:split(",")
+	for _, itemname in ipairs(items) do
+		give_initial_stuff.add(itemname)
+	end
+end
+
+function give_initial_stuff.set_list(list)
+	give_initial_stuff.items = list
+end
+
+function give_initial_stuff.get_list()
+	return give_initial_stuff.items
+end
+
+give_initial_stuff.add_from_csv(stuff_string)
+if minetest.settings:get_bool("give_initial_stuff") then
+	minetest.register_on_newplayer(give_initial_stuff.give)
+end
diff --git a/mods/killme/init.lua b/mods/killme/init.lua
index 06aa39def27daa955d14de848bf00f780f056384..9b674754a48b7cca180e73e60a648b91721de991 100644
--- a/mods/killme/init.lua
+++ b/mods/killme/init.lua
@@ -3,7 +3,7 @@ minetest.register_chatcommand("killme", {
 	func = function(name)
 		local player = minetest.get_player_by_name(name)
 		if player then
-			if minetest.setting_getbool("enable_damage") then
+			if minetest.settings:get_bool("enable_damage") then
 				player:set_hp(0)
 				return true
 			else
diff --git a/mods/stairs/README.txt b/mods/stairs/README.txt
index d32cd71b94b43858e29d83fe7d639404f604bc0d..f2b5b74fac5a6f0bd665ccee00ca26ec41c3e076 100644
--- a/mods/stairs/README.txt
+++ b/mods/stairs/README.txt
@@ -12,5 +12,7 @@ Authors of media (models)
 -------------------------
 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (CC BY-SA 3.0):
   stairs_stair.obj
+GreenXenith (CC BY-SA 3.0)
+  stairs_stair_inner.obj stairs_stair_outer.obj
 
 
diff --git a/mods/stairs/depends.txt b/mods/stairs/depends.txt
index d77ba253124050e2b6e1baea793e53dda4858bd5..4ad96d51599fb734101f6229f6c1a8a509bd6255 100644
--- a/mods/stairs/depends.txt
+++ b/mods/stairs/depends.txt
@@ -1,2 +1 @@
 default
-farming
diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua
index cd37d88eadd87fd357e19854a32dd5f719ba3461..c5d0f48310b5c60849558d8848033c709cb8ac65 100644
--- a/mods/stairs/init.lua
+++ b/mods/stairs/init.lua
@@ -18,7 +18,7 @@ minetest.register_alias("moretrees:slab_acacia_planks", "stairs:slab_acacia_wood
 
 -- Get setting for replace ABM
 
-local replace = minetest.setting_getbool("enable_stairs_replace_abm")
+local replace = minetest.settings:get_bool("enable_stairs_replace_abm")
 
 local function rotate_and_place(itemstack, placer, pointed_thing)
 	local p0 = pointed_thing.under
@@ -49,12 +49,24 @@ end
 -- Node will be called stairs:stair_<subname>
 
 function stairs.register_stair(subname, recipeitem, groups, images, description, sounds)
+	local stair_images = {}
+	for i, image in ipairs(images) do
+		if type(image) == "string" then
+			stair_images[i] = {
+				name = image,
+				backface_culling = true,
+			}
+		elseif image.backface_culling == nil then -- override using any other value
+			stair_images[i] = table.copy(image)
+			stair_images[i].backface_culling = true
+		end
+	end
 	groups.stair = 1
 	minetest.register_node(":stairs:stair_" .. subname, {
 		description = description,
 		drawtype = "mesh",
 		mesh = "stairs_stair.obj",
-		tiles = images,
+		tiles = stair_images,
 		paramtype = "light",
 		paramtype2 = "facedir",
 		is_ground_content = false,
@@ -92,22 +104,22 @@ function stairs.register_stair(subname, recipeitem, groups, images, description,
 	end
 
 	if recipeitem then
+		-- Recipe matches appearence in inventory
 		minetest.register_craft({
 			output = 'stairs:stair_' .. subname .. ' 8',
 			recipe = {
-				{recipeitem, "", ""},
-				{recipeitem, recipeitem, ""},
+				{"", "", recipeitem},
+				{"", recipeitem, recipeitem},
 				{recipeitem, recipeitem, recipeitem},
 			},
 		})
 
-		-- Flipped recipe for the silly minecrafters
+		-- Use stairs to craft full blocks again (1:1)
 		minetest.register_craft({
-			output = 'stairs:stair_' .. subname .. ' 8',
+			output = recipeitem .. ' 3',
 			recipe = {
-				{"", "", recipeitem},
-				{"", recipeitem, recipeitem},
-				{recipeitem, recipeitem, recipeitem},
+				{'stairs:stair_' .. subname, 'stairs:stair_' .. subname},
+				{'stairs:stair_' .. subname, 'stairs:stair_' .. subname},
 			},
 		})
 
@@ -219,6 +231,15 @@ function stairs.register_slab(subname, recipeitem, groups, images, description,
 			},
 		})
 
+		-- Use 2 slabs to craft a full block again (1:1)
+		minetest.register_craft({
+			output = recipeitem,
+			recipe = {
+				{'stairs:slab_' .. subname},
+				{'stairs:slab_' .. subname},
+			},
+		})
+
 		-- Fuel
 		local baseburntime = minetest.get_craft_result({
 			method = "fuel",
@@ -258,17 +279,170 @@ if replace then
 	})
 end
 
+-- Register stairs.
+-- Node will be called stairs:stair_inner_<subname>
+
+function stairs.register_stair_inner(subname, recipeitem, groups, images, description, sounds)
+	local stair_images = {}
+	for i, image in ipairs(images) do
+		if type(image) == "string" then
+			stair_images[i] = {
+				name = image,
+				backface_culling = true,
+			}
+		elseif image.backface_culling == nil then -- override using any other value
+			stair_images[i] = table.copy(image)
+			stair_images[i].backface_culling = true
+		end
+	end
+	groups.stair = 1
+	minetest.register_node(":stairs:stair_inner_" .. subname, {
+		description = description .. " Inner",
+		drawtype = "mesh",
+		mesh = "stairs_stair_inner.obj",
+		tiles = stair_images,
+		paramtype = "light",
+		paramtype2 = "facedir",
+		is_ground_content = false,
+		groups = groups,
+		sounds = sounds,
+		selection_box = {
+			type = "fixed",
+			fixed = {
+				{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+				{-0.5, 0, 0, 0.5, 0.5, 0.5},
+				{-0.5, 0, -0.5, 0, 0.5, 0},
+			},
+		},
+		collision_box = {
+			type = "fixed",
+			fixed = {
+				{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+				{-0.5, 0, 0, 0.5, 0.5, 0.5},
+				{-0.5, 0, -0.5, 0, 0.5, 0},
+			},
+		},
+		on_place = function(itemstack, placer, pointed_thing)
+			if pointed_thing.type ~= "node" then
+				return itemstack
+			end
+
+			return rotate_and_place(itemstack, placer, pointed_thing)
+		end,
+	})
+
+	if recipeitem then
+		minetest.register_craft({
+			output = 'stairs:stair_inner_' .. subname .. ' 7',
+			recipe = {
+				{ "", recipeitem, ""},
+				{ recipeitem, "", recipeitem},
+				{recipeitem, recipeitem, recipeitem},
+			},
+		})
+
+		-- Fuel
+		local baseburntime = minetest.get_craft_result({
+			method = "fuel",
+			width = 1,
+			items = {recipeitem}
+		}).time
+		if baseburntime > 0 then
+			minetest.register_craft({
+				type = "fuel",
+				recipe = 'stairs:stair_inner_' .. subname,
+				burntime = math.floor(baseburntime * 0.875),
+			})
+		end
+	end
+end
+
+-- Register stairs.
+-- Node will be called stairs:stair_outer_<subname>
+
+function stairs.register_stair_outer(subname, recipeitem, groups, images, description, sounds)
+	local stair_images = {}
+	for i, image in ipairs(images) do
+		if type(image) == "string" then
+			stair_images[i] = {
+				name = image,
+				backface_culling = true,
+			}
+		elseif image.backface_culling == nil then -- override using any other value
+			stair_images[i] = table.copy(image)
+			stair_images[i].backface_culling = true
+		end
+	end
+	groups.stair = 1
+	minetest.register_node(":stairs:stair_outer_" .. subname, {
+		description = description .. " Outer",
+		drawtype = "mesh",
+		mesh = "stairs_stair_outer.obj",
+		tiles = stair_images,
+		paramtype = "light",
+		paramtype2 = "facedir",
+		is_ground_content = false,
+		groups = groups,
+		sounds = sounds,
+		selection_box = {
+			type = "fixed",
+			fixed = {
+				{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+				{-0.5, 0, 0, 0, 0.5, 0.5},
+			},
+		},
+		collision_box = {
+			type = "fixed",
+			fixed = {
+				{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+				{-0.5, 0, 0, 0, 0.5, 0.5},
+			},
+		},
+		on_place = function(itemstack, placer, pointed_thing)
+			if pointed_thing.type ~= "node" then
+				return itemstack
+			end
+
+			return rotate_and_place(itemstack, placer, pointed_thing)
+		end,
+	})
+
+	if recipeitem then
+		minetest.register_craft({
+			output = 'stairs:stair_outer_' .. subname .. ' 6',
+			recipe = {
+				{ "", "", ""},
+				{ "", recipeitem, ""},
+				{recipeitem, recipeitem, recipeitem},
+			},
+		})
+
+		-- Fuel
+		local baseburntime = minetest.get_craft_result({
+			method = "fuel",
+			width = 1,
+			items = {recipeitem}
+		}).time
+		if baseburntime > 0 then
+			minetest.register_craft({
+				type = "fuel",
+				recipe = 'stairs:stair_outer_' .. subname,
+				burntime = math.floor(baseburntime * 0.625),
+			})
+		end
+	end
+end
 
 -- Stair/slab registration function.
 -- Nodes will be called stairs:{stair,slab}_<subname>
 
-function stairs.register_stair_and_slab(subname, recipeitem,
-		groups, images, desc_stair, desc_slab, sounds)
+function stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab, sounds)
 	stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds)
+	stairs.register_stair_inner(subname, recipeitem, groups, images, desc_stair, sounds)
+	stairs.register_stair_outer(subname, recipeitem, groups, images, desc_stair, sounds)
 	stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds)
 end
 
-
 -- Register default stairs and slabs
 
 stairs.register_stair_and_slab(
@@ -343,7 +517,7 @@ stairs.register_stair_and_slab(
 
 stairs.register_stair_and_slab(
 	"mossycobble",
-	nil,
+	"default:mossycobble",
 	{cracky = 3},
 	{"default_mossycobble.png"},
 	"Mossy Cobblestone Stair",
@@ -541,16 +715,6 @@ stairs.register_stair_and_slab(
 	default.node_sound_stone_defaults()
 )
 
-stairs.register_stair_and_slab(
-	"straw",
-	"farming:straw",
-	{snappy = 3, flammable = 4},
-	{"farming_straw.png"},
-	"Straw Stair",
-	"Straw Slab",
-	default.node_sound_leaves_defaults()
-)
-
 stairs.register_stair_and_slab(
 	"steelblock",
 	"default:steelblock",
@@ -561,6 +725,16 @@ stairs.register_stair_and_slab(
 	default.node_sound_metal_defaults()
 )
 
+stairs.register_stair_and_slab(
+	"tinblock",
+	"default:tinblock",
+	{cracky = 1, level = 2},
+	{"default_tin_block.png"},
+	"Tin Block Stair",
+	"Tin Block Slab",
+	default.node_sound_metal_defaults()
+)
+
 stairs.register_stair_and_slab(
 	"copperblock",
 	"default:copperblock",
diff --git a/mods/stairs/license.txt b/mods/stairs/license.txt
index 8f16bbd7b8e8e21ccccc6e16cb6380fc32c3b96b..411823aed5441d4d09cb1f2a43d1c0bce68234f4 100644
--- a/mods/stairs/license.txt
+++ b/mods/stairs/license.txt
@@ -21,6 +21,7 @@ Licenses of media (models)
 
 Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
 Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
+Copyright (C) 2017 GreenXenith
 
 You are free to:
 Share — copy and redistribute the material in any medium or format.
diff --git a/mods/stairs/models/stairs_stair_inner.obj b/mods/stairs/models/stairs_stair_inner.obj
new file mode 100644
index 0000000000000000000000000000000000000000..5e4968e81483f560bae32ab34e2a11eef14c029b
--- /dev/null
+++ b/mods/stairs/models/stairs_stair_inner.obj
@@ -0,0 +1,161 @@
+# Blender v2.78 (sub 0) OBJ File: ''
+# www.blender.org
+mtllib stairs_inner_stair.mtl
+o stairs_back_right_stairs_back.001
+v 0.500000 -0.500000 0.500000
+v 0.500000 0.500000 0.500000
+v -0.500000 0.500000 0.500000
+v -0.500000 -0.500000 0.500000
+vt 1.0000 0.0000
+vt 1.0000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.0000
+vn 0.0000 -0.0000 1.0000
+usemtl None.001
+s 1
+f 1/1/1 2/2/1 3/3/1 4/4/1
+o stairs_front_right_stairs_back.003
+v 0.000000 0.000000 -0.500000
+v 0.000000 0.000000 0.000000
+v 0.000000 0.500000 0.000000
+v 0.000000 0.500000 -0.500000
+v -0.500000 0.000000 -0.500000
+v -0.500000 -0.500000 -0.500000
+v -0.500000 0.000000 0.000000
+v -0.500000 0.500000 0.500000
+v -0.500000 0.500000 0.000000
+v -0.500000 -0.500000 0.500000
+vt 0.0000 0.5000
+vt 0.5000 0.5000
+vt 0.5000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.5000
+vt 0.0000 0.0000
+vt 0.5000 0.5000
+vt 1.0000 1.0000
+vt 0.5000 1.0000
+vt 1.0000 0.0000
+vn -1.0000 0.0000 0.0000
+usemtl None
+s 1
+f 5/5/2 6/6/2 7/7/2 8/8/2
+f 9/9/2 10/10/2 11/11/2
+f 11/11/2 12/12/2 13/13/2
+f 10/10/2 14/14/2 11/11/2
+f 14/14/2 12/12/2 11/11/2
+o stairs_bottom
+v -0.500000 -0.500000 0.500000
+v -0.500000 -0.500000 -0.500000
+v 0.500000 -0.500000 -0.500000
+v 0.500000 -0.500000 0.500000
+vt 1.0000 0.0000
+vt 1.0000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.0000
+vn 0.0000 -1.0000 -0.0000
+usemtl None
+s 1
+f 15/15/3 16/16/3 17/17/3 18/18/3
+o stairs_front_left_stairs_front.002
+v -0.500000 0.000000 0.000000
+v -0.500000 0.500000 0.000000
+v 0.000000 0.500000 0.000000
+v 0.000000 0.000000 0.000000
+v -0.500000 -0.500000 -0.500000
+v -0.500000 0.000000 -0.500000
+v 0.500000 0.000000 -0.500000
+v 0.500000 -0.500000 -0.500000
+v 0.000000 0.000000 -0.500000
+v 0.000000 0.500000 -0.500000
+v 0.500000 0.500000 -0.500000
+v 0.500000 0.000000 -0.500000
+vt 1.0000 0.5000
+vt 1.0000 1.0000
+vt 0.5000 1.0000
+vt 0.5000 0.5000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt 0.0000 0.5000
+vt 0.0000 0.0000
+vt 0.5000 0.5000
+vt 0.5000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.5000
+vn 0.0000 0.0000 -1.0000
+usemtl None
+s 1
+f 19/19/4 20/20/4 21/21/4 22/22/4
+f 23/23/4 24/24/4 25/25/4 26/26/4
+f 27/27/4 28/28/4 29/29/4 30/30/4
+o stairs_top_stairs_top.001
+v 0.000000 0.000000 -0.500000
+v -0.500000 0.000000 -0.500000
+v -0.500000 0.000000 0.000000
+v 0.000000 0.000000 0.000000
+v 0.500000 0.500000 -0.500000
+v 0.000000 0.500000 -0.500000
+v 0.000000 0.500000 0.000000
+v 0.500000 0.500000 0.000000
+v -0.500000 0.500000 0.500000
+v 0.500000 0.500000 0.500000
+v 0.500000 0.500000 0.000000
+v -0.500000 0.500000 0.000000
+vt 0.5000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.5000
+vt 0.5000 0.5000
+vt 1.0000 1.0000
+vt 0.5000 1.0000
+vt 0.5000 0.5000
+vt 1.0000 0.5000
+vt 0.0000 0.0000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt 0.0000 0.5000
+vn 0.0000 1.0000 0.0000
+usemtl None
+s 1
+f 31/31/5 32/32/5 33/33/5 34/34/5
+f 35/35/5 36/36/5 37/37/5 38/38/5
+f 39/39/5 40/40/5 41/41/5 42/42/5
+o stairs_back_left_stairs_back.005
+v 0.500000 0.000000 -0.500000
+v 0.500000 0.500000 -0.500000
+v 0.500000 0.500000 0.000000
+v 0.500000 0.000000 0.000000
+v 0.500000 0.000000 0.000000
+v 0.500000 0.500000 0.000000
+v 0.500000 0.500000 0.500000
+v 0.500000 -0.000000 0.500000
+v 0.500000 -0.500000 -0.500000
+v 0.500000 0.000000 -0.500000
+v 0.500000 0.000000 0.000000
+v 0.500000 -0.500000 -0.000000
+v 0.500000 -0.500000 -0.000000
+v 0.500000 0.000000 0.000000
+v 0.500000 -0.000000 0.500000
+v 0.500000 -0.500000 0.500000
+vt 0.5000 0.5000
+vt 0.5000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.5000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt 0.5000 0.5000
+vt 0.5000 0.0000
+vt 0.5000 0.0000
+vt 0.5000 0.5000
+vt 0.0000 0.5000
+vt 0.0000 0.0000
+vt 1.0000 0.5000
+vt 1.0000 1.0000
+vt 0.5000 1.0000
+vt 0.5000 0.5000
+vn 1.0000 0.0000 0.0000
+usemtl None
+s 1
+f 47/43/6 48/44/6 49/45/6 50/46/6
+f 51/47/6 52/48/6 53/49/6 54/50/6
+f 55/51/6 56/52/6 57/53/6 58/54/6
+usemtl None.002
+f 43/55/6 44/56/6 45/57/6 46/58/6
diff --git a/mods/stairs/models/stairs_stair_outer.obj b/mods/stairs/models/stairs_stair_outer.obj
new file mode 100644
index 0000000000000000000000000000000000000000..cc1975b0bb8b8a81414eeb709c3f416d51f88dee
--- /dev/null
+++ b/mods/stairs/models/stairs_stair_outer.obj
@@ -0,0 +1,136 @@
+# Blender v2.78 (sub 0) OBJ File: ''
+# www.blender.org
+mtllib stairs_outer_stair.mtl
+o stairs_bottom
+v -0.500000 -0.500000 0.500000
+v -0.500000 -0.500000 -0.500000
+v 0.500000 -0.500000 -0.500000
+v 0.500000 -0.500000 0.500000
+vt 1.0000 0.0000
+vt 1.0000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.0000
+vn 0.0000 -1.0000 -0.0000
+usemtl None
+s 1
+f 1/1/1 2/2/1 3/3/1 4/4/1
+o stairs_back_left_stairs_left
+v 0.500000 0.000000 0.000000
+v 0.500000 -0.500000 -0.500000
+v 0.500000 0.000000 -0.500000
+v 0.500000 0.500000 0.000000
+v 0.500000 0.500000 0.500000
+v 0.500000 -0.500000 0.500000
+vt 0.5000 0.5000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt 0.5000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.0000
+vn 1.0000 0.0000 0.0000
+usemtl None
+s 1
+f 5/5/2 6/6/2 7/7/2
+f 5/5/2 8/8/2 9/9/2
+f 6/6/2 5/5/2 10/10/2
+f 5/5/2 9/9/2 10/10/2
+o stairs_back_right_stairs_back
+v 0.000000 -0.500000 0.500000
+v 0.000000 -0.000000 0.500000
+v -0.500000 -0.000000 0.500000
+v -0.500000 -0.500000 0.500000
+v 0.500000 -0.500000 0.500000
+v 0.500000 -0.000000 0.500000
+v 0.500000 0.500000 0.500000
+v 0.000000 0.500000 0.500000
+vt 0.5000 0.0000
+vt 0.5000 0.5000
+vt 0.0000 0.5000
+vt 0.0000 0.0000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt 1.0000 1.0000
+vt 0.5000 1.0000
+vn 0.0000 -0.0000 1.0000
+usemtl None
+s 1
+f 11/11/3 12/12/3 13/13/3 14/14/3
+f 15/15/3 16/16/3 12/12/3 11/11/3
+f 16/16/3 17/17/3 18/18/3 12/12/3
+o stairs_top_stairs_top.001
+v 0.000000 0.500000 0.500000
+v 0.501689 0.500000 0.500000
+v 0.501689 0.500000 0.000000
+v 0.000000 0.500000 0.000000
+v -0.500000 -0.000000 0.500000
+v 0.001689 -0.000000 0.500000
+v 0.001689 0.000000 0.000000
+v -0.500000 0.000000 0.000000
+v 0.500000 0.000000 -0.500000
+v -0.500000 0.000000 -0.500000
+v -0.500000 0.000000 0.000000
+v 0.500000 0.000000 0.000000
+vt 0.5000 0.0000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt 0.5000 0.5000
+vt 0.0000 0.0000
+vt 0.5000 0.0000
+vt 0.5000 0.5000
+vt 0.0000 0.5000
+vt 1.0000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.5000
+vt 1.0000 0.5000
+vn 0.0000 1.0000 0.0000
+usemtl None
+s 1
+f 19/19/4 20/20/4 21/21/4 22/22/4
+usemtl None.004
+f 23/23/4 24/24/4 25/25/4 26/26/4
+f 27/27/4 28/28/4 29/29/4 30/30/4
+o stairs_front_left_stairs_front.000
+v -0.500000 -0.500000 -0.500000
+v -0.500000 0.000000 -0.500000
+v 0.500000 0.000000 -0.500000
+v 0.500000 -0.500000 -0.500000
+v 0.500000 0.500000 0.000000
+v 0.500000 0.000000 0.000000
+v 0.000000 0.000000 0.000000
+v 0.000000 0.500000 0.000000
+vt 1.0000 0.0000
+vt 1.0000 0.5000
+vt -0.0000 0.5000
+vt -0.0000 0.0000
+vt 0.5000 0.5000
+vt 0.5000 1.0000
+vt -0.0000 1.0000
+vt -0.0000 0.5000
+vn 0.0000 0.0000 -1.0000
+usemtl None.001
+s 1
+f 31/31/5 32/32/5 33/33/5 34/34/5
+usemtl None.003
+f 37/35/5 38/36/5 35/37/5 36/38/5
+o stairs_front_right_stairs_right.001_stairs_front_left_stairs_front.002
+v -0.500000 -0.500000 0.500000
+v -0.500000 0.000000 0.500000
+v -0.500000 0.000000 -0.500000
+v -0.500000 -0.500000 -0.500000
+v 0.000000 0.000000 0.500000
+v 0.000000 0.500000 0.500000
+v 0.000000 0.500000 -0.000000
+v -0.000000 0.000000 0.000000
+vt 1.0000 0.0000
+vt 1.0000 0.5021
+vt -0.0000 0.5021
+vt -0.0000 0.0000
+vt 1.0000 0.5021
+vt 1.0000 1.0000
+vt 0.5000 1.0000
+vt 0.5000 0.5021
+vn -1.0000 0.0000 0.0000
+usemtl None.002
+s 1
+f 39/39/6 40/40/6 41/41/6 42/42/6
+f 43/43/6 44/44/6 45/45/6 46/46/6
diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua
index 45ac06f661928eb9afc1a7a303a70429311728d2..cfc32ae3bb7b9c64e7aa49309667d3c3ec9bb49e 100644
--- a/mods/tnt/init.lua
+++ b/mods/tnt/init.lua
@@ -7,7 +7,7 @@ local loss_prob = {}
 loss_prob["default:cobble"] = 3
 loss_prob["default:dirt"] = 4
 
-local tnt_radius = tonumber(minetest.setting_get("tnt_radius") or 3)
+local tnt_radius = tonumber(minetest.settings:get("tnt_radius") or 3)
 
 -- Fill a list with data for content IDs, after all nodes are registered
 local cid_data = {}
@@ -78,8 +78,12 @@ local function add_drop(drops, item)
 	end
 end
 
-local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_protection, ignore_on_blast)
-	if not ignore_protection and minetest.is_protected(npos, "") then
+=======
+local basic_flame_on_construct -- cached value
+local function destroy(drops, npos, cid, c_air, c_fire,
+		on_blast_queue, on_construct_queue,
+		ignore_protection, ignore_on_blast, owner)
+	if not ignore_protection and minetest.is_protected(npos, owner) then
 		return cid
 	end
 
@@ -251,13 +255,13 @@ function tnt.burn(pos, nodename)
 	elseif def.on_ignite then
 		def.on_ignite(pos)
 	elseif minetest.get_item_group(name, "tnt") > 0 then
+		minetest.swap_node(pos, {name = name .. "_burning"})
 		minetest.sound_play("tnt_ignite", {pos = pos})
-		minetest.set_node(pos, {name = name .. "_burning"})
 		minetest.get_node_timer(pos):start(1)
 	end
 end
 
-local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
+local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owner)
 	pos = vector.round(pos)
 	-- scan for adjacent TNT nodes first, and enlarge the explosion
 	local vm1 = VoxelManip()
@@ -315,8 +319,8 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
 			local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z}
 			if cid ~= c_air then
 				data[vi] = destroy(drops, p, cid, c_air, c_fire,
-					on_blast_queue, ignore_protection,
-					ignore_on_blast)
+					on_blast_queue, on_construct_queue,
+					ignore_protection, ignore_on_blast, owner)
 			end
 		end
 		vi = vi + 1
@@ -354,14 +358,23 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
 		end
 	end
 
+	for _, queued_data in pairs(on_construct_queue) do
+		queued_data.fn(queued_data.pos)
+	end
+
+	minetest.log("action", "TNT owned by " .. owner .. " detonated at " ..
+		minetest.pos_to_string(pos) .. " with radius " .. radius)
+
 	return drops, radius
 end
 
 function tnt.boom(pos, def)
+	local meta = minetest.get_meta(pos)
+	local owner = meta:get_string("owner")
 	minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = 2*64})
 	minetest.set_node(pos, {name = "tnt:boom"})
 	local drops, radius = tnt_explode(pos, def.radius, def.ignore_protection,
-			def.ignore_on_blast)
+			def.ignore_on_blast, owner)
 	-- append entity drops
 	local damage_radius = (radius / def.radius) * def.damage_radius
 	entity_physics(pos, damage_radius, drops)
@@ -490,17 +503,17 @@ minetest.register_node("tnt:gunpowder_burning", {
 	on_timer = function(pos, elapsed)
 		for dx = -1, 1 do
 		for dz = -1, 1 do
-		for dy = -1, 1 do
-			if not (dx == 0 and dz == 0) then
-				tnt.burn({
-					x = pos.x + dx,
-					y = pos.y + dy,
-					z = pos.z + dz,
-				})
+			if math.abs(dx) + math.abs(dz) == 1 then
+				for dy = -1, 1 do
+					tnt.burn({
+						x = pos.x + dx,
+						y = pos.y + dy,
+						z = pos.z + dz,
+					})
+				end
 			end
 		end
 		end
-		end
 		minetest.remove_node(pos)
 	end,
 	-- unaffected by explosions
@@ -560,9 +573,16 @@ function tnt.register_tnt(def)
 			is_ground_content = false,
 			groups = {dig_immediate = 2, mesecon = 2, tnt = 1, flammable = 5},
 			sounds = default.node_sound_wood_defaults(),
+			after_place_node = function(pos, placer)
+				if placer:is_player() then
+					local meta = minetest.get_meta(pos)
+					meta:set_string("owner", placer:get_player_name())
+				end
+			end,
 			on_punch = function(pos, node, puncher)
 				if puncher:get_wielded_item():get_name() == "default:torch" then
-					minetest.set_node(pos, {name = name .. "_burning"})
+					minetest.swap_node(pos, {name = name .. "_burning"})
+					minetest.registered_nodes[name .. "_burning"].on_construct(pos)
 					minetest.log("action", puncher:get_player_name() ..
 						" ignites " .. node.name .. " at " ..
 						minetest.pos_to_string(pos))
@@ -581,10 +601,12 @@ function tnt.register_tnt(def)
 				}
 			},
 			on_burn = function(pos)
-				minetest.set_node(pos, {name = name .. "_burning"})
+				minetest.swap_node(pos, {name = name .. "_burning"})
+				minetest.registered_nodes[name .. "_burning"].on_construct(pos)
 			end,
 			on_ignite = function(pos, igniter)
-				minetest.set_node(pos, {name = name .. "_burning"})
+				minetest.swap_node(pos, {name = name .. "_burning"})
+				minetest.registered_nodes[name .. "_burning"].on_construct(pos)
 			end,
 		})
 	--end
diff --git a/mods/vessels/init.lua b/mods/vessels/init.lua
index 688413f232eead8599cd11751ce8eeeb54b3306c..43d80922d49613972bfc842d05393c7514e52f32 100644
--- a/mods/vessels/init.lua
+++ b/mods/vessels/init.lua
@@ -94,7 +94,7 @@ minetest.register_craft({
 })
 
 minetest.register_node("vessels:glass_bottle", {
-	description = "Glass Bottle (empty)",
+	description = "Empty Glass Bottle",
 	drawtype = "plantlike",
 	tiles = {"vessels_glass_bottle.png"},
 	inventory_image = "vessels_glass_bottle.png",
@@ -120,7 +120,7 @@ minetest.register_craft( {
 })
 
 minetest.register_node("vessels:drinking_glass", {
-	description = "Drinking Glass (empty)",
+	description = "Empty Drinking Glass",
 	drawtype = "plantlike",
 	tiles = {"vessels_drinking_glass.png"},
 	inventory_image = "vessels_drinking_glass_inv.png",
@@ -146,7 +146,7 @@ minetest.register_craft( {
 })
 
 minetest.register_node("vessels:steel_bottle", {
-	description = "Heavy Steel Bottle (empty)",
+	description = "Empty Heavy Steel Bottle",
 	drawtype = "plantlike",
 	tiles = {"vessels_steel_bottle.png"},
 	inventory_image = "vessels_steel_bottle.png",
@@ -175,7 +175,7 @@ minetest.register_craft( {
 -- Glass and steel recycling
 
 minetest.register_craftitem("vessels:glass_fragments", {
-	description = "Pile of Glass Fragments",
+	description = "Glass Fragments",
 	inventory_image = "vessels_glass_fragments.png",
 })
 
diff --git a/mods/xpanes/init.lua b/mods/xpanes/init.lua
index 77278a5c5b654fc1ef435c3330c6ebf1b0225724..40fddba6740119e6acfdaa961f5228641c284478 100644
--- a/mods/xpanes/init.lua
+++ b/mods/xpanes/init.lua
@@ -159,7 +159,7 @@ xpanes.register_pane("pane", {
 })
 
 xpanes.register_pane("bar", {
-	description = "Iron bar",
+	description = "Iron Bar",
 	textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_bar_top.png"},
 	inventory_image = "xpanes_bar.png",
 	wield_image = "xpanes_bar.png",