Building your own nodes and mods in Minetest
Tutorials – Minetest
Minetest is much more than a clone of a certain popular proprietary game. It offers infinite customization that allows you to create blocks, objects, fun educational exercises, and even games within the game, dishing up features well beyond those of any other closed source alternative.
Although I have written about Minetest [1] before, a four page article hardly does the game justice. In fact, the tag "game" hardly does Minetest justice. The November 2017 issue of Linux Magazine [2] we looked at gameplay, but for the regular readers, actually playing the game should be the least of their concerns.
Minetest allows you to create much more beyond what is served up in the standard package. In a way, Minetest is a blank canvas (Figure 1), and, in the grand tradition of free software, you are not restricted to the default palette, and in fact, you are given the tools to create your own paints and brushes.
All Mods
Minetest is made up of two parts: the main engine and the mods. It is the mods that make the game playable. If you have installed Minetest from your distro's repositories, look into your /usr/share/minetest/games/minetest/
directory. You'll see that the brunt of bringing the game to life is born by the files in the mods/
directory. A "world" in Minetest is, to all practical effects, its mods.
The default world that comes with Minetest is basic. You have a nice variety of materials and things you can craft, but, for example, there are no animals and no monsters. This is by design: The creators of Minetest assume you are going to want to tailor your experience, so they give you the bare minimum, and it is up to you to bring in (or create, as you shall see later) your own modifications.
However, if you want to get into some serious gameplay before tailoring, head over to the Minetest website [3] to see what's available.
Let's grab some animals, shall we? Notice that, apart from the minetest/
directory in /usr/share
, you also have a hidden .minetest
directory in your own home directory. Change into the mods/
subdirectory:
cd ~/.minetest/mods
And download the general mobs and farm animals mods made by Minetest Forums member TenPlus1:
git clone https://github.com/tenplus1/mobs_redo.git git clone https://github.com/tenplus1/mobs_animal.git
Rename the mobs_redo/
folder to mobs/
:
mv mobs_redo mobs
And run Minetest.
Create a new world or pick an old one, and click the Configure button. In the panel on the right, you will see a list of available mods. Pick mobs and tick the enabled checkbox at the top of the window. The mod will turn green as shown in Figure 2. Do the same with the mobs_animal mod.
Now, when you visit your world, there will be animals roaming around. You can hunt them, domesticate them, or just hang out with them – if they are friendly.
Different types of animals hang around different environments. I met warthogs on a savanna-like expanse, but none turned up on a green prairie where cows were roaming (Figure 3).
Many animals, like cows, pigs, warthogs and sheep, give meat when they are killed, or other products when they are right-clicked. For example, right-click a cow with an empty bucket, and you'll get milk. Right-click a sheep with a dye, and you will change its color. Then, right-click it with shears, and you'll get colored wool. In the mobs_animal
directory, you'll find a README document describing different ways you can interact with your four-legged friends.
If you want the whole survival experience, get yourself some monsters from GitHub [4] and the Minetest Wiki [5] and battle it out against zombies, ghosts, and all sorts of creepy-crawlies.
Making Your Own
But, again, you are just playing someone else's game. Although Minetest's gameplay is great, it is not, I think, the most interesting feature. For us tinkerers, that feature would be the mod system, and making your own mods is relatively easy. Minetest has made the API for creating mods part of its framework from the beginning. To program mods, you use Lua [6], a high-level language vaguely reminiscent of Python.
Although we won't go into Lua in much depth here (there are plenty of good guides and tutorials online), it is worth mentioning that in Lua it is all about tables. Lua tables combine the features from arrays, associative arrays, lists, dictionaries, and so on from other languages into one powerful data structure. Even Lua's pseudo object-oriented programming paradigm is table-based. Unsurprisingly, the Minetest modding API relies heavily on tables.
Speaking of which, the basic building block, never better said, of Minetest modding is the node, a glorified table. All physical things in a Minetest world, including invisible ones, are nodes, and every different kind of node is defined by a mod. Let's see how that works by building a basic node.
Open your text editor, and copy what you see in Listing 1.
Listing 1
init.lua – Reinforced Steel Node
minetest.register_node("personal:reinforced_steel", { })
In your mods/
directory create a subdirectory and call it personal
. Save your file there as init.lua
.
Congratulations: You just made your first mod.
The register_node()
function is a Minetest module [7] that inserts a new kind of node into the Minetest world. It takes two parameters: the name and location of the material ("personal:reinforced_steel"
), and a table that contains all the material's characteristics. The table is enclosed in curly brackets ({}
) and, in this case, is empty, so you will see a cube with placeholder values when you use the node.
Although you could load your new node the same way you loaded the pre-built mods you saw above, there is not much to see (Figure 4). Besides, you will not find your node "in nature," as it were; you will have to give it to yourself.
To do this, open Minetest's terminal (inside the game, press F10) and type /giveme personal:reinforced_steel 50
(if the engine complains, give yourself give
privileges with /grantme give
). This will add 50 blocks of your new material to your inventory.
To lay down a block, right-click anywhere on the floor, and you should see something like what you see in Figure 4. It doesn't look very good, does it? That is because it is using a default placeholder texture, with the words "unknown node" scrawled all over it.
Let's prettify it.
Inside your personal/
folder, create new subfolder called textures/
. This is where the Minetest engine will go looking for pictures to plaster over your node.
Create a square image using your preferred image editor. The creators of Minetest recommend using an editor that will allow you to edit individual pixels, so as to keep in line with the legacy look of the game. That is good advice, but I have found that using Inkscape, exporting to a PNG, then downsizing the image to 80x80 pixels using a Cubic interpolation in Gimp, and then blowing it up with no interpolation to 320x320 works fine. If you choose your colors carefully, it gives your designs a nice 16-bit vibe like what you see in Figure 5.
Save your graphic in your textures/
folder as reinforced.png
, and modify your mod to look like what is shown in Listing 2.
Listing 2
init.lua – Reinforced Steel Node
minetest.register_node("personal:reinforced_steel", { tiles = {"reinforced.png"}, })
You don't have to indicate the path to the image, because Minetest looks into all of the mods' textures/
directories. The downside of this is that you have to make the name of your material unique, or you risk getting the wrong material plastered over your node.
In Listing 2, you can see that we have added the first element of the table that gets passed on to register_node()
. It shows how this Lua table is basically the same as an associative array: tiles
is the key, and the value is another table containing the designs for the nodes' faces.
If you now visit your world again, your reinforced_steel
node will look like Figure 6. I am sure you will agree that it looks quite good.
You can have different designs on each face. In that case, the tiles
table would look like this:
tiles = {"top.png", "bottom.png", "right.png", "left.png", "back.png", "front.png"}
You must, of course, change top.png
, bottom.png
, and son for the names of the images you want to use for the respective faces of your node.
Texturing can be much more sophisticated, too, since you can combine several textures together. Take a look at Listing 3. Notice how in this new node the front face gets a combined texture of reinforced.png
with safe_front.png
[8]. Figure 7 shows safe_front.png
, a PNG with transparency. You can overlay it on top of reinforced.png
using the ^
operator.
Listing 3
init.lua – Safe node
... minetest.register_node("personal:safe", { tiles = { "reinforced.png", "reinforced.png", "reinforced.png", "reinforced.png", "reinforced.png" "reinforced.png^safe_front.png" }, })
Add the safe
node to your existing init.lua
. But this time, when you go to test it, instead of "giving" it to yourself when you play (which is kind of cheating), let's give it a recipe
, so you can build it from other materials. You can do this by adding the code shown in Listing 4 to init.lua
.
Listing 4
init.lua – Safe Recipe
... minetest.register_craft ({ output = "personal:safe", recipe = { {"personal:reinforced_steel", "personal:reinforced_steel", "personal:reinforced_steel"}, {"personal:reinforced_steel", "", "personal:reinforced_steel"}, {"personal:reinforced_steel", "personal:reinforced_steel", "personal:reinforced_steel"} }, })
The recipe tells the Minetest engine that players can build a safe in the crafting area by using steel nodes surrounding an empty space, as shown in Figure 8.
Non-Cubic Nodes
There are several more things you may want to do with your nodes. One of them is to change their shapes. As with other mining and crafting games, you can have nodes in the shapes of steps, flat slabs, etc. For your reinforced steel nodes, you may want them to be flat, and you can achieve that with node boxes [9] (see Listing 5).
Listing 5
init.lua – Reinforced Steel Node
minetest.register_node("personal:reinforced_steel", { tiles = {"reinforced.png"}, drawtype = "nodebox", node_box = { type = "fixed", fixed = { {-0.5, -0.5, -0.5, 0.5, -0.3, 0.5}, } } })
There are a few new things in here. First drawtype
tells the Minetest engine that the node may not be a 1x1x1 cube, that it has to take the coordinates for the cuboids that make up the node from a table within the nodebox
table. The nodebox
item itself contains the kind of node box this is going to be, as well as the coordinates of the cuboid(s) that will make up the node.
In this case, the node box is very simple: It is fixed
, in the sense that it doesn't change whether you mount it on the floor, wall, or ceiling, and consists of one rather flat cuboid. You define the shape of each cuboid that makes up the node box using a table that contains the coordinates of two of its opposing corners. The cuboid in Listing 5 is 1 unit square and 0.2 units high (Figure 9).
If you find defining the shape of your node-box nodes using coordinates confusing, you can download the Node Box Editor utility [10]. The Node Box Editor (Figure 10) lets you edit the size and shape of multiple cuboids visually and even apply textures to them. Then you can export your node boxes to Lua code and incorporate them into your mods.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.
-
Gnome OS Transitioning Toward a General-Purpose Distro
If you're looking for the perfectly vanilla take on the Gnome desktop, Gnome OS might be for you.
-
Fedora 41 Released with New Features
If you're a Fedora fan or just looking for a Linux distribution to help you migrate from Windows, Fedora 41 might be just the ticket.
-
AlmaLinux OS Kitten 10 Gives Power Users a Sneak Preview
If you're looking to kick the tires of AlmaLinux's upstream version, the developers have a purrfect solution.
-
Gnome 47.1 Released with a Few Fixes
The latest release of the Gnome desktop is all about fixing a few nagging issues and not about bringing new features into the mix.
-
System76 Unveils an Ampere-Powered Thelio Desktop
If you're looking for a new desktop system for developing autonomous driving and software-defined vehicle solutions. System76 has you covered.
-
VirtualBox 7.1.4 Includes Initial Support for Linux kernel 6.12
The latest version of VirtualBox has arrived and it not only adds initial support for kernel 6.12 but another feature that will make using the virtual machine tool much easier.