diff --git a/game/engine/generator/map/Maze.lua b/game/engine/generator/map/Maze.lua
index e2df15fa40d6dd3abee7bc0e4e4d5b440319a763..778e1814435fe151cd3969a17bafe0dcb455f6a1 100644
--- a/game/engine/generator/map/Maze.lua
+++ b/game/engine/generator/map/Maze.lua
@@ -5,6 +5,7 @@ module(..., package.seeall, class.inherit(engine.Generator))
 
 function _M:init(zone, map, grid_list, data)
 	engine.Generator.init(self, zone, map)
+	self.data = data
 	self.floor = grid_list[data.floor]
 	self.wall = grid_list[data.wall]
 	self.up = grid_list[data.up]
@@ -63,7 +64,7 @@ function _M:generate(lev, old_lev)
 	local ux, uy = 1, 1
 	local dx, dy = math.floor(self.map.w/2)*2-1-2*(1-math.mod(self.map.w,2)), math.floor(self.map.h/2)*2-1-2*(1-math.mod(self.map.h,2))
 	self.map(ux, uy, Map.TERRAIN, self.up)
-	if lev < self.zone.max_level then
+	if lev < self.zone.max_level or self.data.force_last_stair then
 		self.map(dx, dy, Map.TERRAIN, self.down)
 	end
 	if lev > old_lev then
diff --git a/game/engine/generator/map/Roomer.lua b/game/engine/generator/map/Roomer.lua
index f3653f16df541379af8332662dafcacebc4d263c..98e8e0faaed23bc00a086f4b7c4c417352857831 100644
--- a/game/engine/generator/map/Roomer.lua
+++ b/game/engine/generator/map/Roomer.lua
@@ -240,7 +240,7 @@ function _M:generate(lev, old_lev)
 
 	-- Put down stairs
 	local dx, dy
-	if lev < self.zone.max_level then
+	if lev < self.zone.max_level or self.data.force_last_stair then
 		while true do
 			dx, dy = rng.range(1, self.map.w - 1), rng.range(1, self.map.h - 1)
 			if not self.map:checkEntity(dx, dy, Map.TERRAIN, "block_move") and not self.room_map[dx][dy].special then
