diff --git a/game/engine/Particles.lua b/game/engine/Particles.lua
index 37eb47aea223de485d4fc5570263a012d8fb81b4..a1a4aba4bbd0c096a3784e3be51371d8509d154d 100644
--- a/game/engine/Particles.lua
+++ b/game/engine/Particles.lua
@@ -52,7 +52,7 @@ function _M:loaded()
 			local odef = self.def
 			print("[PARTICLE] Loading from /data/gfx/particles/"..self.def..".lua")
 			local f = loadfile("/data/gfx/particles/"..self.def..".lua")
-			setfenv(f, setmetatable(args or {}, {__index=_G}))
+			setfenv(f, setmetatable(self.args or {}, {__index=_G}))
 			def, fct, max = f()
 			max = max or 1000
 			_M.particles_def[odef] = f
diff --git a/game/modules/tome/data/gfx/particles/damage_shield.lua b/game/modules/tome/data/gfx/particles/damage_shield.lua
index 2d5ccd4ead80a6ce89f3bc93203cf0ee73b2b404..232e560bdd8394e46a87fd8d9503ae045cb9ccd1 100644
--- a/game/modules/tome/data/gfx/particles/damage_shield.lua
+++ b/game/modules/tome/data/gfx/particles/damage_shield.lua
@@ -22,6 +22,7 @@ return { generator = function()
 	local a = math.rad(ad)
 	local dir = math.rad(ad + 90)
 	local r = rng.range(14, 18)
+	local dirv = math.rad(2)
 
 	return {
 		trail = 1,
@@ -30,7 +31,7 @@ return { generator = function()
 
 		x = r * math.cos(a), xv = -0.1, xa = 0,
 		y = r * math.sin(a), yv = -0.1, ya = 0,
-		dir = dir, dirv = 1, dira = 0,
+		dir = dir, dirv = dirv, dira = 0,
 		vel = 1, velv = 0, vela = 0,
 
 		r = rng.range(100, 220)/255, rv = rng.range(0, 10), ra = 0,
diff --git a/game/modules/tome/data/gfx/particles/displacement_shield.lua b/game/modules/tome/data/gfx/particles/displacement_shield.lua
index 74521fb4d28c271fe7ad05883ca42f969a64871e..3378903b3e27605f67dafe8914e70db6696a7712 100644
--- a/game/modules/tome/data/gfx/particles/displacement_shield.lua
+++ b/game/modules/tome/data/gfx/particles/displacement_shield.lua
@@ -22,6 +22,7 @@ return { generator = function()
 	local a = math.rad(ad)
 	local dir = math.rad(ad + 90)
 	local r = rng.range(12, 20)
+	local dirv = math.rad(0.4)
 
 	return {
 		trail = 1,
@@ -30,7 +31,7 @@ return { generator = function()
 
 		x = r * math.cos(a), xv = -0.1, xa = 0,
 		y = r * math.sin(a), yv = -0.1, ya = 0,
-		dir = dir, dirv = 1, dira = 0,
+		dir = dir, dirv = dirv, dira = 0,
 		vel = 1, velv = 0, vela = 0,
 
 		r = rng.range(10, 220)/255, rv = rng.range(0, 10), ra = 0,
diff --git a/game/modules/tome/data/gfx/particles/disruption_shield.lua b/game/modules/tome/data/gfx/particles/disruption_shield.lua
index 164548c0840f808b1f21169b086481bd9eec755f..b93dcc32e277d18a3c4765cbb4807c922af90997 100644
--- a/game/modules/tome/data/gfx/particles/disruption_shield.lua
+++ b/game/modules/tome/data/gfx/particles/disruption_shield.lua
@@ -36,7 +36,7 @@ return { generator = function()
 		r = rng.range(130, 220)/255, rv = rng.range(0, 10), ra = 0,
 		g = 0,   gv = 0, ga = 0,
 		b = rng.range(170, 255)/255, bv = rng.range(0, 10), ba = 0,
-		a = 1,   av = 0, aa = 0,
+		a = rng.range(70, 255)/255,   av = 0, aa = 0,
 	}
 end, },
 function(self)
diff --git a/game/modules/tome/data/gfx/particles/phantasm_shield.lua b/game/modules/tome/data/gfx/particles/phantasm_shield.lua
new file mode 100644
index 0000000000000000000000000000000000000000..e80e0e89337c2098365a876062ffb775798099b3
--- /dev/null
+++ b/game/modules/tome/data/gfx/particles/phantasm_shield.lua
@@ -0,0 +1,45 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+return { generator = function()
+	local ad = rng.range(0, 360)
+	local a = math.rad(ad)
+	local dir = math.rad(ad + 90)
+	local r = rng.range(11, 14)
+
+	return {
+		trail = 1,
+		life = 5,
+		size = 4, sizev = 0, sizea = 0,
+
+		x = r * math.cos(a), xv = 0, xa = 0,
+		y = r * math.sin(a), yv = 0, ya = 0,
+		dir = dir, dirv = math.rad(0.7), dira = 0,
+		vel = 0.5, velv = 0, vela = 0,
+
+		r = 127/255, rv = 0, ra = 0,
+		g = 255/255, gv = 0, ga = 0,
+		b = 212/255, bv = 0, ba = 0,
+		a = rng.range(100, 220)/255,   av = 0.05, aa = 0,
+	}
+end, },
+function(self)
+	self.ps:emit(1)
+end,
+15
diff --git a/game/modules/tome/data/gfx/particles/stone_skin.lua b/game/modules/tome/data/gfx/particles/stone_skin.lua
new file mode 100644
index 0000000000000000000000000000000000000000..f98bd0554803602b417da2a3681f5d7945f3c12e
--- /dev/null
+++ b/game/modules/tome/data/gfx/particles/stone_skin.lua
@@ -0,0 +1,46 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+density = density or 1
+return { generator = function()
+	local ad = rng.range(0, 360)
+	local a = math.rad(ad)
+	local dir = math.rad(ad + 90)
+	local r = rng.range(11, 14)
+
+	return {
+		trail = 1,
+		life = 5,
+		size = 4, sizev = 0, sizea = 0,
+
+		x = r * math.cos(a), xv = 0, xa = 0,
+		y = r * math.sin(a), yv = 0, ya = 0,
+		dir = dir, dirv = math.rad(6), dira = 0,
+		vel = 2, velv = 0, vela = 0,
+
+		r = 0xD7/255, rv = 0, ra = 0,
+		g = 0x8E/255, gv = 0, ga = 0,
+		b = 0x45/255, bv = 0, ba = 0,
+		a = rng.range(100, 220)/255,   av = 0.05, aa = 0,
+	}
+end, },
+function(self)
+	self.ps:emit(1 * density)
+end,
+15 * density
diff --git a/game/modules/tome/data/gfx/particles/time_prison.lua b/game/modules/tome/data/gfx/particles/time_prison.lua
index 398862c4383335f3d059ffa4f4dfba9209987a0d..d9be155089820f9069b978552275b068ca1a87ba 100644
--- a/game/modules/tome/data/gfx/particles/time_prison.lua
+++ b/game/modules/tome/data/gfx/particles/time_prison.lua
@@ -25,12 +25,12 @@ return { generator = function()
 
 	return {
 		trail = 1,
-		life = 20,
-		size = 2, sizev = 0.2, sizea = 0,
+		life = 30,
+		size = 2, sizev = 0.08, sizea = 0,
 
 		x = r * math.cos(a), xv = 0, xa = 0,
 		y = r * math.sin(a), yv = 0, ya = 0,
-		dir = dir, dirv = 0, dira = 0,
+		dir = dir, dirv = math.rad(3), dira = math.rad(3) / 3,
 		vel = 1, velv = 0, vela = 0,
 
 		r = rng.range(10, 220)/255, rv = rng.range(0, 10), ra = 0,
@@ -40,6 +40,6 @@ return { generator = function()
 	}
 end, },
 function(self)
-	self.ps:emit(10)
+	self.ps:emit(5)
 end,
-100
+150
diff --git a/game/modules/tome/data/gfx/particles/time_shield.lua b/game/modules/tome/data/gfx/particles/time_shield.lua
index c663aa1b0ab39dd2bbbdeba24d5a291f64bd5c2c..2609b676094efa89a73fda1734a95274ab0a4e32 100644
--- a/game/modules/tome/data/gfx/particles/time_shield.lua
+++ b/game/modules/tome/data/gfx/particles/time_shield.lua
@@ -22,6 +22,7 @@ return { generator = function()
 	local a = math.rad(ad)
 	local dir = math.rad(ad + 90)
 	local r = rng.range(12, 20)
+	local dirv = math.rad(1)
 
 	return {
 		trail = 1,
@@ -30,7 +31,7 @@ return { generator = function()
 
 		x = r * math.cos(a), xv = -0.1, xa = 0,
 		y = r * math.sin(a), yv = -0.1, ya = 0,
-		dir = dir, dirv = 1, dira = 0,
+		dir = dir, dirv = dirv, dira = 0,
 		vel = 1, velv = 0, vela = 0,
 
 		r = rng.range(10, 220)/255, rv = rng.range(0, 10), ra = 0,
diff --git a/game/modules/tome/data/talents/spells/arcane.lua b/game/modules/tome/data/talents/spells/arcane.lua
index e309c764eeaa0f03e02b6e747f721d1c70ecca80..b01a439aaa1ea2f81dd85e0553a1f9c9fe087905 100644
--- a/game/modules/tome/data/talents/spells/arcane.lua
+++ b/game/modules/tome/data/talents/spells/arcane.lua
@@ -99,10 +99,9 @@ newTalent{
 		local power = math.max(0.8, 3 - (self:combatSpellpower(1) * self:getTalentLevel(t)) / 280)
 		self.disruption_shield_absorb = 0
 		game:playSoundNear(self, "talents/arcane")
-		local ps = self:addParticles(Particles.new("disruption_shield", 1))
 		return {
 			shield = self:addTemporaryValue("disruption_shield", power),
-			particle = ps,
+			particle = self:addParticles(Particles.new("disruption_shield", 1)),
 		}
 	end,
 	deactivate = function(self, t, p)
diff --git a/game/modules/tome/data/talents/spells/earth.lua b/game/modules/tome/data/talents/spells/earth.lua
index 99553033261d0e57c9b97c76041c3860cc854c82..b783510159ef2413a833e98fbe7e572b4b639c49 100644
--- a/game/modules/tome/data/talents/spells/earth.lua
+++ b/game/modules/tome/data/talents/spells/earth.lua
@@ -35,9 +35,11 @@ newTalent{
 		local power = 4 + self:combatSpellpower(0.03) * self:getTalentLevel(t)
 		return {
 			armor = self:addTemporaryValue("combat_armor", power),
+			particle = self:addParticles(Particles.new("stone_skin", 1)),
 		}
 	end,
 	deactivate = function(self, t, p)
+		self:removeParticles(p.particle)
 		self:removeTemporaryValue("combat_armor", p.armor)
 		return true
 	end,
diff --git a/game/modules/tome/data/talents/spells/phantasm.lua b/game/modules/tome/data/talents/spells/phantasm.lua
index bd0ab5243cb005373e9fbfa91ab6ad3d41124a5b..5a6e0dc2e9ee257de61c2d7702094fb47e80508d 100644
--- a/game/modules/tome/data/talents/spells/phantasm.lua
+++ b/game/modules/tome/data/talents/spells/phantasm.lua
@@ -56,10 +56,12 @@ newTalent{
 		local power = 4 + self:combatSpellpower(0.04) * self:getTalentLevel(t)
 		game:playSoundNear(self, "talents/heal")
 		return {
+			particle = self:addParticles(Particles.new("phantasm_shield", 1)),
 			def = self:addTemporaryValue("combat_def", power),
 		}
 	end,
 	deactivate = function(self, t, p)
+		self:removeParticles(p.particle)
 		self:removeTemporaryValue("combat_def", p.def)
 		return true
 	end,
@@ -84,10 +86,12 @@ newTalent{
 		local power = 10 + self:combatSpellpower(0.06) * self:getTalentLevel(t)
 		game:playSoundNear(self, "talents/heal")
 		return {
+			particle = self:addParticles(Particles.new("phantasm_shield", 1)),
 			onhit = self:addTemporaryValue("on_melee_hit", {[DamageType.ARCANE]=power}),
 		}
 	end,
 	deactivate = function(self, t, p)
+		self:removeParticles(p.particle)
 		self:removeTemporaryValue("on_melee_hit", p.onhit)
 		return true
 	end,
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 63e395bf2e71c260d01ff79a2006dfc0f17f5c1c..4102cad034db1f952f21bacf613ccb2172b19df1 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -195,9 +195,11 @@ newEffect{
 	on_gain = function(self, err) return "#Target# hardens its skin.", "+Earthen barrier" end,
 	on_lose = function(self, err) return "#Target# skin returns to normal.", "-Earthen barrier" end,
 	activate = function(self, eff)
+		eff.particle = self:addParticles(Particles.new("stone_skin", 1, {density=4}))
 		eff.tmpid = self:addTemporaryValue("resists", {[DamageType.PHYSICAL]=eff.power})
 	end,
 	deactivate = function(self, eff)
+		self:removeParticles(eff.particle)
 		self:removeTemporaryValue("resists", eff.tmpid)
 	end,
 }
diff --git a/ideas/spells.ods b/ideas/spells.ods
index 2526ad6e633d39df8bce7848f339f2c66dd4986f..a4c30ed8909aa589d69874aafbe175b224272bb2 100644
Binary files a/ideas/spells.ods and b/ideas/spells.ods differ