diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua
index 5b5e806f526af72fbc0417664244ce2445d11866..f8a4f0d64c50d59b260270bae335dc08944da8d2 100644
--- a/builtin/game/falling.lua
+++ b/builtin/game/falling.lua
@@ -6,42 +6,46 @@
 
 core.register_entity(":__builtin:falling_node", {
 	initial_properties = {
-		physical = true,
-		collide_with_objects = false,
-		collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
 		visual = "wielditem",
+		visual_size = {x = 0.667, y = 0.667},
 		textures = {},
-		visual_size = {x=0.667, y=0.667},
-	},
+		physical = true,
+		is_visible = false,
+		collide_with_objects = false,
+		collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
+	}
 
 	node = {},
 
 	set_node = function(self, node)
 		self.node = node
-		local prop = {
+		self.object:set_properties({
 			is_visible = true,
 			textures = {node.name},
-		}
-		self.object:set_properties(prop)
+		})
 	end,
 
 	get_staticdata = function(self)
-		return self.node.name
+		return core.serialize(self.node)
 	end,
 
 	on_activate = function(self, staticdata)
-		self.object:set_armor_groups({immortal=1})
-		if staticdata then
-			self:set_node({name=staticdata})
+		-- Set gravity
+		self.object:setacceleration({x = 0, y = -10, z = 0})
+		self.object:set_armor_groups({immortal = 1})
+		
+		local node = core.deserialize(staticdata)
+		if node then
+			self:set_node(node)
+		elseif staticdata ~= "" then
+			self:set_node({name = staticdata})
 		end
 	end,
 
 	on_step = function(self, dtime)
-		-- Set gravity
-		self.object:setacceleration({x=0, y=-10, z=0})
 		-- Turn to actual sand when collides to ground or just move
 		local pos = self.object:getpos()
-		local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
+		local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z} -- Position of bottom center point
 		local bcn = core.get_node(bcp)
 		local bcd = core.registered_nodes[bcn.name]
 		-- Note: walkable is in the node definition, not in item groups
@@ -52,7 +56,7 @@ core.register_entity(":__builtin:falling_node", {
 			if bcd and bcd.leveled and
 					bcn.name == self.node.name then
 				local addlevel = self.node.level
-				if addlevel == nil or addlevel <= 0 then
+				if not addlevel or addlevel <= 0 then
 					addlevel = bcd.leveled
 				end
 				if core.add_node_level(bcp, addlevel) == 0 then
@@ -65,7 +69,7 @@ core.register_entity(":__builtin:falling_node", {
 				core.remove_node(bcp)
 				return
 			end
-			local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
+			local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
 			-- Check what's here
 			local n2 = core.get_node(np)
 			-- If it's not air or liquid, remove node and replace it with
@@ -76,15 +80,13 @@ core.register_entity(":__builtin:falling_node", {
 				if core.registered_nodes[n2.name].buildable_to == false then
 					-- Add dropped items
 					local drops = core.get_node_drops(n2.name, "")
-					local _, dropped_item
 					for _, dropped_item in ipairs(drops) do
 						core.add_item(np, dropped_item)
 					end
 				end
 				-- Run script hook
-				local _, callback
 				for _, callback in ipairs(core.registered_on_dignodes) do
-					callback(np, n2, nil)
+					callback(np, n2)
 				end
 			end
 			-- Create node and remove entity
@@ -94,7 +96,7 @@ core.register_entity(":__builtin:falling_node", {
 			return
 		end
 		local vel = self.object:getvelocity()
-		if vector.equals(vel, {x=0,y=0,z=0}) then
+		if vector.equals(vel, {x = 0, y = 0, z = 0}) then
 			local npos = self.object:getpos()
 			self.object:setpos(vector.round(npos))
 		end
@@ -109,7 +111,7 @@ end
 function drop_attached_node(p)
 	local nn = core.get_node(p).name
 	core.remove_node(p)
-	for _,item in ipairs(core.get_node_drops(nn, "")) do
+	for _, item in ipairs(core.get_node_drops(nn, "")) do
 		local pos = {
 			x = p.x + math.random()/2 - 0.25,
 			y = p.y + math.random()/2 - 0.25,
@@ -121,25 +123,13 @@ end
 
 function check_attached_node(p, n)
 	local def = core.registered_nodes[n.name]
-	local d = {x=0, y=0, z=0}
+	local d = {x = 0, y = 0, z = 0}
 	if def.paramtype2 == "wallmounted" then
-		if n.param2 == 0 then
-			d.y = 1
-		elseif n.param2 == 1 then
-			d.y = -1
-		elseif n.param2 == 2 then
-			d.x = 1
-		elseif n.param2 == 3 then
-			d.x = -1
-		elseif n.param2 == 4 then
-			d.z = 1
-		elseif n.param2 == 5 then
-			d.z = -1
-		end
+		d = core.wallmounted_to_dir(n.param2)
 	else
 		d.y = -1
 	end
-	local p2 = {x=p.x+d.x, y=p.y+d.y, z=p.z+d.z}
+	local p2 = vector.add(p, d)
 	local nn = core.get_node(p2).name
 	local def2 = core.registered_nodes[nn]
 	if def2 and not def2.walkable then
@@ -155,7 +145,7 @@ end
 function nodeupdate_single(p, delay)
 	local n = core.get_node(p)
 	if core.get_item_group(n.name, "falling_node") ~= 0 then
-		local p_bottom = {x=p.x, y=p.y-1, z=p.z}
+		local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
 		local n_bottom = core.get_node(p_bottom)
 		-- Note: walkable is in the node definition, not in item groups
 		if core.registered_nodes[n_bottom.name] and
@@ -166,7 +156,7 @@ function nodeupdate_single(p, delay)
 				(not core.registered_nodes[n_bottom.name].walkable or
 					core.registered_nodes[n_bottom.name].buildable_to) then
 			if delay then
-				core.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false)
+				core.after(0.1, nodeupdate_single, p, false)
 			else
 				n.level = core.get_node_level(p)
 				core.remove_node(p)
@@ -186,14 +176,13 @@ end
 
 function nodeupdate(p, delay)
 	-- Round p to prevent falling entities to get stuck
-	p.x = math.floor(p.x+0.5)
-	p.y = math.floor(p.y+0.5)
-	p.z = math.floor(p.z+0.5)
-
-	for x = -1,1 do
-	for y = -1,1 do
-	for z = -1,1 do
-		nodeupdate_single({x=p.x+x, y=p.y+y, z=p.z+z}, delay or not (x==0 and y==0 and z==0))
+	p = vector.round(p)
+
+	for x = -1, 1 do
+	for y = -1, 1 do
+	for z = -1, 1 do
+		local d = vector.new(x, y, z)
+		nodeupdate_single(vector.add(p, d), delay or not (x == 0 and y == 0 and z == 0))
 	end
 	end
 	end