diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua
index e822278678898e9ca65a4118a8bc43179fd6c1d4..b08ec230e596003866879f0c2b447d351bc77298 100644
--- a/game/engine/Zone.lua
+++ b/game/engine/Zone.lua
@@ -487,27 +487,29 @@ function _M:newLevel(level_data, lev, old_lev, game)
 	map.room_map = nil
 
 	-- Check for connectivity from entrance to exit
-	local a = Astar.new(map, game:getPlayer())
-	print("[LEVEL GENERATION] checking entrance to exit A*", ux, uy, "to", dx, dy)
-	if ux and uy and dx and dy and (ux ~= dx or uy ~= dy) and not spots.no_level_connectivity and not a:calc(ux, uy, dx, dy) then
-		print("Level unconnected, no way from entrance to exit", ux, uy, "to", dx, dy)
-		level:removed()
-		return self:newLevel(level_data, lev, old_lev, game)
-	end
-	for i = 1, #spots do
-		local spot = spots[i]
-		if spot.check_connectivity then
-			local cx, cy
-			if type(spot.check_connectivity) == "string" and spot.check_connectivity == "entrance" then cx, cy = ux, uy
-			elseif type(spot.check_connectivity) == "string" and spot.check_connectivity == "exit" then cx, cy = dx, dy
-			else cx, cy = spot.check_connectivity.x, spot.check_connectivity.y
-			end
+	if not level_data.no_level_connectivity then
+		local a = Astar.new(map, game:getPlayer())
+		print("[LEVEL GENERATION] checking entrance to exit A*", ux, uy, "to", dx, dy)
+		if ux and uy and dx and dy and (ux ~= dx or uy ~= dy)  and not a:calc(ux, uy, dx, dy) then
+			print("Level unconnected, no way from entrance to exit", ux, uy, "to", dx, dy)
+			level:removed()
+			return self:newLevel(level_data, lev, old_lev, game)
+		end
+		for i = 1, #spots do
+			local spot = spots[i]
+			if spot.check_connectivity then
+				local cx, cy
+				if type(spot.check_connectivity) == "string" and spot.check_connectivity == "entrance" then cx, cy = ux, uy
+				elseif type(spot.check_connectivity) == "string" and spot.check_connectivity == "exit" then cx, cy = dx, dy
+				else cx, cy = spot.check_connectivity.x, spot.check_connectivity.y
+				end
 
-			print("[LEVEL GENERATION] checking A*", spot.x, spot.y, "to", cx, cy)
-			if spot.x and spot.y and cx and cy and (spot.x ~= cx or spot.y ~= cy) and not a:calc(spot.x, spot.y, cx, cy) then
-				print("Level unconnected, no way from", spot.x, spot.y, "to", cx, cy)
-				level:removed()
-				return self:newLevel(level_data, lev, old_lev, game)
+				print("[LEVEL GENERATION] checking A*", spot.x, spot.y, "to", cx, cy)
+				if spot.x and spot.y and cx and cy and (spot.x ~= cx or spot.y ~= cy) and not a:calc(spot.x, spot.y, cx, cy) then
+					print("Level unconnected, no way from", spot.x, spot.y, "to", cx, cy)
+					level:removed()
+					return self:newLevel(level_data, lev, old_lev, game)
+				end
 			end
 		end
 	end
diff --git a/game/engine/interface/ActorResource.lua b/game/engine/interface/ActorResource.lua
index ed8871e57ad3b676dee7024526271f6401c89c61..2d66992cb86066cbfcf6f2e8b1a1b092d5c9facc 100644
--- a/game/engine/interface/ActorResource.lua
+++ b/game/engine/interface/ActorResource.lua
@@ -89,7 +89,9 @@ end
 
 --- Regen resources, shout be called in your actor's act() method
 function _M:regenResources()
-	for i, r in ipairs(_M.resources_def) do
+	local r
+	for i = 1, #_M.resources_def do
+		r = _M.resources_def[i]
 		if r.regen_prop then
 			self[r.short_name] = util.bound(self[r.short_name] + self[r.regen_prop], 0, self[r.maxname])
 		end
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 5546bf5b9a5afdc5e3090eab0fdfe85562f28108..bb94069a300994e261b2f9f1c9ab44203bd29cfc 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -83,6 +83,7 @@ function _M:init(t, no_default)
 	t.life_rating = t.life_rating or 10
 	t.mana_rating = t.mana_rating or 10
 	t.stamina_rating = t.stamina_rating or 4
+	t.positive_negative_rating = t.positive_negative_rating or 4
 
 	t.esp = t.esp or {range=10}
 
@@ -103,7 +104,14 @@ function _M:init(t, no_default)
 	t.mana_regen = t.mana_regen or 0.5
 	t.stamina_regen = t.stamina_regen or 0.3 -- Stamina regens slower than mana
 	t.life_regen = t.life_regen or 0.25 -- Life regen real slow
-	t.equilibrium_regen = t.equilibrium_regen or -0.01 -- Equilibrium resets real slow
+	t.equilibrium_regen = t.equilibrium_regen or 0 -- Equilibrium does not regen
+	t.positive_regen = t.positive_regen or -0.1 -- Positive energy slowly decays
+	t.negative_regen = t.negative_regen or -0.1 -- Positive energy slowly decays
+
+	t.max_positive = t.max_positive or 50
+	t.max_negative = t.max_negative or 50
+	t.positive = t.positive or 0
+	t.negative = t.negative or 0
 
 	-- Equilibrium has a default very high max, as bad effects happen even before reaching it
 	t.max_equilibrium = t.max_equilibrium or 100000
