diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua
index 5cb5fde38f05ddd99f7e328e885f9cb1bf288167..245801b2bf7fd7689afa5cd8fba95dff8ae74be9 100644
--- a/game/engine/Actor.lua
+++ b/game/engine/Actor.lua
@@ -62,6 +62,13 @@ function _M:move(x, y, force)
 	return true
 end
 
+--- Moves into the given direction (calls actor:move() internally)
+function _M:moveDir(dir)
+	local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
+	local x, y = self.x + dx, self.y + dy
+	return self:move(x, y)
+end
+
 --- Can the actor go there
 -- @param terrain_only if true checks only the terrain, otherwise checks all entities
 function _M:canMove(x, y, terrain_only)
diff --git a/game/engine/interface/PlayerRest.lua b/game/engine/interface/PlayerRest.lua
index 774828cbbfb39f0a3fedf361e51cf5db45c8b708..62223f2ecd5d6086015dca7d5a9032b688e7c711 100644
--- a/game/engine/interface/PlayerRest.lua
+++ b/game/engine/interface/PlayerRest.lua
@@ -40,7 +40,7 @@ end
 -- Rewrite this method to check for mana, life, whatever. By default we alawys return false so resting will never work
 -- @return true if we can continue to rest, false otherwise
 function _M:restCheck()
-	return false
+	return false, "player:restCheck() method not defined"
 end
 
 --- Stops resting
diff --git a/game/engine/interface/PlayerRun.lua b/game/engine/interface/PlayerRun.lua
new file mode 100644
index 0000000000000000000000000000000000000000..fc7d8ec7b205f15b2b072d70351710c2dbfda479
--- /dev/null
+++ b/game/engine/interface/PlayerRun.lua
@@ -0,0 +1,160 @@
+require "engine.class"
+local Dialog = require "engine.Dialog"
+
+--- Handles player running
+-- This should work for running inside tunnel, alongside walls, in open spaces.<br/>
+module(..., package.seeall, class.make)
+
+local sides =
+{
+	[1] = {left=2, right=4},
+	[2] = {left=3, right=1},
+	[3] = {left=6, right=2},
+	[4] = {left=1, right=7},
+	[6] = {left=9, right=3},
+	[7] = {left=4, right=8},
+	[8] = {left=7, right=9},
+	[9] = {left=8, right=6},
+}
+local turn =
+{
+	[1] = {left=3, right=7},
+	[2] = {left=6, right=4},
+	[3] = {left=9, right=1},
+	[4] = {left=2, right=8},
+	[6] = {left=8, right=2},
+	[7] = {left=1, right=9},
+	[8] = {left=4, right=6},
+	[9] = {left=7, right=3},
+}
+
+local function checkDir(a, dir, dist)
+	dist = dist or 1
+	local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
+	local x, y = a.x + dx * dist, a.y + dy * dist
+	return game.level.map:checkAllEntities(x, y, "block_move", a) and true or false
+end
+
+--- Initializes running
+-- We check the direction sides to know if we are in a tunnel, along a wall or in open space.
+function _M:runInit(dir)
+	local block_left, block_right = false, false
+
+	-- Check sides
+	if checkDir(self, sides[dir].left) then block_left = true end
+	if checkDir(self, sides[dir].right) then block_right = true end
+
+	self.running = {
+		dir = dir,
+		block_left = block_left,
+		block_right = block_right,
+		cnt = 1,
+--		dialog = Dialog:simplePopup("Resting...", "You are running, press any key to stop.", function()
+--			self:runStop()
+--		end),
+	}
+
+	print("run", dir, block_left, block_right)
+
+	self:runStep()
+end
+
+--- Run a turn
+-- For a turn based game you want in you player's act() something like that:<br/>
+-- <pre>
+-- if not self:runStep() then game.paused = true end
+-- </pre><br/>
+-- This will move the actor using the :move() method, this SHOULD have been redefined by the module
+-- to use energy, otherwise running will be free.
+-- @return true if we can continue to run, false otherwise
+function _M:runStep()
+	if not self.running then return false end
+
+	local ret, msg = self:runCheck()
+	if not ret then
+		self:runStop(msg)
+		return false
+	else
+		self:moveDir(self.running.dir)
+		self.running.cnt = self.running.cnt + 1
+		if self.running.newdir then
+			self.running.dir = self.running.newdir
+			self.running.newdir = nil
+		end
+		if self.running.ignore_left then
+			self.running.ignore_left = self.running.ignore_left - 1
+			if self.running.ignore_left <= 0 then self.running.ignore_left = nil end
+		end
+		if self.running.ignore_right then
+			self.running.ignore_right = self.running.ignore_right - 1
+			if self.running.ignore_right <= 0 then self.running.ignore_right = nil end
+		end
+
+		return true
+	end
+end
+
+--- Can we continue running ?
+-- Rewrite this method to hostiles, interresting terrain, whatever.
+-- This method should be called by its submethod, it tries to detect changes in the terrain.<br/>
+-- It will also try to follow tunnels when they simply change direction.
+-- @return true if we can continue to run, false otherwise
+function _M:runCheck()
+	-- Do we change run direction ? We can only choose to change for left or right, never backwards.
+	-- We must also be in a tunnel (both sides blocked)
+	if self.running.block_left and self.running.block_right then
+		-- Turn left
+		if not checkDir(self, self.running.dir) and checkDir(self, self.running.dir, 2) and not checkDir(self, sides[self.running.dir].left) and checkDir(self, sides[self.running.dir].right) then
+			self.running.newdir = turn[self.running.dir].left
+			self.running.ignore_left = 2
+			print("will turn left")
+			return true
+		end
+
+		-- Turn right
+		if not checkDir(self, self.running.dir) and checkDir(self, self.running.dir, 2) and checkDir(self, sides[self.running.dir].left) and not checkDir(self, sides[self.running.dir].right) then
+			self.running.newdir = turn[self.running.dir].right
+			self.running.ignore_right = 2
+			print("will turn right")
+			return true
+		end
+	end
+
+	if not self.running.ignore_left and self.running.block_left ~= checkDir(self, sides[self.running.dir].left) then return false, "terrain change on left side" end
+	if not self.running.ignore_right and self.running.block_right ~= checkDir(self, sides[self.running.dir].right) then return false, "terrain change on right side" end
+	if checkDir(self, self.running.dir) then return false, "terrain ahead blocks" end
+
+	return true
+end
+
+--- Stops running
+function _M:runStop(msg)
+	if not self.running then return false end
+
+--	game:unregisterDialog(self.running.dialog)
+
+	if msg then
+		game.log("Ran for %d turns (stop reason: %s).", self.running.cnt, msg)
+	end
+
+	self.running = nil
+	return true
+end
+
+--- Scan the run direction and sides with the given function
+function _M:runScan(fct)
+	-- Ahead
+	local dx, dy = dir_to_coord[self.running.dir][1], dir_to_coord[self.running.dir][2]
+	local x, y = self.x + dx, self.y + dy
+	fct(x, y)
+
+	-- Ahead left
+	local dx, dy = dir_to_coord[sides[self.running.dir].left][1], dir_to_coord[sides[self.running.dir].left][2]
+	local x, y = self.x + dx, self.y + dy
+	fct(x, y)
+
+	-- Ahead right
+	local dx, dy = dir_to_coord[sides[self.running.dir].right][1], dir_to_coord[sides[self.running.dir].right][2]
+	local x, y = self.x + dx, self.y + dy
+	fct(x, y)
+end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 3fdc69a99a0eaf97f76dc22ba879905edaf4ae09..aca0896a164263eb13c99eb5fe17b672a7611b67 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -297,7 +297,7 @@ function _M:setupCommands()
 		[{"_DOWN","shift"}] = function() self.target:freemove(2) end,
 		[{"_KP4","shift"}] = function() self.target:freemove(4) end,
 		[{"_KP6","shift"}] = function() self.target:freemove(6) end,
