diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua
index 6d89aae1..aa2be212 100644
--- a/mods/default/furnace.lua
+++ b/mods/default/furnace.lua
@@ -90,6 +90,137 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player
 	return stack:get_count()
 end
 
+local function swap_node(pos, name)
+	local node = minetest.get_node(pos)
+	if node.name == name then
+		return
+	end
+	node.name = name
+	minetest.swap_node(pos, node)
+end
+
+local function furnace_node_timer(pos, elapsed)
+	--
+	-- Inizialize metadata
+	--
+	local meta = minetest.get_meta(pos)
+	local fuel_time = meta:get_float("fuel_time") or 0
+	local src_time = meta:get_float("src_time") or 0
+	local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
+
+	local inv = meta:get_inventory()
+	local srclist = inv:get_list("src")
+	local fuellist = inv:get_list("fuel")
+	local dstlist = inv:get_list("dst")
+
+	--
+	-- Cooking
+	--
+
+	-- Check if we have cookable content
+	local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
+	local cookable = true
+
+	if cooked.time == 0 then
+		cookable = false
+	end
+
+	-- Check if we have enough fuel to burn
+	if fuel_time < fuel_totaltime then
+		-- The furnace is currently active and has enough fuel
+		fuel_time = fuel_time + 1
+
+		-- If there is a cookable item then check if it is ready yet
+		if cookable then
+			src_time = src_time + 1
+			if src_time >= cooked.time then
+				-- Place result in dst list if possible
+				if inv:room_for_item("dst", cooked.item) then
+					inv:add_item("dst", cooked.item)
+					inv:set_stack("src", 1, aftercooked.items[1])
+					src_time = 0
+				end
+			end
+		end
+	else
+		-- Furnace ran out of fuel
+		if cookable then
+			-- We need to get new fuel
+			local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
+
+			if fuel.time == 0 then
+				-- No valid fuel in fuel list
+				fuel_totaltime = 0
+				fuel_time = 0
+				src_time = 0
+			else
+				-- Take fuel from fuel list
+				inv:set_stack("fuel", 1, afterfuel.items[1])
+
+				fuel_totaltime = fuel.time
+				fuel_time = 0
+			end
+		else
+			-- We don't need to get new fuel since there is no cookable item
+			fuel_totaltime = 0
+			fuel_time = 0
+			src_time = 0
+		end
+	end
+
+	--
+	-- Update formspec, infotext and node
+	--
+	local formspec = inactive_formspec
+	local item_state = ""
+	local item_percent = 0
+	if cookable then
+		item_percent = math.floor(src_time / cooked.time * 100)
+		item_state = item_percent .. "%"
+	else
+		if srclist[1]:is_empty() then
+			item_state = "Empty"
+		else
+			item_state = "Not cookable"
+		end
+	end
+
+	local fuel_state = "Empty"
+	local active = "inactive "
+	local result = false
+
+	if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then
+		active = "active "
+		local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
+		fuel_state = fuel_percent .. "%"
+		formspec = active_formspec(fuel_percent, item_percent)
+		swap_node(pos, "default:furnace_active")
+		-- make sure timer restarts automatically
+		result = true
+	else
+		if not fuellist[1]:is_empty() then
+			fuel_state = "0%"
+		end
+		swap_node(pos, "default:furnace")
+		-- stop timer on the inactive furnace
+		local timer = minetest.get_node_timer(pos)
+		timer:stop()
+	end
+
+	local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
+
+	--
+	-- Set meta values
+	--
+	meta:set_float("fuel_totaltime", fuel_totaltime)
+	meta:set_float("fuel_time", fuel_time)
+	meta:set_float("src_time", src_time)
+	meta:set_string("formspec", formspec)
+	meta:set_string("infotext", infotext)
+
+	return result
+end
+
 --
 -- Node definitions
 --
