diff --git a/src/g_game.c b/src/g_game.c
index 13fdab8777ab277df306a332a56fb99d8d189a6b..a35d89aa1403cbd2d387aea4c843616e4729db18 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -45,6 +45,7 @@
 #include "lua_hook.h"
 #include "b_bot.h"
 #include "m_cond.h" // condition sets
+#include "lua_script.h"
 
 #include "lua_hud.h"
 
@@ -2194,8 +2195,20 @@ boolean G_Responder(event_t *ev)
 //
 boolean G_LuaResponder(event_t *ev)
 {
-	return (ev->type == ev_keydown && LUA_HookKey(ev->data1, HOOK(KeyDown))) ||
-		(ev->type == ev_keyup && LUA_HookKey(ev->data1, HOOK(KeyUp)));
+	boolean cancelled = false;
+
+	if (ev->type == ev_keydown)
+	{
+		cancelled = LUA_HookKey(ev, HOOK(KeyDown));
+		LUA_InvalidateUserdata(ev);
+	}
+	else if (ev->type == ev_keyup)
+	{
+		cancelled = LUA_HookKey(ev, HOOK(KeyUp));
+		LUA_InvalidateUserdata(ev);
+	}
+
+	return cancelled;
 }
 
 //
@@ -5240,4 +5253,3 @@ INT32 G_TicsToMilliseconds(tic_t tics)
 {
 	return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
 }
-
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 223b83c61f7d9c35a451a3ea217344a341fe7126..55f3bb81763d43d0d283548493af7b67be06dcd4 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -13,6 +13,7 @@
 #include "r_defs.h"
 #include "d_player.h"
 #include "s_sound.h"
+#include "d_event.h"
 
 /*
 Do you know what an 'X Macro' is? Such a macro is called over each element of
@@ -107,7 +108,7 @@ void LUA_HookInt(INT32 integer, int hook);
 void LUA_HookBool(boolean value, int hook);
 int  LUA_HookPlayer(player_t *, int hook);
 int  LUA_HookTiccmd(player_t *, ticcmd_t *, int hook);
-int  LUA_HookKey(INT32 keycode, int hook); // Hooks for key events
+int  LUA_HookKey(event_t *event, int hook); // Hooks for key events
 
 void LUA_HookThinkFrame(void);
 int  LUA_HookMobjLineCollide(mobj_t *, line_t *);
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index d1b0d3bdd21b26184f49079c622ae16ec23f5f87..1e04621264097ff10bbc9467f501d712bc941067 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -588,12 +588,12 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type)
 	return hook.status;
 }
 
-int LUA_HookKey(INT32 keycode, int hook_type)
+int LUA_HookKey(event_t *event, int hook_type)
 {
 	Hook_State hook;
 	if (prepare_hook(&hook, false, hook_type))
 	{
-		lua_pushinteger(gL, keycode);
+		LUA_PushUserdata(gL, event, META_KEYEVENT);
 		call_hooks(&hook, 1, 1, res_true);
 	}
 	return hook.status;