Author(s): Paul Brown

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.

Figure 1: You can model the worlds of Minetest in more ways than one.

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.

Figure 2: Activate mods in the Configure screen.

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).

Figure 3: It is exciting to meet your first cow.

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.

Figure 4: Your first node.

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.

Figure 5: A reinforced steel texture created with Inkscape.

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.

Figure 6: A texture node is a good-looking node.

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" }, })

Figure 7: A transparent texture can be used as an overlay on top of another texture.

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.

Figure 8: Crafting a safe using reinforced steel nodes.

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).

Figure 9: You can change the shape of a node using node boxes.

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.