Luanti Guide by dibesfer

Menu

Introduction

hills

Luanti is a voxel game engine written in C++ that allows you to mod it with Lua.

Games 🕹️

When you start Luanti for the first time it will tell you to download a game. A game is necessary to generate worlds.

Some famous games made with this engine are Minetest the game, VoxeLibre and NodeCore

Some little pearls are Void, Cavegame and Colorlandia

Servers

Some famous servers are Your Land, Capture the Flag and SquareOne

See the server list here servers.luanti.org or see the Epic Server List

Make your server for free with playit.gg with this guide

Nodes and entities

Luanti worlds are made of blocks or voxels, luanti calls them nodes. They are static elements and can have different shapes "drawtype"

Entities are objects that aren't attached to a grid position like nodes. Typically for objects that move like NPCs

Modding basics

Go to your luanti folder and get into /mods create a new folder mymod, inside create two files:

mod.conf

name = mymod

init.lua

--Here goes the code

Modding with Lua

There are some functions to do what you want to do. They are called Global callback registration functions

Salute the player:

core.register_on_joinplayer(function(player, last_login)
    local playername = player:get_player_name()
    core.chat_send_player(playername, "Hi " .. playername .. "!")
end)

♪ Play a sound when a player joins

Have a welcomesound.ogg file in /sounds folder

local music_file = "welcomesound"
local sound = nil

core.register_on_joinplayer(function(player, last_login)
    sound = core.sound_play(music_file, {
            loop = false,
            gain = 0.5 ,  -- Adjust volume
            name = "welcoming sound",  -- Identifier for the sound
    })
end)

Create new nodes

core.register_node('blank:grass', {
    description = 'Beautiful grass node',
    tiles = { 'grass.png' },
    groups = { dig_immediate = 3 },
    is_ground_content = true
})

Use /giveme blank:grass to get the node.

Create your game

To start from zero we will create our own game.

We need to go to our luanti installation path and enter /games. Create a folder, for example: "Blank".

Inside of it we will create a file called game.conf

title = Blank
author = dibesfer
description = Absolute blank template to start your projects from.
disallowed_mapgens = v6

Also we will create a /mods folder

Inside of it we will create the main mod we will just call blank

Inside of /blank we will create a mod.conf and init.lua files.

mod.conf (name = blank)

init.lua we will work upon of this.

We will also create a folder /textures for storing our assets.

Create A Full Biome

Want to make your own voxel world like Minecraft? follow this short steps guide with images

Objectives:

  1. Create a node (stone, water, river_water)
  2. Create a biome (grass, dirt)
  3. Create a plant (flower, long plant)
  4. Create an ore (ruby, sapphire, emerald, mese)
  5. Create an schematic (tree)

Create your first node

In order to create worlds with most map generators like v7, valleys, flat... Luanti needs to set three essential nodes: stone, water and river water.

core.register_node('blank:stone', {
    description = 'Stone',
    tiles = { 'stone.png' },
    groups = { dig_immediate = 3 },
    paramtype = "light"
})
core.register_node('blank:water', {
    description = 'Water',
    tiles = { 'water.png' },
    groups = { dig_immediate = 3 },
    paramtype = "light"
})
core.register_node('blank:river_water', {
    description = 'River Water',
    tiles = { 'river_water.png' },
    groups = { dig_immediate = 3 },
    paramtype = "light"
})

Now we register the aliases

core.register_alias('mapgen_stone', 'blank:stone')
core.register_alias('mapgen_water_source', 'blank:water')
core.register_alias('mapgen_river_water_source', 'blank:river_water')

Mapgen v6 needs a lot more of essential nodes like lava so we will skip it to keep it simple.

With these nodes we will have a world like this (if we select Valleys mapgen)

Let's paint it green adding some grass.

Create a biome ⛰️

Lets create a grass and dirt node.

grass dirt
core.register_node('blank:grass', {
    description = 'Grass',
    tiles = { 'grass.png' },
    groups = { dig_immediate = 3 },
    paramtype = "light",
})
core.register_node('blank:dirt', {
    description = 'Dirt',
    tiles = { 'dirt.png' },
    groups = { dig_immediate = 3 },
    paramtype = "light",
})

Register the biome

core.register_biome({
    name = "grassland",
    node_top = "blank:grass",
    depth_top = 1,
    node_filler = "blank:dirt",
    depth_filler = 4,
    node_riverbed = "blank:river_water",
    node_stone = "blank:stone",
    node_water = "blank:water",
    depth_riverbed = 2,
    y_max = 31000,
    y_min = -100,
    heat_point = 10,
    humidity_point = 10,
})

Now we have this (v7 mapgen)

Create a flower 🌺

Let's create two vegetations, flower and long plant.

flower long plant rosa
core.register_node("blank:flower", {
    description = "Blank Flower",
    drawtype = "plantlike",
    waving = 1,
    tiles = { "flower.png"},
    inventory_image = "flower.png",
    wield_image = "flower.png",
    sunlight_propagates = true,
    paramtype = "light",
    walkable = false,
    groups = { dig_immediate = 3},
})

Register a decoration

core.register_decoration({
    name = "blank_flower",
    deco_type = "simple",
    place_on = {"blank:grass"},
    sidelen = 16,
    fill_ratio = 0.005,
    y_max = 31000,
    y_min = 0,
    decoration = { "blank:blank_flower"},
})

