diff --git a/src/lua_libs.h b/src/lua_libs.h
index d19ad88578de24bfa4a3f14163f2b39ac750c717..25552eacbe507a9c09f18007923959f0220a9e9a 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -42,6 +42,7 @@ extern lua_State *gL;
 
 #define META_CVAR "CONSVAR_T*"
 
+#define META_SECTORLINES "SECTOR_T*LINES"
 #define META_SIDENUM "LINE_T*SIDENUM"
 
 #define META_HUDINFO "HUDINFO_T*"
diff --git a/src/lua_maplib.c b/src/lua_maplib.c
index 0a5c5712a821a08110675e430b7967b60d773415..b6b5147a9abbfa939c14e3bb14a5f7bc0af9cf39 100644
--- a/src/lua_maplib.c
+++ b/src/lua_maplib.c
@@ -37,6 +37,7 @@ enum sector_e {
 	sector_thinglist,
 	sector_heightsec,
 	sector_camsec,
+	sector_lines,
 	sector_ffloors
 };
 
@@ -52,6 +53,7 @@ static const char *const sector_opt[] = {
 	"thinglist",
 	"heightsec",
 	"camsec",
+	"lines",
 	"ffloors",
 	NULL};
 
@@ -260,6 +262,67 @@ static int sector_iterate(lua_State *L)
 	return 3;
 }
 
+// sector.lines, i -> sector.lines[i]
+// sector.lines.valid, for validity checking
+static int sectorlines_get(lua_State *L)
+{
+	line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
+	size_t i;
+	size_t numoflines = 0;
+	lua_settop(L, 2);
+	if (!lua_isnumber(L, 2))
+	{
+		int field = luaL_checkoption(L, 2, NULL, valid_opt);
+		if (!seclines)
+		{
+			if (field == 0) {
+				lua_pushboolean(L, 0);
+				return 1;
+			}
+			return luaL_error(L, "accessed sector_t doesn't exist anymore.");
+		} else if (field == 0) {
+			lua_pushboolean(L, 1);
+			return 1;
+		}
+	}
+
+	// check first linedef to figure which of its sectors owns this sector->lines pointer
+	// then check that sector's linecount to get a maximum index
+	//if (!seclines[0])
+		//return luaL_error(L, "no lines found!"); // no first linedef?????
+	if (seclines[0]->frontsector->lines == seclines)
+		numoflines = seclines[0]->frontsector->linecount;
+	else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
+		numoflines = seclines[0]->backsector->linecount;
+	//if neither sector has it then ???
+
+	if (!numoflines)
+		return luaL_error(L, "no lines found!");
+
+	i = (size_t)lua_tointeger(L, 2);
+	if (i >= numoflines)
+		return 0;
+	LUA_PushUserdata(L, seclines[i], META_LINE);
+	return 1;
+}
+
+static int sectorlines_num(lua_State *L)
+{
+	line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
+	size_t numoflines = 0;
+	// check first linedef to figure which of its sectors owns this sector->lines pointer
+	// then check that sector's linecount to get a maximum index
+	//if (!seclines[0])
+		//return luaL_error(L, "no lines found!"); // no first linedef?????
+	if (seclines[0]->frontsector->lines == seclines)
+		numoflines = seclines[0]->frontsector->linecount;
+	else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
+		numoflines = seclines[0]->backsector->linecount;
+	//if neither sector has it then ???
+	lua_pushinteger(L, numoflines);
+	return 1;
+}
+
 static int sector_get(lua_State *L)
 {
 	sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@@ -325,6 +388,9 @@ static int sector_get(lua_State *L)
 			return 0;
 		LUA_PushUserdata(L, &sectors[sector->camsec], META_SECTOR);
 		return 1;
+	case sector_lines: // lines
+		LUA_PushUserdata(L, sector->lines, META_SECTORLINES);
+		return 1;
 	case sector_ffloors: // ffloors
 		lua_pushcfunction(L, lib_iterateSectorFFloors);
 		LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
@@ -1234,6 +1300,14 @@ static int mapheaderinfo_get(lua_State *L)
 
 int LUA_MapLib(lua_State *L)
 {
+	luaL_newmetatable(L, META_SECTORLINES);
+		lua_pushcfunction(L, sectorlines_get);
+		lua_setfield(L, -2, "__index");
+
+		lua_pushcfunction(L, sectorlines_num);
+		lua_setfield(L, -2, "__len");
+	lua_pop(L, 1);
+
 	luaL_newmetatable(L, META_SECTOR);
 		lua_pushcfunction(L, sector_get);
 		lua_setfield(L, -2, "__index");