diff --git a/mesecons/init.lua b/mesecons/init.lua
index d980419345be2e607065ad97e07f9beb850eb698..aa3f001fafdb8ebeccbbf4ca0f817849f8926ffa 100644
--- a/mesecons/init.lua
+++ b/mesecons/init.lua
@@ -3,41 +3,105 @@
 -- |  \/  | |___ ____  |___ |      |    | | \  | |____
 -- |      | |        | |    |      |    | |  \ |     |
 -- |      | |___ ____| |___ |____  |____| |   \| ____|
--- by Jeija, Uberi (Temperest), sfan5, VanessaE, 
+-- by Jeija, Uberi (Temperest), sfan5, VanessaE
 --
 --
 --
 -- This mod adds mesecons[=minecraft redstone] and different receptors/effectors to minetest.
---
 -- See the documentation on the forum for additional information, especially about crafting
 --
--- For developer documentation see the Developers' section on mesecons.tk 
+--
+-- For developer documentation see the Developers' section on mesecons.TK
+--
+--
+--
+--Quick draft for the mesecons array in the node's definition
+--mesecons =
+--{
+--	receptor =
+--	{
+--		state = mesecon.state.on/off
+--		rules = rules/get_rules
+--	}
+--	effector =
+--	{
+--		action_on = function
+--		action_off = function
+--		action_change = function
+--		rules = rules/get_rules
+--	}
+--	conductor = 
+--	{
+--		state = mesecon.state.on/off
+--		offstate = opposite state (for state = on only)
+--		onstate = opposite state (for state = off only)
+--		rules = rules/get_rules
+--	}
+--}
 
 
 -- PUBLIC VARIABLES
 mesecon={} -- contains all functions and all global variables
-mesecon.actions_on={} -- Saves registered function callbacks for mesecon on
-mesecon.actions_off={} -- Saves registered function callbacks for mesecon off
-mesecon.actions_change={} -- Saves registered function callbacks for mesecon change
-mesecon.receptors={}
-mesecon.effectors={}
-mesecon.conductors={}
-
--- INCLUDE SETTINGS
+mesecon.actions_on={} -- Saves registered function callbacks for mesecon on | DEPRECATED
+mesecon.actions_off={} -- Saves registered function callbacks for mesecon off | DEPRECATED
+mesecon.actions_change={} -- Saves registered function callbacks for mesecon change | DEPRECATED
+mesecon.receptors={} --  saves all information about receptors  | DEPRECATED
+mesecon.effectors={} --  saves all information about effectors  | DEPRECATED
+mesecon.conductors={} -- saves all information about conductors | DEPRECATED
+
+-- Settings
 dofile(minetest.get_modpath("mesecons").."/settings.lua")
 
---Presets (eg default rules)
+-- Presets (eg default rules)
 dofile(minetest.get_modpath("mesecons").."/presets.lua");
 
---Internal API
+
+-- Utilities like comparing positions,
+-- adding positions and rules,
+-- mostly things that make the source look cleaner
+dofile(minetest.get_modpath("mesecons").."/util.lua");
+
+-- Internal stuff
+-- This is the most important file
+-- it handles signal transmission and basically everything else
+-- It is also responsible for managing the nodedef things,
+-- like calling action_on/off/change
 dofile(minetest.get_modpath("mesecons").."/internal.lua");
 
---Deprecated stuff
+-- Deprecated stuff
+-- To be removed in future releases
 dofile(minetest.get_modpath("mesecons").."/legacy.lua");
 
--- API API API API API API API API API API API API API API API API API API
+-- API
+-- these are the only functions you need to remember
+
+function mesecon:receptor_on(pos, rules)
+	rules = rules or mesecon.rules.default
+
+	for _, rule in ipairs(rules) do
+		local np = {
+		x = pos.x + rule.x,
+		y = pos.y + rule.y,
+		z = pos.z + rule.z}
+		if mesecon:rules_link(pos, np, rules) then
+			mesecon:turnon(np, pos)
+		end
+	end
+end
 
+function mesecon:receptor_off(pos, rules)
+	rules = rules or mesecon.rules.default
 
+	for _, rule in ipairs(rules) do
+		local np = {
+		x = pos.x + rule.x,
+		y = pos.y + rule.y,
+		z = pos.z + rule.z}
+		if mesecon:rules_link(pos, np, rules) and not mesecon:connected_to_pw_src(np) then
+			mesecon:turnoff(np, pos)
+		end
+	end
+end
 
 
 print("[OK] mesecons")
diff --git a/mesecons/internal.lua b/mesecons/internal.lua
index ce72d388f1e805afa4aa28c7bb164bdfd2113482..d438a537efea2aeddde527821f11d05723da414c 100644
--- a/mesecons/internal.lua
+++ b/mesecons/internal.lua
@@ -1,6 +1,7 @@
 -- INTERNAL
 
---Receptors
+-- Receptors
+-- Nodes that can power mesecons
 function mesecon:is_receptor_node(nodename)
 	if  minetest.registered_nodes[nodename]
 	and minetest.registered_nodes[nodename].mesecons
@@ -35,11 +36,9 @@ function mesecon:receptor_get_rules(node)
 	if  minetest.registered_nodes[node.name].mesecons
 	and minetest.registered_nodes[node.name].mesecons.receptor then
 		local rules = minetest.registered_nodes[node.name].mesecons.receptor.rules
