diff --git a/game/engines/default/engine/Game.lua b/game/engines/default/engine/Game.lua
index a691eb922c46a14018015725a16bb28fb8be8847..c81ecc4466ce1d5fb864d8a362334757828fec40 100644
--- a/game/engines/default/engine/Game.lua
+++ b/game/engines/default/engine/Game.lua
@@ -218,6 +218,20 @@ function _M:tick()
 	end
 
 	if self.cleanSounds then self:cleanSounds() end
+
+	-- Run tick end stuff
+	if self.on_tick_end and #self.on_tick_end > 0 then
+		local fs = self.on_tick_end
+		self.on_tick_end = {}
+		for i = 1, #fs do fs[i]() end
+	end
+end
+
+--- Register things to do on tick end
+function _M:onTickEnd(f)
+	self.on_tick_end = self.on_tick_end or {}
+
+	self.on_tick_end[#self.on_tick_end+1] = f
 end
 
 --- Called when a zone leaves a level
diff --git a/game/engines/default/engine/KeyBind.lua b/game/engines/default/engine/KeyBind.lua
index aed119905e993a6d989742564b93e5513b57dc6e..5597d5cad68463f7653c3dc418984cb6a143eb67 100644
--- a/game/engines/default/engine/KeyBind.lua
+++ b/game/engines/default/engine/KeyBind.lua
@@ -225,8 +225,6 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup, ismouse)
 		end end
 	end
 
-	if isup then return end
-
 	return engine.KeyCommand.receiveKey(self, sym, ctrl, shift, alt, meta, unicode, isup)
 end
 
diff --git a/game/engines/default/engine/KeyCommand.lua b/game/engines/default/engine/KeyCommand.lua
index 41b2ec16bc5b12e5730df2d9b61d938f3703bcfd..096c0f7bb0b39b7abc602a0d6bfd861753ee42ea 100644
--- a/game/engines/default/engine/KeyCommand.lua
+++ b/game/engines/default/engine/KeyCommand.lua
@@ -53,8 +53,6 @@ end
 function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
 	self:handleStatus(sym, ctrl, shift, alt, meta, unicode, isup)
 
-	if isup then return end
-
 	if self.ignore[sym] then return end
 
 	-- Convert locale
@@ -64,7 +62,7 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
 
 	if not self.commands[sym] and not self.commands[self.__DEFAULT] then
 		if self.on_input and unicode then self.on_input(unicode) handled = true end
