diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua
index 5bcc235c64decc7616474003cb3e93111763dd2c..38d6d2071705aa0c43294049b619be35a0a775b7 100644
--- a/game/engines/default/engine/Entity.lua
+++ b/game/engines/default/engine/Entity.lua
@@ -577,6 +577,14 @@ function _M:addTemporaryValue(prop, v, noupdate)
 				local b = (base[prop] or 1) - 1
 				b = 1 - (1 - b) * (1 - v)
 				base[prop] = b + 1
+			elseif method == "highest" then
+				base["__thighest_"..prop] = base["__thighest_"..prop] or {}
+				base["__thighest_"..prop][id] = v
+				base[prop] = table.max(base["__thighest_"..prop])
+			elseif method == "lowest" then
+				base["__tlowest_"..prop] = base["__tlowest_"..prop] or {}
+				base["__tlowest_"..prop][id] = v
+				base[prop] = table.min(base["__tlowest_"..prop])
 			else
 				base[prop] = (base[prop] or 0) + v
 			end
@@ -645,6 +653,16 @@ function _M:removeTemporaryValue(prop, id, noupdate)
 				local b = base[prop] - 1
 				b = 1 - (1 - b) / (1 - v)
 				base[prop] = b + 1
+			elseif method == "highest" then
+				base["__thighest_"..prop] = base["__thighest_"..prop] or {}
+				base["__thighest_"..prop][id] = nil
+				base[prop] = table.max(base["__thighest_"..prop])
+				if not next(base["__thighest_"..prop]) then base["__thighest_"..prop] = nil end
+			elseif method == "lowest" then
+				base["__tlowest_"..prop] = base["__tlowest_"..prop] or {}
+				base["__tlowest_"..prop][id] = nil
+				base[prop] = table.min(base["__tlowest_"..prop])
+				if not next(base["__tlowest_"..prop]) then base["__tlowest_"..prop] = nil end
 			else
 				base[prop] = base[prop] - v
 			end
diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua
index fc0d061b461fe3c271b56285deac2c8f877c79ee..513cde4ac560d74d58170dd195eada5cefaebcfa 100644
--- a/game/engines/default/engine/utils.lua
+++ b/game/engines/default/engine/utils.lua
@@ -23,6 +23,26 @@ function lpeg.anywhere (p)
 	return lpeg.P{ p + 1 * lpeg.V(1) }
 end
 
+function table.min(t)
+	local m = nil
+	for _, v in pairs(t) do
+		if not m then m = v
+		else m = math.min(m, v)
+		end
+	end
+	return m
+end
+
+function table.max(t)
+	local m = nil
+	for _, v in pairs(t) do
+		if not m then m = v
+		else m = math.max(m, v)
+		end
+	end
+	return m
+end
+
 function table.print(src, offset)
 	offset = offset or ""
 	for k, e in pairs(src) do
@@ -263,6 +283,10 @@ function string.ordinal(number)
 	return number..suffix
 end
 
+function string.trim(str)
+	return str:gsub("^%s*(.-)%s*$", "%1")
+end
+
 function string.a_an(str)
 	local first = str:sub(1, 1)
 	if first == "a" or first == "e" or first == "i" or first == "o" or first == "u" or first == "y" then return "an "..str
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 28605690e17937b137b12fcf0340da8a8a096f89..2a61a13145051e518296dd096d67b367ecec95d0 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -73,6 +73,9 @@ _M.temporary_values_conf.movement_speed = "mult0"
 _M.temporary_values_conf.combat_physspeed = "mult0"
 _M.temporary_values_conf.combat_spellspeed = "mult0"
 
+-- Damage cap takes the lowest
+_M.temporary_values_conf.flat_damage_cap = "lowest"
+
 function _M:init(t, no_default)
 	-- Define some basic combat stats
 	self.energyBase = 0
@@ -154,6 +157,9 @@ function _M:init(t, no_default)
 	t.inc_damage = t.inc_damage or {}
 	t.inc_damage_actor_type = t.inc_damage_actor_type or {}
 