-		[{"_KP8","shift"}] = function() self.target:freemove(7) end,
+		[{"_KP8","shift"}] = function() self.target:freemove(8) end,
 		[{"_KP2","shift"}] = function() self.target:freemove(2) end,
 		[{"_KP1","shift"}] = function() self.target:freemove(1) end,
 		[{"_KP3","shift"}] = function() self.target:freemove(3) end,
@@ -338,6 +338,20 @@ function _M:setupCommands()
 		_RIGHTPAREN = function() self.player:activateHotkey(11) end,
 		_EQUALS = function() self.player:activateHotkey(12) end,
 
+		-- running
+		[{"_LEFT","shift"}] = function() self.player:runInit(4) end,
+		[{"_RIGHT","shift"}] = function() self.player:runInit(6) end,
+		[{"_UP","shift"}] = function() self.player:runInit(8) end,
+		[{"_DOWN","shift"}] = function() self.player:runInit(2) end,
+		[{"_KP4","shift"}] = function() self.player:runInit(4) end,
+		[{"_KP6","shift"}] = function() self.player:runInit(6) end,
+		[{"_KP8","shift"}] = function() self.player:runInit(8) end,
+		[{"_KP2","shift"}] = function() self.player:runInit(2) end,
+		[{"_KP1","shift"}] = function() self.player:runInit(1) end,
+		[{"_KP3","shift"}] = function() self.player:runInit(3) end,
+		[{"_KP7","shift"}] = function() self.player:runInit(7) end,
+		[{"_KP9","shift"}] = function() self.player:runInit(9) end,
+
 		-- resting
 		[{"_r","shift"}] = function()
 			self.player:restInit()
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 418a56d17b7f9480d081425952522bfdaea4471b..4ad776ede7828d04611f79e73fb3a27f068f2041 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -1,12 +1,20 @@
 require "engine.class"
 require "mod.class.Actor"
 require "engine.interface.PlayerRest"
+require "engine.interface.PlayerRun"
 local Savefile = require "engine.Savefile"
 local Map = require "engine.Map"
 local Dialog = require "engine.Dialog"
 local ActorTalents = require "engine.interface.ActorTalents"
 