diff --git a/game/modules/tome/data/gfx/terrain/granite_wall_lichen.png b/game/modules/tome/data/gfx/terrain/granite_wall_lichen.png
new file mode 100644
index 0000000000000000000000000000000000000000..113ad44c7d4a7c6da18bf3025987805c9bde7d5f
Binary files /dev/null and b/game/modules/tome/data/gfx/terrain/granite_wall_lichen.png differ
diff --git a/game/modules/tome/data/gfx/terrain/maze_floor.png b/game/modules/tome/data/gfx/terrain/maze_floor.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a5fa937057cb880268526e8be3c9cbbd1fe1b6c
Binary files /dev/null and b/game/modules/tome/data/gfx/terrain/maze_floor.png differ
diff --git a/game/modules/tome/data/gfx/terrain/maze_teleport.png b/game/modules/tome/data/gfx/terrain/maze_teleport.png
new file mode 100644
index 0000000000000000000000000000000000000000..318dcd74fb72687bfc75b5151b10d12d67fe62cb
Binary files /dev/null and b/game/modules/tome/data/gfx/terrain/maze_teleport.png differ
diff --git a/game/modules/tome/data/zones/maze/grids.lua b/game/modules/tome/data/zones/maze/grids.lua
new file mode 100644
index 0000000000000000000000000000000000000000..840f331d9ecca0a59ebe048ebb04d7c5a6d72701
--- /dev/null
+++ b/game/modules/tome/data/zones/maze/grids.lua
@@ -0,0 +1,22 @@
+load("/data/general/grids/basic.lua")
+
+newEntity{
+	define_as = "QUICK_EXIT",
+	name = "teleporting circle to the surface", image = "terrain/maze_teleport.png",
+	display = '>', color_r=255, color_g=0, color_b=255,
+	change_level = 1, change_zone = "wilderness",
+}
+
+newEntity{
+	define_as = "MAZE_FLOOR",
+	name = "floor", image = "terrain/maze_floor.png",
+	display = '.', color_r=255, color_g=255, color_b=255,
+}
+
+newEntity{
+	define_as = "MAZE_WALL",
+	name = "wall", image = "terrain/granite_wall_lichen.png",
+	display = '#', color_r=255, color_g=255, color_b=255,
+	block_move = true,
+	block_sight = true,
+}
diff --git a/game/modules/tome/data/zones/maze/npcs.lua b/game/modules/tome/data/zones/maze/npcs.lua
new file mode 100644
index 0000000000000000000000000000000000000000..b107ab1ce4b00b272f8eafa6b61175846c22cf6a
--- /dev/null
+++ b/game/modules/tome/data/zones/maze/npcs.lua
@@ -0,0 +1,31 @@
+load("/data/general/npcs/vermin.lua")
+load("/data/general/npcs/wolf.lua")
+load("/data/general/npcs/troll.lua")
+load("/data/general/npcs/snake.lua")
+
+local Talents = require("engine.interface.ActorTalents")
+
+-- The boss of trollshaws, no "rarity" field means it will not be randomly generated
+newEntity{ define_as = "TROLL_BILL",
+	type = "giant", subtype = "troll", unique = true,
+	name = "Bill the Stone Troll",
+	display = "T", color=colors.VIOLET,
+	desc = [[Big, brawny, powerful and with a taste for hobbit. He has friends called Bert and Tom.
+	He is wielding a small tree trunk and towering toward you.
+	He should have turned to stone long ago, how could he still walk?!]],
+	level_range = {7, 10}, exp_worth = 2,
+	max_life = 250, life_rating = 17, fixed_rating = true,
+	max_stamina = 85,
+	stats = { str=25, dex=10, cun=8, mag=10, con=20 },
+
+	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
+	equipment = resolvers.equip{ {type="weapon", subtype="greatmaul", defined="GREATMAUL_BILL_TRUNK"}, },
+	drops = resolvers.drops{chance=100, nb=3, {ego_chance=100} },
+
+	talents = resolvers.talents{
+		[Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1,
+	},
+
+	autolevel = "warrior",
+	ai = "dumb_talented_simple", ai_state = { talent_in=4, },
+}
diff --git a/game/modules/tome/data/zones/maze/objects.lua b/game/modules/tome/data/zones/maze/objects.lua
new file mode 100644
index 0000000000000000000000000000000000000000..8db31735bbd23c29e5c8d4c2c265962ac7c71426
--- /dev/null
+++ b/game/modules/tome/data/zones/maze/objects.lua
@@ -0,0 +1,20 @@
+load("/data/general/objects/objects.lua")
+
+-- Artifact, droped (and used!) by Bill the Stone Troll
+
+newEntity{ base = "BASE_GREATMAUL",
+	define_as = "GREATMAUL_BILL_TRUNK",
+	name = "Bill's Tree Trunk", unique=true,
+	require = { stat = { str=25 }, },
+	cost = 5,
+	combat = {
+		dam = 30,
+		apr = 7,
+		physcrit = 1.5,
+		dammod = {str=1.3},
+		damrange = 1.7,
+	},
+
+	wielder = {
+	},
+}
diff --git a/game/modules/tome/data/zones/maze/zone.lua b/game/modules/tome/data/zones/maze/zone.lua
new file mode 100644
index 0000000000000000000000000000000000000000..455060db68357419eb5d71c31fa8c6481411e790
--- /dev/null
+++ b/game/modules/tome/data/zones/maze/zone.lua
@@ -0,0 +1,46 @@
+return {
+	name = "The Maze",
+	level_range = {7, 18},
+	level_scheme = "player",
+	max_level = 7,
+	width = 40, height = 40,
+--	all_remembered = true,
+--	all_lited = true,
+--	persistant = true,
+	generator =  {
+		map = {
+			class = "engine.generator.map.Maze",
+			up = "UP",
+			down = "DOWN",
+			wall = "MAZE_WALL",
+			floor = "MAZE_FLOOR",
+		},
+		actor = {
+			class = "engine.generator.actor.Random",
+			nb_npc = {20, 30},
+			ood = {chance=5, range={1, 10}},
+			adjust_level = {-1, 2},
+			guardian = "TROLL_BILL",
+		},
+		object = {
+			class = "engine.generator.object.Random",
+			nb_object = {4, 6},
+			ood = {chance=5, range={1, 10}},
+			filters = { {type="potion" }, {type="potion" }, {type="potion" }, {type="scroll" }, {}, {} }
+		},
+	},
+	levels =
+	{
+		[1] = {
+			generator = { map = {
+				up = "UP_WILDERNESS",
+			}, },
+		},
+		[7] = {
+			generator = { map = {
+				force_last_stair = true,
+				down = "QUICK_EXIT",
+			}, },
+		},
+	},
+}
diff --git a/ideas/zones.ods b/ideas/zones.ods
index 96ed0b2ff9e86ea42159edb92c196bd190de3c43..dd93e8bfa647bba439392bab9a5fd931047c57da 100644
Binary files a/ideas/zones.ods and b/ideas/zones.ods differ