diff --git a/game/engine/Entity.lua b/game/engine/Entity.lua
index 187bf033c228111e5b8cc860cfe4d8de25f10dc8..97d93b9e7cbaba2b6345e29e2c6d3bb60ed602c6 100644
--- a/game/engine/Entity.lua
+++ b/game/engine/Entity.lua
@@ -114,6 +114,37 @@ function _M:resolve(t)
 	-- Finish resolving stuff
 	if t == self then
 		if self.resolveLevel then self:resolveLevel() end
+
+		if self.unique and type(self.unique) == "boolean" then
+			self.unique = self.name
+		end
+	end
+end
+
+--- Call when the entity is actually added to a level/whatever
+-- This helps ensuring uniqueness of uniques
+function _M:added()
+	if self.unique then
+		game.uniques[self.unique] = true
+		print("Added unique", self.unique)
+	end
+end
+
+--- Call when the entity is actually removed from existance
+-- This helps ensuring uniqueness of uniques.
+-- This recursively remvoes inventories too, if you need anythign special, overload this
+function _M:removed()
+	if self.inven then
+		for _, inven in pairs(self.inven) do
+			for i, o in ipairs(inven) do
+				o:removed()
+			end
+		end
+	end
+
+	if self.unique then
+		game.uniques[self.unique] = nil
+		print("Removed unique", self.unique)
 	end
 end
 
diff --git a/game/engine/Game.lua b/game/engine/Game.lua
index 90fb58e9dc1ce57ff8089c9266ddd2bb32c8dacd..35f76636b57539d6a68b8f7c345e369442d91180 100644
--- a/game/engine/Game.lua
+++ b/game/engine/Game.lua
@@ -21,6 +21,8 @@ function _M:init(keyhandler)
 
 	self.mouse = engine.Mouse.new()
 	self.mouse:setCurrent()
+
+	self.uniques = {}
 end
 
 function _M:loaded()
diff --git a/game/engine/Level.lua b/game/engine/Level.lua
index 63730141f9d91fe7fe4cdf30e8bf7518408e5044..9fb0be9c2cb15c92b662dbb9a4b65fabbec0ba01 100644
--- a/game/engine/Level.lua
+++ b/game/engine/Level.lua
@@ -130,3 +130,15 @@ end
 function _M:getEntitiesList(type)
 	return self.entities_list[type]
 end
+
+--- Removed, so we remove all entities
+function _M:removed()
+	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
+		local z = i + j * self.map.w
+		if self.map.map[z] then
+			for _, e in pairs(self.map.map[z]) do
+				e:removed()
+			end
+		end
+	end end
+end
diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua
index 24468a241acca9e0094117891ce0142f0b0e992a..a09b12d822bd9a58985512a230d7d8a8deab6e5b 100644
--- a/game/engine/Zone.lua
+++ b/game/engine/Zone.lua
@@ -87,11 +87,16 @@ end
 
 --- Checks an entity against a filter
 function _M:checkFilter(e, filter)
+	if e.unique and game.uniques[e.unique] then print("refused unique", e.name, e.unique) return false end
+
 	if not filter then return true end
 
 	if filter.type and filter.type ~= e.type then return false end
 	if filter.subtype and filter.subtype ~= e.subtype then return false end
 	if filter.name and filter.name ~= e.name then return false end
+
+	if e.unique then print("accepted unique", e.name, e.unique) end
+
 	return true
 end
 
@@ -210,20 +215,28 @@ function _M:getLevelData(lev)
 	return res
 end
 
---- Asks the zone to generate a level of level "lev"
--- @param lev the level (from 1 to zone.max_level)
--- @return a Level object
-function _M:getLevel(game, lev, old_lev, no_close)
+--- Leave the level, forgetting uniques and such
+function _M:leaveLevel(no_close)
+print("leaving unique")
 	-- Before doing anything else, close the current level
 	if not no_close and game.level and game.level.map then
 		if game.level.data.persistant then
 			local save = Savefile.new(game.save_name)
 			save:saveLevel(game.level)
 			save:close()
+		else
+			game.level:removed()
 		end
 
 		game.level.map:close()
 	end
+end
+
+--- Asks the zone to generate a level of level "lev"
+-- @param lev the level (from 1 to zone.max_level)
+-- @return a Level object
+function _M:getLevel(game, lev, old_lev, no_close)
+	self:leaveLevel(no_close)
 
 	local level_data = self:getLevelData(lev)
 
diff --git a/game/engine/generator/actor/Random.lua b/game/engine/generator/actor/Random.lua
index 0ea98007fa702b7e98f674c91e54fa9a04fcbb4b..a75425912d590b312dc55bb994b600c4ecb5b9bd 100644
--- a/game/engine/generator/actor/Random.lua
+++ b/game/engine/generator/actor/Random.lua
@@ -34,6 +34,7 @@ function _M:generate()
 			if tries < 100 then
 				m:move(x, y, true)
 				self.level:addEntity(m)
