diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua
index c4b3c9a4c..22ccd9b4f 100644
--- a/mods/ENTITIES/mcl_minecarts/rails.lua
+++ b/mods/ENTITIES/mcl_minecarts/rails.lua
@@ -239,10 +239,26 @@ local function make_mesecons(base_name, suffix, base_mesecons)
 		mesecons.conductor = table.copy(base_mesecons.conductor)
 
 		if mesecons.conductor.onstate then
-			mesecons.conductor.onstate = base_mesecons.conductor.onstate..suffix
+			if type(mesecons.conductor.onstate) == "function" then
+				local old_onstate = mesecons.conductor.onstate
+				mesecons.conductor.onstate = function(pos, node)
+					local res = old_onstate(pos, node)
+					return {res[1]..suffix, res[2]}
+				end
+			else
+				mesecons.conductor.onstate = base_mesecons.conductor.onstate..suffix
+			end
 		end
 		if base_mesecons.conductor.offstate then
-			mesecons.conductor.offstate = base_mesecons.conductor.offstate..suffix
+			if type(mesecons.conductor.offstate) == "function" then
+				local old_offstate = mesecons.conductor.offstate
+				mesecons.conductor.offstate = function(pos, node)
+					local res = old_offstate(pos, node)
+					return {res[1]..suffix, res[2]}
+				end
+			else
+				mesecons.conductor.offstate = base_mesecons.conductor.offstate..suffix
+			end
 		end
 	end
 
diff --git a/mods/ENTITIES/mcl_minecarts/rails/powered.lua b/mods/ENTITIES/mcl_minecarts/rails/powered.lua
index f249799bb..976672e7e 100644
--- a/mods/ENTITIES/mcl_minecarts/rails/powered.lua
+++ b/mods/ENTITIES/mcl_minecarts/rails/powered.lua
@@ -21,8 +21,12 @@ mod.register_curves_rail("mcl_minecarts:golden_rail_v2",{
 	mesecons = {
 		conductor = {
 			state = mesecon.state.off,
-			offstate = "mcl_minecarts:golden_rail_v2",
-			onstate  = "mcl_minecarts:golden_rail_v2_on",
+			offstate = function(pos, node)
+				return {"mcl_minecarts:golden_rail_v2", node.param2}
+			end,
+			onstate  = function(pos, node)
+				return {"mcl_minecarts:golden_rail_v2_on", node.param2}
+			end,
 			rules = mod.rail_rules_long,
 		},
 	},
@@ -73,8 +77,12 @@ mod.register_curves_rail("mcl_minecarts:golden_rail_v2_on",{
 	mesecons = {
 		conductor = {
 			state = mesecon.state.on,
-			offstate = "mcl_minecarts:golden_rail_v2",
-			onstate  = "mcl_minecarts:golden_rail_v2_on",
+			offstate = function(pos, node)
+				return {"mcl_minecarts:golden_rail_v2", node.param2}
+			end,
+			onstate  = function(pos, node)
+				return {"mcl_minecarts:golden_rail_v2_on", node.param2}
+			end,
 			rules = mod.rail_rules_long,
 		},
 	},
diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua
index d7983d353..dbe5ba283 100644
--- a/mods/ITEMS/REDSTONE/mesecons/internal.lua
+++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua
@@ -272,6 +272,9 @@ function mesecon.is_conductor_on(node, rulename)
 	local conductor = mesecon.get_conductor(node.name)
 	if conductor then
 		if conductor.state then
+			if type(conductor.state) == "function" then
+				return conductor.state(node) == mesecon.state.on
+			end
 			return conductor.state == mesecon.state.on
 		end
 		if conductor.states then
@@ -293,6 +296,9 @@ function mesecon.is_conductor_off(node, rulename)
 	local conductor = mesecon.get_conductor(node.name)
 	if conductor then
 		if conductor.state then
+			if type(conductor.state) == "function" then
+				return conductor.state(node) == mesecon.state.off
+			end
 			return conductor.state == mesecon.state.off
 		end
 		if conductor.states then
@@ -402,7 +408,15 @@ function mesecon.turnon(pos, link)
 				end
 			end
 
-			mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link))
+			local conductor_on_state = mesecon.get_conductor_on(node, f.link)
+			if type(conductor_on_state) == "function" then
+				conductor_on_state = conductor_on_state(f.pos, node)
+			end
+			if type(conductor_on_state) == "table" then
+				mesecon.swap_node_force(f.pos, conductor_on_state[1], conductor_on_state[2])
+			else
+				mesecon.swap_node_force(f.pos, conductor_on_state)
+			end
 		elseif mesecon.is_effector(node.name) then
 			mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth)
 			if mesecon.is_effector_off(node.name) then
@@ -471,7 +485,15 @@ function mesecon.turnoff(pos, link)
 				end
 			end
 
-			mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
+			local conductor_off_state = mesecon.get_conductor_off(node, f.link)
+			if type(conductor_off_state) == "function" then
+				conductor_off_state = conductor_off_state(f.pos, node)
+			end
+			if type(conductor_off_state) == "table" then
+				mesecon.swap_node_force(f.pos, conductor_off_state[1], conductor_off_state[2])
+			else
+				mesecon.swap_node_force(f.pos, conductor_off_state)
+			end
 		elseif mesecon.is_effector(node.name) then
 			insert(signals, {
 				pos = f.pos,
diff --git a/mods/ITEMS/REDSTONE/mesecons/services.lua b/mods/ITEMS/REDSTONE/mesecons/services.lua
index 7d1fce2d8..d13c6091e 100644
--- a/mods/ITEMS/REDSTONE/mesecons/services.lua
+++ b/mods/ITEMS/REDSTONE/mesecons/services.lua
@@ -21,7 +21,13 @@ function mesecon.on_placenode(pos, node)
 			end
 			mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
 		elseif mesecon.is_conductor_on(node) then
-			minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)})
+			local offstate = mesecon.get_conductor_off(node)
+			if type(offstate) == "function" then
+				local res = offstate(pos, node)
+				core.swap_node(pos, {name = res[1], param2 = res[2]})
+			else
+				core.swap_node(pos, {name = offstate})
+			end
 		end
 	end
 