@@ -468,7 +476,7 @@ function _M:onTakeHit(value, src)
 	end
 
 	-- Achievements
-	if src and src:resolveSource().player and value >= 600 then
+	if src and src.resolveSource and src:resolveSource().player and value >= 600 then
 		world:gainAchievement("SIZE_MATTERS", src:resolveSource())
 	end
 
@@ -487,7 +495,7 @@ function _M:die(src)
 	engine.interface.ActorLife.die(self, src)
 
 	-- Gives the killer some exp for the kill
-	if src and src:resolveSource().gainExp then
+	if src and src.resolveSource and src:resolveSource().gainExp then
 		src:resolveSource():gainExp(self:worthExp(src:resolveSource()))
 	end
 	-- Do we get a blooooooody death ?
@@ -508,7 +516,7 @@ function _M:die(src)
 		src:incStamina(src:getTalentLevel(src.T_UNENDING_FRENZY) * 2)
 	end
 
-	if src and src:resolveSource().player then
+	if src and src.resolveSource and src:resolveSource().player then
 		-- Achievements
 		local p = src:resolveSource()
 		if p.life == 1 then world:gainAchievement("THAT_WAS_CLOSE", p) end
@@ -547,6 +555,8 @@ function _M:levelup()
 
 	self:incMaxMana(self.mana_rating)
 	self:incMaxStamina(self.stamina_rating)
+	self:incMaxPositive(self.positive_negative_rating)
+	self:incMaxNegative(self.positive_negative_rating)
 	-- Healp up on new level
 	self.life = self.max_life
 	self.mana = self.max_mana
@@ -647,6 +657,8 @@ function _M:learnTalent(t_id, force, nb)
 	if t.type[1]:find("^wild%-gift/") and not self:knowTalent(self.T_EQUILIBRIUM_POOL) then self:learnTalent(self.T_EQUILIBRIUM_POOL, true) end
 	if t.type[1]:find("^technique/") and not self:knowTalent(self.T_STAMINA_POOL) then self:learnTalent(self.T_STAMINA_POOL, true) end
 	if t.type[1]:find("^corruption/") and not self:knowTalent(self.T_VIM_POOL) then self:learnTalent(self.T_VIM_POOL, true) end
+	if t.type[1]:find("^divine/") and (t.positive or t.sustain_positive) and not self:knowTalent(self.T_POSITIVE_POOL) then self:learnTalent(self.T_POSITIVE_POOL, true) end
+	if t.type[1]:find("^divine/") and (t.negative or t.sustain_negative) and not self:knowTalent(self.T_NEGATIVE_POOL) then self:learnTalent(self.T_NEGATIVE_POOL, true) end
 
 	-- If we learn an archery talent, also learn to shoot
 	if t.type[1]:find("^technique/archery") and not self:knowTalent(self.T_SHOOT) then self:learnTalent(self.T_SHOOT, true) end
@@ -683,6 +695,14 @@ function _M:preUseTalent(ab, silent)
 			game.logPlayer(self, "You do not have enough stamina to activate %s.", ab.name)
 			return false
 		end
+		if ab.sustain_positive and self.max_positive < ab.sustain_positive and not self:isTalentActive(ab.id) then
+			game.logPlayer(self, "You do not have enough positive energy to activate %s.", ab.name)
+			return false
+		end
+		if ab.sustain_negative and self.max_negative < ab.sustain_negative and not self:isTalentActive(ab.id) then
+			game.logPlayer(self, "You do not have enough negative energy to activate %s.", ab.name)
+			return false
+		end
 	else
 		if ab.mana and self:getMana() < ab.mana * (100 + self.fatigue) / 100 then
 			game.logPlayer(self, "You do not have enough mana to cast %s.", ab.name)
@@ -692,6 +712,14 @@ function _M:preUseTalent(ab, silent)
 			game.logPlayer(self, "You do not have enough stamina to use %s.", ab.name)
 			return false
 		end
+		if ab.positive and self:getPositive() < ab.positive * (100 + self.fatigue) / 100 then
+			game.logPlayer(self, "You do not have enough positive energy to use %s.", ab.name)
+			return false
+		end
+		if ab.negative and self:getNegative() < ab.negative * (100 + self.fatigue) / 100 then
+			game.logPlayer(self, "You do not have enough negative energy to use %s.", ab.name)
+			return false
+		end
 	end
 
 	-- Equilibrium is special, it has no max, but the higher it is the higher the chance of failure (and loss of the turn)
@@ -766,6 +794,12 @@ function _M:postUseTalent(ab, ret)
 			if ab.sustain_equilibrium then
 				self:incEquilibrium(ab.sustain_equilibrium)
 			end
+			if ab.sustain_positive then
+				self.max_positive = self.max_positive - ab.sustain_positive
+			end
+			if ab.sustain_negative then
+				self.max_negative = self.max_negative - ab.sustain_negative
+			end
 		else
 			if ab.sustain_mana then
 				self.max_mana = self.max_mana + ab.sustain_mana
@@ -776,6 +810,12 @@ function _M:postUseTalent(ab, ret)
 			if ab.sustain_equilibrium then
 				self:incEquilibrium(-ab.sustain_equilibrium)
 			end
+			if ab.sustain_positive then
+				self.max_positive = self.max_positive + ab.sustain_positive
+			end
+			if ab.sustain_negative then
+				self.max_negative = self.max_negative + ab.sustain_negative
+			end
 		end
 	else
 		if ab.mana then