+				m:added()
 
 				-- Levelup ?
 				if self.adjust_level then
@@ -58,6 +59,7 @@ function _M:generate()
 			if tries < 100 then
 				m:move(x, y, true)
 				self.level:addEntity(m)
+				m:added()
 
 				-- Levelup ?
 				if self.adjust_level then
diff --git a/game/engine/generator/object/Random.lua b/game/engine/generator/object/Random.lua
index bdea35335931fddf112ff3448eca9c5ac8448be5..17cfd161f406e4462eee7d5e54363f25c1265f2c 100644
--- a/game/engine/generator/object/Random.lua
+++ b/game/engine/generator/object/Random.lua
@@ -33,6 +33,7 @@ function _M:generate()
 			end
 			if tries < 100 then
 				self.map(x, y, Map.OBJECT, o)
+				o:added()
 			end
 		end
 	end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index d9ab9a8734419639d392e1fb31a185b45fce80ac..66d9bd1adf364700abee2d83f7c955d5ed829485 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -137,7 +137,7 @@ end
 function _M:save()
 	return class.save(self, {w=true, h=true, zone=true, player=true, level=true, entities=true,
 		energy_to_act=true, energy_per_tick=true, turn=true, paused=true, save_name=true,
-		always_target=true, gfxmode=true;
+		always_target=true, gfxmode=true, uniques=true
 	}, true)
 end
 
@@ -150,6 +150,7 @@ end
 
 function _M:changeLevel(lev, zone)
 	if zone then
+		if self.zone then self.zone:leaveLevel() end
 		self.zone = Zone.new(zone)
 	end
 	self.zone:getLevel(self, lev, (self.level and not zone) and self.level.level or -1000)
