diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 46b789526f3e18131cb355a0d0e59a036cfb55ad..5fd10d418ff480a1e53d2111c1cdc14e75fbe3fe 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -2077,6 +2077,8 @@ methods:
   ^ returns actual emerged pmin, actual emerged pmax
 - write_to_map():  Writes the data loaded from the VoxelManip back to the map.
   ^ important: data must be set using VoxelManip:set_data before calling this
+- get_node_at(pos): Returns a MapNode table of the node currently loaded in 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
 - set_data(data):  Sets the data contents of the VoxelManip object
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index deeb5966f572fb74e44d17293b7b875320d6bf79..fedaccd0fd58c603d83de1b2513e345634b1490c 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -35,10 +35,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h"
 #include "pathfinder.h"
 
-
 #define GET_ENV_PTR ServerEnvironment* env =                                   \
 				dynamic_cast<ServerEnvironment*>(getEnv(L));                   \
-				if( env == NULL) return 0
+				if (env == NULL) return 0
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index 2a3cfcafa3393349e1cc559c8a71e65dde7760b7..554a573430827d37a593f2670d5332587c8ac7b8 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "lua_api/l_vmanip.h"
 #include "lua_api/l_internal.h"
+#include "common/c_content.h"
 #include "common/c_converter.h"
 #include "emerge.h"
 #include "environment.h"
@@ -27,6 +28,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "server.h"
 #include "mapgen.h"
 
+#define GET_ENV_PTR ServerEnvironment* env =                                   \
+				dynamic_cast<ServerEnvironment*>(getEnv(L));                   \
+				if (env == NULL) return 0
+
 // garbage collector
 int LuaVoxelManip::gc_object(lua_State *L)
 {
@@ -105,13 +110,37 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
 	return 0;
 }
 
-int LuaVoxelManip::l_update_liquids(lua_State *L)
+int LuaVoxelManip::l_get_node_at(lua_State *L)
 {
+	NO_MAP_LOCK_REQUIRED;
+	GET_ENV_PTR;
+
 	LuaVoxelManip *o = checkobject(L, 1);
+	v3s16 pos        = read_v3s16(L, 2);
 
-	Environment *env = getEnv(L);
-	if (!env)
-		return 0;
+	pushnode(L, o->vm->getNodeNoExNoEmerge(pos), env->getGameDef()->ndef());
+	return 1;
+}
+
+int LuaVoxelManip::l_set_node_at(lua_State *L)
+{
+	NO_MAP_LOCK_REQUIRED;
+	GET_ENV_PTR;
+
+	LuaVoxelManip *o = checkobject(L, 1);
+	v3s16 pos        = read_v3s16(L, 2);
+	MapNode n        = readnode(L, 3, env->getGameDef()->ndef());
+
+	o->vm->setNodeNoEmerge(pos, n);
+
+	return 0;
+}
+
+int LuaVoxelManip::l_update_liquids(lua_State *L)
+{
+	GET_ENV_PTR;
+
+	LuaVoxelManip *o = checkobject(L, 1);
 
 	Map *map = &(env->getMap());
 	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
@@ -399,6 +428,8 @@ const luaL_reg LuaVoxelManip::methods[] = {
 	luamethod(LuaVoxelManip, read_from_map),
 	luamethod(LuaVoxelManip, get_data),
 	luamethod(LuaVoxelManip, set_data),
+	luamethod(LuaVoxelManip, get_node_at),
+	luamethod(LuaVoxelManip, set_node_at),
 	luamethod(LuaVoxelManip, write_to_map),
 	luamethod(LuaVoxelManip, update_map),
 	luamethod(LuaVoxelManip, update_liquids),
diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h
index 70468b3448498a7a39042333275bd4a689dfff02..608b555561036fc8eb043df0efb45c01ffbc5d05 100644
--- a/src/script/lua_api/l_vmanip.h
+++ b/src/script/lua_api/l_vmanip.h
@@ -47,6 +47,9 @@ class LuaVoxelManip : public ModApiBase {
 	static int l_set_data(lua_State *L);
 	static int l_write_to_map(lua_State *L);
 
+	static int l_get_node_at(lua_State *L);
+	static int l_set_node_at(lua_State *L);
+
 	static int l_update_map(lua_State *L);
 	static int l_update_liquids(lua_State *L);