diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 9975a8bd9293175930d298de1b13b9b95e089b76..8386e58940f1c015063f8ec0b9f512adc3f274f0 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -1780,7 +1780,7 @@ function _M:setupCommands()
 			print("===============")
 		end end,
 		[{"_g","ctrl"}] = function() if config.settings.cheat then
-			self:changeLevel(1, "orcs+steam-quarry")
+			self:changeLevel(game.level.level + 1)
 do return end
 			local o = game.zone:makeEntity(game.level, "object", {subtype="sling", random_object=true}, nil, true)
 			if o then
diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index 9e0158042ababe868f55d331588ad51921f03912..4fb65d46389da7c581b46d2640a231c6632a6dff 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -2461,3 +2461,6 @@ function _M:allowOnlineEvent()
 	if self.birth.grab_online_event_forbid then return end
 	return true
 end
+
+function _M:infiniteDungeonChallenge(zone, lev, data, id_layout_name, id_grids_name)
+end
diff --git a/game/modules/tome/data/zones/infinite-dungeon/zone.lua b/game/modules/tome/data/zones/infinite-dungeon/zone.lua
index 221f186d5f0292e9bc56f3c4b5201c07fadeded9..a5b3d48c6587261ba7487fa07112055d268cb45d 100644
--- a/game/modules/tome/data/zones/infinite-dungeon/zone.lua
+++ b/game/modules/tome/data/zones/infinite-dungeon/zone.lua
@@ -96,22 +96,19 @@ return {
 		},
 	},
 	alter_level_data = function(zone, lev, data)
-		if lev < 5 or rng.percent(30) then return end
+		if lev < 3 or rng.percent(30) then game.state:infiniteDungeonChallenge(zone, lev, data, "default", "default") return end
 
 		-- Randomize the size of the dungeon, increasing it slightly as the game progresses.
 		-- Also change enemy count to fit with the new size.		
 		local size = 50
 		local vx = math.ceil(math.random(0.75, 1.25) * size)
 		local vy = math.ceil(math.random(0.75, 1.25) * size)