diff --git a/mods/ITEMS/REDSTONE/mesecons/util.lua b/mods/ITEMS/REDSTONE/mesecons/util.lua
index 12dbc0240..8613c7af7 100644
--- a/mods/ITEMS/REDSTONE/mesecons/util.lua
+++ b/mods/ITEMS/REDSTONE/mesecons/util.lua
@@ -342,6 +342,7 @@ function mesecon.vm_commit()
 		if tbl.dirty then
 			local vm = tbl.vm
 			vm:set_data(tbl.data)
+			vm:set_param2_data(tbl.param2)
 			vm:write_to_map()
 			vm:update_map()
 		end
@@ -387,10 +388,13 @@ end
 -- Sets a node’s name during a VoxelManipulator-based transaction.
 --
 -- Existing param1, param2, and metadata are left alone.
-function mesecon.vm_swap_node(pos, name)
+function mesecon.vm_swap_node(pos, name, param2)
 	local tbl = vm_get_or_create_entry(pos)
 	local index = tbl.va:indexp(pos)
 	tbl.data[index] = minetest.get_content_id(name)
+	if param2 then
+		tbl.param2[index] = param2
+	end
 	tbl.dirty = true
 end
 
@@ -426,14 +430,15 @@ end
 --
 -- This function can only be used to change the node’s name, not its parameters
 -- or metadata.
-function mesecon.swap_node_force(pos, name)
+function mesecon.swap_node_force(pos, name, param2)
 	if vm_cache then
-		return mesecon.vm_swap_node(pos, name)
+		return mesecon.vm_swap_node(pos, name, param2)
 	else
 		-- This serves to both ensure the mapblock is loaded and also hand us
 		-- the old node table so we can preserve param2.
 		local node = mesecon.get_node_force(pos)
 		node.name = name
+		node.param2 = param2 or node.param2
 		minetest.swap_node(pos, node)
 	end
 end