diff --git a/game/modules/tome/data/talents/spells/shades.lua b/game/modules/tome/data/talents/spells/shades.lua
index 56056a9ce15e0e0d2f163536d7a9b6dc964c3a95..bbf639d6e9615f07cd15cf7247d7d2d0eb715be8 100644
--- a/game/modules/tome/data/talents/spells/shades.lua
+++ b/game/modules/tome/data/talents/spells/shades.lua
@@ -219,6 +219,7 @@ newTalent{
 	tactical = { ATTACK = 2, ESCAPE = 1 },
 	requires_target = true,
 	getDuration = function(self, t) return math.floor(3 + self:getTalentLevel(t)) end,
+	getHealth = function(self, t) return 0.2 + self:combatTalentSpellDamage(t, 20, 500) / 1000 end,
 	action = function(self, t)
 		-- Find space
 		local x, y = util.findFreeGrid(self.x, self.y, 1, true, {[Map.ACTOR]=true})
@@ -242,7 +243,8 @@ newTalent{
 		m.on_added_to_level = nil
 
 		m.energy.value = 0
-		m.life = m.life
+		m.max_life = m.max_life * t.getHealth(self, t)
+		m.life = util.bound(m.life, 0, m.max_life)
 		m.forceLevelup = function() end
 		m.on_die = nil
 		m.on_acquire_target = nil
@@ -269,7 +271,8 @@ newTalent{
 		return true
 	end,
 	info = function(self, t)
-		return ([[Through the shadows you forge a temporary copy of yourself, existing for %d turns.]]):
-		format(t.getDuration(self, t))
+		return ([[Through the shadows you forge a temporary copy of yourself, existing for %d turns.
+		The copy possess your exact talents and stats and has %d%% life.]]):
+		format(t.getDuration(self, t), t.getHealth(self, t) * 100)
 	end,
 }
diff --git a/src/wait.c b/src/wait.c
index 5c687d4a5f16c5e6b71f9b753e6385b4bae469d8..cd6c07b9769d3d43e7ecb54c90aebedc814fc390 100644
--- a/src/wait.c
+++ b/src/wait.c
@@ -93,6 +93,11 @@ static void hook_wait_display(lua_State *L, lua_Debug *ar)
 {
 	waited_count++;
 	SDL_PumpEvents();
+
+	static int last_tick = 0;
+	int now = SDL_GetTicks();
+	if (now - last_tick < 300) return;
+	last_tick = now;
 	on_redraw();
 }