Now we see the flowers spawning in the world!

Create and register an ore 💎

Let's create ruby, emerald, sapphire and mese

ruby emerald sapphire mese
core.register_node('blank:ruby', {
    description = 'Ruby',
    tiles = { 'ruby.png' },
    groups = { dig_immediate = 3 },
    is_ground_content = true
})

Register it

core.register_ore({
    ore_type = "scatter",
    ore = "blank:ruby",
    wherein = "blank:stone",
    clust_scarcity = 8 * 8 * 8,
    clust_num_ores = 16,
    clust_size = 16,
    y_max = 31000,
    y_min = -127,
})

Now we see the ores. Plenty of ores

Trees 🌲

Create wood and leaves, create a tree, create a schematic, register a decoration

Wood Leaves
core.register_node('blank:wood', {
    description = 'Wood',
    tiles = { 'wood.png' },
    groups = { dig_immediate = 3 },
})

core.register_node('blank:leaves', {
    description = 'Leaves',
    tiles = { 'leaves.png' },
    groups = { dig_immediate = 3 },
})

Go in-game an build a tree.

Download Worldedit mod and enable it on your world.

Build a tree and select the opposite vertices of an imaginary box.

We set first position with //1 and second position with //2

Save an schematic writing //mtschemcreate tree

Now navigate to your world path and enter the schems folder.

Take that file and put it into a new folder inside your mod called schematics.

Register the decoration

core.register_decoration({
    name = "tree",
    deco_type = "schematic",
    place_on = {"blank:grass"},
    place_offset_y = 1,
    sidelen = 16,
    fill_ratio = 0.001,
    biomes = "normalland",
    y_max = 31000,
    y_min = 0,
    schematic = core.get_modpath("blank") .. "/schematics/tree.mts",
    flags = "place_center_x, place_center_z",
    rotation = "random",
})

We use place_offset_y=1 because by default Luanti places decorations at ground level.

Now trees will spawn all over the place


Routepaper

1- Create your first voxel

---dirt and stone---
Register your firstly created voxel as a land basement, you'll quickly see how the world spreads with your creation
Register your firstly created stone voxel as a land basement underground, you'll quickly see how the world is filled with stone below your feet :)

2- Create your first decoration

---flowers and decorations---
But you see, the world is still inert, it's time to fill it with colored flowers and grass!
Register your first created decoration (flowers and grass are recommended)

3- Create your first ore

---ores and gold---
So what's the meaning of all that stone below your feet? Let's fill it with brilliant ores!

Register your firstly created ores, time to fill that depths with shiny minerals

4- Create your first biome

    ill skip schematics till the end

            

Blank

Blank is a minimal template. It was made along with this tutorial.

Blank contains only 11 nodes and 1 item the "" hand

grass, stone, dirt, ruby, sapphire, mese, water, river water, flower, wood, leaves

You can download it from Luanti ContentDB here

Colorize your messages

Let's store this info in mod storage and create a variable for color

local storage = core.get_mod_storage()
default_color = "#FFFFFF" -- White

Function to get a player's saved color

local function get_player_color(player_name)
    return storage:get_string(player_name) ~= "" and storage:get_string(player_name) or default_color
end

Command to set chat color

core.register_chatcommand("setcolor", {
    params = "#RRGGBB",
    description = "Set your chat color",
    func = function(name, param)
        if param:match("^#%x%x%x%x%x%x$") then
            storage:set_string(name, param)
            return true, "Chat color set to " .. param
        else
            return false, "Invalid color format! Use rgb #RRGGBB"
        end
    end,
})

Modify player messages

core.register_on_chat_message(function(name, message)
    local color = get_player_color(name)
    core.chat_send_all(core.colorize(color, "<" .. name .. "> " .. message))
    return true 
end)

return true stops default chat handling. Now use /setcolor #ff0000 to turn the text red.

Use a resource like rgbcolorpicker.com to get your color rgb code!

colored chat

Textures

Tired of boring plain textures?

Use gimp to apply Filter > Noise > HSV Noise

gimp edition gimp edition

Now the world looks like this

noise textures landscape

Colorize Textures

Let's create a plain black and white (or grayscale) texture image.

plain white wool

Use the texture modifier ^[colorize:#ff0000:180 to set a RGB color red and a ratio: 0-only the texture to 255-only the color

core.register_node('blank:wool', {
    description = 'Wool',
    tiles = { 'wool.png' },
    groups = { dig_immediate = 3 },
    paramtype = "light",
})

core.register_node('blank:red_wool', {
    description = 'Wool',
    tiles = { "wool.png^[colorize:#ff0000:180" },
    groups = { dig_immediate = 3 },
    paramtype = "light",
})

Use colors like green #00FF00 or blue #0000FF

Let's get creative

Meet the player (change camera model with C)

Future Tutorials 🎓

- Create an entity

- Create a recipe

- Create a tool

Luanti website

Luanti docs

Luanti api

rubenwardy - Modding book

Credits

Author: dibesfer - dibesfer@gmail.com

Coded with HTML, CSS and javascript on VSCodium

Host: github pages

luanti - celeron55 (Perttu Ahola) celeron55@gmail.com

Fonts: Ubuntu and Ubuntu Mono

Google Code Prettify

Stats

Local visits:

Total visits:


2025/02/11

by dibesfer

Contact dibesfer@gmail.com