1. Introduction
1.1 Context
1.2. What you will learn
2. Dig types, digging times, and tool uses
2.1 Dig types
2.2 Digging times
2.3 Tool uses
2.4 Other tool and node properties
3. How to add new tiers of tools and nodes
4. Suggestions for the main developpers of Minetest After struggling for years to understand digging times and dig types, reading countless questions about it in the forums with the answers generally being "My interpretation of the documentation is...." without really being any clearer, or being sure of their answers, and after researching this for a while myself, I've finally come to understand how these concepts are handled in Minetest.
Now I can finally get to coding my ideas into actual mods that work as intended! In this tutorial, you will be able to understand what the dig types are, how the digging times are calculated, what maxlevel and other values really do, how tool uses are calculated, and you will be able to create your own, new tiers of tools and nodes. To start, let's understand what dig types actually are.
Nodes (or blocks) in Minetest can be assigned to certain "groups".
In the case of nodes, groups are mostly used to define what kind of tool is needed to break this block.
For instance, let's take a loot at the definition of the diamond block:
Code: Select all
minetest.register_node("default:diamondblock", {
description = S("Diamond Block"),
tiles = {"default_diamond_block.png"},
is_ground_content = false,
groups = {cracky = 1, level = 3},
sounds = default.node_sound_stone_defaults(),
})
In the groups section you can see that it has the cracky group assigned, which means that pickaxes are the tool intended to break them.
Other dig types include snappy, crumbly, and oddly_breakable_by_hand, among others. The full list of dig types can be found in the Lua API Documentation.
The number next to the digging type will be referred to as the node's "rating" or "group rating" from here on out.
The node's rating does not actually define how long it takes for it to be broken by a tool. It is merely an "identifier" of sorts, that allows the actual tools to decide how long it'll take them to break the node.
That is, even though most tools are programmed in a way that it takes longer to break a rating 1 node than it takes to break a rating 2 node, and it takes longer to break a rating 2 node than it takes to break a rating 3 node, there's nothing stopping YOU, the mod developper, from making a tool that breaks nodes faster the harder they are (that is, they break diamond blocks faster than they break gold blocks, and break gold blocks faster than they break stone blocks).
As I said earlier, it's the tool, not the node, that decides which nodes they break, and at which speed, depending on their group ratings.
Let's now take a look at a tool from the game:
Code: Select all
minetest.register_tool("default:pick_stone", {
description = S("Stone Pickaxe"),
inventory_image = "default_tool_stonepick.png",
tool_capabilities = {
full_punch_interval = 1.3,
max_drop_level=0,
groupcaps={
cracky = {times={[2]=2.0, [3]=1.00}, uses=20, maxlevel=1},
},
damage_groups = {fleshy=3},
},
sound = {breaks = "default_tool_breaks"},
groups = {pickaxe = 1}
})
If you take a look at the groupcaps section of the table, you'll find that this tool can only break nodes that are in the cracky group (such as stone, iron ore, etc).
Furthermore, they define the maxlevel, which is the maximum level of node that this tool can break.
If you go back and look at the diamond block, you'll see that not only does it have a group and a group rating, it also has a level.
This can be used to make a tool that can break all the cracky nodes in default, but only up to and including level 2 for example, which would allow the tool to break every single block, including obsidian and bronze block, which are cracky rating 1, but that same tool would not be able to mine diamond blocks, because even though the diamond block is a cracky node, and it has a group rating of 1, which we said that our tool can break, the diamond block has a level of 3, and our tool can only break nodes up to level 2. Now that we understand how dig types, group ratings and node levels work, we will take a look at how the game calculates digging times.
If you recall from earlier, in the definition of the stone pickaxe, not only does it say that it can break cracky nodes up to and including level 1 (do not mistake level for group rating), there are also some weird numbers in between.
These numbers represent how long the tool takes to break nodes. Between [] are the group ratings of the nodes, and next to the ratings are decimal numbers that represent how long, in seconds, the tool will take to break a node.
In the case of the stone pickaxe, it can break cracky nodes that have a rating of 2 in 2.0 seconds, and cracky nodes with a rating of 3 in 1.0 seconds. Note that nodes with cracky rating of 1 or any other rating other than 2 and 3 are not mentioned in the tool definition, so any nodes that have a cracky rating of 1 will not be able to be mined by the stone pickaxe. It's not that it doesn't drop anything, it will just not be able to mine it.
You can set the time to any positive decimal value larger than 0.15. Why? Anything smaller and the game will make it take 0.15 seconds to mine each block. There is no delay when mining blocks by repeatedly clicking the nodes, this only applies to holding the left click. So you could theoretically go faster than 0.15 seconds between nodes mined by clicking really fast.
Remember that the 1, 2 and 3 ratings of all default blocks are just "identifiers", you don't need to make rating 1 nodes be mined slower than rating 2, you can set the times at any values you like. The amount of times you can use a tool, or tool uses, are calculated using a simple mathematical function.
As it is explained on the API Documentation, tool uses are calculated based on the difference between the tool's maxlevel property, and the node's level.
Note: Do not confuse a node's level, which is defined inside the node's groups property under the identifier level, with the node's group rating. As explained earlier, the groups rating is an "identifier" of sorts, for the node's tier. However, the rating isn't used in calculating the uses a tool has when breaking a node, its level is used. A node can be cracky rating 2, and node level = 3.
The way uses are calculated is simple:
For nodes with the same level as the tool's maxlevel, said tool can break as many of those nodes as its uses.
As an example, a tool with maxlevel = 3 and uses = 15 will be able to break 15 nodes that have level = 3, like, for example, default:diamondblock.
You could say that breaking a diamond block with this tool takes one use.
However, when the node you're breaking has a lower level than the tool's maxlevel, the number of nodes you can break with the tool increases exponentially, three times to be exact, for every level that the node is below the tool's maxlevel. As an example, default:obsidian has a node level of 2, so our tool will be able to break 3 times as many obsidian nodes as it can break diamond blocks. In this case, the tool would be able to mine 45 obsidian nodes before breaking.
You could say that breaking an obsidian node with this tool takes 1/3 uses, which is to say, you need to break three obsidian nodes to consume one use of the tool.
If you're more mathematically inclined, here's a formula for you to calculate the amount of actual uses a tool has, depending on the difference between a tool's maxlevel and a node's level:
leveldiff = maxlevel-level
actualuses = uses * 3^leveldiff
Note: maxlevel, level and uses are actual parameters you can set in the code, actualuses and leveldiff aren't.
In this table from the API Documentation, you can see a similar example, with a tool with maxlevel = 2, and uses = 20, the amount of actual uses the tool has depending on the leveldiff.
A leveldiff of 0, and it takes 1 node broken to consume 1 use. A leveldiff of 1 and it takes 3 broken nodes to consume 1 use. A leveldiff of 2 and it takes 9 nodes to consume 1 use. A leveldiff of 3 and it takes 27 blocks to consume one tool use. You get the idea.
Although these properties are described in the API in a way that is easy to understand, I'll give a quick summary for people here too.
If you click the property name, it will open the documentation on the exact line where that property is explained. You can also press Ctrl+F when you have opened the documentation and type the word or property you want to learn about, and it will show you exactly where that property is explained in the documentation.
full_punch_interval is a tool property that refers to the time you need to wait between clicks in order to deal full damage.
max_drop_level is the maximum level a node can have and still drop an item. If you use this tool to break a node that has a higher level than this, and this tool can still break the node, the node will not drop anything. This can be useful if you want to have a tool that can break certain nodes but not give any items after they break it. Now we finally reach the fun part!
Do you want, like me, to add new, stronger tools to your mod that can break the stronger nodes that you add?
You now can, and it's not confusing anymore. No weird, hard to understand tables.
Only clear words, straight from my experiments!
Right, so, remember how I said earlier that ratings are just identifiers of sorts, and for some reason they go in reverse? Like rating 1 means stronger than rating 3 but level 3 means stronger than level 1.
That just made no sense to me! Still doesn't really. Although I can understand how it functions, I can't understand why would the devs choose to implement such a confusing system.
In any case, as the node's group rating is just an ID, you are allowed to make your own nodes with any rating you want. For example, following the default way of adding nodes, if you wanted to add a node that was one tier above diamond, you could make it crumbly rating 0. As diamond blocks are rating 1, and the strongest tools in the default mod can only mine up to (or rather down to) rating 1, adding a node with rating 0 would essentially make all vanilla tools unable to mine this new node.
Here is an example I used for testing this, in order to eventually add new tiers to my mod:
Code: Select all
minetest.register_node("[redacted modname]:testblock", {
description = "Test Block",
tiles = {"[redacted]_amethyst_block.png"},
is_ground_content = false,
groups = {cracky = 0, level = 3},
sounds = default.node_sound_stone_defaults(),
})
If we now add a new tool that can mine nodes with ratings of 0 like this:
Code: Select all
minetest.register_tool([redacted]..":pick_test", {
description = "hello there general kenobi",
tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level = 3,
inventory_image = "[redacted]_tool_mithril_pick.png",
groupcaps = {
cracky = {times = {[0] = 6, [1] = 3, [2] = 2, [3] = 1}, uses = 6000, maxlevel = 3}
},
damage_groups = {fleshy = 1}
},
sound = {breaks = "default_tool_breaks"},
groups = {pickaxe = 1}
})
But wait, it doesn't end here!
Do you want to go further?
Of course you do!
If you want to add even more tiers of tools and nodes, you could make them have a negative rating! Like, next, after rating 0, you could add a node with cracky rating -1, and a tool made to be able to break that kind of rating! I've tested it and it works!
But, again, ratings are just IDs for tiers of tools and nodes, you don't need to follow the illogical order of the default mod, you can make the next tier of nodes after diamond be cracky rating 4, and make them take longer to mine than rating 3 or 1. No need to go backwards, advance, to infinity and beyond!
Make tools and nodes with ratings of 4, 5, 6, 7, and more. It can finally make sense.
I tried it with decimal values, such as -4.5 or 5.2. These values will work and won't throw any exceptions, but thanks to a kind user named LMD, I believe the reason it works is because these numbers are being rounded/truncated to make them into integers. So don't use decimal values, it will give you unexpected and undesirable results.
This was my last test, by the way:
Code: Select all
minetest.register_tool([redacted]..":pick_test", {
description = "hello there general kenobi",
tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level = 3,
inventory_image = "[redacted]_tool_mithril_pick.png",
groupcaps = {
cracky = {times = {[0] = 6, [1] = 3, [2] = 2, [3] = 1, ["yes, my friend :)"] = 6}, uses = 6000, maxlevel = 3}
},
damage_groups = {fleshy = 1}
},
sound = {breaks = "default_tool_breaks"},
groups = {pickaxe = 1}
})
minetest.register_node("[redacted]:testblock", {
description = "Test Block",
tiles = {"[redacted]_amethyst_block.png"},
is_ground_content = false,
groups = {cracky = "yes, my friend :)", level = 3},
sounds = default.node_sound_stone_defaults(),
})
It has its limitations; the rating must be an integer between -31999 and 31999. Other than that, you're good to go.
And that's it! Have fun! I'll go back to making my mod in peace, without getting headaches because of this. Please! Update the documentation. It's extremely well explained most of the times, but when it comes to dig types and digging times it's a whole headache.
You can include bits and pieces of this tutorial if you wish, just please, make it easier for noobs like myself to understand.
Also, might be a good idea to change all the ratings of 1 to 3, and all the ratings of 3 to 1, so that it follows a logical progression of "bigger number = bigger wait for the node to become not a node anymore", and so that it's easier for people to understand how it works, how digging times are calculated, and how to add new tiers of tools and nodes to the game.
Thank you so much for this incredible program. Have an amazing day!