	-- internal var net_master stores all slave nodes
	-- sparktech_net_passive = are used to follow nets, do not count towards energy
	-- sparktech_net_trigger = trigger updates
	-- Updates blocks every seconds

	local function compare_vec(va, vb)
		if va == nil or vb == nil then
				return false
		end
		return va.x == vb.x and va.y == vb.y and va.z == vb.z
	end


	local function add_node_to_net(pos, master) -- stores node in master meta
		local meta = minetest.get_meta(master)
		-- format x:y:z|x2:y2:z2
		local net_master = meta:get_string("net_master")
		net_master = net_master .. "|" .. pos.x .. ":" .. pos.y .. ":" .. pos.z;
		meta:set_string("net_master", net_master)
		local slavem = minetest.get_meta(pos)
		slavem:set_string("net_master", "")
	end


	-- All nodes processed in a build cycle
	-- Keeping track of caller nodes alone allows duplication
	local processed = {}

	-- The master of the network should not be limited to one branch
	local master = nil

	local function net_build(pos, callerpos, master_arg)
		-- Option to force the master node
		if (master_arg ~= nil) then
			master = master_arg
		end

		local onode = minetest.get_node(pos)

		-- Add node to the list of processed nodes so that it won’t be processed again
		-- A node can show up multiple times in this list!
		processed[#processed + 1] = pos

		-- LOGIC to check only x sides, can be done eventually lol
		-- e.g furnace only allows from below , or solar panels
		-- before this need api to make cables connect from those side only too! otherwise it makes no sense for viewers
		-- in game
		local top = {x = pos.x, y = pos.y + 1, z = pos.z}
		local bottom = {x = pos.x, y = pos.y - 1, z = pos.z}
		local left = {x = pos.x - 1, y = pos.y, z = pos.z}
		local right = {x = pos.x + 1, y = pos.y, z = pos.z}
		local front = {x = pos.x, y = pos.y, z = pos.z - 1}
		local back = {x = pos.x, y = pos.y, z = pos.z + 1}
		-- if at this point master is set to "none" the master is NOT known!
		-- in this case for every next block it has to be checked if it is a suitable master, if it is place your stuff in it
		for sidename, nodepos in pairs({top=top, bottom=bottom, left=left, right=right, front=front, back=back}) do -- as long as the order of directions is ok its ok
			-- if the position has already been processed ignore it
			local already_processed = false
			for _, cpos in pairs(processed) do
				if compare_vec(cpos, nodepos) then
		already_processed = true
		break
				end
			end
			if (not already_processed) then
				local node = minetest.get_node(nodepos)
				local meta = minetest.get_meta(nodepos)
				local net_passive = minetest.get_item_group(node.name,"sparktech_net_passive")
				if (net_passive == 0 and meta:get_int("sparktech_net_passive") == 1) then
					net_passive = 1
				end
				local net_trigger = minetest.get_item_group(node.name,"sparktech_net_trigger")
				-- net passives are followed along to create the network (aka cables) but they do not get power,
				-- and are not considered by the network
				-- TODO recursion
				local ntrigontrig = (net_trigger == 1 and (minetest.get_item_group(onode.name, "sparktech_net_trigger") == 0)) -- Only allow trigger node if the source node it not a trigger node
				if (net_trigger == 1 and master == nil) then
		master = nodepos;
		meta:set_string("net_master", nil)
				end -- if no master is set the code will just run around checking for one, if it doesnt find one well, doesnt matter, its just cables then
				if (master ~= nil and ntrigontrig and nodepos ~= master) then -- we have a master, so we can store stuff in it :D
		meta:set_string("net_master", nil)
		-- the node is a trigger, so we store their stuff in the master node
		-- at this point it could be the master if we set it above
		add_node_to_net(nodepos, master) -- we set all relevant data for this node, lets continue there

		-- Now the node shouldn’t be processed by the net_build anymore
		processed[#processed + 1] = nodepos
				end
				if (net_passive ~= 0 or ntrigontrig) then
				net_build(nodepos, pos)
				end
			end
		end
		-- To have a clear enviroment for the next build we clear the processed list at the final return
		-- TODO This will cause problems if another network is build before the previous network finishes building
		-- Only the node triggering a build won’t have a caller
		if (callerpos == nil) then
			processed = {}
			master = nil
		end
		
		return -- at this point all nodes have been processed, so we can return to the calling node
	end

	local function add_node(pos, newnode)
		local meta = minetest.get_meta(pos)
		if (minetest.get_item_group(newnode.name, "sparktech_net_passive") == 1 or meta:get_int("sparktech_net_passive") ~= 0) then
			net_build(pos) -- only call this with none if the node really is not a trigger, otherwise the net will be build from it but it will not be contained
		elseif (minetest.get_item_group(newnode.name, "sparktech_net_trigger") == 1 ) then
			meta:set_string("net_master", nil)
			net_build(pos, nil, pos)
		end
	end

	minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
			add_node(pos, newnode)
	end)

	local function remove_node(pos, oldnode)
		if (minetest.get_item_group(oldnode.name, "sparktech_net_passive") == TRUE) or (minetest.get_item_group(oldnode.name, "sparktech_net_trigger") == TRUE) then
			minetest.debug("removing nodes...")
			local top = {x = pos.x, y = pos.y + 1, z = pos.z}
			local bottom = {x = pos.x, y = pos.y - 1, z = pos.z}
			local left = {x = pos.x - 1, y = pos.y, z = pos.z}
			local right = {x = pos.x + 1, y = pos.y, z = pos.z}
			local front = {x = pos.x, y = pos.y, z = pos.z - 1}
			local back = {x = pos.x, y = pos.y, z = pos.z + 1}
			for sidename, nodepos in pairs({top=top, bottom=bottom, left=left, right=right, front=front, back=back}) do
				local target_node = minetest.get_node(nodepos)
				add_node(nodepos, target_node)
			end
		end
	end

	minetest.register_on_dignode(function(pos, oldnode, digger)
			remove_node(pos, oldnode) -- FIXME Get rid of this! Somehow detect if a dynamic net_passive node is destroyed instead of updating speculatively
			-- TODO: I am not sure what this is for, just to get every dig in general? but we already dont allow those nodes to be dug, so dunno
	end)

	sparktech.add_node_to_net = add_node
	sparktech.remove_node_from_net = remove_node
