diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index da48a30cf76d69828a9b7179c42f899a41586151..e5a93b39b32398f44b8e64c3aa281e9fcbc5f79c 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -296,6 +296,13 @@ function _M:act()
 		end
 	end
 
+	-- Auto stealth?
+	if self:isTalentActive(self.T_AUTOMATIC_STEALTH) and not self:isTalentActive(self.T_STEALTH) then
+		local t = self:getTalentFromId(self.T_STEALTH)
+		if self:preUseTalent(t, true, true) and not self:isTalentCoolingDown(t) then
+			self:useTalent(self.T_STEALTH)
+		end
+	end
 
 	if self:attr("stunned") then
 		self.stunned_counter = (self.stunned_counter or 0) + (self:attr("stun_immune") or 0) * 100
@@ -1583,6 +1590,7 @@ function _M:postUseTalent(ab, ret)
 		self:antimagicBackslash(4 + self:getTalentLevelRaw(ab))
 	end
 
+	self.changed = true
 	if not ab.no_energy then
 		if ab.is_spell then
 			self:useEnergy(game.energy_to_act * self:combatSpellSpeed())
diff --git a/game/modules/tome/data/talents/cunning/cunning.lua b/game/modules/tome/data/talents/cunning/cunning.lua
index 446271d7c6f490e8fa6d18cde4a343764551436e..d7209dc5d308c8a1ea3b56d8feb217f678069796 100644
--- a/game/modules/tome/data/talents/cunning/cunning.lua
+++ b/game/modules/tome/data/talents/cunning/cunning.lua
@@ -18,6 +18,7 @@
 -- darkgod@te4.org
 
 -- Cunning talents
+newTalentType{ allow_random=true, type="cunning/stealth-base", name = "stealth", description = "Allows the user to enter stealth." }
 newTalentType{ allow_random=true, type="cunning/stealth", name = "stealth", description = "Allows the user to enter stealth." }
 newTalentType{ allow_random=true, type="cunning/trapping", name = "trapping", description = "The knowledge of trap laying and assorted trickeries." }
 newTalentType{ allow_random=true, type="cunning/traps", name = "traps", description = "Collection of known traps." }
diff --git a/game/modules/tome/data/talents/cunning/stealth.lua b/game/modules/tome/data/talents/cunning/stealth.lua
index 3efd831121d6c1a16b5346a3672617d8b043e095..534b1e6cc455b600200d1c68932424b8e5eef6e7 100644
--- a/game/modules/tome/data/talents/cunning/stealth.lua
+++ b/game/modules/tome/data/talents/cunning/stealth.lua
@@ -17,6 +17,23 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+newTalent{
+	name = "Automatic Stealth",
+	type = {"cunning/stealth-base", 1},
+	mode = "sustained", no_sustain_autoreset = true,
+	points = 1,
+	cooldown = 0,
+	activate = function(self, t)
+		return {}
+	end,
+	deactivate = function(self, t, p)
+		return true
+	end,
+	info = function(self, t)
+		return [[When active, automatically try to enter stealth when possible.]]
+	end,
+}
+
 newTalent{
 	name = "Stealth",
 	type = {"cunning/stealth", 1},
@@ -24,25 +41,40 @@ newTalent{
 	mode = "sustained", no_sustain_autoreset = true,
 	points = 5,
 	cooldown = 10,
+	no_energy = true,
 	getStealthPower = function(self, t) return 4 + self:getCun(10) * self:getTalentLevel(t) end,
 	getRadius = function(self, t) return math.floor(10 - self:getTalentLevel(t) * 1.1) end,
-	activate = function(self, t)
+	on_learn = function(self, t)
+		if self:getTalentLevelRaw(t) == 1 then
+			self:learnTalent(self.T_AUTOMATIC_STEALTH, true, 1)
+		end
+	end,
+	on_unlearn = function(self, t)
+		if self:getTalentLevelRaw(t) == 0 then
+			self:unlearnTalent(self.T_AUTOMATIC_STEALTH)
+		end
+	end,
+	on_pre_use = function(self, t, silent)
+		if self:isTalentActive(t.id) then return true end
 		local armor = self:getInven("BODY")[1]
 		if armor and (armor.subtype == "heavy" or armor.subtype == "massive") then
-			game.logPlayer(self, "You cannot Stealth with such heavy armour!")
+			if not silent then game.logPlayer(self, "You cannot Stealth with such heavy armour!") end
 			return nil
 		end
 
 		-- Check nearby actors
+		if not self.x or not self.y or not game.level then return end
 		local grids = core.fov.circle_grids(self.x, self.y, t.getRadius(self, t), true)
 		for x, yy in pairs(grids) do for y in pairs(yy) do
 			local actor = game.level.map(x, y, game.level.map.ACTOR)
 			if actor and actor ~= self and actor:reactionToward(self) < 0 and not rng.percent(self.hide_chance or 0) then
-				game.logPlayer(self, "You cannot Stealth with nearby foes watching!")
+				if not silent then game.logPlayer(self, "You cannot Stealth with nearby foes watching!") end
 				return nil
 			end
 		end end
-
+		return true
+	end,
+	activate = function(self, t)
 		local res = {
 			stealth = self:addTemporaryValue("stealth", t.getStealthPower(self, t)),
 			lite = self:addTemporaryValue("lite", -1000),