-		if not rules then
-			return mesecon.rules.default
-		elseif type(rules) == 'function' then
+		if type(rules) == 'function' then
 			return rules(node)
-		else
+		elseif rules then
 			return rules
 		end
 	end
@@ -54,18 +53,20 @@ function mesecon:receptor_get_rules(node)
 			end
 		end
 	end
-	return nil
+	return mesecon.rules.default
 end
 
 -- Effectors
+-- Nodes that can be powered by mesecons
 function mesecon:is_effector_on(nodename)
-	if  minetest.registered_nodes[nodename]
-	and minetest.registered_nodes[nodename].mesecons
-	and minetest.registered_nodes[nodename].mesecons.effector
-	and minetest.registered_nodes[nodename].mesecons.effector.state == mesecon.state.on then
+	if   minetest.registered_nodes[nodename]
+	and  minetest.registered_nodes[nodename].mesecons
+	and  minetest.registered_nodes[nodename].mesecons.effector
+	and (minetest.registered_nodes[nodename].mesecons.effector.action_off
+	or   minetest.registered_nodes[nodename].mesecons.effector.action_change) then
 		return true
 	end
-	for i, effector in ipairs(mesecon.effectors) do --TODO
+	for _, effector in ipairs(mesecon.effectors) do --TODO
 		if effector.onstate == nodename then
 			return true
 		end
@@ -74,13 +75,14 @@ function mesecon:is_effector_on(nodename)
 end
 
 function mesecon:is_effector_off(nodename)
-	if  minetest.registered_nodes[nodename]
-	and minetest.registered_nodes[nodename].mesecons
-	and minetest.registered_nodes[nodename].mesecons.effector
-	and minetest.registered_nodes[nodename].mesecons.effector.state == mesecon.state.off then
+	if   minetest.registered_nodes[nodename]
+	and  minetest.registered_nodes[nodename].mesecons
+	and  minetest.registered_nodes[nodename].mesecons.effector
+	and (minetest.registered_nodes[nodename].mesecons.effector.action_on
+	or   minetest.registered_nodes[nodename].mesecons.effector.action_change) then
 		return true
 	end
-	for i, effector in ipairs(mesecon.effectors) do --TODO
+	for _, effector in ipairs(mesecon.effectors) do --TODO
 		if effector.offstate == nodename then
 			return true
 		end
@@ -101,11 +103,9 @@ function mesecon:effector_get_input_rules(node)
 	if  minetest.registered_nodes[node.name].mesecons
 	and minetest.registered_nodes[node.name].mesecons.effector then
 		local rules = minetest.registered_nodes[node.name].mesecons.effector.rules
-		if not rules then
-			return mesecon.rules.default
-		elseif type(rules) == 'function' then
+		if type(rules) == 'function' then
 			return rules(node)
-		else
+		elseif rules then
 			return rules
 		end
 	end
@@ -121,6 +121,7 @@ function mesecon:effector_get_input_rules(node)
 			end
 		end
 	end
+	return mesecon.rules.default
 end
 
 --Signals
@@ -153,11 +154,11 @@ end
 
 function mesecon:changesignal(pos) --TODO
 	local node = minetest.env:get_node(pos)
-	if  minetest.registered_nodes[nodename]
-	and minetest.registered_nodes[nodename].mesecons
-	and minetest.registered_nodes[nodename].mesecons.effector
-	and minetest.registered_nodes[nodename].mesecons.effector.action_change then
-		minetest.registered_nodes[nodename].mesecons.action_change(pos, node)
+	if  minetest.registered_nodes[node.name]
+	and minetest.registered_nodes[node.name].mesecons
+	and minetest.registered_nodes[node.name].mesecons.effector
+	and minetest.registered_nodes[node.name].mesecons.effector.action_change then
+		minetest.registered_nodes[node.name].mesecons.effector.action_change(pos, node)
 	end
 	for i, action in ipairs(mesecon.actions_change) do
 		action(pos, node) 
@@ -178,7 +179,7 @@ function mesecon:get_rules(name)
 	end
 end
 
---Conductor system stuff
+-- Conductors
 
 function mesecon:get_conductor_on(offstate)
 	if  minetest.registered_nodes[offstate]
@@ -248,11 +249,9 @@ function mesecon:conductor_get_rules(node)
 	and minetest.registered_nodes[node.name].mesecons
 	and minetest.registered_nodes[node.name].mesecons.conductor then
 		local rules = minetest.registered_nodes[node.name].mesecons.conductor.rules
-		if not rules then
-			return mesecon.rules.default
-		elseif type(rules) == 'function' then
+		if type(rules) == 'function' then
 			return rules(node)
-		else
+		elseif rules then
 			return rules
 		end
 	end
@@ -266,6 +265,7 @@ function mesecon:conductor_get_rules(node)
 			end
 		end
 	end
+	return mesecon.rules.default
 end
 
 --
@@ -292,11 +292,8 @@ function mesecon:turnon(pos)
 		local rules = mesecon:conductor_get_rules(node)
 		minetest.env:add_node(pos, {name=mesecon:get_conductor_on(node.name), param2 = node.param2})
 