@@ -106,9 +237,26 @@ minetest.register_node("default:furnace", {
 	legacy_facedir_simple = true,
 	is_ground_content = false,
 	sounds = default.node_sound_stone_defaults(),
-	
+
 	can_dig = can_dig,
-	
+
+	on_timer = furnace_node_timer,
+
+	on_construct = function(pos)
+		local meta = minetest.get_meta(pos)
+		meta:set_string("formspec", inactive_formspec)
+		local inv = meta:get_inventory()
+		inv:set_size('src', 1)
+		inv:set_size('fuel', 1)
+		inv:set_size('dst', 4)
+	end,
+
+	on_metadata_inventory_put = function(pos)
+		-- start timer function, it will sort out whether furnace can burn or not.
+		local timer = minetest.get_node_timer(pos)
+		timer:start(1.0)
+	end,
+
 	allow_metadata_inventory_put = allow_metadata_inventory_put,
 	allow_metadata_inventory_move = allow_metadata_inventory_move,
 	allow_metadata_inventory_take = allow_metadata_inventory_take,
@@ -138,154 +286,12 @@ minetest.register_node("default:furnace_active", {
 	legacy_facedir_simple = true,
 	is_ground_content = false,
 	sounds = default.node_sound_stone_defaults(),
-	
+	on_timer = furnace_node_timer,
+
 	can_dig = can_dig,
-	
+
 	allow_metadata_inventory_put = allow_metadata_inventory_put,
 	allow_metadata_inventory_move = allow_metadata_inventory_move,
 	allow_metadata_inventory_take = allow_metadata_inventory_take,
 })
 
---
--- ABM
---
-
-local function swap_node(pos, name)
-	local node = minetest.get_node(pos)
-	if node.name == name then
-		return
-	end
-	node.name = name
-	minetest.swap_node(pos, node)
-end
-
-minetest.register_abm({
-	nodenames = {"default:furnace", "default:furnace_active"},
-	interval = 1.0,
-	chance = 1,
-	action = function(pos, node, active_object_count, active_object_count_wider)
-		--
-		-- Inizialize metadata
-		--
-		local meta = minetest.get_meta(pos)
-		local fuel_time = meta:get_float("fuel_time") or 0
-		local src_time = meta:get_float("src_time") or 0
-		local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
-		
-		--
-		-- Inizialize inventory
-		--
-		local inv = meta:get_inventory()
-		for listname, size in pairs({
-				src = 1,
-				fuel = 1,
-				dst = 4,
-		}) do
-			if inv:get_size(listname) ~= size then
-				inv:set_size(listname, size)
-			end
-		end
-		local srclist = inv:get_list("src")
-		local fuellist = inv:get_list("fuel")
-		local dstlist = inv:get_list("dst")
-		
-		--
-		-- Cooking
-		--
-		
-		-- Check if we have cookable content
-		local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
-		local cookable = true
-		
-		if cooked.time == 0 then
-			cookable = false
-		end
-		
-		-- Check if we have enough fuel to burn
-		if fuel_time < fuel_totaltime then
-			-- The furnace is currently active and has enough fuel
-			fuel_time = fuel_time + 1
-			
-			-- If there is a cookable item then check if it is ready yet
-			if cookable then
-				src_time = src_time + 1
-				if src_time >= cooked.time then
-					-- Place result in dst list if possible
-					if inv:room_for_item("dst", cooked.item) then
-						inv:add_item("dst", cooked.item)
-						inv:set_stack("src", 1, aftercooked.items[1])
-						src_time = 0
-					end
-				end
-			end
-		else
-			-- Furnace ran out of fuel
-			if cookable then
-				-- We need to get new fuel
-				local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
-				
-				if fuel.time == 0 then
-					-- No valid fuel in fuel list
-					fuel_totaltime = 0
-					fuel_time = 0
-					src_time = 0
-				else
-					-- Take fuel from fuel list
-					inv:set_stack("fuel", 1, afterfuel.items[1])
-					
-					fuel_totaltime = fuel.time
-					fuel_time = 0
-					
-				end
-			else
-				-- We don't need to get new fuel since there is no cookable item
-				fuel_totaltime = 0
-				fuel_time = 0
-				src_time = 0
-			end
-		end
-		
-		--
-		-- Update formspec, infotext and node
-		--
-		local formspec = inactive_formspec
-		local item_state = ""
-		local item_percent = 0
-		if cookable then
-			item_percent =  math.floor(src_time / cooked.time * 100)
-			item_state = item_percent .. "%"
-		else
-			if srclist[1]:is_empty() then
-				item_state = "Empty"
-			else
-				item_state = "Not cookable"
-			end
-		end
-		
-		local fuel_state = "Empty"
-		local active = "inactive "
-		if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then
-			active = "active "
-			local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
-			fuel_state = fuel_percent .. "%"
-			formspec = active_formspec(fuel_percent, item_percent)
-			swap_node(pos, "default:furnace_active")
-		else
-			if not fuellist[1]:is_empty() then
-				fuel_state = "0%"
-			end
-			swap_node(pos, "default:furnace")
-		end
-		
-		local infotext =  "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
-		
-		--
-		-- Set meta values
-		--
-		meta:set_float("fuel_totaltime", fuel_totaltime)
-		meta:set_float("fuel_time", fuel_time)
-		meta:set_float("src_time", src_time)
-		meta:set_string("formspec", formspec)
-		meta:set_string("infotext", infotext)
-	end,
-})