-module(..., package.seeall, class.inherit(mod.class.Actor, engine.interface.PlayerRest))
+--- Defines the player for ToME
+-- It is a normal actor, with some redefined methods to handle user interaction.<br/>
+-- It is also able to run and rest.
+module(..., package.seeall, class.inherit(
+	mod.class.Actor,
+	engine.interface.PlayerRest,
+	engine.interface.PlayerRun
+))
 
 function _M:init(t, no_default)
 	t.body = {
@@ -74,8 +82,8 @@ function _M:act()
 	-- Clean log flasher
 	game.flash:empty()
 
-	-- Resting ?
-	if not self:restStep() then
+	-- Resting ? Running ? Otherwise pause
+	if not self:restStep() and not self:runStep() then
 		game.paused = true
 	end
 end
@@ -148,16 +156,20 @@ function _M:activateHotkey(id)
 	end
 end
 
---- Can we continue resting ?
--- We can rest if no hostiles are in sight, and if we need life/mana/stamina (and their regen rates allows them to fully regen)
-function _M:restCheck()
+local function spotHostiles(self)
 	local seen = false
 	-- Check for visible monsters, only see LOS actors, so telepathy wont prevent resting
 	core.fov.calc_circle(self.x, self.y, 20, game.level.map.opaque, function(map, x, y)
 		local actor = map(x, y, map.ACTOR)
 		if actor and self:reactionToward(actor) < 0 and self:canSee(actor) then seen = true end
 	end, game.level.map)
-	if seen then return false, "hostile spotted" end
+	return seen
+end
+
+--- Can we continue resting ?
+-- We can rest if no hostiles are in sight, and if we need life/mana/stamina (and their regen rates allows them to fully regen)
+function _M:restCheck()
+	if spotHostiles(self) then return false, "hostile spotted" end
 
 	-- Check ressources, make sure they CAN go up, otherwise we will never stop
 	if self:getMana() < self:getMaxMana() and self.mana_regen > 0 then return true end
@@ -166,3 +178,24 @@ function _M:restCheck()
 
 	return false, "all resources and life at maximun"
 end
+
+--- Can we continue running?
+-- We can run if no hostiles are in sight, and if we no interresting terrains are next to us
+function _M:runCheck()
+	if spotHostiles(self) then return false, "hostile spotted" end
+
+	-- Notice any noticable terrain
+	local noticed = false
+	self:runScan(function(x, y)
+		-- Only notice interresting terrains
+		local grid = game.level.map(x, y, Map.TERRAIN)
+		if grid and grid.notice then noticed = "interresting terrain" end
+
+		-- Objects are always interresting
+		local obj = game.level.map:getObject(x, y, 1)
+		if obj then noticed = "object seen" end
+	end)
+	if noticed then return false, noticed end
+
+	return engine.interface.PlayerRun.runCheck(self)
+end
diff --git a/game/modules/tome/data/general/grids/basic.lua b/game/modules/tome/data/general/grids/basic.lua
index 9985c1c2e5515e8367d34deb4de75a444c625051..c03b3e3bad035064a6c9df2f3133cfcb2e9b733d 100644
--- a/game/modules/tome/data/general/grids/basic.lua
+++ b/game/modules/tome/data/general/grids/basic.lua
@@ -3,6 +3,7 @@ newEntity{
 	name = "exit to the wilds",
 	display = '<', color_r=255, color_g=0, color_b=255,
 	always_remember = true,
+	notice = true,
 	change_level = 1,
 	change_zone = "wilderness",
 }
@@ -11,6 +12,7 @@ newEntity{
 	define_as = "UP",
 	name = "previous level",
 	display = '<', color_r=255, color_g=255, color_b=0,
+	notice = true,
 	always_remember = true,
 	change_level = -1,
 }
@@ -19,6 +21,7 @@ newEntity{
 	define_as = "DOWN",
 	name = "next level",
 	display = '>', color_r=255, color_g=255, color_b=0,
+	notice = true,
 	always_remember = true,
 	change_level = 1,
 }
@@ -43,6 +46,7 @@ newEntity{
 	define_as = "DOOR",
 	name = "door", image = "terrain/granite_door1.png",
 	display = '+', color_r=238, color_g=154, color_b=77,
+	notice = true,
 	always_remember = true,
 	block_sight = true,
 	door_opened = "DOOR_OPEN",
diff --git a/game/modules/tome/data/talents/physical/dualweapon.lua b/game/modules/tome/data/talents/physical/dualweapon.lua
index f812a531c6ff6632f607d03c9da6d083c21ce793..1b0b85eb629a18fe4fce33ef6ed87fd91af56dc8 100644
--- a/game/modules/tome/data/talents/physical/dualweapon.lua
+++ b/game/modules/tome/data/talents/physical/dualweapon.lua
@@ -5,7 +5,7 @@ newTalent{
 	points = 5,
 	require = { stat = { dex=14 } },
 	info = function(self, t)
-		return ([[Reduces the damage penality of the off-hand weapon to %d%%]]):format(100 / (2 - self:getTalentLevel(t) / 6))
+		return ([[Increases the damage of the off-hand weapon to %d%%.]]):format(100 / (2 - self:getTalentLevel(t) / 6))
 	end,
 }