-		for i, rule in ipairs(rules) do
-			local np = {}
-			np.x = pos.x + rule.x
-			np.y = pos.y + rule.y
-			np.z = pos.z + rule.z
+		for _, rule in ipairs(rules) do
+			local np = mesecon:addPosRule(pos, rule)
 
 			if mesecon:rules_link(pos, np) then
 				mesecon:turnon(np)
@@ -319,11 +316,8 @@ function mesecon:turnoff(pos) --receptor rules used because output could have be
 		local rules = mesecon:conductor_get_rules(node)
 		minetest.env:add_node(pos, {name=mesecon:get_conductor_off(node.name), param2 = node.param2})
 
-		for i, rule in ipairs(rules) do
-			local np = {
-			x = pos.x + rule.x,
-			y = pos.y + rule.y,
-			z = pos.z + rule.z,}
+		for _, rule in ipairs(rules) do
+			local np = mesecon:addPosRule(pos, rule)
 
 			if mesecon:rules_link(pos, np) then
 				mesecon:turnoff(np)
@@ -345,7 +339,7 @@ function mesecon:connected_to_pw_src(pos, checked)
 	local c = 1
 	checked = checked or {}
 	while checked[c] ~= nil do --find out if node has already been checked (to prevent from endless loop)
-		if  compare_pos(checked[c], pos) then
+		if mesecon:cmpPos(checked[c], pos) then
 			return false, checked
 		end
 		c = c + 1
@@ -368,11 +362,8 @@ function mesecon:connected_to_pw_src(pos, checked)
 		return false, checked
 	end
 
-	for i, rule in ipairs(rules) do
-		local np = {}
-		np.x = pos.x + rule.x
-		np.y = pos.y + rule.y
-		np.z = pos.z + rule.z
+	for _, rule in ipairs(rules) do
+		local np = mesecon:addPosRule(pos, rule)
 		if mesecon:rules_link(pos, np) then
 			connected, checked = mesecon:connected_to_pw_src(np, checked)
 			if connected then 
@@ -410,13 +401,9 @@ function mesecon:rules_link(output, input, dug_outputrules) --output/input are p
 
 
 	for _, outputrule in ipairs(outputrules) do
-		if  outputrule.x + output.x == input.x
-		and outputrule.y + output.y == input.y
-		and outputrule.z + output.z == input.z then -- Check if output sends to input
+		if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then -- Check if output sends to input
 			for _, inputrule in ipairs(inputrules) do
-				if  inputrule.x + input.x == output.x
-				and inputrule.y + input.y == output.y
-				and inputrule.z + input.z == output.z then --Check if input accepts from output
+				if  mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then --Check if input accepts from output
 					return true
 				end
 			end
@@ -447,11 +434,8 @@ function mesecon:is_powered_by_conductor(pos)
 		return false
 	end
 
-	for i, rule in ipairs(rules) do
-		local con_pos = {
-		x = pos.x + rule.x,
-		y = pos.y + rule.y,
-		z = pos.z + rule.z}
+	for _, rule in ipairs(rules) do
+		local con_pos = mesecon:addPosRule(pos, rule)
 
 		con_node = minetest.env:get_node(con_pos)
 
@@ -482,10 +466,7 @@ function mesecon:is_powered_by_receptor(pos)
 	end
 
 	for i, rule in ipairs(rules) do
-		local rcpt_pos = {
-		x = pos.x + rule.x,
-		y = pos.y + rule.y,
-		z = pos.z + rule.z}
+		local rcpt_pos = mesecon:addPosRule(pos, rule)
 
 		rcpt_node = minetest.env:get_node(rcpt_pos)
 
@@ -509,10 +490,6 @@ function mesecon:updatenode(pos)
     end
 end
 
-function compare_pos(pos1, pos2)
-	return pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z
-end
-
 --Rules rotation Functions:
 function mesecon:rotate_rules_right(rules)
 	local nr={};
diff --git a/mesecons/legacy.lua b/mesecons/legacy.lua
index 3f87b1ba8a9fe420657d1fec6a3645c8c9ac2b2a..947c100919b2afb1b47343a91f3274b66465e8ea 100644
--- a/mesecons/legacy.lua
+++ b/mesecons/legacy.lua
@@ -38,38 +38,6 @@ function mesecon:register_effector(onstate, offstate, input_rules, get_input_rul
 		 get_input_rules = get_input_rules})
 end
 
-function mesecon:receptor_on(pos, rules)
-	if rules == nil then
-		rules = mesecon:get_rules("default")
-	end
-
-	for i, rule in ipairs(rules) do
-		local np = {
-		x = pos.x + rule.x,
-		y = pos.y + rule.y,
-		z = pos.z + rule.z}
-		if mesecon:rules_link(pos, np, rules) then
-			mesecon:turnon(np, pos)
-		end
-	end
-end
-
-function mesecon:receptor_off(pos, rules)
-	if rules == nil then
-		rules = mesecon:get_rules("default")
-	end
-
-	for i, rule in ipairs(rules) do
-		local np = {
-		x = pos.x + rule.x,
-		y = pos.y + rule.y,
-		z = pos.z + rule.z}
-		if mesecon:rules_link(pos, np, rules) and not mesecon:connected_to_pw_src(np) then
-			mesecon:turnoff(np, pos)
-		end
-	end
-end
-
 function mesecon:register_on_signal_on(action)
 	table.insert(mesecon.actions_on, action)
 end