-	elseif self.commands[sym] and (ctrl or shift or alt or meta) and not self.commands[sym].anymod then
+	elseif not isup and self.commands[sym] and (ctrl or shift or alt or meta) and not self.commands[sym].anymod then
 		local mods = {}
 		if alt then mods[#mods+1] = "alt" end
 		if ctrl then mods[#mods+1] = "ctrl" end
@@ -75,15 +73,15 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
 			self.commands[sym][mods](sym, ctrl, shift, alt, meta, unicode)
 			handled = true
 		end
-	elseif self.commands[sym] and self.commands[sym].plain then
+	elseif not isup and self.commands[sym] and self.commands[sym].plain then
 		self.commands[sym].plain(sym, ctrl, shift, alt, meta, unicode)
 		handled = true
-	elseif self.commands[self.__DEFAULT] and self.commands[self.__DEFAULT].plain then
+	elseif not isup and self.commands[self.__DEFAULT] and self.commands[self.__DEFAULT].plain then
 		self.commands[self.__DEFAULT].plain(sym, ctrl, shift, alt, meta, unicode)
 		handled = true
 	end
 
-	if self.atLast then self.atLast(sym, ctrl, shift, alt, meta, unicode) handled = true  end
+	if not isup and self.atLast then self.atLast(sym, ctrl, shift, alt, meta, unicode) handled = true  end
 	return handled
 end
 
diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua
index b8653ff1a72f8583332e0415c5d583e412a4ed91..ae76081cb3372ae7fdf90262472987222d278a30 100644
--- a/game/engines/default/engine/ui/Dialog.lua
+++ b/game/engines/default/engine/ui/Dialog.lua
@@ -228,6 +228,8 @@ function _M:init(title, w, h, x, y, alpha, font, showup, skin)
 	self.force_x = x
 	self.force_y = y
 
+	self.first_display = true
+
 	Base.init(self, {}, true)
 
 	self:resize(w, h, true)
@@ -556,9 +558,14 @@ end
 function _M:innerDisplay(x, y, nb_keyframes)
 end
 
+function _M:firstDisplay()
+end
+
 function _M:toScreen(x, y, nb_keyframes)
 	if self.__hidden then return end
 
+	if self.first_display then self:firstDisplay() end
+
 	local zoom = 1
 	if self.__showup then
 		local eff = self.__showup_effect or "pop"
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 74bc090385e45acc277dc31ac3e72cacdad7006d..4dafa96739f2465bb64f50ee7f8ece9060e01d96 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -150,9 +150,6 @@ function _M:run()
 	self.logSeen = function(e, style, ...) if e and e.x and e.y and self.level.map.seens(e.x, e.y) then self.log(style, ...) end end
 	self.logPlayer = function(e, style, ...) if e == self.player or e == self.party then self.log(style, ...) end end
 
-	-- List of stuff to do on tick end
-	self.on_tick_end = {}
-
 	-- Ok everything is good to go, activate the game in the engine!
 	self:setCurrent()
 
@@ -821,13 +818,8 @@ function _M:tick()
 		-- Fun stuff: this can make the game realtime, although calling it in display() will make it work better
 		-- (since display is on a set FPS while tick() ticks as much as possible
 		-- engine.GameEnergyBased.tick(self)
-	end
-
-	-- Run tick end stuff
-	if #self.on_tick_end > 0 then
-		local fs = self.on_tick_end
-		self.on_tick_end = {}
-		for i = 1, #fs do fs[i]() end
+	else
+		engine.Game.tick(self)
 	end
 
 	-- Check damages to log
@@ -874,12 +866,6 @@ function _M:delayedLogDamage(src, target, dam, desc)
 	t.total = t.total + dam
 end
 
---- Register things to do on tick end
--- This is used for recall spells to let the tick finish before switching levels
-function _M:onTickEnd(f)
-	self.on_tick_end[#self.on_tick_end+1] = f
-end
-
 --- Called every game turns
 -- Does nothing, you can override it
 function _M:onTurn()
diff --git a/game/modules/tome/data/gfx/shaders/sun.frag b/game/modules/tome/data/gfx/shaders/sun.frag
index 7cfce0c5144526a943e478a92fe9af21388d5769..153278461e41f31d5271e52225c9ef98ab2d2ddd 100644
--- a/game/modules/tome/data/gfx/shaders/sun.frag
+++ b/game/modules/tome/data/gfx/shaders/sun.frag
@@ -1,27 +1,48 @@
+#extension GL_EXT_gpu_shader4: enable
 uniform sampler2D tex;
+vec3 Color1 = vec3(0.9, 0.8, 0.0);
+vec3 Color2 = vec3(0.6, 0.4, 0.0);
+uniform float tick;
 
-void main(void)
+int LFSR_Rand_Gen(in int n)
 {
-//	gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
+	// <<, ^ and & require GL_EXT_gpu_shader4.
+	n = (n << 13) ^ n;
+	return (n * (n*n*15731+789221) + 1376312589) & 0x7fffffff;
+}
+
+float LFSR_Rand_Gen_f( in int n )
+{
+	return float(LFSR_Rand_Gen(n));
+}
 
-	int blursize = 3;
-	float blur = 3.0;
-	vec2 offset = 1.0 / vec2(512.0, 512.0);
+float noise3f(in vec3 p)
+{
+	ivec3 ip = ivec3(floor(p));
+	vec3 u = fract(p);
+	u = u*u*(3.0-2.0*u);
+
+	int n = ip.x + ip.y*57 + ip.z*113;
 
-	// Center Pixel
-	vec4 sample = vec4(0.0,0.0,0.0,0.0);
-	float factor = ((float(blursize)*2.0)+1.0);
-	factor = factor * factor;
+	float res = mix(mix(mix(LFSR_Rand_Gen_f(n+(0+57*0+113*0)),
+		LFSR_Rand_Gen_f(n+(1+57*0+113*0)),u.x),
+		mix(LFSR_Rand_Gen_f(n+(0+57*1+113*0)),
+			LFSR_Rand_Gen_f(n+(1+57*1+113*0)),u.x),u.y),
+		mix(mix(LFSR_Rand_Gen_f(n+(0+57*0+113*1)),
+			LFSR_Rand_Gen_f(n+(1+57*0+113*1)),u.x),
+			mix(LFSR_Rand_Gen_f(n+(0+57*1+113*1)),
+				LFSR_Rand_Gen_f(n+(1+57*1+113*1)),u.x),u.y),u.z);
 
-	for(int i = -blursize; i <= blursize; i++)
-	{
-		for(int j = -blursize; j <= blursize; j++)
-		{
-			sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
-		}
-	}
-	sample /= (blur*2.0) * (blur*2.0);
-	gl_FragColor = sample * 0.8;
+	return 1.0 - res*(1.0/1073741824.0);
+}
 
-//	gl_FragColor += vec4(0.3, 0.3, 0.3, 0);
+void main()
+{
+	float intensity =
+		abs(noise3f(vec3(gl_TexCoord[0].xy*100.0 + vec2(30.0,0.0), tick/3000.0)) - 0.25) +
+		abs(noise3f(vec3(gl_TexCoord[0].xy*100.0 + vec2(40.0,0.0), tick/3000.0)) - 0.125) +
+		abs(noise3f(vec3(gl_TexCoord[0].xy*100.0 + vec2(50.0,0.0), tick/3000.0)) - 0.0625);
+//	vec3 color = mix(Color1, Color2, intensity);
+	vec4 base = texture2D(tex, gl_TexCoord[0].xy);
+	gl_FragColor = vec4(base.rgb * 0.7 + base.rgb * intensity * 0.3, 1.0);
 }
diff --git a/src/core_lua.c b/src/core_lua.c
index 70212c8370bcf5a960908811b3f880152d03f1a0..3c4ae6c63678af18f3a770b62efaf68096a3d761 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -198,12 +198,18 @@ static int lua_get_scancode_name(lua_State *L)
 
 	return 1;
 }
+static int lua_flush_key_events(lua_State *L)
+{
+	SDL_FlushEvents(SDL_KEYDOWN, SDL_TEXTINPUT);
+	return 0;
+}
 
 static const struct luaL_reg keylib[] =
 {
 	{"set_current_handler", lua_set_current_keyhandler},
 	{"modState", lua_get_mod_state},
 	{"symName", lua_get_scancode_name},
+	{"flush", lua_flush_key_events},
 	{NULL, NULL},
 };
 
diff --git a/src/main.c b/src/main.c
index 720edba03181d238af317d31f39fa376d2442346..fce4d39f06525d0cf1341853c9f9481291decd4a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -236,10 +236,15 @@ extern SDL_Cursor *mouse_cursor;
 extern SDL_Cursor *mouse_cursor_down;
 void on_event(SDL_Event *event)
 {
+	static char *last_unicode = NULL;
+
 	switch (event->type) {
+	case SDL_TEXTINPUT:
+		if (last_unicode) free(last_unicode);
+		last_unicode = strdup(event->text.text);
+		break;
 	case SDL_KEYDOWN:
 	case SDL_KEYUP:
-	case SDL_TEXTINPUT:
 		if (current_keyhandler != LUA_NOREF)
 		{
 			lua_rawgeti(L, LUA_REGISTRYINDEX, current_keyhandler);
@@ -247,8 +252,7 @@ void on_event(SDL_Event *event)
 			lua_gettable(L, -2);
 			lua_remove(L, -2);
 			lua_rawgeti(L, LUA_REGISTRYINDEX, current_keyhandler);
-			if (event->type != SDL_TEXTINPUT) lua_pushnumber(L, event->key.keysym.scancode);
-			else lua_pushnumber(L, 0);
+			lua_pushnumber(L, event->key.keysym.scancode);
 
 			SDL_Keymod _pKeyState = SDL_GetModState();
 			lua_pushboolean(L, (_pKeyState & KMOD_CTRL) ? TRUE : FALSE);
@@ -256,9 +260,11 @@ void on_event(SDL_Event *event)
 			lua_pushboolean(L, (_pKeyState & KMOD_ALT) ? TRUE : FALSE);
 			lua_pushboolean(L, (_pKeyState & KMOD_GUI) ? TRUE : FALSE);
 
-			if (event->type == SDL_TEXTINPUT)
+			if (last_unicode)
 			{
-				lua_pushstring(L, event->text.text);
+				lua_pushstring(L, last_unicode);
+				free(last_unicode);
+				last_unicode = NULL;
 			}
 			else
 				lua_pushnil(L);