diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 9249703f6c23b2819c251e34734e19a1b666d2b7..b4a5fa1d8777c24852e11d58fb2e2218342c38b2 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -2647,7 +2647,9 @@ for 2D noise, and it must be must be larger than 1 for 3D noise (otherwise
   of 3D noise with values starting at `pos={x=,y=,z=}`
 * `get2dMap_flat(pos)`: returns a flat `<size.x * size.y>` element array of 2D noise
   with values starting at `pos={x=,y=}`
+    * if the param `buffer` is present, this table will be used to store the result instead
 * `get3dMap_flat(pos)`: Same as `get2dMap_flat`, but 3D noise
+    * if the param `buffer` is present, this table will be used to store the result instead
 
 ### `VoxelManip`
 An interface to the `MapVoxelManipulator` for Lua.
@@ -2665,8 +2667,9 @@ The map will be pre-loaded if two positions are passed to either.
   the `VoxelManip` at that position
 * `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at
   that position
-* `get_data()`: Gets the data read into the `VoxelManip` object
-    * returns raw node data is in the form of an array of node content IDs
+* `get_data(buffer)`: Gets the data read into the `VoxelManip` object
+    * returns raw node data in the form of an array of node content IDs
+    * if the param `buffer` is present, this table will be used to store the result instead
 * `set_data(data)`: Sets the data contents of the `VoxelManip` object
 * `update_map()`: Update map after writing chunk back to map.
     * To be used only by `VoxelManip` objects created by the mod itself;
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp
index 84f8875b803f3ff618f072139464d5e3bf330879..86ae9dba7b77a023fc8271c404f15efd80f85b30 100644
--- a/src/script/lua_api/l_noise.cpp
+++ b/src/script/lua_api/l_noise.cpp
@@ -174,9 +174,9 @@ int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
 	n->perlinMap2D(p.X, p.Y);
 
 	lua_newtable(L);
-	for (int y = 0; y != n->sy; y++) {
+	for (u32 y = 0; y != n->sy; y++) {
 		lua_newtable(L);
-		for (int x = 0; x != n->sx; x++) {
+		for (u32 x = 0; x != n->sx; x++) {
 			lua_pushnumber(L, n->result[i++]);
 			lua_rawseti(L, -2, x + 1);
 		}
@@ -191,14 +191,19 @@ int LuaPerlinNoiseMap::l_get2dMap_flat(lua_State *L)
 	NO_MAP_LOCK_REQUIRED;
 
 	LuaPerlinNoiseMap *o = checkobject(L, 1);
-	v2f p = check_v2f(L, 2);
+	v2f p                = check_v2f(L, 2);
+	bool use_buffer      = lua_istable(L, 3);
 
 	Noise *n = o->noise;
 	n->perlinMap2D(p.X, p.Y);
 
 	size_t maplen = n->sx * n->sy;
 
-	lua_newtable(L);
+	if (use_buffer)
+		lua_pushvalue(L, 3);
+	else
+		lua_newtable(L);
+
 	for (size_t i = 0; i != maplen; i++) {
 		lua_pushnumber(L, n->result[i]);
 		lua_rawseti(L, -2, i + 1);
@@ -222,11 +227,11 @@ int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
 	n->perlinMap3D(p.X, p.Y, p.Z);
 
 	lua_newtable(L);
-	for (int z = 0; z != n->sz; z++) {
+	for (u32 z = 0; z != n->sz; z++) {
 		lua_newtable(L);
-		for (int y = 0; y != n->sy; y++) {
+		for (u32 y = 0; y != n->sy; y++) {
 			lua_newtable(L);
-			for (int x = 0; x != n->sx; x++) {
+			for (u32 x = 0; x != n->sx; x++) {
 				lua_pushnumber(L, n->result[i++]);
 				lua_rawseti(L, -2, x + 1);
 			}
@@ -243,7 +248,8 @@ int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
 	NO_MAP_LOCK_REQUIRED;
 
 	LuaPerlinNoiseMap *o = checkobject(L, 1);
-	v3f p = check_v3f(L, 2);
+	v3f p                = check_v3f(L, 2);
+	bool use_buffer      = lua_istable(L, 3);
 
 	if (!o->m_is3d)
 		return 0;
@@ -253,7 +259,11 @@ int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
 
 	size_t maplen = n->sx * n->sy * n->sz;
 
-	lua_newtable(L);
+	if (use_buffer)
+		lua_pushvalue(L, 3);
+	else
+		lua_newtable(L);
+
 	for (size_t i = 0; i != maplen; i++) {
 		lua_pushnumber(L, n->result[i]);
 		lua_rawseti(L, -2, i + 1);
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index 061ee6036ea2f920d1d32dc2b80c44398531c3a8..ac6c10303d183ea8c38688c1d7df8dcad6e1df62 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -63,12 +63,18 @@ int LuaVoxelManip::l_get_data(lua_State *L)
 	NO_MAP_LOCK_REQUIRED;
 
 	LuaVoxelManip *o = checkobject(L, 1);
+	bool use_buffer  = lua_istable(L, 2);
+
 	MMVManip *vm = o->vm;
 
-	int volume = vm->m_area.getVolume();
+	u32 volume = vm->m_area.getVolume();
 
-	lua_newtable(L);
-	for (int i = 0; i != volume; i++) {
+	if (use_buffer)
+		lua_pushvalue(L, 2);
+	else
+		lua_newtable(L);
+
+	for (u32 i = 0; i != volume; i++) {
 		lua_Integer cid = vm->m_data[i].getContent();
 		lua_pushinteger(L, cid);
 		lua_rawseti(L, -2, i + 1);
@@ -87,8 +93,8 @@ int LuaVoxelManip::l_set_data(lua_State *L)
 	if (!lua_istable(L, 2))
 		return 0;
 
-	int volume = vm->m_area.getVolume();
-	for (int i = 0; i != volume; i++) {
+	u32 volume = vm->m_area.getVolume();
+	for (u32 i = 0; i != volume; i++) {
 		lua_rawgeti(L, 2, i + 1);
 		content_t c = lua_tointeger(L, -1);
 
@@ -228,10 +234,10 @@ int LuaVoxelManip::l_get_light_data(lua_State *L)
 	LuaVoxelManip *o = checkobject(L, 1);
 	MMVManip *vm = o->vm;
 
-	int volume = vm->m_area.getVolume();
+	u32 volume = vm->m_area.getVolume();
 
 	lua_newtable(L);
-	for (int i = 0; i != volume; i++) {
+	for (u32 i = 0; i != volume; i++) {
 		lua_Integer light = vm->m_data[i].param1;
 		lua_pushinteger(L, light);
 		lua_rawseti(L, -2, i + 1);
@@ -250,8 +256,8 @@ int LuaVoxelManip::l_set_light_data(lua_State *L)
 	if (!lua_istable(L, 2))
 		return 0;
 
-	int volume = vm->m_area.getVolume();
-	for (int i = 0; i != volume; i++) {
+	u32 volume = vm->m_area.getVolume();
+	for (u32 i = 0; i != volume; i++) {
 		lua_rawgeti(L, 2, i + 1);
 		u8 light = lua_tointeger(L, -1);
 
@@ -270,10 +276,10 @@ int LuaVoxelManip::l_get_param2_data(lua_State *L)
 	LuaVoxelManip *o = checkobject(L, 1);
 	MMVManip *vm = o->vm;
 
-	int volume = vm->m_area.getVolume();
+	u32 volume = vm->m_area.getVolume();
 
 	lua_newtable(L);
-	for (int i = 0; i != volume; i++) {
+	for (u32 i = 0; i != volume; i++) {
 		lua_Integer param2 = vm->m_data[i].param2;
 		lua_pushinteger(L, param2);
 		lua_rawseti(L, -2, i + 1);
@@ -292,8 +298,8 @@ int LuaVoxelManip::l_set_param2_data(lua_State *L)
 	if (!lua_istable(L, 2))
 		return 0;
 
-	int volume = vm->m_area.getVolume();
-	for (int i = 0; i != volume; i++) {
+	u32 volume = vm->m_area.getVolume();
+	for (u32 i = 0; i != volume; i++) {
 		lua_rawgeti(L, 2, i + 1);
 		u8 param2 = lua_tointeger(L, -1);