Day 0 - Stuff that I’ve done so far…

So far we have minetest building from within our development base image (plus some for this project) and running properly from a docker container. Additionally we have a minimal module that can be added to the environment and has a simple node that can be placed in the world.

This is what I’ve done already.

The docker image

The Strange Crew dev-base image is our starting point. Minetest provides its own as well, which is great for just building. The dev-base image contains more than is strictly necessary just for building, but also vim and tmux and is set up as a development environment. This image contains fairly recent releases of C++, Python, and Meson.

The Minetest contains the libraries that are needed to build the client or the server (or both) in the compiling directions.

Since our base image is based on ubuntu we used the debian version. We included everything except g++:

FROM strangecrew/dev-base

RUN apt-get install -yy \
    cmake \
    libpng-dev \
    libjpeg-dev \
    libxxf86vm-dev \
    libgl1-mesa-dev \
    libsqlite3-dev \
    libogg-dev \
    libvorbis-dev \
    libopenal-dev \
    libcurl4-gnutls-dev \
    libfreetype6-dev \
    zlib1g-dev \
    libgmp-dev \

This not all that is needed, but it’s enough to start the next step.

Building Minetest

To build minetest you need to be in the image. So first build that (call it minetest-dev). Then simply start it:

docker run -it --rm -v $(pwd):/work $(pwd)/.dev-home:/home/dev-user minetest-dev

The volume mounts are useful with the base image. You won’t need .dev-home unless you intend to perform authenticated operations with git.

First you simple clone minetest and then clone irrilich inside of it:

git clone /work/minetest
git clone --depth 1 /work/minetest/lib/irrlichtmt

Here I clone our fork of minetest because in the very near future I’ll be modifying it. For now it is a straight up copy. I clone more of it because I intend to work on it, while in the case of irrilicht I probably won’t need to.

Then the build:

cd /work/minetest

Running Minetest

Running minetest requires two additional things. First the dev-user must be in the audio group:

RUN adduser dev-user audio

So that got added to the image. Furthermore, there are a lot of arguments to docker in order to really build AND run minetest. The biggest issues I needed to figure out were how to open up the sound and hardware acceleration to the container. That requires some additional mounts that I found with search on stackoverflow. The whole script is:

docker run -it --rm \
    -v $(pwd)/.dev-home:/home/dev-user \
    -v $(pwd):/work \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v ${XDG_RUNTIME_DIR}/pulse/native:${XDG_RUNTIME_DIR}/pulse/native \
    --device /dev/snd \
    --device /dev/dri/card0 \
    --user dev-user \
    --workdir /work \
    -e TERM \
    -e DISPLAY \
    -e PULSE_SERVER=unix:${XDG_RUNTIME_DIR}/pulse/native \

The first volume is for a home directory that is persistent. This will end up including .ssh, .gitconfig (if you are developing) and .local for pip installs.

The second volume opens up the current working directory as /work

The third gives access to the X Window System display.

The fourth is for the pulseaudio system that Ubuntu uses.

Then two devices, audio and video, need to be exposed. The latter is for GL hardware acceleration.

Then the workdir is set to where the work will be. Just a helpful thing.

We expose TERM so that vim and NERDTree work (with fonts), DISPLAY so minetest knows what to open, and PULSE_SERVER again for sound with pulseaudio.

And then I called my docker image “testenv-dev”, which makes sense to me but probably won’t you.

Once you start the script you should get a $ prompt and be in /work. To start minetest:

cd minetest

Getting started with mod development

Not being too into learning from videos, this part took a sec but it turns out there’s really not a whole lot to it. My sources of information were:

I am also building what will probably amount to something like a Nether Portal so I refered to its source some. I do not know Lua but this has not yet been a huge issue. It did take me a moment to find what I wanted (wanted to have the node walk-through) because it’s not just some simple node, but eventually I found the function where they create the node and found “walkable = false” to be the key element.

Additionally there is a series of videos being created by a reddit poster:

Videos don’t work for me though (just not my learning style) so I didn’t reference them. They are in the process of being made for those who do though.

First thing I needed was to understand exactly what the format of images are. I looked at the source to the default mod and found them to be simple 16x16 pixel anythings. Tiles can be of any size but this is like the small one with the biggest blocks in-game.

So I made a 16x16 pure black image and put it in the textures.

To create a node out of this simple image is as simple as registering it as a node in init.lua:

minetest.register_node("stargate:derp", {
    description = "Just a test node.",
    tiles = {"stargate_derp.png"},
    is_ground_content = true,
    walkable = false,
    light_source = 10

Then mod.conf describes the module to Minetest.

This function/method register_node takes a name for the node as an id, and a map of values that describe it. The obvious description value gives it text that shows up in-game when its hovered over in the inventory. The tiles value tells the engine what to draw on the faces of the node. In this case its just the one image from all angles (more is covered in the book and API documentation).

Not sure yet what is_ground_content does, but walkable=false makes it so you can walk through it. Also, light_source makes it light up the surrounding area, which is an odd thing for an empty void to do.


View from outside


New node in the inventory.


Walking inside shows a frame at first entry.


Being inside turns off the world.


Lighting its surroundings.


Next in line on this project is setting up unit tests and responding to the player’s interaction with the node.