diff --git a/mesecons/presets.lua b/mesecons/presets.lua
index 450f03960bd41ac7385940aea784a895d5eee632..463a0f80321d7bed7297106133e362318d83cad1 100644
--- a/mesecons/presets.lua
+++ b/mesecons/presets.lua
@@ -1,7 +1,7 @@
 mesecon.rules={}
 mesecon.state = {}
 
-mesecon.rules.default = 
+mesecon.rules.default =
 {{x=0,  y=0,  z=-1},
 {x=1,  y=0,  z=0},
 {x=-1, y=0,  z=0},
@@ -15,5 +15,13 @@ mesecon.rules.default =
 {x=0,  y=1,  z=-1},
 {x=0,  y=-1, z=-1}}
 
+mesecon.rules.buttonlike =
+{{x = 1,  y = 0, z = 0},
+{x = 1,  y = 1, z = 0},
+{x = 1,  y =-1, z = 0},
+{x = 1,  y =-1, z = 1},
+{x = 1,  y =-1, z =-1},
+{x = 2,  y = 0, z = 0}}
+
 mesecon.state.on = "on"
 mesecon.state.off = "off"
diff --git a/mesecons/util.lua b/mesecons/util.lua
new file mode 100644
index 0000000000000000000000000000000000000000..b95cf6e5f75940461dd2ed5220b0bfb386a9982a
--- /dev/null
+++ b/mesecons/util.lua
@@ -0,0 +1,15 @@
+function mesecon:swap_node(pos, name)
+	local node = minetest.env:get_node(pos)
+	local data = minetest.env:get_meta(pos):to_table()
+	node.name = name
+	minetest.env:add_node(pos, node)
+	minetest.env:get_meta(pos):from_table(data)
+end
+
+function mesecon:addPosRule(p, r)
+	return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
+end
+
+function mesecon:cmpPos(p1, p2)
+	return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
+end
diff --git a/mesecons_button/init.lua b/mesecons_button/init.lua
index 25251c6325e5fc98a0bccdce8f67622997c9ab9d..f5c0eb945cefb853f1f40ab7b39340256dbd103a 100644
--- a/mesecons_button/init.lua
+++ b/mesecons_button/init.lua
@@ -1,7 +1,10 @@
 -- WALL BUTTON
