diff --git a/src/doomdata.h b/src/doomdata.h
index e6857323eaf67e2e29af7540f955f7e9203c3122..5c692aec237b2b363483f85f86bbaaa3a8f58a7d 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -196,6 +196,9 @@ typedef struct
 #pragma pack()
 #endif
 
+#define NUMMAPTHINGARGS 6
+#define NUMMAPTHINGSTRINGARGS 2
+
 // Thing definition, position, orientation and type,
 // plus visibility flags and attributes.
 typedef struct
@@ -208,6 +211,8 @@ typedef struct
 	UINT8 extrainfo;
 	taglist_t tags;
 	fixed_t scale;
+	INT32 args[NUMMAPTHINGARGS];
+	char *stringargs[NUMMAPTHINGSTRINGARGS];
 	struct mobj_s *mobj;
 } mapthing_t;
 
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 88458816035f2a357eb8945a88b60d82b83fe193..636bde088d856219f74f7febb71f44013df559ad 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -175,6 +175,9 @@ static const struct {
 	{META_SIDENUM,      "line_t.sidenum"},
 	{META_LINEARGS,     "line_t.args"},
 	{META_LINESTRINGARGS, "line_t.stringargs"},
+
+	{META_THINGARGS,     "mapthing.args"},
+	{META_THINGSTRINGARGS, "mapthing.stringargs"},
 #ifdef HAVE_LUA_SEGS
 	{META_NODEBBOX,     "node_t.bbox"},
 	{META_NODECHILDREN, "node_t.children"},
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 375041506e7f7a480b1485fa7214cb526338b4c2..5bcb36b42a228ef3344457e6e2b20e585da7eee2 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -54,6 +54,8 @@ extern lua_State *gL;
 #define META_SIDENUM "LINE_T*SIDENUM"
 #define META_LINEARGS "LINE_T*ARGS"
 #define META_LINESTRINGARGS "LINE_T*STRINGARGS"
+#define META_THINGARGS "MAPTHING_T*ARGS"
+#define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS"
 #ifdef HAVE_LUA_SEGS
 #define META_NODEBBOX "NODE_T*BBOX"
 #define META_NODECHILDREN "NODE_T*CHILDREN"
diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c
index 4269ae377c1a1e3c35eac30617015a573500930c..af9f922f3351705f0418c43c3bab4bac06fa8d5b 100644
--- a/src/lua_mobjlib.c
+++ b/src/lua_mobjlib.c
@@ -761,6 +761,42 @@ static int mobj_set(lua_State *L)
 #undef NOSETPOS
 #undef NOFIELD
 
+// args, i -> args[i]
+static int thingargs_get(lua_State *L)
+{
+	INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_THINGARGS));
+	int i = luaL_checkinteger(L, 2);
+	if (i < 0 || i >= NUMMAPTHINGARGS)
+		return luaL_error(L, LUA_QL("mapthing_t.args") " index cannot be %d", i);
+	lua_pushinteger(L, args[i]);
+	return 1;
+}
+
+// #args -> NUMMAPTHINGARGS
+static int thingargs_len(lua_State* L)
+{
+	lua_pushinteger(L, NUMMAPTHINGARGS);
+	return 1;
+}
+
+// stringargs, i -> stringargs[i]
+static int thingstringargs_get(lua_State *L)
+{
+	char **stringargs = *((char***)luaL_checkudata(L, 1, META_THINGSTRINGARGS));
+	int i = luaL_checkinteger(L, 2);
+	if (i < 0 || i >= NUMMAPTHINGSTRINGARGS)
+		return luaL_error(L, LUA_QL("mapthing_t.stringargs") " index cannot be %d", i);
+	lua_pushstring(L, stringargs[i]);
+	return 1;
+}
+
+// #stringargs -> NUMMAPTHINGSTRINGARGS
+static int thingstringargs_len(lua_State *L)
+{
+	lua_pushinteger(L, NUMMAPTHINGSTRINGARGS);
+	return 1;
+}
+
 static int mapthing_get(lua_State *L)
 {
 	mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
@@ -802,6 +838,16 @@ static int mapthing_get(lua_State *L)
 		number = mt->extrainfo;
 	else if(fastcmp(field,"tag"))
 		number = Tag_FGet(&mt->tags);
+	else if(fastcmp(field,"args"))
+	{
+		LUA_PushUserdata(L, mt->args, META_THINGARGS);
+		return 1;
+	}
+	else if(fastcmp(field,"stringargs"))
+	{
+		LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS);
+		return 1;
+	}
 	else if(fastcmp(field,"mobj")) {
 		LUA_PushUserdata(L, mt->mobj, META_MOBJ);
 		return 1;
@@ -918,6 +964,22 @@ int LUA_MobjLib(lua_State *L)
 		lua_setfield(L, -2, "__newindex");
 	lua_pop(L,1);
 
+	luaL_newmetatable(L, META_THINGARGS);
+		lua_pushcfunction(L, thingargs_get);
+		lua_setfield(L, -2, "__index");
+
+		lua_pushcfunction(L, thingargs_len);
+		lua_setfield(L, -2, "__len");
+	lua_pop(L, 1);
+
+	luaL_newmetatable(L, META_THINGSTRINGARGS);
+		lua_pushcfunction(L, thingstringargs_get);
+		lua_setfield(L, -2, "__index");
+
+		lua_pushcfunction(L, thingstringargs_len);
+		lua_setfield(L, -2, "__len");
+	lua_pop(L, 1);
+
 	luaL_newmetatable(L, META_MAPTHING);
 		lua_pushcfunction(L, mapthing_get);
 		lua_setfield(L, -2, "__index");
diff --git a/src/p_setup.c b/src/p_setup.c
index 802c877db4a21b4f1730e4b22c0b51ca1ba46d63..351ce3861bf278c0e700bfb7ae19cf10ef38ed1b 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1282,6 +1282,8 @@ static void P_LoadThings(UINT8 *data)
 		mt->extrainfo = (UINT8)(mt->type >> 12);
 		Tag_FSet(&mt->tags, 0);
 		mt->scale = FRACUNIT;
+		memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
+		memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
 		mt->pitch = mt->roll = 0;
 
 		mt->type &= 4095;
@@ -1616,6 +1618,22 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
 		mapthings[i].options |= MTF_OBJECTSPECIAL;
 	else if (fastcmp(param, "ambush") && fastcmp("true", val))
 		mapthings[i].options |= MTF_AMBUSH;
+
+	else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
+	{
+		size_t argnum = atol(param + 3);
+		if (argnum >= NUMMAPTHINGARGS)
+			return;
+		mapthings[i].args[argnum] = atol(val);
+	}
+	else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
+	{
+		size_t argnum = param[9] - '0';
+		if (argnum >= NUMMAPTHINGSTRINGARGS)
+			return;
+		mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
+		M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1);
+	}
 }
 
 /** From a given position table, run a specified parser function through a {}-encapsuled text.
@@ -1810,13 +1828,15 @@ static void P_LoadTextmap(void)
 	{
 		// Defaults.
 		mt->x = mt->y = 0;
-		mt->angle = 0;
+		mt->angle = mt->pitch = mt->roll = 0;
 		mt->type = 0;
 		mt->options = 0;
 		mt->z = 0;
 		mt->extrainfo = 0;
 		Tag_FSet(&mt->tags, 0);
 		mt->scale = FRACUNIT;
+		memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
+		memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
 		mt->mobj = NULL;
 
 		TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);