One of the most important blocks in every automation machine built inside minetest is the node breaker. It is a very expensive block to craft but it can harvest resources from the environment as if you were there.

It’s most basic use is to harvest wheat or stone in an endless cycle of repetitive work that no one is interested doing.

So how do we replicate some of it’s features?

minetest.register_node("awittymodname:nodebreaker", {
        description = "Node breaker",
        on_punch = function(pos, node, player, pointed_thing)
                -- do something amazing here
        end,
})

This is how we register a node called nodebreaker in the mod named awittymodname.

I added only two fields to the node properties and the interesting one is on_punch.

Obvioulsy when we will punch the node nothing will happen because there is no meaningful code inside the function, that’s just a seed to get going.

Let’s make it destroy some node.

minetest.register_node("awittymodname:nodebreaker", {
        description = "Node breaker",
        on_punch = function(pos, node, player, pointed_thing)
                -- there are 6 possible directions
                -- one for every face of the cube
                -- this will return the exiting vector
                -- associated with the face 0
                local direction = minetest.facedir_to_dir(0)

                -- add the direction vector to
                -- the node position to get the target
                local target_position = vector.add(pos, dir)

                -- dig the node as if a player did
                minetest.dig_node(target_position)

        end,
})

This implementation uses the facedir to dir and vector API

So now every time we punch the node breaker the node facing the face 0 will be destroyed.

But that wont drop resources, dammit!

minetest.register_node("awittymodname:nodebreaker", {
        description = "Node breaker",
        on_punch = function(pos, node, player, pointed_thing)
                -- there are 6 possible directions
                -- one for every face of the cube
                -- this will return the exiting vector
                -- associated with the face 0
                local direction = minetest.facedir_to_dir(0)

                -- add the direction vector to
                -- the node position to get the target
                local target_position = vector.add(pos, direction)

                -- get the node in target_position
                -- return nil if it does not exists
                local target_node = minetest.get_node_or_nil(target_position)

                -- if there is a node in target position
                if target_node then

                        -- get a list of item names
                        -- the target node would drop
                        -- if digged by a player with bare hands
                        local target_node_drop = minetest.get_node_drops(target_node.name, nil)

                        -- for every item the node would drop
                        -- add it to the game in the target node position
                        for _, dropname in ipairs(target_node_drop) do
                                minetest.add_item(target_position, dropname)
                        end

                        -- and finally
                        -- dig the node as if a player did
                        minetest.dig_node(target_position)
                end

        end,
})

By using the get node drops API we can obtain the list of item names that the node will drop if digged and by using the add item API we add the items to the world.

So now our node breaker can dig blocks as if a player would, by dropping the resources in the world.

This is very good but still requires to punch the node to dig it, maybe it’s time to think about timers…

Key points

We can create nodes to fit our needs.

It is very simple to emulate the work of a player.