diff --git a/game/modules/tome/data/general/npcs/bear.lua b/game/modules/tome/data/general/npcs/bear.lua
new file mode 100644
index 0000000000000000000000000000000000000000..7fcb95a77d025a6a4e09504ab2fc24129aac3660
--- /dev/null
+++ b/game/modules/tome/data/general/npcs/bear.lua
@@ -0,0 +1,75 @@
+local Talents = require("engine.interface.ActorTalents")
+
+newEntity{
+	define_as = "BASE_NPC_BEAR",
+	type = "animal", subtype = "bear",
+	display = "q", color=colors.WHITE,
+	body = { INVEN = 10 },
+
+	max_stamina = 100,
+
+	autolevel = "warrior",
+	ai = "dumb_talented_simple", ai_state = { talent_in=5, },
+	energy = { mod=0.9 },
+	stats = { str=18, dex=13, mag=5, con=15 },
+
+	combat_armor = 1, combat_def = 1,
+	combat = { dam=resolvers.rngavg(12,25), atk=10, apr=10, physspeed=2 },
+	life_rating = 13,
+	tmasteries = resolvers.tmasteries{ ["physical/other"]=0.25 },
+
+	resists = { [DamageType.FIRE] = 20, [DamageType.COLD] = 20, [DamageType.POISON] = 20 },
+}
+
+newEntity{ base = "BASE_NPC_BEAR",
+	name = "brown bear", color=colors.UMBER,
+	desc = [[The weakest of bears, covered in brown shaggy fur.]],
+	level_range = {5, 50}, exp_worth = 1,
+	rarity = 7,
+	max_life = resolvers.rngavg(100,150),
+	combat_armor = 7, combat_def = 3,
+	talents = resolvers.talents{ [Talents.T_STUN]=1 },
+}
+
+newEntity{ base = "BASE_NPC_BEAR",
+	name = "black bear", color=colors.BLACK,
+	desc = [[Do you smell like honey, 'cause this bear wants honey.]],
+	level_range = {6, 50}, exp_worth = 1,
+	rarity = 7,
+	max_life = resolvers.rngavg(120,150),
+	combat_armor = 8, combat_def = 3,
+	talents = resolvers.talents{ [Talents.T_STUN]=1 },
+}
+
+newEntity{ base = "BASE_NPC_BEAR",
+	name = "cave bear", color=colors.DARK_SLATE_GRAY,
+	desc = [[It has come down from its cave foraging for food. Unfortunately, it found you.]],
+	level_range = {7, 50}, exp_worth = 1,
+	rarity = 8,
+	max_life = resolvers.rngavg(130,150),
+	combat_armor = 9, combat_def = 4,
+	combat = { dam=resolvers.rngavg(13,17), atk=7, apr=7, physspeed=2 },
+	talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1,},
+}
+
+newEntity{ base = "BASE_NPC_BEAR",
+	name = "war bear", color=colors.DARK_UMBER,
+	desc = [[Bears with tusks, trained to kill.]],
+	level_range = {8, 50}, exp_worth = 1,
+	rarity = 8,
+	max_life = resolvers.rngavg(140,150),
+	combat_armor = 9, combat_def = 4,
+	combat = { dam=resolvers.rngavg(13,17), atk=10, apr=7, physspeed=2 },
+	talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1,},
+}
+
+newEntity{ base = "BASE_NPC_BEAR",
+	name = "grizzly bear", color=colors.LIGHT_UMBER,
+	desc = [[A huge, beastly bear, more savage than most of its kind.]],
+	level_range = {10, 50}, exp_worth = 1,
+	rarity = 9,
+	max_life = resolvers.rngavg(150,170),
+	combat_armor = 10, combat_def = 5,
+	combat = { dam=resolvers.rngavg(15,20), atk=10, apr=7, physspeed=2 },
+	talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=2,},
+}
diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua
index 04d9ca15fb91273e69755a68c5a2f58610fd81bf..7983052843e3dc57532297c0b0f407aa077a56c9 100644
--- a/game/modules/tome/data/general/objects/world-artifacts.lua
+++ b/game/modules/tome/data/general/objects/world-artifacts.lua
@@ -31,7 +31,7 @@ newEntity{
 	level_range = {1, 10},
 	display = "~", color=colors.YELLOW,
 	encumber = 1,
-	rarity = 100,
+	rarity = 1,
 	desc = [[A small crystal phial, with the light of Earendil's Star contained inside. Its light is imperishable, and near it darkness cannot endure.]],
 	cost = 2000,
 
diff --git a/game/modules/tome/data/zones/tower-amon-sul/objects.lua b/game/modules/tome/data/zones/tower-amon-sul/objects.lua
index e259bbcf4e9afb24af3827893e14671869619b27..fcb879de0b1f6237fc0fb4e6d557e91a5634ea58 100644
--- a/game/modules/tome/data/zones/tower-amon-sul/objects.lua
+++ b/game/modules/tome/data/zones/tower-amon-sul/objects.lua
@@ -2,7 +2,7 @@ load("/data/general/objects/objects.lua")
 
 -- Artifact, droped (and used!) by the Shade of Angmar
 newEntity{ base = "BASE_STAFF",
-	define_as = "STAFF_ANGMAR",
+	define_as = "STAFF_ANGMAR", rarity=false,
 	name = "Angmar's Fall", unique=true,
 	require = { stat = { mag=25 }, },
 	cost = 5,
diff --git a/game/modules/tome/data/zones/tower-amon-sul/zone.lua b/game/modules/tome/data/zones/tower-amon-sul/zone.lua
index 7eddaee077b5972878748c908ba332c5505052a4..0ba0656ded033d986bc987a0320bf7d2f82d547c 100644
--- a/game/modules/tome/data/zones/tower-amon-sul/zone.lua
+++ b/game/modules/tome/data/zones/tower-amon-sul/zone.lua
@@ -27,7 +27,7 @@ return {
 		},
 		object = {
 			class = "engine.generator.object.Random",
-			nb_object = {4, 6},
+			nb_object = {40, 60},
 			filters = { {type="potion" }, {type="potion" }, {type="potion" }, {type="scroll" }, {}, {} }
 		},
 	},
diff --git a/game/modules/tome/resolvers.lua b/game/modules/tome/resolvers.lua
index 4ade719cdf6a89682084c194050219adf1c0850c..f7f5d9aa697bb75789d81a495921633cd4af10d9 100644
--- a/game/modules/tome/resolvers.lua
+++ b/game/modules/tome/resolvers.lua
@@ -19,7 +19,7 @@ function resolvers.calc.equip(t, e)
 
 			-- Do not drop it unless it is an ego or better
 			if not o.egoed and not o.unique then o.no_drop = true end
-			print(o.name, o.unique, o.no_drop)
+			o:added()
 		end
 	end
 	-- Delete the origin field
@@ -44,6 +44,7 @@ function resolvers.calc.inventory(t, e)
 		if o then
 			print("Zone made us an inventory according to filter!", o:getName())
 			e:addObject(e.INVEN_INVEN, o)
+			o:added()
 		end
 	end
 	e:sortInven()
@@ -73,6 +74,7 @@ function resolvers.calc.drops(t, e)
 		if o then
 			print("Zone made us an drop according to filter!", o:getName())
 			e:addObject(e.INVEN_INVEN, o)
+			o:added()
 		end
 	end
 	-- Delete the origin field