+	t.flat_damage_armor = t.flat_damage_armor or {}
+	t.flat_damage_cap = t.flat_damage_cap or {}
+
 	-- Default regen
 	t.air_regen = t.air_regen or 3
 	t.mana_regen = t.mana_regen or 0.5
@@ -631,14 +637,14 @@ function _M:loadBuildOrder(file)
 		local line = f:readLine()
 		if not line then break end
 		line = line:gsub('[\r\n"]', '')
-		local split = line:split(',')
+		local split = line:split(lpeg.S",; \t")
 
 		if split[1] == "#Name" then cur = "name"
 		elseif split[1] == "#Stats" then cur = "stats"
 		elseif split[1] == "#Talents" then cur = "talents"
 		elseif split[1] == "#Types" then cur = "types"
 		else
-			if cur == "name" then b.name = split[1]
+			if cur == "name" then b.name = table.concat(split, " "):trim()
 			elseif cur == "stats" then
 				b.stats = {}
 				for i, s in ipairs(split) do if s ~= "" then table.insert(b.stats, s) end end
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index cfe782c4b74408bdb1776bb260506f434c81e2a8..68a428974a0220317d071e29b3ec78b0eaed0f8c 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -191,6 +191,24 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 			dam = t.on_damage(target, t, type, dam)
 		end
 
+		-- Flat damage reduction ("armour")
+		if target.flat_damage_armor then
+			local dec = (target.flat_damage_armor.all or 0) + (target.flat_damage_armor[type] or 0)
+			dam = math.max(0, dam - dec)
+			print("[PROJECTOR] after flat damage armor", dam)
+		end
+
+		-- Flat damage cap
+		if target.flat_damage_cap then
+			local cap = nil
+			if target.flat_damage_cap.all then cap = target.flat_damage_cap.all end
+			if target.flat_damage_cap[type] then cap = target.flat_damage_cap[type] end
+			if cap and cap > 0 then
+				dam = math.max(math.min(dam, cap), 0)
+				print("[PROJECTOR] after flat damage cap", dam)
+			end
+		end
+
 		if src:attr("stunned") then
 			dam = dam * 0.3
 			print("[PROJECTOR] stunned dam", dam)
@@ -254,7 +272,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 		if target ~= src and target.attr and target:attr("damage_resonance") and not target:hasEffect(target.EFF_RESONANCE) then
 			target:setEffect(target.EFF_RESONANCE, 5, {damtype=type, dam=target:attr("damage_resonance_on_hit")})
 		end
-		
+
 		if not target.dead and dam > 0 and type == DamageType.MIND and src and src.knowTalent and src:knowTalent(src.T_MADNESS) then
 			local t = src:getTalentFromId(src.T_MADNESS)
 			t.doMadness(target, t, src)
diff --git a/game/modules/tome/data/general/objects/egos/torques-powers.lua b/game/modules/tome/data/general/objects/egos/torques-powers.lua
index 175f61d7a9c85f3fed4ad65fb644d896a427f283..273c0a19bb6a5a4cf33d8bec2b6c31047ad52300 100644
--- a/game/modules/tome/data/general/objects/egos/torques-powers.lua
+++ b/game/modules/tome/data/general/objects/egos/torques-powers.lua
@@ -19,11 +19,11 @@
 
 --[[
 Torques
-psionic Shield
+psionic shield
 psychoportation
 clear mind
 adrenaline rush
-
+mind wave
 ]]
 
 newEntity{
diff --git a/game/modules/tome/data/general/objects/egos/totems-powers.lua b/game/modules/tome/data/general/objects/egos/totems-powers.lua
index d8c0bb218e869ade55a952886a9360cb27f658d8..7a5a54f041617ec3b660a97cc9aee18c7138d2b2 100644
--- a/game/modules/tome/data/general/objects/egos/totems-powers.lua
+++ b/game/modules/tome/data/general/objects/egos/totems-powers.lua
@@ -22,7 +22,7 @@ Totems
 *healing
 *cure illness
 *cure poisons
-thorny skin
+*thorny skin
 ]]
 
 newEntity{