diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index 10cab225bc4d874be00031bbbd2a0fe4e9f7590e..0b48bda81a324d9eebeb97455491b585413f9d86 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -1665,89 +1665,8 @@ function _M:createRandomZone(zbase)
 	return zone, boss
 end
 
-function _M:createRandomBoss(base, data)
-	local b = base:clone()
-	data = data or {level=1}
-
-	------------------------------------------------------------
-	-- Basic stuff, name, rank, ...
-	------------------------------------------------------------
-	local ngd, name
-	if base.random_name_def then
-		ngd = NameGenerator2.new("/data/languages/names/"..base.random_name_def:gsub("#sex#", base.female and "female" or "male")..".txt")
-		name = ngd:generate(nil, base.random_name_min_syllables, base.random_name_max_syllables)
-	else
-		ngd = NameGenerator.new(randart_name_rules.default)
-		name = ngd:generate()
-	end
-	if data.name_scheme then
-		b.name = data.name_scheme:gsub("#rng#", name):gsub("#base#", b.name)
-	else
-		b.name = name.." the "..b.name
-	end
-	b.unique = b.name
-	b.randboss = true
-	local boss_id = "RND_BOSS_"..b.name:upper():gsub("[^A-Z]", "_")
-	b.define_as = boss_id
-	b.color = colors.VIOLET
-	b.rank = data.rank or (rng.percent(30) and 4 or 3.5)
-	b.level_range[1] = data.level
-	b.fixed_rating = true
-	if data.life_rating then
-		b.life_rating = data.life_rating(b.life_rating)
-	else
-		b.life_rating = b.life_rating * 1.7 + rng.range(4, 9)
-	end
-	b.max_life = b.max_life or 150
-
-	if b.can_multiply or b.clone_on_hit then
-		b.clone_base = base:clone()
-		b.clone_base:resolve()
-		b.clone_base:resolve(nil, true)
-	end
-
-	-- Force resolving some stuff
-	if type(b.max_life) == "table" and b.max_life.__resolver then b.max_life = resolvers.calc[b.max_life.__resolver](b.max_life, b, b, b, "max_life", {}) end
-
-	-- All bosses have alll body parts .. yes snake bosses can use archery and so on ..
-	-- This is to prevent them from having unusable talents
-	b.inven = {}
-	b.body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1, TOOL = 1, QUIVER = 1 }
-	b:initBody()
-
-	b:resolve()
-
-	-- Start with sustains sustained
-	b[#b+1] = resolvers.sustains_at_birth()
-
-	-- Leveling stats
-	b.autolevel = "random_boss"
-	b.auto_stats = {}
-
-	-- Always smart
-	if data.ai then b.ai = data.ai
-	else b.ai = (b.rank > 3) and "tactical" or b.ai
-	end
-	b.ai_state = { talent_in=1, ai_move=data.ai_move or "move_astar" }
-
-	-- Remove default equipment, if any
-	local todel = {}
-	for k, resolver in pairs(b) do if type(resolver) == "table" and resolver.__resolver and (resolver.__resolver == "equip" or resolver.__resolver == "drops") then todel[#todel+1] = k end end
-	for _, k in ipairs(todel) do b[k] = nil end
-
-	-- Boss worthy drops
-	b[#b+1] = resolvers.drops{chance=100, nb=data.loot_quantity or 3, {tome_drops=data.loot_quality or "boss"} }
-	if not data.no_loot_randart then b[#b+1] = resolvers.drop_randart{} end
-
-	-- On die
-	if data.on_die then
-		b.rng_boss_on_die = b.on_die
-		b.rng_boss_on_die_custom = data.on_die
-		b.on_die = function(self, src)
-			self:check("rng_boss_on_die_custom", src)
-			self:check("rng_boss_on_die", src)
-		end
-	end
+function _M:applyRandomClass(b, data, instant)
+	if not data.level then data.level = b.level end
 
 	------------------------------------------------------------
 	-- Apply talents from classes
@@ -1768,10 +1687,12 @@ function _M:createRandomBoss(base, data)
 		if config.settings.cheat then b.desc = (b.desc or "").."\nClass: "..class.name end
 
 		-- Add stats
-		b.stats = b.stats or {}
-		for stat, v in pairs(class.stats or {}) do
-			b.stats[stat] = (b.stats[stat] or 10) + v
-			for i = 1, v do b.auto_stats[#b.auto_stats+1] = b.stats_def[stat].id end
+		if b.auto_stats then
+			b.stats = b.stats or {}
+			for stat, v in pairs(class.stats or {}) do
+				b.stats[stat] = (b.stats[stat] or 10) + v
+				for i = 1, v do b.auto_stats[#b.auto_stats+1] = b.stats_def[stat].id end
+			end
 		end
 
 		-- Add talent categories
@@ -1783,19 +1704,11 @@ function _M:createRandomBoss(base, data)
 		-- Add starting equipment
 		local apply_resolvers = function(k, resolver)
 			if type(resolver) == "table" and resolver.__resolver and resolver.__resolver == "equip" then
-				resolver[1].id = nil
-				-- Make sure we equip some nifty stuff instead of player's starting iron stuff
-				for i, d in ipairs(resolver[1]) do
-					d.name = nil
-					d.ego_chance = nil
-					d.tome_drops = data.loot_quality or "boss"
-					d.force_drop = (data.drop_equipment == nil) and true or data.drop_equipment
-				end
-				b[#b+1] = resolver
 			elseif k == "innate_alchemy_golem" then 
 				b.innate_alchemy_golem = true
 			elseif k == "birth_create_alchemist_golem" then
 				b.birth_create_alchemist_golem = resolver
+				if instant then b:check("birth_create_alchemist_golem") end
 			elseif k == "soul" then
 				b.soul = util.bound(1 + math.ceil(data.level / 10), 1, 10) -- Does this need to scale?
 			end
@@ -1845,7 +1758,13 @@ function _M:createRandomBoss(base, data)
 				print(" * talent", tid)
 				local max = (t.points == 1) and 1 or math.ceil(t.points * 1.2)
 				local step = max / 50
-				b.learn_tids[tid] = math.ceil(step * data.level)
+				local lev = math.ceil(step * data.level)
+				if instant then
+					if b:getTalentLevelRaw(tid) < lev then b:learnTalent(tid, true, lev - b:getTalentLevelRaw(tid)) end
+					if t.mode == "sustained" and data.auto_sustain then b:forceUseTalent(tid, {ignore_energy=true}) end
+				else
+					b.learn_tids[tid] = lev
+				end
 			end
 		end
 	end
@@ -1864,6 +1783,96 @@ function _M:createRandomBoss(base, data)
 		if not c then break end
 		apply_class(table.clone(c, true))
 	end
+end
+
+function _M:createRandomBoss(base, data)
+	local b = base:clone()
+	data = data or {level=1}
+
+	------------------------------------------------------------
+	-- Basic stuff, name, rank, ...
+	------------------------------------------------------------
+	local ngd, name
+	if base.random_name_def then
+		ngd = NameGenerator2.new("/data/languages/names/"..base.random_name_def:gsub("#sex#", base.female and "female" or "male")..".txt")
+		name = ngd:generate(nil, base.random_name_min_syllables, base.random_name_max_syllables)
+	else
+		ngd = NameGenerator.new(randart_name_rules.default)
+		name = ngd:generate()
+	end
+	if data.name_scheme then
+		b.name = data.name_scheme:gsub("#rng#", name):gsub("#base#", b.name)
+	else
+		b.name = name.." the "..b.name
+	end
+	b.unique = b.name
+	b.randboss = true
+	local boss_id = "RND_BOSS_"..b.name:upper():gsub("[^A-Z]", "_")
+	b.define_as = boss_id
+	b.color = colors.VIOLET
+	b.rank = data.rank or (rng.percent(30) and 4 or 3.5)
+	b.level_range[1] = data.level
+	b.fixed_rating = true
+	if data.life_rating then
+		b.life_rating = data.life_rating(b.life_rating)
+	else
+		b.life_rating = b.life_rating * 1.7 + rng.range(4, 9)
+	end
+	b.max_life = b.max_life or 150
+
+	if b.can_multiply or b.clone_on_hit then
+		b.clone_base = base:clone()
+		b.clone_base:resolve()
+		b.clone_base:resolve(nil, true)
+	end
+
+	-- Force resolving some stuff
+	if type(b.max_life) == "table" and b.max_life.__resolver then b.max_life = resolvers.calc[b.max_life.__resolver](b.max_life, b, b, b, "max_life", {}) end
+
+	-- All bosses have alll body parts .. yes snake bosses can use archery and so on ..
+	-- This is to prevent them from having unusable talents
+	b.inven = {}
+	b.body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1, TOOL = 1, QUIVER = 1 }
+	b:initBody()
+
+	b:resolve()
+
+	-- Start with sustains sustained
+	b[#b+1] = resolvers.sustains_at_birth()
+
+	-- Leveling stats
+	b.autolevel = "random_boss"
+	b.auto_stats = {}
+
+	-- Always smart
+	if data.ai then b.ai = data.ai
+	else b.ai = (b.rank > 3) and "tactical" or b.ai
+	end
+	b.ai_state = { talent_in=1, ai_move=data.ai_move or "move_astar" }
+
+	-- Remove default equipment, if any
+	local todel = {}
+	for k, resolver in pairs(b) do if type(resolver) == "table" and resolver.__resolver and (resolver.__resolver == "equip" or resolver.__resolver == "drops") then todel[#todel+1] = k end end
+	for _, k in ipairs(todel) do b[k] = nil end
+
+	-- Boss worthy drops
+	b[#b+1] = resolvers.drops{chance=100, nb=data.loot_quantity or 3, {tome_drops=data.loot_quality or "boss"} }
+	if not data.no_loot_randart then b[#b+1] = resolvers.drop_randart{} end
+
+	-- On die
+	if data.on_die then
+		b.rng_boss_on_die = b.on_die
+		b.rng_boss_on_die_custom = data.on_die
+		b.on_die = function(self, src)
+			self:check("rng_boss_on_die_custom", src)
+			self:check("rng_boss_on_die", src)
+		end
+	end
+
+	------------------------------------------------------------
+	-- Apply talents from classes
+	------------------------------------------------------------
+	self:applyRandomClass(b, data)
 
 	b.rnd_boss_on_added_to_level = b.on_added_to_level
 	b._rndboss_resources_boost = data.resources_boost
diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua
index 0c72a87d7f600550352249d10421e588e96220b1..88b6f350bdd8dfd090171891b3a7b170e15085d9 100644
--- a/game/modules/tome/class/NPC.lua
+++ b/game/modules/tome/class/NPC.lua
@@ -435,12 +435,30 @@ function _M:addedToLevel(level, x, y)
 			for tid, lev in pairs(self.talents) do
 				self:learnTalent(tid, true, lev)
 			end
+			if not self.randboss and self.rank >= 3.5 then
+				local data = {auto_sustain=true}
+				if self.rank == 3.5 then data = {auto_sustain=true, nb_classes=1}
+				elseif self.rank == 4 then data = {auto_sustain=true, nb_classes=1}
+				elseif self.rank == 5 then data = {auto_sustain=true, nb_classes=2}
+				elseif self.rank >= 10 then data = {auto_sustain=true, nb_classes=3}
+				end
+				game.state:applyRandomClass(self, data, true)
+			end
 			self:attr("difficulty_boosted", 1)
 		elseif game.difficulty == game.DIFFICULTY_MADNESS and not game.party:hasMember(self) then
 			-- Increase talent level
 			for tid, lev in pairs(self.talents) do
 				self:learnTalent(tid, true, math.ceil(lev * 1.7))
 			end
+			if not self.randboss and self.rank >= 3.5 then
+				local data = {auto_sustain=true}
+				if self.rank == 3.5 then data = {auto_sustain=true, nb_classes=1}
+				elseif self.rank == 4 then data = {auto_sustain=true, nb_classes=2}
+				elseif self.rank == 5 then data = {auto_sustain=true, nb_classes=3}
+				elseif self.rank >= 10 then data = {auto_sustain=true, nb_classes=5}
+				end
+				game.state:applyRandomClass(self, data, true)
+			end
 			self:attr("difficulty_boosted", 1)
 		end
 	end
diff --git a/game/modules/tome/data/birth/descriptors.lua b/game/modules/tome/data/birth/descriptors.lua
index f6bcb27a36d72ba63b01d97bb2019a1cc1dde3b6..0c3f31b6d4096cadd9e272f78640f35e8faa048d 100644
--- a/game/modules/tome/data/birth/descriptors.lua
+++ b/game/modules/tome/data/birth/descriptors.lua
@@ -214,6 +214,7 @@ newBirthDescriptor{
 		"Absolutely unfair game setting.  You are really mentally ill to play this mode!",
 		"All zone levels increased by 120% + 5",
 		"All creature talent levels increased by 100%",
+		"Bosses will have randomly selected talents",
 		"Player rank is normal instead of elite",
 		"Player can earn Insane version of achievements if also playing in Roguelike or Adventure permadeath mode.",
 	},
@@ -239,6 +240,7 @@ newBirthDescriptor{
 		"All zone levels increased by 150% + 10",
 		"All creature talent levels increased by 170%",
 		"Rare creatures are far more frequent and random bosses start to appear",
+		"Bosses will have randomly selected talents",
 		"Player is being hunted! Randomly all foes in a radius will get a feeling of where she/he is",
 		"Player rank is normal instead of elite",
 		"Player can earn Madness version of achievements if also playing in Roguelike or Adventure permadeath mode.",
diff --git a/game/modules/tome/data/texts/unlock-difficulty_insane.lua b/game/modules/tome/data/texts/unlock-difficulty_insane.lua
index 746d77d476c4118033b9fee9c190ce4015439e65..aa0d60e6bc85339c53594e732f34fac39d3ba70e 100644
--- a/game/modules/tome/data/texts/unlock-difficulty_insane.lua
+++ b/game/modules/tome/data/texts/unlock-difficulty_insane.lua
@@ -26,6 +26,7 @@ But no! If nightmare mode couldn't bring you down, Insane mode will!
 Insane features:#YELLOW#
 - All zone levels increased by 120% + 5
 - All creature talent levels increased by 100%
+- Bosses will have randomly selected talents
 - Player rank is normal instead of elite
 - Player can earn Insane version of achievements if also playing in Roguelike permadeath mode.
 
diff --git a/game/modules/tome/data/texts/unlock-difficulty_madness.lua b/game/modules/tome/data/texts/unlock-difficulty_madness.lua
index 063dc1433ddd09b890a07876e630f4b734e78810..0a6c5547399778e306af551e1e60b98004afade3 100644
--- a/game/modules/tome/data/texts/unlock-difficulty_madness.lua
+++ b/game/modules/tome/data/texts/unlock-difficulty_madness.lua
@@ -27,6 +27,7 @@ Madness features:#YELLOW#
 - All zone levels increased by 150% + 10
 - All creature talent levels increased by 170%
 - Rare creatures are far more frequent and random bosses start to appear
+- Bosses will have randomly selected talents
 - Player is being hunted! Randomly all foes in a radius will get a feeling of where she/he is
 - Player rank is normal instead of elite
 - Player can earn Madness version of achievements if also playing in Roguelike or Adventure permadeath mode.