diff --git a/src/g_game.c b/src/g_game.c
index d92db011213d158af2f6842dcfa0b5caa38171ec..0bc1e85e70119f6d7fc979c2578a3d63ddb5018a 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2286,7 +2286,7 @@ boolean G_LuaResponder(event_t *ev)
 	}
 	else if (ev->type == ev_text)
 	{
-		cancelled = LUA_HookKey(ev, HOOK(TextInput));
+		cancelled = LUA_HookText(ev, HOOK(TextInput));
 		LUA_InvalidateUserdata(ev);
 	}
 
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 19775eb8a20cfa0e38b4ffe79ded3efe694923de..95ee67e1b7e3b4ac9118be54bf5ede45825a1b16 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -238,6 +238,7 @@ static const struct {
 	{META_LUABANKS,     "luabanks[]"},
 
 	{META_KEYEVENT,     "keyevent_t"},
+	{META_TEXTEVENT,    "textevent_t"},
 	{META_MOUSE,        "mouse_t"},
 	{NULL,              NULL}
 };
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 65dc81ddf22d10277f3232a31cc6f678a879ea0f..e49c22438c855b59ac21f0b8841344f434ca0235 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -135,6 +135,7 @@ 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(event_t *event, int hook); // Hooks for key events
+int  LUA_HookText(event_t *event, int hook); // Hooks for text events
 
 void LUA_HookPreThinkFrame(void);
 void LUA_HookThinkFrame(void);
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index 1bf3caf65fa502f70b447374b6b21600d6261c87..a39745438db6c8b9a690b0a24c3240f74f1975cc 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -690,6 +690,17 @@ int LUA_HookKey(event_t *event, int hook_type)
 	return hook.status;
 }
 
+int LUA_HookText(event_t *event, int hook_type)
+{
+	Hook_State hook;
+	if (prepare_hook(&hook, false, hook_type))
+	{
+		LUA_PushUserdata(gL, event, META_TEXTEVENT);
+		call_hooks(&hook, 1, res_true);
+	}
+	return hook.status;
+}
+
 void LUA_HookHUD(int hook_type, huddrawlist_h list)
 {
 	Hook_State hook;
diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c
index 054ae4cc450ac5d75dae8c16c5df2083965ae572..eb9fe7dc55a5947b6d5594f01fcda962ccfa0178 100644
--- a/src/lua_inputlib.c
+++ b/src/lua_inputlib.c
@@ -234,6 +234,28 @@ static int lib_lenGameKeyDown(lua_State *L)
 	return 1;
 }
 
+////////////////
+// TEXT EVENT //
+////////////////
+
+static int textevent_get(lua_State *L)
+{
+	event_t *event = *((event_t **)luaL_checkudata(L, 1, META_TEXTEVENT));
+	const char *field = luaL_checkstring(L, 2);
+
+	I_Assert(event != NULL);
+
+	if (fastcmp(field,"text"))
+	{
+		char s[2] = { event->key, 0 };
+		lua_pushstring(L, s);
+	}
+	else
+		return luaL_error(L, "textevent_t has no field named %s", field);
+
+	return 1;
+}
+
 ///////////////
 // KEY EVENT //
 ///////////////
@@ -299,6 +321,7 @@ static int mouse_num(lua_State *L)
 
 int LUA_InputLib(lua_State *L)
 {
+	LUA_RegisterUserdataMetatable(L, META_TEXTEVENT, textevent_get, NULL, NULL);
 	LUA_RegisterUserdataMetatable(L, META_KEYEVENT, keyevent_get, NULL, NULL);
 	LUA_RegisterUserdataMetatable(L, META_MOUSE, mouse_get, NULL, mouse_num);
 
diff --git a/src/lua_libs.h b/src/lua_libs.h
index e1585f488a8a6205b1ee967dcfeffac125680fee..592f46df560435b085b9fe025a263d6b1317e042 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -93,6 +93,7 @@ extern boolean ignoregameinputs;
 
 #define META_LUABANKS "LUABANKS[]*"
 
+#define META_TEXTEVENT "TEXTEVENT_T*"
 #define META_KEYEVENT "KEYEVENT_T*"
 #define META_MOUSE "MOUSE_T*"