+-- A button that when pressed emits power for 1 second
+-- and then turns off again
+
 minetest.register_node("mesecons_button:button_off", {
-    drawtype = "nodebox",
-    tiles = {
+	drawtype = "nodebox",
+	tiles = {
 	"jeija_wall_button_sides.png",	
 	"jeija_wall_button_sides.png",
 	"jeija_wall_button_sides.png",
@@ -9,24 +12,34 @@ minetest.register_node("mesecons_button:button_off", {
 	"jeija_wall_button_sides.png",
 	"jeija_wall_button_off.png"
 	},
-    paramtype = "light",
-    paramtype2 = "facedir",
-    legacy_wallmounted = true,
-    walkable = false,
-    sunlight_propagates = true,
-    selection_box = {
-        type = "fixed",
-	fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
-    },
-    node_box = {
-        type = "fixed",	
-	fixed = {
+	paramtype = "light",
+	paramtype2 = "facedir",
+	legacy_wallmounted = true,
+	walkable = false,
+	sunlight_propagates = true,
+	selection_box = {
+	type = "fixed",
+		fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
+	},
+	node_box = {
+		type = "fixed",	
+		fixed = {
 		{ -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 },	-- the thin plate behind the button
 		{ -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 }	-- the button itself
 	}
-    },
-    groups = {dig_immediate=2, mesecon = 3, mesecon_needs_receiver = 1},
-    description = "Button",
+	},
+	groups = {dig_immediate=2, mesecon_needs_receiver = 1},
+	description = "Button",
+	on_punch = function (pos, node)
+		mesecon:swap_node(pos, "mesecons_button:button_on")
+		local rules=mesecon.button_get_rules(node.param2)
+      	 	mesecon:receptor_on(pos, rules)
+		minetest.after(1, mesecon.button_turnoff, {pos=pos, param2=node.param2})
+	end,
+	mesecons = {receptor = {
+		state = mesecon.state.off,
+		rules = button_get_rules
+	}}
 })
 
 minetest.register_node("mesecons_button:button_on", {
@@ -45,48 +58,41 @@ minetest.register_node("mesecons_button:button_on", {
 	walkable = false,
 	light_source = LIGHT_MAX-7,
 	sunlight_propagates = true,
-    selection_box = {
-        type = "fixed",
-	fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
-    },
-    node_box = {
-        type = "fixed",
+	selection_box = {
+		type = "fixed",
+		fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
+	},
+	node_box = {
+	type = "fixed",
 	fixed = {
 		{ -6/16, -6/16,  6/16, 6/16, 6/16, 8/16 },
 		{ -4/16, -2/16, 11/32, 4/16, 2/16, 6/16 }
 	}
     },
-	groups = {dig_immediate=2, not_in_creative_inventory=1, mesecon = 3, mesecon_needs_receiver = 1},
+	groups = {dig_immediate=2, not_in_creative_inventory=1, mesecon_needs_receiver = 1},
 	drop = 'mesecons_button:button_off',
 	description = "Button",
+	mesecons = {receptor = {
+		state = mesecon.state.on,
+		rules = button_get_rules
+	}}
 })
 
-minetest.register_on_punchnode(function(pos, node, puncher)
-	if node.name == "mesecons_button:button_off" then
-		minetest.env:add_node(pos, {name="mesecons_button:button_on",param2=node.param2})
-		local rules=mesecon.button_get_rules(node.param2)
-        	mesecon:receptor_on(pos, rules)
-		minetest.after(1, mesecon.button_turnoff, {pos=pos, param2=node.param2})
-	end
-end)
-
 mesecon.button_turnoff = function (params)
 	if minetest.env:get_node(params.pos).name=="mesecons_button:button_on" then
-		minetest.env:add_node(params.pos, {name="mesecons_button:button_off", param2=params.param2})
+		mesecon:swap_node(params.pos, "mesecons_button:button_off")
 		local rules=mesecon.button_get_rules(params.param2)
 		mesecon:receptor_off(params.pos, rules)
 	end
 end
 
-mesecon.button_get_rules = function(param2)
-	local rules=mesecon:get_rules("button")
-	if param2 == 2 then
+mesecon.button_get_rules = function(node)
+	local rules = mesecon.rules.buttonlike
+	if node.param2 == 2 then
 		rules=mesecon:rotate_rules_left(rules)
-	end
-	if param2 == 3 then
+	elseif node.param2 == 3 then
 		rules=mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules))
-	end
-	if param2 == 0 then
+	elseif node.param2 == 0 then
 		rules=mesecon:rotate_rules_right(rules)
 	end
 	return rules
@@ -98,14 +104,3 @@ minetest.register_craft({
 		{'"group:mesecon_conductor_craftable"','"default:stone"'},
 	}
 })
-
-mesecon:add_rules("button", {
-{x = 1,  y = 0, z = 0},
-{x = 1,  y = 1, z = 0},
-{x = 1,  y =-1, z = 0},
-{x = 1,  y =-1, z = 1},
-{x = 1,  y =-1, z =-1},
-{x = 2,  y = 0, z = 0},})
-
-mesecon:add_receptor_node_off("mesecons_button:button_off", nil, mesecon.button_get_rules)
-mesecon:add_receptor_node("mesecons_button:button_on", nil, mesecon.button_get_rules)
diff --git a/mesecons_commandblock/init.lua b/mesecons_commandblock/init.lua
index 345ca7cb005897d773a0eba7e01b0f55f6712575..b61c85b2313e5cd55d76e2f33e9e22c551a3a425 100644
--- a/mesecons_commandblock/init.lua
+++ b/mesecons_commandblock/init.lua
@@ -87,11 +87,42 @@ local resolve_player = function(name, pos)
 	return name
 end
 
+local commandblock_action_on = function(pos, node)
+	if node.name ~= "mesecons_commandblock:commandblock_off" then
+		return
+	end
+
+	mesecon:swap_node(pos, "mesecons_commandblock:commandblock_on")
+
+	local meta = minetest.env:get_meta(pos)
+	local command = minetest.chatcommands[meta:get_string("command")]
+	if command == nil then
+		return
+	end
+	local owner = meta:get_string("owner")
+	if owner == "" then
+		return
+	end
+	local has_privs, missing_privs = minetest.check_player_privs(owner, command.privs)
+	if not has_privs then
+		minetest.chat_send_player(owner, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
+		return
+	end
+	local player = resolve_player(meta:get_string("player"), pos)
+	command.func(player, meta:get_string("param"))
+end
+
+local commandblock_action_off = function(pos, node)
+	if node.name == "mesecons_commandblock:commandblock_on" then
+		mesecon:swap_node(pos, "mesecons_commandblock:commandblock_off")
+	end
+end
+
 minetest.register_node("mesecons_commandblock:commandblock_off", {
 	description = "Command Block",
 	tiles = {"jeija_commandblock_off.png"},
 	inventory_image = minetest.inventorycube("jeija_commandblock_off.png"),
-	groups = {cracky=2, mesecon_effector_off=1, mesecon=2},
+	groups = {cracky=2, mesecon_effector_off=1},
 	on_construct = construct,
 	after_place_node = after_place,
 	on_receive_fields = receive_fields,
@@ -99,11 +130,14 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
 		local owner = minetest.env:get_meta(pos):get_string("owner")
 		return owner == "" or owner == player:get_player_name()
 	end,
+	mesecons = {effector = {
+		action_on = commandblock_action_on
+	}}
 })
 
 minetest.register_node("mesecons_commandblock:commandblock_on", {
 	tiles = {"jeija_commandblock_on.png"},
-	groups = {cracky=2, mesecon_effector_on=1, mesecon=2, not_in_creative_inventory=1},
+	groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1},
 	light_source = 10,
 	drop = "mesecons_commandblock:commandblock_off",
 	on_construct = construct,
@@ -113,45 +147,7 @@ minetest.register_node("mesecons_commandblock:commandblock_on", {
 		local owner = minetest.env:get_meta(pos):get_string("owner")
 		return owner == "" or owner == player:get_player_name()
 	end,
+	mesecons = {effector = {
+		action_off = commandblock_action_off
+	}}
 })
-
-mesecon:register_effector("mesecons_commandblock:commandblock_on", "mesecons_commandblock:commandblock_off")
-
-local swap_node = function(pos, name)
-	local node = minetest.env:get_node(pos)
-	local data = minetest.env:get_meta(pos):to_table()
-	node.name = name
-	minetest.env:add_node(pos, node)
-	minetest.env:get_meta(pos):from_table(data)
-end
-
-mesecon:register_on_signal_on(function(pos, node)
-	if node.name ~= "mesecons_commandblock:commandblock_off" then
-		return
-	end
-
-	swap_node(pos, "mesecons_commandblock:commandblock_on")
-
-	local meta = minetest.env:get_meta(pos)
-	local command = minetest.chatcommands[meta:get_string("command")]
-	if command == nil then
-		return
-	end
-	local owner = meta:get_string("owner")
-	if owner == "" then
-		return
-	end
-	local has_privs, missing_privs = minetest.check_player_privs(owner, command.privs)
-	if not has_privs then
-		minetest.chat_send_player(owner, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
-		return
-	end
-	local player = resolve_player(meta:get_string("player"), pos)
-	command.func(player, meta:get_string("param"))
-end)
-
-mesecon:register_on_signal_off(function(pos, node)
-	if node.name == "mesecons_commandblock:commandblock_on" then
-		swap_node(pos, "mesecons_commandblock:commandblock_off")
-	end
-end)
\ No newline at end of file
diff --git a/mesecons_delayer/init.lua b/mesecons_delayer/init.lua
index c732a17008f9d6eaa047b0d839f3c260d4174cf7..ca2825826ecde2e928eb93a4231b8e9bdca30627 100644
--- a/mesecons_delayer/init.lua
+++ b/mesecons_delayer/init.lua
@@ -1,9 +1,91 @@
+-- Function that get the input/output rules of the delayer
+local delayer_get_output_rules = function(node)
+	local rules = {}
+	if node.param2 == 0 then
+		table.insert(rules, {x = 1, y = 0, z = 0})
+	elseif node.param2 == 2 then
+		table.insert(rules, {x =-1, y = 0, z = 0})
+	elseif node.param2 == 1 then
+		table.insert(rules, {x = 0, y = 0, z =-1})
+	elseif node.param2 == 3 then
+		table.insert(rules, {x = 0, y = 0, z = 1})
+	end
+	return rules
+end
+
+local delayer_get_input_rules = function(node)
+	local rules = {}
+	if node.param2 == 0 then
+		table.insert(rules, {x =-1, y = 0, z = 0})
+	elseif node.param2 == 2 then
+		table.insert(rules, {x = 1, y = 0, z = 0})
+	elseif node.param2 == 1 then
+		table.insert(rules, {x = 0, y = 0, z = 1})
+	elseif node.param2 == 3 then
+		table.insert(rules, {x = 0, y = 0, z =-1})
+	end
+	return rules
+end
+
+-- Functions that are called after the delay time
+
+local delayer_turnon = function(params)
+	local rules = delayer_get_output_rules(params)
+	mesecon:receptor_on(params.pos, rules)
+end
+
+local delayer_turnoff = function(params)
+	local rules = delayer_get_output_rules(params)
+	mesecon:receptor_off(params.pos, rules)
+end
+
+local delayer_update = function(pos, node)
+	print("update")
+	if string.find(node.name, "mesecons_delayer:delayer_off")~=nil then
+		local time = 0
+		if node.name=="mesecons_delayer:delayer_off_1" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_on_1")
+			time=0.1
+		elseif node.name=="mesecons_delayer:delayer_off_2" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_on_2")
+			time=0.3
+		elseif node.name=="mesecons_delayer:delayer_off_3" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_on_3")
+			time=0.5
+		elseif node.name=="mesecons_delayer:delayer_off_4" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_on_4")
+			time=1
+		end
+		minetest.after(time, delayer_turnon, {pos=pos, param2=node.param2})
+	end
+
+	if string.find(node.name, "mesecons_delayer:delayer_on")~=nil then
+		local time = 0
+		if node.name=="mesecons_delayer:delayer_on_1" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_off_1")
+			time=0.1
+		elseif node.name=="mesecons_delayer:delayer_on_2" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_off_2")
+			time=0.3
+		elseif node.name=="mesecons_delayer:delayer_on_3" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_off_3")
+			time=0.5
+		elseif node.name=="mesecons_delayer:delayer_on_4" then
+			mesecon:swap_node(pos, "mesecons_delayer:delayer_off_4")
+			time=1
+		end
+		minetest.after(time, delayer_turnoff, {pos=pos, param2=node.param2})
+	end
+end
+
+--Actually register the 2 (states) x 4 (delay times) delayers
+
 for i = 1, 4 do
 local groups = {}
 if i == 1 then 
-	groups = {bendy=2,snappy=1,dig_immediate=2, mesecon = 3}
+	groups = {bendy=2,snappy=1,dig_immediate=2}
 else
-	groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1, mesecon = 3}
+	groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1}
 end
 
 boxes = {{ -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 },		-- the main slab
@@ -46,6 +128,29 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
 	sunlight_propagates = true,
 	is_ground_content = true,
 	drop = 'mesecons_delayer:delayer_off_1',
+	on_punch = function (pos, node)
+		if node.name=="mesecons_delayer:delayer_off_1" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_off_2")
+		elseif node.name=="mesecons_delayer:delayer_off_2" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_off_3")
+		elseif node.name=="mesecons_delayer:delayer_off_3" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_off_4")
+		elseif node.name=="mesecons_delayer:delayer_off_4" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_off_1")
+		end
+	end,
+	mesecons = {
+		receptor =
+		{
+			state = mesecon.state.off,
+			rules = delayer_get_output_rules
+		},
+		effector =
+		{
+			rules = delayer_get_input_rules,
+			action_change = delayer_update
+		}
+	}
 })
 
 
@@ -69,147 +174,34 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
 		type = "fixed",
 		fixed = boxes
 	},
-	groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1, mesecon = 3},
+	groups = {bendy = 2, snappy = 1, dig_immediate = 2, not_in_creative_inventory = 1},
 	paramtype = "light",
 	paramtype2 = "facedir",
 	sunlight_propagates = true,
 	is_ground_content = true,
 	drop = 'mesecons_delayer:delayer_off_1',
-})
-end
-
-
-
-
-minetest.register_on_punchnode(function (pos, node)
-	mesecon.delayer_get_output_rules(node.param2)
-	if node.name=="mesecons_delayer:delayer_off_1" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2})
-	end
-	if node.name=="mesecons_delayer:delayer_off_2" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2})
-	end
-	if node.name=="mesecons_delayer:delayer_off_3" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2})
-	end
-	if node.name=="mesecons_delayer:delayer_off_4" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2})
-	end
-end)
-
-minetest.register_on_punchnode(function (pos, node)
-	mesecon.delayer_get_output_rules(node.param2)
-	if node.name=="mesecons_delayer:delayer_on_1" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_2", param2=node.param2})
-	end
-	if node.name=="mesecons_delayer:delayer_on_2" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_3", param2=node.param2})
-	end
-	if node.name=="mesecons_delayer:delayer_on_3" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_4", param2=node.param2})
-	end
-	if node.name=="mesecons_delayer:delayer_on_4" then
-		minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_1", param2=node.param2})
-	end
-end)
-
-mesecon.delayer_update = function(pos, node)
-	if string.find(node.name, "mesecons_delayer:delayer_off")~=nil then
-		local time = 0
-		if node.name=="mesecons_delayer:delayer_off_1" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_1", param2=node.param2})
-			time=0.1
-		end
-		if node.name=="mesecons_delayer:delayer_off_2" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_2", param2=node.param2})
-			time=0.3
-		end
-		if node.name=="mesecons_delayer:delayer_off_3" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_3", param2=node.param2})
-			time=0.5
-		end
-		if node.name=="mesecons_delayer:delayer_off_4" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_on_4", param2=node.param2})
-			time=1
-		end
-		minetest.after(time, mesecon.delayer_turnon, {pos=pos, param2=node.param2})
-	end
-
-	if string.find(node.name, "mesecons_delayer:delayer_on")~=nil then
-		local time = 0
+	on_punch = function (pos, node)
 		if node.name=="mesecons_delayer:delayer_on_1" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2})
