diff --git a/game/engine/Generator.lua b/game/engine/Generator.lua
index 5a79fcd6319c01a59da0f5831b497d49747be87d..f8fe51028ecbc778e0e0b6cc498bc3ce82e834ae 100644
--- a/game/engine/Generator.lua
+++ b/game/engine/Generator.lua
@@ -20,10 +20,11 @@
 require "engine.class"
 module(..., package.seeall, class.make)
 
-function _M:init(zone, map, level)
+function _M:init(zone, map, level, spots)
 	self.zone = zone
 	self.map = map
 	self.level = level
+	self.spots = spots
 
 	-- Setup the map's room-map
 	if not map.room_map then
diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua
index 6c0ac30947c6e921637a7a34fc669132f86ad566..779433551295036dc8874f138653b8ac5ee78dbd 100644
--- a/game/engine/Zone.lua
+++ b/game/engine/Zone.lua
@@ -20,6 +20,7 @@
 require "engine.class"
 local Savefile = require "engine.Savefile"
 local Map = require "engine.Map"
+local Astar = require "engine.Astar"
 
 --- Defines a zone: a set of levels, with depth, nps, objects, level generator, ...
 module(..., package.seeall, class.make)
@@ -450,7 +451,7 @@ function _M:newLevel(level_data, lev, old_lev, game)
 
 	level.ups = {{x=ux, y=uy}}
 	level.downs = {{x=dx, y=dy}}
-	level.spots = spots
+	level.spots = spots or {}
 
 	-- Generate objects
 	if level_data.generator.object then
@@ -482,5 +483,29 @@ function _M:newLevel(level_data, lev, old_lev, game)
 	-- Delete the room_map, now useless
 	map.room_map = nil
 
+	-- Check for connectivity from entrance to exit
+	local a = Astar.new(map, game:getPlayer())
+	if ux and uy and dx and dy and not a:calc(ux, uy, dx, dy) then
+		print("Level unconnected, no way from entrance to exit")
+		level:removed()
+		return self:newLevel(level_data, lev, old_lev, game)
+	end
+	for i = 1, #spots do
+		local spot = spots[i]
+		if spot.check_connectivity then
+			local cx, cy
+			if type(spot.check_connectivity) == "string" and spot.check_connectivity == "entrance" then cx, cy = ux, uy
+			elseif type(spot.check_connectivity) == "string" and spot.check_connectivity == "exit" then cx, cy = dx, dy
+			else cx, cy = spot.check_connectivity.x, spot.check_connectivity.y
+			end
+
+			if not a:calc(spot.x, spot.y, cx, cy) then
+				print("Level unconnected, no way from", spot.x, spot.y, "to", cx, cy)
+				level:removed()
+				return self:newLevel(level_data, lev, old_lev, game)
+			end
+		end
+	end
+
 	return level
 end
diff --git a/game/engine/generator/actor/Random.lua b/game/engine/generator/actor/Random.lua
index 6caa279d259ec829a6315936f15d003cd05ca9e3..b31e1e177c02330f18f227639681b429ae5a2a1f 100644
--- a/game/engine/generator/actor/Random.lua
+++ b/game/engine/generator/actor/Random.lua
@@ -22,8 +22,8 @@ local Map = require "engine.Map"
 require "engine.Generator"
 module(..., package.seeall, class.inherit(engine.Generator))
 
-function _M:init(zone, map, level)
-	engine.Generator.init(self, zone, map, level)
+function _M:init(zone, map, level, spots)
+	engine.Generator.init(self, zone, map, level, spots)
 	local data = level.data.generator.actor
 
 	if data.adjust_level then
@@ -52,6 +52,7 @@ function _M:generate()
 				tries = tries + 1
 			end
 			if tries < 100 then