-		local enemy_count = math.ceil((vx + vy) * 0.35)
-		data.width = vx
-		data.height = vy
-		data.generator.actor.nb_npc = {enemy_count-5, enemy_count+5}
 		
 		-- Takent from random zone generation, modified slightly for use here.
 		-- Grab a random layout for the floor.		
 		local layouts = {
 			{
+				id_layout_name = "forest",
 				class = "engine.generator.map.Forest",
 				edge_entrances = rng.table{{2,8}, {4,6}, {6,4}, {8,2}},
 				zoom = rng.range(2,6),
@@ -120,11 +117,13 @@ return {
 				noise = "fbm_perlin",
 			},
 			{
+				id_layout_name = "cavern",
 				class = "engine.generator.map.Cavern",
 				zoom = math.random(10, 20),
 				min_floor = math.floor(rng.range(vx * vy * 0.4 / 2, vx * vy * 0.4)),
 			},
 			{
+				id_layout_name = "default",
 				class = "engine.generator.map.Roomer",
 				nb_rooms = 14,
 				rooms = {"random_room", {"pit",3}, {"greater_vault",7}},
@@ -132,10 +131,12 @@ return {
 				lite_room_chance = 50,
 			},
 			{
+				id_layout_name = "maze",
 				class = "engine.generator.map.Maze",
 				widen_w = math.random(1,7), widen_h = math.random(1,7),
 			},
 			{
+				id_layout_name = "town",
 				class = "engine.generator.map.Town",
 				building_chance = math.random(50,90),
 				max_building_w = math.random(5,11), max_building_h = math.random(5,11),
@@ -144,41 +145,53 @@ return {
 				rooms = {{"greater_vault",2}},
 			},
 			{
+				id_layout_name = "building",
 				class = "engine.generator.map.Building",
 				lite_room_chance = rng.range(0, 100),
 				max_block_w = rng.range(7, 20), max_block_h = rng.range(7, 20),
 				max_building_w = rng.range(2, 8), max_building_h = rng.range(2, 8),
 			},
 			{
+				id_layout_name = "octopus",
 				class = "engine.generator.map.Octopus",
 				main_radius = {0.3, 0.4},
 				arms_radius = {0.1, 0.2},
 				arms_range = {0.7, 0.8},
 				nb_rooms = {3, 9},
 			},
+			{
+				id_layout_name = "hexa",
+				class = "engine.generator.map.Hexacle",
+				segment_wide_chance = 70,
+				nb_segments = 8,
+				nb_layers = 6,
+				segment_miss_percent = 10,
+				force_square_size = true,
+			},
 		}
 		self:triggerHook{"InfiniteDungeon:getLayouts", layouts=layouts}
 		
-		data.generator.map = rng.table(layouts)
+		local layout = rng.table(layouts)
+		data.generator.map = layout
 		
 		local vgrids = rng.table{
-			{floor="GRASS", wall="TREE", door="GRASS_ROCK", down="GRASS_DOWN2"}, -- tree
-			{floor="FLOOR", wall="WALL", door="DOOR", down="DOWN"}, -- wall
-			{floor="UNDERGROUND_FLOOR", wall="UNDERGROUND_TREE", door="UNDERGROUND_ROCK", down="UNDERGROUND_LADDER_DOWN"}, -- underground
-			{floor="CRYSTAL_FLOOR", wall={"CRYSTAL_WALL","CRYSTAL_WALL2","CRYSTAL_WALL3","CRYSTAL_WALL4","CRYSTAL_WALL5","CRYSTAL_WALL6","CRYSTAL_WALL7","CRYSTAL_WALL8","CRYSTAL_WALL9","CRYSTAL_WALL10","CRYSTAL_WALL11","CRYSTAL_WALL12","CRYSTAL_WALL13","CRYSTAL_WALL14","CRYSTAL_WALL15","CRYSTAL_WALL16","CRYSTAL_WALL17","CRYSTAL_WALL18","CRYSTAL_WALL19","CRYSTAL_WALL20",}, door="CRYSTAL_ROCK", down="CRYSTAL_LADDER_DOWN"}, -- crystals
-			{floor="UNDERGROUND_SAND", wall="SANDWALL", door="UNDERGROUND_SAND", down="SAND_LADDER_DOWN"}, -- sand
-			{floor="SAND", wall="PALMTREE", door="DESERT_ROCK", down="SAND_DOWN2"}, -- desert
-			{floor="SLIME_FLOOR", wall="SLIME_WALL", door="SLIME_DOOR", down="SLIME_DOWN"}, -- slime
-			{floor="JUNGLE_GRASS", wall="JUNGLE_TREE", door="JUNGLE_ROCK", down="JUNGLE_GRASS_DOWN2"}, -- jungle
-			{floor="CAVEFLOOR", wall="CAVEWALL", door="CAVE_ROCK", down="CAVE_LADDER_DOWN"}, -- cave
-			{floor="BURNT_GROUND", wall="BURNT_TREE", door="BURNT_GROUND", down="BURNT_DOWN6"}, -- burntland
-			{floor="ROCKY_GROUND", wall="MOUNTAIN_WALL", door="ROCKY_GROUND", down="ROCKY_DOWN2"}, -- mountain
-			{floor="ROCKY_GROUND", wall="ROCKY_SNOWY_TREE", door="ROCKY_GROUND", down="ROCKY_DOWN2"}, -- mountain_forest
-			{floor="SNOWY_GRASS_2", wall="SNOWY_TREE_2", door="SNOWY_GRASS_2", down="snowy_DOWN2"}, -- snowy_forest
-			{floor="VOID", wall="SPACETIME_RIFT2", door="VOID", down="RIFT2"}, -- temporal_void
-			{floor="WATER_FLOOR_FAKE", wall="WATER_WALL_FAKE", door="WATER_DOOR_FAKE", down="WATER_DOWN_FAKE"}, -- water
-			{floor="LAVA_FLOOR_FAKE", wall="LAVA_WALL_FAKE", door="LAVA_FLOOR_FAKE", down="LAVA_DOWN_FAKE"}, -- lava
-			{floor="AUTUMN_GRASS", wall="AUTUMN_TREE", door="AUTUMN_GRASS", down="AUTUMN_GRASS_DOWN2"}, -- autumn_forest
+			{id_grids_name="tree", floor="GRASS", wall="TREE", door="GRASS_ROCK", down="GRASS_DOWN2"},
+			{id_grids_name="wall", floor="FLOOR", wall="WALL", door="DOOR", down="DOWN"},
+			{id_grids_name="underground", floor="UNDERGROUND_FLOOR", wall="UNDERGROUND_TREE", door="UNDERGROUND_ROCK", down="UNDERGROUND_LADDER_DOWN"},
+			{id_grids_name="crystals", floor="CRYSTAL_FLOOR", wall={"CRYSTAL_WALL","CRYSTAL_WALL2","CRYSTAL_WALL3","CRYSTAL_WALL4","CRYSTAL_WALL5","CRYSTAL_WALL6","CRYSTAL_WALL7","CRYSTAL_WALL8","CRYSTAL_WALL9","CRYSTAL_WALL10","CRYSTAL_WALL11","CRYSTAL_WALL12","CRYSTAL_WALL13","CRYSTAL_WALL14","CRYSTAL_WALL15","CRYSTAL_WALL16","CRYSTAL_WALL17","CRYSTAL_WALL18","CRYSTAL_WALL19","CRYSTAL_WALL20",}, door="CRYSTAL_ROCK", down="CRYSTAL_LADDER_DOWN"},
+			{id_grids_name="sand", floor="UNDERGROUND_SAND", wall="SANDWALL", door="UNDERGROUND_SAND", down="SAND_LADDER_DOWN"},
+			{id_grids_name="desert", floor="SAND", wall="PALMTREE", door="DESERT_ROCK", down="SAND_DOWN2"},
+			{id_grids_name="slime", floor="SLIME_FLOOR", wall="SLIME_WALL", door="SLIME_DOOR", down="SLIME_DOWN"},
+			{id_grids_name="jungle", floor="JUNGLE_GRASS", wall="JUNGLE_TREE", door="JUNGLE_ROCK", down="JUNGLE_GRASS_DOWN2"},
+			{id_grids_name="cave", floor="CAVEFLOOR", wall="CAVEWALL", door="CAVE_ROCK", down="CAVE_LADDER_DOWN"},
+			{id_grids_name="burntland", floor="BURNT_GROUND", wall="BURNT_TREE", door="BURNT_GROUND", down="BURNT_DOWN6"},
+			{id_grids_name="mountain", floor="ROCKY_GROUND", wall="MOUNTAIN_WALL", door="ROCKY_GROUND", down="ROCKY_DOWN2"},
+			{id_grids_name="mountain_forest", floor="ROCKY_GROUND", wall="ROCKY_SNOWY_TREE", door="ROCKY_GROUND", down="ROCKY_DOWN2"},
+			{id_grids_name="snowy_forest", floor="SNOWY_GRASS_2", wall="SNOWY_TREE_2", door="SNOWY_GRASS_2", down="snowy_DOWN2"},
+			{id_grids_name="temporal_void", floor="VOID", wall="SPACETIME_RIFT2", door="VOID", down="RIFT2"},
+			{id_grids_name="water", floor="WATER_FLOOR_FAKE", wall="WATER_WALL_FAKE", door="WATER_DOOR_FAKE", down="WATER_DOWN_FAKE"},
+			{id_grids_name="lava", floor="LAVA_FLOOR_FAKE", wall="LAVA_WALL_FAKE", door="LAVA_FLOOR_FAKE", down="LAVA_DOWN_FAKE"},
+			{id_grids_name="autumn_forest", floor="AUTUMN_GRASS", wall="AUTUMN_TREE", door="AUTUMN_GRASS", down="AUTUMN_GRASS_DOWN2"},
 		}
 		self:triggerHook{"InfiniteDungeon:getGrids", grids=vgrids}
 		
@@ -196,6 +209,19 @@ return {
 		data.generator.map.down = vgrids.down
 		data.generator.map.door = vgrids.door
 		data.generator.map["'"] = vgrids.door
+
+		data.width = vx
+		data.height = vy
+
+		if layout.force_square_size then
+			data.width = math.max(vx, vy)
+			data.height = data.width
+		end
+
+		local enemy_count = math.ceil((vx + vy) * 0.35)
+		data.generator.actor.nb_npc = {enemy_count-5, enemy_count+5}
+
+		game.state:infiniteDungeonChallenge(zone, lev, data, data.generator.map.id_layout_name, vgrids.id_grids_name)
 	end,
 	post_process = function(level)
 		-- Provide some achievements