-			time=0.1
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_on_2")
+		elseif node.name=="mesecons_delayer:delayer_on_2" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_on_3")
+		elseif node.name=="mesecons_delayer:delayer_on_3" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_on_4")
+		elseif node.name=="mesecons_delayer:delayer_on_4" then
+			mesecon:swap_node(pos,"mesecons_delayer:delayer_on_1")
 		end
-		if node.name=="mesecons_delayer:delayer_on_2" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2})
-			time=0.3
-		end
-		if node.name=="mesecons_delayer:delayer_on_3" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2})
-			time=0.5
-		end
-		if node.name=="mesecons_delayer:delayer_on_4" then
-			minetest.env:add_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2})
-			time=1
-		end
-		minetest.after(time, mesecon.delayer_turnoff, {pos=pos, param2=node.param2})
-	end
-end
-
-mesecon:register_on_signal_change(mesecon.delayer_update)
-
-mesecon.delayer_turnon=function(params)
-	local rules = mesecon.delayer_get_output_rules(params.param2)
-	mesecon:receptor_on(params.pos, rules)
-end
-
-mesecon.delayer_turnoff=function(params)
-	local rules = mesecon.delayer_get_output_rules(params.param2)
-	mesecon:receptor_off(params.pos, rules)
-end
-
-mesecon.delayer_get_output_rules = function(param2)
-	local rules = {}
-	if param2 == 0 then
-		table.insert(rules, {x = 1, y = 0, z = 0})
-	elseif param2 == 2 then
-		table.insert(rules, {x =-1, y = 0, z = 0})
-	elseif param2 == 1 then
-		table.insert(rules, {x = 0, y = 0, z =-1})
-	elseif param2 == 3 then
-		table.insert(rules, {x = 0, y = 0, z = 1})
-	end
-	return rules
-end
-
-mesecon.delayer_get_input_rules = function(param2)
-	local rules = {}
-	if param2 == 0 then
-		table.insert(rules, {x =-1, y = 0, z = 0})
-	elseif param2 == 2 then
-		table.insert(rules, {x = 1, y = 0, z = 0})
-	elseif param2 == 1 then
-		table.insert(rules, {x = 0, y = 0, z = 1})
-	elseif param2 == 3 then
-		table.insert(rules, {x = 0, y = 0, z =-1})
-	end
-	return rules
+	end,
+	mesecons = {
+		receptor =
+		{
+			state = mesecon.state.on,
+			rules = delayer_get_output_rules
+		},
+		effector =
+		{
+			rules = delayer_get_input_rules,
+			action_change = delayer_update
+		}
+	}
+})
 end