+				self.spots[#self.spots+1] = {x=x, y=y, gardian=true, check_connectivity="entrance"}
 				self.zone:addEntity(self.level, m, "actor", x, y)
 				print("Guardian allocated: ", self.guardian, m.uid, m.name)
 			end
diff --git a/game/engine/generator/map/Forest.lua b/game/engine/generator/map/Forest.lua
new file mode 100644
index 0000000000000000000000000000000000000000..619bb6df75b207430adf13056fea237354260c96
--- /dev/null
+++ b/game/engine/generator/map/Forest.lua
@@ -0,0 +1,143 @@
+-- TE4 - T-Engine 4
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+require "engine.class"
+local Map = require "engine.Map"
+require "engine.Generator"
+module(..., package.seeall, class.inherit(engine.Generator))
+
+function _M:init(zone, map, level, data)
+	engine.Generator.init(self, zone, map, level)
+	self.data = data
+	self.grid_list = self.zone.grid_list
+	self.noise = data.noise or "fbm_perlin"
+	self.zoom = data.zoom or 5
+	self.max_percent = data.max_percent or 80
+	self.sqrt_percent = data.sqrt_percent or 30
+	self.hurst = data.hurst or nil
+	self.lacunarity = data.lacunarity or nil
+	self.octave = data.octave or 4
+end
+
+function _M:resolve(c)
+	local res = self.data[c]
+	if type(res) == "function" then
+		return res()
+	elseif type(res) == "table" then
+		return res[rng.range(1, #res)]
+	else
+		return res
+	end
+end
+
+function _M:generate(lev, old_lev)
+	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
+		self.map(i, j, Map.TERRAIN, self.grid_list[self.floor])
+	end end
+
+	-- make the noise
+	local noise = core.noise.new(2, self.hurst, self.lacunarity)
+	for i = 1, self.map.w do
+		for j = 1, self.map.h do
+			local v = math.floor((noise[self.noise](noise, self.zoom * i / self.map.w, self.zoom * j / self.map.h, self.octave) / 2 + 0.5) * self.max_percent)
+			if (v >= self.sqrt_percent and rng.percent(v)) or (v < self.sqrt_percent and rng.percent(math.sqrt(v))) then
+				self.map(i-1, j-1, Map.TERRAIN, self.grid_list[self:resolve("wall")])
+			else
+				self.map(i-1, j-1, Map.TERRAIN, self.grid_list[self:resolve("floor")])
+			end
+		end
+	end
+
+	local ux, uy, dx, dy, spots
+	if self.data.edge_entrances then
+		ux, uy, dx, dy, spots = self:makeStairsSides(lev, old_lev, self.data.edge_entrances, spots)
+	else
+		ux, uy, dx, dy, spots = self:makeStairsInside(lev, old_lev, spots)
+	end
+
+	return ux, uy, dx, dy, spots
+end
+
+--- Create the stairs inside the level
+function _M:makeStairsInside(lev, old_lev, spots)
+	-- Put down stairs
+	local dx, dy
+	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.map.room_map[dx][dy].special then
+				self.map(dx, dy, Map.TERRAIN, self.grid_list[self:resolve("down")])
+				self.map.room_map[dx][dy].special = "exit"
+				break
+			end
+		end
+	end
+
+	-- Put up stairs
+	local ux, uy
+	while true do
+		ux, uy = rng.range(1, self.map.w - 1), rng.range(1, self.map.h - 1)
+		if not self.map:checkEntity(ux, uy, Map.TERRAIN, "block_move") and not self.map.room_map[ux][uy].special then
+			self.map(ux, uy, Map.TERRAIN, self.grid_list[self:resolve("up")])
+			self.map.room_map[ux][uy].special = "exit"
+			break
+		end
+	end
+
+	return ux, uy, dx, dy, spots
+end
+
+--- Create the stairs on the sides
+function _M:makeStairsSides(lev, old_lev, sides, spots)
+	-- Put down stairs
+	local dx, dy
+	if lev < self.zone.max_level or self.data.force_last_stair then
+		while true do
+			if     sides[2] == 4 then dx, dy = 0, rng.range(0, self.map.h - 1)
+			elseif sides[2] == 6 then dx, dy = self.map.w - 1, rng.range(0, self.map.h - 1)
+			elseif sides[2] == 8 then dx, dy = rng.range(0, self.map.w - 1), 0
+			elseif sides[2] == 2 then dx, dy = rng.range(0, self.map.w - 1), self.map.h - 1
+			end
+
+			if not self.map.room_map[dx][dy].special then
+				self.map(dx, dy, Map.TERRAIN, self.grid_list[self:resolve("down")])
+				self.map.room_map[dx][dy].special = "exit"
+				break
+			end
+		end
+	end
+
+	-- Put up stairs
+	local ux, uy
+	while true do
+		if     sides[1] == 4 then ux, uy = 0, rng.range(0, self.map.h - 1)
+		elseif sides[1] == 6 then ux, uy = self.map.w - 1, rng.range(0, self.map.h - 1)
+		elseif sides[1] == 8 then ux, uy = rng.range(0, self.map.w - 1), 0
+		elseif sides[1] == 2 then ux, uy = rng.range(0, self.map.w - 1), self.map.h - 1
+		end
+
+		if not self.map.room_map[ux][uy].special then
+			self.map(ux, uy, Map.TERRAIN, self.grid_list[self:resolve("up")])
+			self.map.room_map[ux][uy].special = "exit"
+			break
+		end
+	end
+
+	return ux, uy, dx, dy, spots
+end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 8c1601c3622c75b51d85cf844582d99ab8578b6e..89417a78aab6cc186ad02ed9c0f1d5e460524c75 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -503,8 +503,7 @@ function _M:setupCommands()
 
 	self.key:addCommands{
 		[{"_d","ctrl"}] = function()
-			if config.settings.tome.cheat then self:changeLevel(3, "moria") end
---			if config.settings.tome.cheat then self:changeLevel(1, "wilderness-arda-fareast") end
+			if config.settings.tome.cheat then self:changeLevel(1, "test") end
 		end,
 	}
 	self.key:addBinds
diff --git a/game/modules/tome/data/zones/test/grids.lua b/game/modules/tome/data/zones/test/grids.lua
new file mode 100644
index 0000000000000000000000000000000000000000..649dff9ed66f0d608b12a4bb999101dcdd42386a
--- /dev/null
+++ b/game/modules/tome/data/zones/test/grids.lua
@@ -0,0 +1,21 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+load("/data/general/grids/basic.lua")
+load("/data/general/grids/forest.lua")
diff --git a/game/modules/tome/data/zones/test/npcs.lua b/game/modules/tome/data/zones/test/npcs.lua
new file mode 100644
index 0000000000000000000000000000000000000000..66f585828f4fa1d3c0f48ffcdacc530ef0ff4f46
--- /dev/null
+++ b/game/modules/tome/data/zones/test/npcs.lua
@@ -0,0 +1,81 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+load("/data/general/npcs/orc.lua")
+load("/data/general/npcs/troll.lua")
+
+local Talents = require("engine.interface.ActorTalents")
+
+-- The boss of Moria, no "rarity" field means it will not be randomly generated
+newEntity{ define_as = "GOLBUG",
+	type = "humanoid", subtype = "orc", unique = true,
+	name = "Golbug the Destroyer",
+	display = "o", color=colors.VIOLET,
+	desc = [[A huge and muscular orc of unknown breed. He looks both menacing and cunning...]],
+	level_range = {28, 45}, exp_worth = 2,
+	max_life = 350, life_rating = 16, fixed_rating = true,
+	max_stamina = 245,
+	rank = 4,
+	size_category = 3,
+	stats = { str=22, dex=19, cun=34, mag=10, con=16 },
+
+	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1, NECK=1, HEAD=1, },
+	equipment = resolvers.equip{
+		{type="weapon", subtype="mace", ego_chance=100, autoreq=true},
+		{type="armor", subtype="shield", ego_chance=100, autoreq=true},
+		{type="armor", subtype="head", autoreq=true},
+		{type="armor", subtype="massive", ego_chance=50, autoreq=true},
+	},
+	resolvers.drops{chance=100, nb=5, {ego_chance=100} },
+	resolvers.drops{chance=100, nb=1, {type="jewelry", subtype="orb", defined="ORB_MANY_WAYS"} },
+
+	stun_immune = 1,
+	see_invisible = 5,
+
+	resolvers.talents{
+		[Talents.T_HEAVY_ARMOUR_TRAINING]=1,
+		[Talents.T_MASSIVE_ARMOUR_TRAINING]=3,
+		[Talents.T_WEAPON_COMBAT]=6,
+		[Talents.T_MACE_MASTERY]=6,
+		[Talents.T_SHIELD_PUMMEL]=4,
+		[Talents.T_RUSH]=4,
+		[Talents.T_RIPOSTE]=4,
+		[Talents.T_BLINDING_SPEED]=4,
+		[Talents.T_OVERPOWER]=3,
+		[Talents.T_ASSAULT]=3,
+		[Talents.T_SHIELD_WALL]=3,
+		[Talents.T_SHIELD_EXPERTISE]=2,
+
+		[Talents.T_BELLOWING_ROAR]=3,
+		[Talents.T_WING_BUFFET]=2,
+		[Talents.T_FIRE_BREATH]=4,
+
+		[Talents.T_ICE_CLAW]=3,
+		[Talents.T_ICY_SKIN]=4,
+		[Talents.T_ICE_BREATH]=4,
+	},
+
+	autolevel = "warrior",
+	ai = "dumb_talented_simple", ai_state = { talent_in=2, },
+
+	on_die = function(self, who)
+--		who:resolveSource():grantQuest("tol-falas")
+--		who:resolveSource():setQuestStatus("tol-falas", engine.Quest.DONE)
+	end,
+}
diff --git a/game/modules/tome/data/zones/test/objects.lua b/game/modules/tome/data/zones/test/objects.lua
new file mode 100644
index 0000000000000000000000000000000000000000..b5facd63f5b34e95c1aab209db0f312a8aef3e91
--- /dev/null
+++ b/game/modules/tome/data/zones/test/objects.lua
@@ -0,0 +1,20 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+load("/data/general/objects/objects.lua")
diff --git a/game/modules/tome/data/zones/test/traps.lua b/game/modules/tome/data/zones/test/traps.lua
new file mode 100644
index 0000000000000000000000000000000000000000..e5201481de6fe45b57f3ad3c6dab9523fa929074
--- /dev/null
+++ b/game/modules/tome/data/zones/test/traps.lua
@@ -0,0 +1,21 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+load("/data/general/traps/elemental.lua")
+load("/data/general/traps/alarm.lua")
diff --git a/game/modules/tome/data/zones/test/zone.lua b/game/modules/tome/data/zones/test/zone.lua
new file mode 100644
index 0000000000000000000000000000000000000000..4d8f0862585fe274e6d89daa8a5103f24c071913
--- /dev/null
+++ b/game/modules/tome/data/zones/test/zone.lua
@@ -0,0 +1,63 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+return {
+	name = "Mines of Moria",
+	level_range = {20, 30},
+	level_scheme = "player",
+	max_level = 4,
+	decay = {300, 800},
+	actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end,
+	width = 50, height = 50,
+--	all_remembered = true,
+	all_lited = true,
+--	persistant = "zone",
+	generator =  {
+		map = {
+			class = "engine.generator.map.Forest",
+			edge_entrances = {4,6},
+			floor = "GRASS",
+			wall = "TREE",
+			up = "UP",
+			down = "DOWN",
+		},
+--[[
+		actor = {
+			class = "engine.generator.actor.Random",
+			nb_npc = {40, 50},
+		},
+		object = {
+			class = "engine.generator.object.Random",
+			nb_object = {12, 16},
+		},
+		trap = {
+			class = "engine.generator.trap.Random",
+			nb_trap = {20, 30},
+		},
+]]
+	},
+	levels =
+	{
+		[1] = {
+			generator = { map = {
+				up = "UP_WILDERNESS",
+			}, },
+		},
+	},
+}
diff --git a/game/modules/tome/data/zones/trollshaws/zone.lua b/game/modules/tome/data/zones/trollshaws/zone.lua
index 2fe579ba9dd938218e823a6ea2330f2b7b8f6282..93d440940984a80d38e6413d3db64258f4c4c8a0 100644
--- a/game/modules/tome/data/zones/trollshaws/zone.lua
+++ b/game/modules/tome/data/zones/trollshaws/zone.lua
@@ -31,15 +31,14 @@ return {
 	ambiant_music = "elven_town.ogg",
 	generator =  {
 		map = {
-			class = "engine.generator.map.Roomer",
-			nb_rooms = 10,
+			class = "engine.generator.map.Forest",
 			edge_entrances = {4,6},
-			rooms = {"forest_clearing"},
-			['.'] = function() if rng.chance(20) then return "FLOWER" else return "GRASS" end end,
-			['#'] = "TREE",
+			zoom = 5,
+			noise = "fbm_perlin",
+			floor = function() if rng.chance(20) then return "FLOWER" else return "GRASS" end end,,
+			wall = "TREE",
 			up = "UP",
 			down = "DOWN",
-			door = "GRASS",
 		},
 		actor = {
 			class = "engine.generator.actor.Random",
diff --git a/src/noise.c b/src/noise.c
index fbaa719f0ede78f30ffb951ebc8fc32ac540d9d0..ec58dc3865698809fb56ed3c385428fde8c5359b 100644
--- a/src/noise.c
+++ b/src/noise.c
@@ -73,10 +73,10 @@ static int noise_simplex(lua_State *L)
 static int noise_fbm_simplex(lua_State *L)
 {
 	noise_t *n = (noise_t*)auxiliar_checkclass(L, "noise{core}", 1);
-	float octave = luaL_checknumber(L, 2);
 	float p[4];
 	int i;
-	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 3 + i);
+	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 2 + i);
+	float octave = luaL_checknumber(L, 2 + i);
 
 	lua_pushnumber(L, TCOD_noise_fbm_simplex(n->noise, p, octave));
 	return 1;
@@ -85,10 +85,10 @@ static int noise_fbm_simplex(lua_State *L)
 static int noise_turbulence_simplex(lua_State *L)
 {
 	noise_t *n = (noise_t*)auxiliar_checkclass(L, "noise{core}", 1);
-	float octave = luaL_checknumber(L, 2);
 	float p[4];
 	int i;
-	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 3 + i);
+	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 2 + i);
+	float octave = luaL_checknumber(L, 2 + i);
 
 	lua_pushnumber(L, TCOD_noise_turbulence_simplex(n->noise, p, octave));
 	return 1;
@@ -108,10 +108,10 @@ static int noise_perlin(lua_State *L)
 static int noise_fbm_perlin(lua_State *L)
 {
 	noise_t *n = (noise_t*)auxiliar_checkclass(L, "noise{core}", 1);
-	float octave = luaL_checknumber(L, 2);
 	float p[4];
 	int i;
-	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 3 + i);
+	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 2 + i);
+	float octave = luaL_checknumber(L, 2 + i);
 
 	lua_pushnumber(L, TCOD_noise_fbm_perlin(n->noise, p, octave));
 	return 1;
@@ -120,10 +120,10 @@ static int noise_fbm_perlin(lua_State *L)
 static int noise_turbulence_perlin(lua_State *L)
 {
 	noise_t *n = (noise_t*)auxiliar_checkclass(L, "noise{core}", 1);
-	float octave = luaL_checknumber(L, 2);
 	float p[4];
 	int i;
-	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 3 + i);
+	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 2 + i);
+	float octave = luaL_checknumber(L, 2 + i);
 
 	lua_pushnumber(L, TCOD_noise_turbulence_perlin(n->noise, p, octave));
 	return 1;
@@ -143,10 +143,10 @@ static int noise_wavelet(lua_State *L)
 static int noise_fbm_wavelet(lua_State *L)
 {
 	noise_t *n = (noise_t*)auxiliar_checkclass(L, "noise{core}", 1);
-	float octave = luaL_checknumber(L, 2);
 	float p[4];
 	int i;
-	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 3 + i);
+	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 2 + i);
+	float octave = luaL_checknumber(L, 2 + i);
 
 	lua_pushnumber(L, TCOD_noise_fbm_wavelet(n->noise, p, octave));
 	return 1;
@@ -155,10 +155,10 @@ static int noise_fbm_wavelet(lua_State *L)
 static int noise_turbulence_wavelet(lua_State *L)
 {
 	noise_t *n = (noise_t*)auxiliar_checkclass(L, "noise{core}", 1);
-	float octave = luaL_checknumber(L, 2);
 	float p[4];
 	int i;
-	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 3 + i);
+	for (i = 0; i < n->ndim; i++) p[i] = luaL_checknumber(L, 2 + i);
+	float octave = luaL_checknumber(L, 2 + i);
 
 	lua_pushnumber(L, TCOD_noise_turbulence_wavelet(n->noise, p, octave));
 	return 1;