diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index a27d3011725eb839954db3cf0c4bd3c7d64420a3..952022961001c3c8732437fe98f685cae8f3282c 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -100,6 +100,9 @@ function _M:run()
 
 	self.log(self.flash.GOOD, "Welcome to #00FF00#Tales of Maj'Eyal!")
 
+	-- List of stuff to do on tick end
+	self.on_tick_end = {}
+
 	-- Setup inputs
 	self:setupCommands()
 	self:setupMouse()
@@ -492,10 +495,23 @@ function _M:tick()
 		-- (since display is on a set FPS while tick() ticks as much as possible
 		-- engine.GameEnergyBased.tick(self)
 	end
+
+	-- Run tick end stuff
+	if #self.on_tick_end > 0 then
+		for i = 1, #self.on_tick_end do self.on_tick_end[i]() end
+		self.on_tick_end = {}
+	end
+
 	if savefile_pipe.saving then self.player.changed = true end
 	if self.paused and not savefile_pipe.saving then return true end
 end
 
+--- Register things to do on tick end
+-- This is used for recall spells to let the tick finish before switching levels
+function _M:onTickEnd(f)
+	self.on_tick_end[#self.on_tick_end+1] = f
+end
+
 --- Called every game turns
 -- Does nothing, you can override it
 function _M:onTurn()
diff --git a/game/modules/tome/data/general/npcs/all.lua b/game/modules/tome/data/general/npcs/all.lua
index 34f58ee08c56094e34befff25b1217e943171fd1..bc840793627461a58a2909718d588535b597d638 100644
--- a/game/modules/tome/data/general/npcs/all.lua
+++ b/game/modules/tome/data/general/npcs/all.lua
@@ -36,6 +36,7 @@ loadIfNot("/data/general/npcs/fire-drake.lua")
 loadIfNot("/data/general/npcs/ghost.lua")
 loadIfNot("/data/general/npcs/ghoul.lua")
 --loadIfNot("/data/general/npcs/gwelgoroth.lua")
+loadIfNot("/data/general/npcs/horror.lua")
 loadIfNot("/data/general/npcs/jelly.lua")
 loadIfNot("/data/general/npcs/minor-demon.lua")
 loadIfNot("/data/general/npcs/major-demon.lua")
diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua
new file mode 100644
index 0000000000000000000000000000000000000000..36ed62975f09a8df94a294dbca335071c3af2425
--- /dev/null
+++ b/game/modules/tome/data/general/npcs/horror.lua
@@ -0,0 +1,116 @@
+-- ToME - Tales of Maj'Eyal
+-- 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
+
+-- last updated:  10:46 AM 2/3/2010
+
+local Talents = require("engine.interface.ActorTalents")
+
+newEntity{
+	define_as = "BASE_NPC_HORROR",
+	type = "horror", subtype = "eldritch",
+	display = "h", color=colors.WHITE,
+	body = { INVEN = 10 },
+	autolevel = "warrior",
+	ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=3, },
+
+	stats = { str=22, dex=20, wil=15, con=15 },
+	energy = { mod=1 },
+	combat_armor = 0, combat_def = 0,
+	combat = { dam=5, atk=15, apr=7, dammod={str=0.6} },
+	infravision = 20,
+	max_life = resolvers.rngavg(10,20),
+	rank = 2,
+	size_category = 3,
+}
+
+newEntity{ base="BASE_NPC_HORROR", define_as = "GRGGLCK_TENTACLE",
+	name = "Grgglck's Tentacle",
+	color = colors.GREY,
+	desc = [[This is one of Grgglck's tentacle, it looks more vulnerable than the main body.]],
+	level_range = {20, nil}, exp_worth = 0,
+	max_life = 100, life_rating = 3, fixed_rating = true,
+	equilibrium_regen = -20,
+	rank = 3,
+	no_breath = 1,
+	size_category = 2,
+
+	stun_immune = 1,
+	knockback_immune = 1,
+	teleport_immune = 1,
+
+	resists = { all=50, [DamageType.DARKNESS] = 100 },
+
+	combat = { dam=resolvers.mbonus(25, 15), atk=500, apr=500, dammod={str=1} },
+
+	autolevel = "warrior",
+	ai = "dumb_talented_simple", ai_state = { talent_in=3, ai_move="move_astar" },
+
+	on_act = function(self)
+		if self.summoner.dead then
+			self:die()
+			game.logSeen(self, "#AQUAMARINE#With Grgglck's death its tentacle also falls lifeless on the ground!")
+		end
+	end,
+
+	on_die = function(self, who)
+		if self.summoner and not self.summoner.dead then
+			game.logSeen(self, "#AQUAMARINE#As %s falls you notice that %s seems to shudder in pain!", self.name, self.summoner.name)
+			self.summoner:takeHit(self.max_life, who)
+		end
+	end,
+}
+
+newEntity{ base="BASE_NPC_HORROR", define_as = "TEST",
+	name = "Grgglck the Devouring Darkness", unique = true,
+	color = colors.DARK_GREY,
+	rarity = 50,
+	desc = [[An horror from the deepest pits of the earth. It looks like a huge pile of tentacles all trying to reach for you.
+You can discern a huge ruond mouth covered in razor-sharp teeth.]],
+	level_range = {20, nil}, exp_worth = 2,
+	max_life = 300, life_rating = 25, fixed_rating = true,
+	equilibrium_regen = -20,
+	negative_regen = 20,
+	rank = 3.5,
+	no_breath = 1,
+	size_category = 4,
+	movement_speed = 0.5,
+
+	stun_immune = 1,
+	knockback_immune = 1,
+
+	combat = { dam=resolvers.mbonus(100, 15), atk=500, apr=0, dammod={str=1.2} },
+
+	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
+        resolvers.drops{chance=100, nb=1, {unique=true} },
+	resolvers.drops{chance=100, nb=5, {ego_chance=100} },
+
+	resists = { all=500 },
+
+	resolvers.talents{
+		[Talents.T_STARFALL]=4,
+		[Talents.T_MOONLIGHT_RAY]=4,
+		[Talents.T_PACIFICATION_HEX]=4,
+		[Talents.T_BURNING_HEX]=4,
+		[Talents.T_INVOKE_TENTACLE]=1,
+	},
+	resolvers.sustains_at_birth(),
+
+	autolevel = "warriormage",
+	ai = "dumb_talented_simple", ai_state = { talent_in=3, ai_move="move_astar" },
+}
diff --git a/game/modules/tome/data/general/npcs/multihued-drake.lua b/game/modules/tome/data/general/npcs/multihued-drake.lua
index 85a4b80c8cade82e672f842d9dab7c6eea6d9dee..dd2fea6f0374522adc22196549ecd9fd41b5900d 100644
--- a/game/modules/tome/data/general/npcs/multihued-drake.lua
+++ b/game/modules/tome/data/general/npcs/multihued-drake.lua
@@ -131,7 +131,7 @@ newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE",
 	},
 }
 
-newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE", define_as="TEST",
+newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE",
 	unique = true,
 	name = "Ureslak the Prismatic", color=colors.VIOLET, display="D",
 	desc = [[A huge multi-hued drake. It seems to shift color rapidly.]],
diff --git a/game/modules/tome/data/lore/infinite-dungeon.lua b/game/modules/tome/data/lore/infinite-dungeon.lua
index a904a7cc5bb5534d49a657b9f3dba85440e06cf5..5a9bb2cda4d5fbce309fe3db7212ff8330a35969 100644
--- a/game/modules/tome/data/lore/infinite-dungeon.lua
+++ b/game/modules/tome/data/lore/infinite-dungeon.lua
@@ -26,7 +26,7 @@ newLore{
 	category = "ruined dungeon",
 	name = "clue (ruined dungeon)",
 	lore = [[There is an inscription here:
-#{italic}#"The river flows in its bed of stone...#{normal}#]],
+#{italic}#The river flows in its bed of stone...#{normal}#]],
 }
 
 newLore{
@@ -35,7 +35,7 @@ newLore{
 	name = "clue (ruined dungeon)",
 	lore = [[There is an inscription here:
 #{italic}#...The feather flies gently in the wind.
-The tree's root run deep...#{normal}#]],
+The tree's roots run deep...#{normal}#]],
 }
 
 newLore{
diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua
index 37b7c0d74768634b149446f97b981e59ace48452..a093d23d93b6715aa8e5f233abdd6895870741a8 100644
--- a/game/modules/tome/data/talents/misc/npcs.lua
+++ b/game/modules/tome/data/talents/misc/npcs.lua
@@ -1002,3 +1002,42 @@ newTalent{
 		The damage will increase with Magic stat.]]):format(self:combatTalentSpellDamage(t, 10, 170), 20 + self:getTalentLevel(t) * 10, self:combatTalentSpellDamage(t, 10, 220))
 	end,
 }
+
+newTalent{
+	name = "Invoke Tentacle",
+	type = {"wild-gift/other", 1},
+	cooldown = 1,
+	range = 20,
+	direct_hit = true,
+	action = function(self, t)
+		local tg = {type="hit", range=self:getTalentRange(t), talent=t}
+		local tx, ty = self:getTarget(tg)
+		if not tx or not ty then return nil end
+
+		-- Find space
+		local x, y = util.findFreeGrid(tx, ty, 3, true, {[Map.ACTOR]=true})
+		if not x then
+			game.logPlayer(self, "Not enough space to invoke!")
+			return
+		end
+
+		-- Find an actor with that filter
+		local m = game.zone:makeEntityByName(game.level, "actor", "GRGGLCK_TENTACLE")
+		if m then
+			m.exp_worth = 0
+			m:resolve()
+
+			m.summoner = self
+			m.summon_time = 10
+
+			game.zone:addEntity(game.level, m, "actor", x, y)
+
+			game.logSeen(self, "%s spawns one of its tentacle!", self.name:capitalize())
+		end
+
+		return true
+	end,
+	info = function(self, t)
+		return ([[Invoke your tentacles on your victim.]])
+	end,
+}
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 30ab05622bd1e64f0249999c1bec14c68aa9d443..28e78caf2ba68c3e3fa2a39fd0b42993f32b74f3 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -1825,8 +1825,10 @@ newEffect{
 	end,
 	deactivate = function(self, eff)
 		if self:canBe("worldport") then
-			game.logPlayer(self, "You are yanked out of this place!")
-			game:changeLevel(1, game.player.last_wilderness)
+			game:onTickEnd(function()
+				game.logPlayer(self, "You are yanked out of this place!")
+				game:changeLevel(1, game.player.last_wilderness)
+			end)
 		else
 			game.logPlayer(self, "Space restabilizes around you.")
 		end
@@ -1855,8 +1857,10 @@ newEffect{
 		end
 
 		if self:canBe("worldport") then
-			game.logPlayer(self, "You are yanked out of this place!")
-			game:changeLevel(1, "town-angolwen")
+			game:onTickEnd(function()
+				game.logPlayer(self, "You are yanked out of this place!")
+				game:changeLevel(1, "town-angolwen")
+			end)
 		else
 			game.logPlayer(self, "Space restabilizes around you.")
 		end
diff --git a/ideas/actor-types.ods b/ideas/actor-types.ods
index 7b2520eaed9d75f69ba157ffb6cd05ad895b675d..7067e85b2183783b5aff153800f86443eeaad034 100644
Binary files a/ideas/actor-types.ods and b/ideas/actor-types.ods differ