-
-all_rules = {{x = 1, y = 0, z = 0}, {x =-1, y = 0, z = 0}, {x = 0, y = 0, z =-1}, {x = 0, y = 0, z = 1}} --required to check if a newly placed should be turned on
-
-mesecon:add_receptor_node("mesecons_delayer:delayer_on_1", all_rules, mesecon.delayer_get_output_rules)
-mesecon:add_receptor_node("mesecons_delayer:delayer_on_2", all_rules, mesecon.delayer_get_output_rules)
-mesecon:add_receptor_node("mesecons_delayer:delayer_on_3", all_rules, mesecon.delayer_get_output_rules)
-mesecon:add_receptor_node("mesecons_delayer:delayer_on_4", all_rules, mesecon.delayer_get_output_rules)
-
-mesecon:add_receptor_node_off("mesecons_delayer:delayer_off_1", all_rules, mesecon.delayer_get_output_rules)
-mesecon:add_receptor_node_off("mesecons_delayer:delayer_off_2", all_rules, mesecon.delayer_get_output_rules)
-mesecon:add_receptor_node_off("mesecons_delayer:delayer_off_3", all_rules, mesecon.delayer_get_output_rules)
-mesecon:add_receptor_node_off("mesecons_delayer:delayer_off_4", all_rules, mesecon.delayer_get_output_rules)
-
-mesecon:register_effector("mesecons_delayer:delayer_on_1", "mesecons_delayer:delayer_off_1", all_rules, mesecon.delayer_get_input_rules)
-mesecon:register_effector("mesecons_delayer:delayer_on_2", "mesecons_delayer:delayer_off_2", all_rules, mesecon.delayer_get_input_rules)
-mesecon:register_effector("mesecons_delayer:delayer_on_3", "mesecons_delayer:delayer_off_3", all_rules, mesecon.delayer_get_input_rules)
-mesecon:register_effector("mesecons_delayer:delayer_on_4", "mesecons_delayer:delayer_off_4", all_rules, mesecon.delayer_get_input_rules)
diff --git a/mesecons_lightstone/init.lua b/mesecons_lightstone/init.lua
index 9edd99d9f4c331e23028ebe447c60e0011d94fd4..d8b523c5503e1d75ce34caefd151b2abad2d438d 100644
--- a/mesecons_lightstone/init.lua
+++ b/mesecons_lightstone/init.lua
@@ -5,7 +5,6 @@ function mesecon:lightstone_add(name, base_item, texture_off, texture_on)
 	groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2},
 	description=name.." Lightstone",
 	mesecons = {effector = {
-		state = mesecon.state.off,
 		action_on = function (pos, node)
 			minetest.env:add_node(pos, {name="mesecons_lightstone:lightstone_" .. name .. "_on"})
 			mesecon:receptor_on(pos)
@@ -19,7 +18,6 @@ function mesecon:lightstone_add(name, base_item, texture_off, texture_on)
 	drop = "node mesecons_lightstone:lightstone_" .. name .. "_off 1",
 	light_source = LIGHT_MAX-2,
 	mesecons = {effector = {
-		state = mesecon.state.on,
 		action_off = function (pos, node)
 			minetest.env:add_node(pos, {name="mesecons_lightstone:lightstone_" .. name .. "_off"})
 			mesecon:receptor_off(pos)
diff --git a/mesecons_switch/init.lua b/mesecons_switch/init.lua
index 2af5101cf9deafc7eb73c490e5776b09ee5cabe4..0519e03fd3b179dad42b95c7ea38c7c2aba141eb 100644
--- a/mesecons_switch/init.lua
+++ b/mesecons_switch/init.lua
@@ -9,7 +9,7 @@ minetest.register_node("mesecons_switch:mesecon_switch_off", {
 		state = mesecon.state.off
 	}},
 	on_punch = function(pos, node)
-		minetest.env:add_node(pos, {name="mesecons_switch:mesecon_switch_on", param2=node.param2})
+		mesecon:swap_node(pos, "mesecons_switch:mesecon_switch_on")
 		mesecon:receptor_on(pos)
 	end
 })
@@ -23,7 +23,7 @@ minetest.register_node("mesecons_switch:mesecon_switch_on", {
 		state = mesecon.state.on
 	}},
 	on_punch = function(pos, node)
-		minetest.env:add_node(pos, {name="mesecons_switch:mesecon_switch_off", param2=node.param2})
+		mesecon:swap_node(pos, "mesecons_switch:mesecon_switch_off")
 		mesecon:receptor_off(pos)
 	end
 })