@@ -784,6 +824,12 @@ function _M:postUseTalent(ab, ret)
 		if ab.stamina then
 			self:incStamina(-ab.stamina * (100 + self.fatigue) / 100)
 		end
+		if ab.positive then
+			self:incPositive(-ab.positive * (100 + self.fatigue) / 100)
+		end
+		if ab.negative then
+			self:incNegative(-ab.negative * (100 + self.fatigue) / 100)
+		end
 		-- Equilibrium is not affected by fatigue
 		if ab.equilibrium then
 			self:incEquilibrium(ab.equilibrium)
@@ -830,6 +876,8 @@ function _M:getTalentFullDescription(t)
 	if t.stamina or t.sustain_stamina then d[#d+1] = "#6fff83#Stamina cost: #ffcc80#"..(t.stamina or t.sustain_stamina) end
 	if t.equilibrium or t.sustain_equilibrium then d[#d+1] = "#6fff83#Equilibrium cost: #00ff74#"..(t.equilibrium or t.sustain_equilibrium) end
 	if t.vim or t.sustain_vim then d[#d+1] = "#6fff83#Vim cost: #888888#"..(t.vim or t.sustain_vim) end
+	if t.positive or t.sustain_positive then d[#d+1] = "#6fff83#Positive energy cost: #GOLD#"..(t.positive or t.sustain_positive) end
+	if t.negative or t.sustain_negative then d[#d+1] = "#6fff83#Negative energy cost: #GREY#"..(t.negative or t.sustain_negative) end
 	if self:getTalentRange(t) > 1 then d[#d+1] = "#6fff83#Range: #FFFFFF#"..self:getTalentRange(t)
 	else d[#d+1] = "#6fff83#Range: #FFFFFF#melee/personal"
 	end
diff --git a/game/modules/tome/class/PlayerDisplay.lua b/game/modules/tome/class/PlayerDisplay.lua
index b86e18b5f7028109aa1ddfcaddc5890e60373b94..48a630cbfd36eb9b7f948225dc5d4b4f0802782e 100644
--- a/game/modules/tome/class/PlayerDisplay.lua
+++ b/game/modules/tome/class/PlayerDisplay.lua
@@ -69,12 +69,15 @@ function _M:display()
 	if game.player:knowTalent(game.player.T_MANA_POOL) then
 		self.surface:drawColorString(self.font, ("#7fffd4#Mana:    #00ff00#%d/%d"):format(game.player:getMana(), game.player.max_mana), 0, h, 255, 255, 255) h = h + self.font_h
 	end
-	if game.player:knowTalent(game.player.T_SOUL_POOL) then
-		self.surface:drawColorString(self.font, ("#777777#Soul:    #00ff00#%d/%d"):format(game.player:getSoul(), game.player.max_soul), 0, h, 255, 255, 255) h = h + self.font_h
-	end
 	if game.player:knowTalent(game.player.T_EQUILIBRIUM_POOL) then
 		self.surface:drawColorString(self.font, ("#00ff74#Equi:    #00ff00#%d"):format(game.player:getEquilibrium()), 0, h, 255, 255, 255) h = h + self.font_h
 	end
+	if game.player:knowTalent(game.player.T_POSITIVE_POOL) then
+		self.surface:drawColorString(self.font, ("#7fffd4#Positive:#GOLD#%d/%d"):format(game.player:getPositive(), game.player.max_positive), 0, h, 255, 255, 255) h = h + self.font_h
+	end
+	if game.player:knowTalent(game.player.T_NEGATIVE_POOL) then
+		self.surface:drawColorString(self.font, ("#7fffd4#Negative:#GREY#%d/%d"):format(game.player:getNegative(), game.player.max_negative), 0, h, 255, 255, 255) h = h + self.font_h
+	end
 
 	h = h + self.font_h
 	self.surface:drawColorString(self.font, ("STR: #00ff00#%3d"):format(game.player:getStr()), 0, h, 255, 255, 255) h = h + self.font_h
diff --git a/game/modules/tome/class/generator/actor/Sandworm.lua b/game/modules/tome/class/generator/actor/Sandworm.lua
index 7f2841c6a3b4a6525dc9a04ffdabc1250355e9aa..1d94ce38946b1599db1392c22700d5f53f910a23 100644
--- a/game/modules/tome/class/generator/actor/Sandworm.lua
+++ b/game/modules/tome/class/generator/actor/Sandworm.lua
@@ -26,12 +26,10 @@ local Random = require "engine.generator.actor.Random"
 module(..., package.seeall, class.inherit(engine.Generator))
 
 function _M:init(zone, map, level, spots)
-	engine.Generator.init(self, zone, map)
-	self.level = level
+	engine.Generator.init(self, zone, map, level, spots)
 	self.data = level.data.generator.actor
-	self.spots = spots
 
-	self.random = Random.new(zone, map, level)
+	self.random = Random.new(zone, map, level, spots)
 end
 
 function _M:generate()
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index c2d397cdac5213d8f7a21d622319a546b8a5d96c..10de968e1e3fad546c4ef5d5c9d359b90ce05b44 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -297,6 +297,19 @@ function _M:attackTargetWith(target, weapon, damtype, mult)
 		end
 	end end
 
+	-- Weapon of light cast
+	if hitted and self:knowTalent(self.T_WEAPON_OF_LIGHT) and self:isTalentActive(self.T_WEAPON_OF_LIGHT) then
+		local dam = 7 + self:getTalentLevel(self.T_WEAPON_OF_LIGHT) * self:combatSpellpower(0.092)
+		DamageType:get(DamageType.LIGHT).projector(self, target.x, target.y, DamageType.LIGHT, dam)
+		self:incPositive(-3)
+		if self:getPositive() <= 0 then
+			local old = self.energy.value
+			self.energy.value = 100000
+			self:useTalent(self.T_WEAPON_OF_LIGHT)
+			self.energy.value = old
+		end
+	end
+
 	-- Shadow cast
 	if hitted and self:knowTalent(self.T_SHADOW_COMBAT) and self:isTalentActive(self.T_SHADOW_COMBAT) and self:getMana() > 0 then
 		local dam = 3 + self:getTalentLevel(self.T_SHADOW_COMBAT) * 2
diff --git a/game/modules/tome/data/birth/classes/divine.lua b/game/modules/tome/data/birth/classes/divine.lua
index a7179e62fdde6f7e4f5a019f40837ef5a43494ef..0414ee83246d6ebbc0f210988baad112a4faefe0 100644
--- a/game/modules/tome/data/birth/classes/divine.lua
+++ b/game/modules/tome/data/birth/classes/divine.lua
@@ -57,17 +57,17 @@ newBirthDescriptor{
 		["divine/light"]={false, 0},
 	},
 	talents = {
+		[ActorTalents.T_SEARING_LIGHT] = 1,
 		[ActorTalents.T_CHANT_OF_FORTITUDE] = 1,
 		[ActorTalents.T_WEAPON_COMBAT] = 1,
 		[ActorTalents.T_HEAVY_ARMOUR_TRAINING] = 1,
-		[ActorTalents.T_MASSIVE_ARMOUR_TRAINING] = 1,
 	},
 	copy = {
 		max_life = 110,
 		life_rating = 12,
 		resolvers.equip{ id=true,
 			{type="weapon", subtype="mace", name="iron mace", autoreq=true},
-			{type="armor", subtype="massive", name="iron plate armour", autoreq=true}
+			{type="armor", subtype="heavy", name="iron heavy armour", autoreq=true}
 		},
 	},
 }
diff --git a/game/modules/tome/data/factions.lua b/game/modules/tome/data/factions.lua
index 791027261b46b1b289c06fae5427f2ddaaab0935..38fe7f8b1d7757e721a221c27795beadb398452a 100644
--- a/game/modules/tome/data/factions.lua
+++ b/game/modules/tome/data/factions.lua
@@ -19,21 +19,23 @@
 
 -- CSV export
 local src = [[
-,Enemies,,Reunited Kingdom,Shire,Lonely Mountain,Eryn Lasgalen,Angolwen,Tol Falas,,Water lair|H,Assassin lair|H,,Sunwall,Orc Pride
-Enemies,,,,,,,,,,,,,,
-,,,,,,,,,,,,,,
-Reunited Kingdom,-1,,,,,,,,,,,,,
-Shire,-1,,1,,,,,,,,,,,
-Lonely Mountain,-1,,0.5,1,,,,,,,,,,
-Eryn Lasgalen,-1,,0.5,1,0.3,,,,,,,,,
-Angolwen,-1,,,,,,,,,,,,,
-Tol Falas,,,-1,-1,-1,-1,-1,,,,,,,
-,,,,,,,,,,,,,,
-Water lair|H,-1,,,,,,,,,,,,,
-Assassin lair|H,,,,,,,,,,,,,,
-,,,,,,,,,,,,,,
-Sunwall,-1,,,,,,0,-1,,,-1,,,
-Orc Pride,,,-1,-1,-1,-1,-1,-1,,,,,-1,
+,Enemies,,Reunited Kingdom,Shire,Lonely Mountain,Eryn Lasgalen,Angolwen,Tol Falas,,Water lair|H,Assassin lair|H,,Sunwall,Orc Pride,,Sandworm Burrowers
+Enemies,,,,,,,,,,,,,,,,
+,,,,,,,,,,,,,,,,
+Reunited Kingdom,-1,,,,,,,,,,,,,,,
+Shire,-1,,1,,,,,,,,,,,,,
+Lonely Mountain,-1,,0.5,1,,,,,,,,,,,,
+Eryn Lasgalen,-1,,0.5,1,0.3,,,,,,,,,,,
+Angolwen,-1,,,,,,,,,,,,,,,
+Tol Falas,,,-1,-1,-1,-1,-1,,,,,,,,,
+,,,,,,,,,,,,,,,,
+Water lair|H,-1,,,,,,,,,,,,,,,
+Assassin lair|H,,,,,,,,,,,,,,,,
+,,,,,,,,,,,,,,,,
+Sunwall,-1,,,,,,0,-1,,,-1,,,,,
+Orc Pride,,,-1,-1,-1,-1,-1,-1,,,,,-1,,,
+,,,,,,,,,,,,,,,,
+Sandworm Burrowers,,,,,,,,,,,,,,,,
 ]]
 
 local facts = {}
diff --git a/game/modules/tome/data/general/npcs/snake.lua b/game/modules/tome/data/general/npcs/snake.lua
index fc842373f92d29a8ae087cd1e9a7780632d20123..fd69b80ffe8d129a59952fcb85d103d1a6b949c1 100644
--- a/game/modules/tome/data/general/npcs/snake.lua
+++ b/game/modules/tome/data/general/npcs/snake.lua
@@ -107,8 +107,8 @@ newEntity{ base = "BASE_NPC_SNAKE",
 newEntity{ base = "BASE_NPC_SNAKE",
 	name = "anaconda", color=colors.YELLOW_GREEN,
 	desc = [[You recoil in fear as you notice this huge, 10 meter long snake.  It seeks to crush the life out of you.]],
-	level_range = {1, 50}, exp_worth = 1,
-	rarity = 1,
+	level_range = {20, 50}, exp_worth = 1,
+	rarity = 9,
 	rank = 9,
 	max_life = resolvers.rngavg(100,120),
 	combat_armor = 14, combat_def = 5,
diff --git a/game/modules/tome/data/talents/divine/chants.lua b/game/modules/tome/data/talents/divine/chants.lua
index 901781a6237f2b99451f0408eb58a9bf30b9eb41..743ae57b7be51bb955797b0e2253638428a3d035 100644
--- a/game/modules/tome/data/talents/divine/chants.lua
+++ b/game/modules/tome/data/talents/divine/chants.lua
@@ -36,6 +36,7 @@ newTalent{
 	require = divi_req1,
 	points = 5,
 	cooldown = 30,
+	sustain_positive = 20,
 	tactical = {
 		BUFF = 10,
 	},
@@ -75,6 +76,7 @@ newTalent{
 	require = divi_req2,
 	points = 5,
 	cooldown = 30,
+	sustain_positive = 20,
 	tactical = {
 		BUFF = 10,
 	},
@@ -112,6 +114,7 @@ newTalent{
 	require = divi_req3,
 	points = 5,
 	cooldown = 30,
+	sustain_positive = 20,
 	tactical = {
 		BUFF = 10,
 	},
@@ -154,6 +157,7 @@ newTalent{
 	require = divi_req4,
 	points = 5,
 	cooldown = 30,
+	sustain_positive = 20,
 	tactical = {
 		BUFF = 10,
 	},
diff --git a/game/modules/tome/data/talents/divine/combat.lua b/game/modules/tome/data/talents/divine/combat.lua
index fd27cc27eb74eab7d2b0fc67dbdefb94eeb37bc6..ea34bf2d1387d0375ccd57d44945f547261c8e69 100644
--- a/game/modules/tome/data/talents/divine/combat.lua
+++ b/game/modules/tome/data/talents/divine/combat.lua
@@ -23,26 +23,25 @@ newTalent{
 	mode = "sustained",
 	require = divi_req1,
 	points = 5,
-	cooldown = 30,
+	cooldown = 10,
+	sustain_positive = 10,
 	tactical = {
 		BUFF = 10,
 	},
 	range = 20,
 	activate = function(self, t)
-		local dam = 7 + self:getTalentLevel(t) * self:combatSpellpower(0.092)
 		game:playSoundNear(self, "talents/spell_generic2")
 		local ret = {
-			onhit = self:addTemporaryValue("melee_project", {[DamageType.LIGHT]=dam}),
 		}
 		return ret
 	end,
 	deactivate = function(self, t, p)
-		self:removeTemporaryValue("melee_project", p.onhit)
 		return true
 	end,
 	info = function(self, t)
 		return ([[Infuse your weapon of the power of the Sun, doing %0.2f light damage with each hit.
-		The damage will increase with the Magic stat]]):format(8 + self:combatSpellpower(0.092) * self:getTalentLevel(t))
+		Each hit will drain 3 positive energy, the spell ends when energy reaches 0.
+		The damage will increase with the Magic stat]]):format(7 + self:combatSpellpower(0.092) * self:getTalentLevel(t))
 	end,
 }
 
@@ -52,6 +51,7 @@ newTalent{
 	require = divi_req2,
 	points = 5,
 	cooldown = 22,
+	positive = 25,
 	tactical = {
 		ATTACK = 10,
 	},
@@ -64,7 +64,7 @@ newTalent{
 		local _ _, x, y = self:canProject(tg, x, y)
 		game:playSoundNear(self, "talents/spell_generic")
 		local target = game.level.map(x, y, Map.ACTOR)
-		if target and target:checkHit(src:combatSpellpower(), target:combatMentalResist(), 0, 95, 15)then
+		if target and target:checkHit(self:combatSpellpower(), target:combatMentalResist(), 0, 95, 15)then
 			target:setEffect(self.EFF_MARTYRDOM, 10, {power=8 * self:getTalentLevelRaw(t)})
 		else
 			return
@@ -85,7 +85,8 @@ newTalent{
 	type = {"divine/combat",3},
 	require = divi_req3,
 	points = 5,
-	cooldown = 10,
+	cooldown = 6,
+	positive = 10,
 	tactical = {
 		ATTACK = 10,
 	},
@@ -115,7 +116,8 @@ newTalent{
 	type = {"divine/combat", 4},
 	require = divi_req4,
 	points = 5,
-	cooldown = 20,
+	cooldown = 10,
+	positive = 10,
 	tactical = {
 		ATTACKAREA = 10,
 	},
diff --git a/game/modules/tome/data/talents/divine/light.lua b/game/modules/tome/data/talents/divine/light.lua
index 557900c579ba06588fb4cfd71dbd96f2154363e2..2ee4fc62c1c588f85a4600102601b0d890d4dc08 100644
--- a/game/modules/tome/data/talents/divine/light.lua
+++ b/game/modules/tome/data/talents/divine/light.lua
@@ -23,6 +23,7 @@ newTalent{
 	require = spells_req1,
 	points = 5,
 	cooldown = 40,
+	positive = -10,
 	tactical = {
 		HEAL = 10,
 	},
@@ -42,8 +43,8 @@ newTalent{
 	type = {"divine/light", 2},
 	require = spells_req2,
 	points = 5,
---	mana = 60,
 	cooldown = 10,
+	positive = -20,
 	tactical = {
 		HEAL = 10,
 	},
@@ -76,6 +77,7 @@ newTalent{
 	require = spells_req3,
 	points = 5,
 --	mana = 30,
+	positive = -20,
 	cooldown = 60,
 	action = function(self, t)
 		self:setEffect(self.EFF_DAMAGE_SHIELD, 10, {power=(10 + self:getMag(30)) * self:getTalentLevel(t)})
@@ -92,56 +94,15 @@ newTalent{
 	type = {"divine/light", 4},
 	require = spells_req4,
 	points = 5,
---	mana = 60,
 	cooldown = 100,
+	positive = -30,
 	tactical = {
 		ATTACK = 10,
 	},
 	action = function(self, t)
-		-- Find space
-		local x, y = util.findFreeGrid(self.x, self.y, 5, true, {[Map.ACTOR]=true})
-		if not x then
-			game.logPlayer(self, "Not enough space to invoke the guardian!")
-			return
-		end
-		print("Invoking guardian on", x, y)
-
-		local NPC = require "mod.class.NPC"
-		local bear = NPC.new{
-			type = "animal", subtype = "bear",
-			display = "q", color=colors.LIGHT_GREEN,
-			name = "guardian bear", faction = self.faction,
-			desc = [[A bear summoned by the powers of nature to help you.]],
-			autolevel = "warrior",
-			ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=3, },
-			energy = { mod=1 },
-			stats = { str=18, dex=13, mag=5, con=15 },
-			resolvers.tmasteries{ ["technique/other"]=0.25 },
-
-			resolvers.talents{ [Talents.T_STUN]=2 },
-			max_stamina = 100,
-
-			resists = { [DamageType.COLD] = 20, [DamageType.NATURE] = 20 },
-			level_range = {self.level, self.level}, exp_worth = 0,
-
-			max_life = resolvers.rngavg(100,150),
-			life_rating = 10,
-
-			combat_armor = 7, combat_def = 3,
-			combat = { dam=resolvers.rngavg(12,25), atk=10, apr=10, physspeed=2 },
-
-			summoner = self,
-			summon_time = util.bound(self:getTalentLevel(t) * self:combatSpellpower(0.10), 5, 90),
-		}
-
-		bear:resolve()
-		game.zone:addEntity(game.level, bear, "actor", x, y)
-
-		game:playSoundNear(self, "talents/spell_generic")
 		return true
 	end,
 	info = function(self, t)
-		return ([[Call upon the forces of nature to summon a bear ally for %d turns.
-		The power of the ally will increase with the Magic stat]]):format(util.bound(self:getTalentLevel(t) * self:combatSpellpower(0.10), 5, 90))
+		return ([[NOT FINISHED]])
 	end,
 }
diff --git a/game/modules/tome/data/talents/divine/sun.lua b/game/modules/tome/data/talents/divine/sun.lua
index 1669457b1925342265be9e9313c3bb99d19b7fa8..84040579199a0b304ec799ea7ebef5ab816ee331 100644
--- a/game/modules/tome/data/talents/divine/sun.lua
+++ b/game/modules/tome/data/talents/divine/sun.lua
@@ -22,7 +22,8 @@ newTalent{
 	type = {"divine/sun", 1},
 	require = divi_req1,
 	points = 5,
-	cooldown = 9,
+	cooldown = 6,
+	positive = -15,
 	tactical = {
 		ATTACK = 10,
 	},
@@ -38,7 +39,7 @@ newTalent{
 		-- Add a lasting map effect
 		game.level.map:addEffect(self,
 			x, y, 4,
-			DamageType.LIGHT, 6 + self:combatSpellpower(0.2) * self:getTalentLevel(t),
+			DamageType.LIGHT, 6 + self:combatSpellpower(0.3) * self:getTalentLevel(t),
 			0,
 			5, nil,
 			{type="light_zone"},
@@ -50,7 +51,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		return ([[Calls the power of the Sun into a searing light doing %0.2f damage and leaving a spot on the ground for 4 turns doing %0.2f damage.
-		The damage will increase with the Magic stat]]):format(6 + self:combatSpellpower(0.3) * self:getTalentLevel(t), 6 + self:combatSpellpower(0.2) * self:getTalentLevel(t))
+		The damage will increase with the Magic stat]]):format(6 + self:combatSpellpower(0.3) * self:getTalentLevel(t), 6 + self:combatSpellpower(0.3) * self:getTalentLevel(t))
 	end,
 }
 
@@ -60,6 +61,7 @@ newTalent{
 	require = divi_req2,
 	points = 5,
 	cooldown = 22,
+	positive = -15,
 	tactical = {
 		ATTACK = 10,
 	},
@@ -70,7 +72,7 @@ newTalent{
 		local grids = self:project(tg, self.x, self.y, DamageType.BLIND, 3 + self:getTalentLevel(t))
 		self:project(tg, self.x, self.y, DamageType.LITE, 1)
 		if self:getTalentLevel(t) then
-			self:project(tg, self.x, self.y, DamageType.LIGHT, 4 + self:combatSpellpower(0.1) * self:getTalentLevel(t))
+			self:project(tg, self.x, self.y, DamageType.LIGHT, 4 + self:combatSpellpower(0.15) * self:getTalentLevel(t))
 		end
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "sunburst", {radius=tg.radius, grids=grids, tx=self.x, ty=self.y, max_alpha=80})
 		game:playSoundNear(self, "talents/flame")
@@ -81,7 +83,7 @@ newTalent{
 		At level 3 it will start dealing %0.2f light damage.
 		The damage will increase with the Magic stat]]):
 		format(
-			4 + self:combatSpellpower(0.1) * self:getTalentLevel(t)
+			4 + self:combatSpellpower(0.15) * self:getTalentLevel(t)
 		)
 	end,
 }
@@ -91,7 +93,8 @@ newTalent{
 	type = {"divine/sun",3},
 	require = divi_req3,
 	points = 5,
-	cooldown = 10,
+	cooldown = 7,
+	positive = -20,
 	tactical = {
 		ATTACK = 10,
 	},
@@ -100,7 +103,7 @@ newTalent{
 		local tg = {type="beam", range=self:getTalentRange(t), talent=t}
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
-		self:project(tg, x, y, DamageType.FIRE, self:spellCrit(10 + self:combatSpellpower(0.2) * self:getTalentLevel(t)))
+		self:project(tg, x, y, DamageType.FIRE, self:spellCrit(10 + self:combatSpellpower(0.4) * self:getTalentLevel(t)))
 		local _ _, x, y = self:canProject(tg, x, y)
 		game.level.map:particleEmitter(self.x, self.y, math.max(math.abs(x-self.x), math.abs(y-self.y)), "light_beam", {tx=x-self.x, ty=y-self.y})
 
@@ -108,9 +111,9 @@ newTalent{
 		return true
 	end,
 	info = function(self, t)
-		return ([[Fire a beam of sun flames at your foes, burning all those in line for %0.2f light damage.
+		return ([[Fire a beam of sun flames at your foes, burning all those in line for %0.2f fire damage.
 		The damage will increase with the Magic stat]]):
-		format(10 + self:combatSpellpower(0.2) * self:getTalentLevel(t))
+		format(10 + self:combatSpellpower(0.4) * self:getTalentLevel(t))
 	end,
 }
 
@@ -119,14 +122,15 @@ newTalent{
 	type = {"divine/sun", 4},
 	require = divi_req4,
 	points = 5,
-	cooldown = 35,
+	cooldown = 15,
+	positive = -20,
 	tactical = {
 		ATTACKAREA = 10,
 	},
 	range = 3,
 	action = function(self, t)
 		local tg = {type="ball", range=0, radius=3, friendlyfire=false, talent=t}
-		local grids = self:project(tg, self.x, self.y, DamageType.LIGHT, self:spellCrit(10 + self:combatSpellpower(0.17) * self:getTalentLevel(t)))
+		local grids = self:project(tg, self.x, self.y, DamageType.LIGHT, self:spellCrit(10 + self:combatSpellpower(0.27) * self:getTalentLevel(t)))
 
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "sunburst", {radius=tg.radius, grids=grids, tx=self.x, ty=self.y})
 
@@ -134,7 +138,7 @@ newTalent{
 		return true
 	end,
 	info = function(self, t)
-		return ([[Conjures a furious burst of sunlight, dealing %0.2f light damage to all those around you in a radius of 3.
-		The damage will increase with the Magic stat]]):format(self:getTalentLevel(t), 10 + self:combatSpellpower(0.17) * self:getTalentLevel(t))
+		return ([[Conjures a furious burst of sunlight, dealing %0.2f light damage to all those around you in a radius of 4.
+		The damage will increase with the Magic stat]]):format(self:getTalentLevel(t), 10 + self:combatSpellpower(0.27) * self:getTalentLevel(t))
 	end,
 }
diff --git a/game/modules/tome/data/talents/misc/misc.lua b/game/modules/tome/data/talents/misc/misc.lua
index 6151fc42263ef4fcf8d227e024368759a048d914..2244cc4d06fe416a4e4916e9c055248a65772247 100644
--- a/game/modules/tome/data/talents/misc/misc.lua
+++ b/game/modules/tome/data/talents/misc/misc.lua
@@ -52,6 +52,20 @@ newTalent{
 	mode = "passive",
 	hide = true,
 }
+newTalent{
+	name = "Positive Pool",
+	type = {"base/class", 1},
+	info = "Allows you to have a positive energy pool.",
+	mode = "passive",
+	hide = true,
+}
+newTalent{
+	name = "Negative Pool",
+	type = {"base/class", 1},
+	info = "Allows you to have a negative energy pool.",
+	mode = "passive",
+	hide = true,
+}
 
 newTalent{
 	name = "Improved Health I",
diff --git a/game/modules/tome/data/talents/spells/divination.lua b/game/modules/tome/data/talents/spells/divination.lua
index 69414b24f455ae89c4a4c480880bcdd0f5e1cc4c..574273f3f93c4d837d4053d97b9bf691396766bd 100644
--- a/game/modules/tome/data/talents/spells/divination.lua
+++ b/game/modules/tome/data/talents/spells/divination.lua
@@ -58,7 +58,7 @@ newTalent{
 		if self:getTalentLevel(t) < 3 then
 			self:showEquipInven("Identify object", function(o) return not o:isIdentified() end, function(o)
 				o:identify(true)
-				game.logPlayer(self, "You identify: "..o:getName{do_color=true})
+				game.logPlayer(self, "You identify: %s", o:getName{do_color=true})
 				return true
 			end)
 			return true
diff --git a/game/modules/tome/data/talents/spells/fire.lua b/game/modules/tome/data/talents/spells/fire.lua
index d93a083bd238159939f3106af2edf894784d801f..143cab10f1d90ce51d4f38c2091fd4003e833388 100644
--- a/game/modules/tome/data/talents/spells/fire.lua
+++ b/game/modules/tome/data/talents/spells/fire.lua
@@ -33,13 +33,13 @@ newTalent{
 		local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
-		self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(25 + self:combatSpellpower(1.2) * self:getTalentLevel(t)), {type="flame"})
+		self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(25 + self:combatSpellpower(0.8) * self:getTalentLevel(t)), {type="flame"})
 		game:playSoundNear(self, "talents/fire")
 		return true
 	end,
 	info = function(self, t)
 		return ([[Conjures up a bolt of fire, setting the target ablaze and doing %0.2f fire damage over 3 turns.
-		The damage will increase with the Magic stat]]):format(25 + self:combatSpellpower(1.2) * self:getTalentLevel(t))
+		The damage will increase with the Magic stat]]):format(25 + self:combatSpellpower(0.8) * self:getTalentLevel(t))
 	end,
 }
 
diff --git a/game/modules/tome/data/zones/sandworm-lair/npcs.lua b/game/modules/tome/data/zones/sandworm-lair/npcs.lua
index f1b2560b2c2f87eabc1d5a5cb9217e4c7b6780f4..a48ecca781f67cc4916d7f9db7887f9720b7619d 100644
--- a/game/modules/tome/data/zones/sandworm-lair/npcs.lua
+++ b/game/modules/tome/data/zones/sandworm-lair/npcs.lua
@@ -35,7 +35,7 @@ newEntity{ define_as = "SANDWORM_TUNNELER",
 	Maybe following it is the only way to move around here...]],
 	level_range = {12, 50}, exp_worth = 0,
 	max_life = 10000,
-	faction = "sandworm burrowers",
+	faction = "sandworm-burrowers",
 	energy = {mod=1},
 
 	move_body = 1,
diff --git a/game/modules/tome/data/zones/sandworm-lair/zone.lua b/game/modules/tome/data/zones/sandworm-lair/zone.lua
index 9b79d42321195ae46fc37823aa3b6434d8972dbb..74e584273f749c5527b8fb2b915a1cad365a8ac2 100644
--- a/game/modules/tome/data/zones/sandworm-lair/zone.lua
+++ b/game/modules/tome/data/zones/sandworm-lair/zone.lua
@@ -25,6 +25,7 @@ return {
 	decay = {300, 800},
 	actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end,
 	width = 50, height = 50,
+	no_level_connectivity = true,
 --	all_remembered = true,
 --	all_lited = true,
 	persistant = "zone",
diff --git a/game/modules/tome/data/zones/tol-falas/npcs.lua b/game/modules/tome/data/zones/tol-falas/npcs.lua
index f12ae19920a940e5f1413a54758dc9f62bd5a099..e73ad86d73ef9d0efe4665c7c2b3e1a54a511193 100644
--- a/game/modules/tome/data/zones/tol-falas/npcs.lua
+++ b/game/modules/tome/data/zones/tol-falas/npcs.lua
@@ -57,6 +57,7 @@ newEntity{ define_as = "THE_MASTER",
 	see_invisible = 20,
 	undead = 1,
 	self_resurrect = 1,
+	open_door = 1,
 
 	resolvers.talents{
 		[Talents.T_SUMMON]=1,
diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua
index 798a2335740c3c82177f24c7c729080fc319e52c..56e18084d67eefb6f346d180fc9fec8117152fd6 100644
--- a/game/modules/tome/load.lua
+++ b/game/modules/tome/load.lua
@@ -74,7 +74,8 @@ ActorResource:defineResource("Stamina", "stamina", ActorTalents.T_STAMINA_POOL,
 ActorResource:defineResource("Mana", "mana", ActorTalents.T_MANA_POOL, "mana_regen", "Mana represents your reserve of magical energies. Each spell cast consumes mana and each sustained spell reduces your maximum mana.")
 ActorResource:defineResource("Equilibrium", "equilibrium", ActorTalents.T_EQUILIBRIUM_POOL, "equilibrium_regen", "Equilibrium represents your stand in the grand balance of nature. The closer it is to 0 the more in-balance you are. Being out of equilibrium will impact negatively on your ability to use Wild Gifts.")
 ActorResource:defineResource("Vim", "vim", ActorTalents.T_VIM_POOL, "vim_regen", "Vim represents the amount of life energies/souls you have stolen. Each corruption talents requires some.")
---ActorResource:defineResource("Destiny", "destiny", nil, "destiny_regen", "")
+ActorResource:defineResource("Positive", "positive", ActorTalents.T_POSITIVE_POOL, "positive_regen", "Positive energy represents your reserve of powitive power. It slowly decreases.")
+ActorResource:defineResource("Negative", "negative", ActorTalents.T_NEGATIVE_POOL, "negative_regen", "Negative energy represents your reserve of negative power. It slowly decreases.")
 
 -- Actor stats
 ActorStats:defineStat("Strength",	"str", 10, 1, 100, "Strength defines your character's ability to apply physical force. It increases your melee damage, damage done with heavy weapons, your chance to resist physical effects, and carrying capacity.")
diff --git a/ideas/factions.ods b/ideas/factions.ods
index 55563a1dfed20f88bcdba97dca2e6a87a2f477e0..2ea66ef2410da5a518e1f00d8993fc44ebbcb94c 100644
Binary files a/ideas/factions.ods and b/ideas/factions.ods differ
diff --git a/ideas/zones.ods b/ideas/zones.ods
index 510e4ea89fb5675987b6e3038d46030378ca35e2..c1fc3e2049d4dd4d681ce6ad21f1cdc7c07a7cf4 100644
Binary files a/ideas/zones.ods and b/ideas/zones.ods differ