Minetest Lua Client Modding API Reference 5.1.0


** WARNING: The client API is currently unstable, and may break/change without warning. **

Content and functionality can be added to Minetest 0.4.15-dev+ by using Lua
scripting in run-time loaded mods.

A mod is a self-contained bunch of scripts, textures and other related
things that is loaded by and interfaces with Minetest.

Transferring client-sided mods from the server to the client is planned, but not implemented yet.

If you see a deficiency in the API, feel free to attempt to add the
functionality in the engine and API. You can send such improvements as
source code patches on GitHub (

Programming in Lua

If you have any difficulty in understanding this, please read
Programming in Lua.


Mods are loaded during client startup from the mod load paths by running
the init.lua scripts in a shared environment.


Mod load path


In a run-in-place version (e.g. the distributed windows version):

On an installed version on Linux:

Modpack support

NOTE: Not implemented yet.

Mods can be put in a subdirectory, if the parent directory, which otherwise
should be a mod, contains a file named modpack.conf.
The file is a key-value store of modpack details.

Mod directory structure

├── modname
|   ├── depends.txt
|   ├── init.lua
└── another


The location of this directory.


List of mods that have to be loaded before loading this mod.

A single line contains a single modname.

Optional dependencies can be defined by appending a question mark
to a single modname. Their meaning is that if the specified mod
is missing, that does not prevent this mod from being loaded.


The main Lua script. Running this script should register everything it
wants to register. Subsequent execution depends on minetest calling the
registered callbacks.

minetest.setting_get(name) and minetest.setting_getbool(name) can be used
to read custom or existing settings at load time, if necessary.


Media files (sounds) that will be transferred to the
client and will be available for use by the mod.

Naming convention for registered textual names

Registered names should generally be in this format:

"modname:<whatever>" (<whatever> can have characters a-zA-Z0-9_)

This is to prevent conflicting names from corrupting maps and is
enforced by the mod loader.


In the mod experimental, there is the ideal item/node/entity name tnt.
So the name should be experimental:tnt.

Enforcement can be overridden by prefixing the name with :. This can
be used for overriding the registrations of some other mod.

Example: Any mod can redefine experimental:tnt by using the name


when registering it.
(also that mod is required to have experimental as a dependency)

The : prefix can also be used for maintaining backwards compatibility.


NOTE: max_hear_distance and connecting to objects is not implemented.

Only Ogg Vorbis files are supported.

For positional playing of sounds, only single-channel (mono) files are
supported. Otherwise OpenAL will play them non-positionally.

Mods should generally prefix their sounds with modname_, e.g. given
the mod name "foomod", a sound could be called:


Sounds are referred to by their name with a dot, a single digit and the
file extension stripped out. When a sound is played, the actual sound file
is chosen randomly from the matching sounds.

When playing the sound foomod_foosound, the sound is chosen randomly
from the available ones of the following files:

Examples of sound parameter tables:

-- Play locationless
    gain = 1.0, -- default
-- Play locationless, looped
    gain = 1.0, -- default
    loop = true,
-- Play in a location
    pos = {x = 1, y = 2, z = 3},
    gain = 1.0, -- default
    max_hear_distance = 32, -- default, uses an euclidean metric
-- Play connected to an object, looped
    object = <an ObjectRef>,
    gain = 1.0, -- default
    max_hear_distance = 32, -- default, uses an euclidean metric
    loop = true,

Looped sounds must either be connected to an object or played locationless.


Representations of simple things


{x=num, y=num, z=num}

For helper functions see “Vector helpers”.


Flag Specifier Format

Flags using the standardized flag specifier format can be specified in either of
two ways, by string or table.

The string format is a comma-delimited set of flag names; whitespace and
unrecognized flag fields are ignored. Specifying a flag in the string sets the
flag, and specifying a flag prefixed by the string "no" explicitly
clears the flag from whatever the default may be.

In addition to the standard string flag format, the schematic flags field can
also be a table of flag names to boolean values representing whether or not the
flag is set. Additionally, if a field with the flag name prefixed with "no"
is present, mapped to a boolean of any value, the specified flag is unset.

E.g. A flag field of value

{place_center_x = true, place_center_y=false, place_center_z=true}

is equivalent to

{place_center_x = true, noplace_center_y=true, place_center_z=true}

which is equivalent to

"place_center_x, noplace_center_y, place_center_z"

or even

"place_center_x, place_center_z"

since, by default, no schematic attributes are set.


Formspec defines a menu. It is a string, with a somewhat strange format.

Spaces and newlines can be inserted between the blocks, as is used in the






Minecraft-like player inventory






list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]

list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]

listring[<inventory location>;<list name>]






image[<X>,<Y>;<W>,<H>;<texture name>]

item_image[<X>,<Y>;<W>,<H>;<item name>]


background[<X>,<Y>;<W>,<H>;<texture name>]

background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]









image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]

image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]

item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]


image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]

textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]

textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]

tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]


dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]



table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]

tableoptions[<opt 1>;<opt 2>;...]

tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]

Note: do not use a element name starting with key_; those names are reserved to
pass key press events to formspec!

Spatial Vectors

For the following functions x can be either a vector or a number:

Helper functions

Minetest namespace reference



Global callback registration functions

Call these functions only at load time!






Client Environment

Storage API

Mod channels

![Mod channels communication scheme](docs/mod channels.png)




Class reference


An interface to use mod channels on client and server



An interface to manipulate minimap on client UI



An interface to get or set information about the camera and camera-node.
Please do not try to access the reference until the camera is initialized, otherwise the reference will be nil.


         x = number,
         y = number,
         max = number,
         actual = number


An interface to retrieve information about the player.


        speed = float,
        jump = float,
        gravity = float,
        sneak = boolean,
        sneak_glitch = boolean
       fast = float,
       air = float,
       default = float,
       walk = float,
       jump = float,
       crouch = float,
       fast = float,
       climb = float,
       liquid_fluidity = float,
       liquid_sink = float,
       liquid_fluidity_smooth = float,
       gravity = float,


An interface to read config files in the format of minetest.conf.

It can be created via Settings(filename).



Node metadata: reference extra data and functionality stored in a node.
Can be obtained via minetest.get_meta(pos).



Node Definition

        has_on_construct = bool,        -- Whether the node has the on_construct callback defined
        has_on_destruct = bool,         -- Whether the node has the on_destruct callback defined
        has_after_destruct = bool,      -- Whether the node has the after_destruct callback defined
        name = string,                  -- The name of the node e.g. "air", "default:dirt"
        groups = table,                 -- The groups of the node
        paramtype = string,             -- Paramtype of the node
        paramtype2 = string,            -- ParamType2 of the node
        drawtype = string,              -- Drawtype of the node
        mesh = <string>,                -- Mesh name if existant
        minimap_color = <Color>,        -- Color of node on minimap *May not exist*
        visual_scale = number,          -- Visual scale of node
        alpha = number,                 -- Alpha of the node. Only used for liquids
        color = <Color>,                -- Color of node *May not exist*
        palette_name = <string>,        -- Filename of palette *May not exist*
        palette = <{                    -- List of colors
        waving = number,                -- 0 of not waving, 1 if waving
        connect_sides = number,         -- Used for connected nodes
        connects_to = {                 -- List of nodes to connect to
        post_effect_color = Color,      -- Color overlayed on the screen when the player is in the node
        leveled = number,               -- Max level for node
        sunlight_propogates = bool,     -- Whether light passes through the block
        light_source = number,          -- Light emitted by the block
        is_ground_content = bool,       -- Whether caves should cut through the node
        walkable = bool,                -- Whether the player collides with the node
        pointable = bool,               -- Whether the player can select the node
        diggable = bool,                -- Whether the player can dig the node
        climbable = bool,               -- Whether the player can climb up the node
        buildable_to = bool,            -- Whether the player can replace the node by placing a node on it
        rightclickable = bool,          -- Whether the player can place nodes pointing at this node
        damage_per_second = number,     -- HP of damage per second when the player is in the node
        liquid_type = <string>,         -- A string containing "none", "flowing", or "source" *May not exist*
        liquid_alternative_flowing = <string>, -- Alternative node for liquid *May not exist*
        liquid_alternative_source = <string>, -- Alternative node for liquid *May not exist*
        liquid_viscosity = <number>,    -- How fast the liquid flows *May not exist*
        liquid_renewable = <boolean>,   -- Whether the liquid makes an infinite source *May not exist*
        liquid_range = <number>,        -- How far the liquid flows *May not exist*
        drowning = bool,                -- Whether the player will drown in the node
        floodable = bool,               -- Whether nodes will be replaced by liquids (flooded)
        node_box = table,               -- Nodebox to draw the node with
        collision_box = table,          -- Nodebox to set the collision area
        selection_box = table,          -- Nodebox to set the area selected by the player
        sounds = {                      -- Table of sounds that the block makes
            sound_footstep = SimpleSoundSpec,
            sound_dig = SimpleSoundSpec,
            sound_dug = SimpleSoundSpec
        legacy_facedir_simple = bool,   -- Whether to use old facedir
        legacy_wallmounted = bool       -- Whether to use old wallmounted

Item Definition

        name = string,                  -- Name of the item e.g. "default:stone"
        description = string,           -- Description of the item e.g. "Stone"
        type = string,                  -- Item type: "none", "node", "craftitem", "tool"
        inventory_image = string,       -- Image in the inventory
        wield_image = string,           -- Image in wieldmesh
        palette_image = string,         -- Image for palette
        color = Color,                  -- Color for item
        wield_scale = Vector,           -- Wieldmesh scale
        stack_max = number,             -- Number of items stackable together
        usable = bool,                  -- Has on_use callback defined
        liquids_pointable = bool,       -- Whether you can point at liquids with the item
        tool_capabilities = <table>,    -- If the item is a tool, tool capabilities of the item
        groups = table,                 -- Groups of the item
        sound_place = SimpleSoundSpec,  -- Sound played when placed
        sound_place_failed = SimpleSoundSpec, -- Sound played when placement failed
        node_placement_prediction = string -- Node placed in client until server catches up

Chat command definition (register_chatcommand)

    params = "<name> <privilege>", -- Short parameter description
    description = "Remove privilege from player", -- Full description
    func = function(param),        -- Called when command is run.
                                   -- Returns boolean success and text output.

Server info

    address = "", -- The domain name/IP address of a remote server or "" for a local server.
    ip = "",             -- The IP address of the server.
    port = 30000,                     -- The port the client is connected to.
    protocol_version = 30             -- Will not be accurate at start up as the client might not be connected to the server yet, in that case it will be 0.

HUD Definition (hud_add, hud_get)

        hud_elem_type = "image", -- see HUD element types, default "text"
    --  ^ type of HUD element, can be either of "image", "text", "statbar", or "inventory"
        position = {x=0.5, y=0.5},
    --  ^ Left corner position of element, default `{x=0,y=0}`.
        name = "<name>",    -- default ""
        scale = {x=2, y=2}, -- default {x=0,y=0}
        text = "<text>",    -- default ""
        number = 2,         -- default 0
        item = 3,           -- default 0
    --  ^ Selected item in inventory.  0 for no item selected.
        direction = 0,      -- default 0
    --  ^ Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top
        alignment = {x=0, y=0},   -- default {x=0, y=0}
    --  ^ See "HUD Element Types"
        offset = {x=0, y=0},      -- default {x=0, y=0}
    --  ^ See "HUD Element Types"
        size = { x=100, y=100 },  -- default {x=0, y=0}
    --  ^ Size of element in pixels

Escape sequences

Most text can contain escape sequences, that can for example color the text.
There are a few exceptions: tab headers, dropdowns and vertical labels can’t.
The following functions provide escape sequences:


#RGB defines a color in hexadecimal format.

#RGBA defines a color in hexadecimal format and alpha channel.

#RRGGBB defines a color in hexadecimal format.

#RRGGBBAA defines a color in hexadecimal format and alpha channel.

Named colors are also supported and are equivalent to
CSS Color Module Level 4.
To specify the value of the alpha channel, append #AA to the end of the color name
(e.g. colorname#08). For named colors the hexadecimal string representing the alpha
value must (always) be two hexadecimal digits.


{a = alpha, r = red, g = green, b = blue} defines an ARGB8 color.

HUD element types

The position field is used for all element types.

To account for differing resolutions, the position coordinates are the percentage
of the screen, ranging in value from 0 to 1.

The name field is not yet used, but should contain a description of what the
HUD element represents. The direction field is the direction in which something
is drawn.

0 draws from left to right, 1 draws from right to left, 2 draws from
top to bottom, and 3 draws from bottom to top.

The alignment field specifies how the item will be aligned. It ranges from -1 to 1,
with 0 being the center, -1 is moved to the left/up, and 1 is to the right/down.
Fractional values can be used.

The offset field specifies a pixel offset from the position. Contrary to position,
the offset is not scaled to screen size. This allows for some precisely-positioned
items in the HUD.

Note: offset will adapt to screen DPI as well as user defined scaling factor!

Below are the specific uses for fields in each type; fields not listed for that type are ignored.

Note: Future revisions to the HUD API may be incompatible; the HUD API is still
in the experimental stages.


Displays an image on the HUD.


Displays text on the HUD.


Displays a horizontal bar made up of half-images.



Displays distance to selected world position.

Particle definition (add_particle)

    pos = {x=0, y=0, z=0},
    velocity = {x=0, y=0, z=0},
    acceleration = {x=0, y=0, z=0},
--  ^ Spawn particle at pos with velocity and acceleration
    expirationtime = 1,
--  ^ Disappears after expirationtime seconds
    size = 1,
    collisiondetection = false,
--  ^ collisiondetection: if true collides with physical objects
    collision_removal = false,
--  ^ collision_removal: if true then particle is removed when it collides,
--  ^ requires collisiondetection = true to have any effect
    vertical = false,
--  ^ vertical: if true faces player using y axis only
    texture = "image.png",
--  ^ Uses texture (string)
    animation = {Tile Animation definition},
--  ^ optional, specifies how to animate the particle texture
    glow = 0
--  ^ optional, specify particle self-luminescence in darkness

ParticleSpawner definition (add_particlespawner)

    amount = 1,
    time = 1,
--  ^ If time is 0 has infinite lifespan and spawns the amount on a per-second base
    minpos = {x=0, y=0, z=0},
    maxpos = {x=0, y=0, z=0},
    minvel = {x=0, y=0, z=0},
    maxvel = {x=0, y=0, z=0},
    minacc = {x=0, y=0, z=0},
    maxacc = {x=0, y=0, z=0},
    minexptime = 1,
    maxexptime = 1,
    minsize = 1,
    maxsize = 1,
--  ^ The particle's properties are random values in between the bounds:
--  ^ minpos/maxpos, minvel/maxvel (velocity), minacc/maxacc (acceleration),
--  ^ minsize/maxsize, minexptime/maxexptime (expirationtime)
    collisiondetection = false,
--  ^ collisiondetection: if true uses collision detection
    collision_removal = false,
--  ^ collision_removal: if true then particle is removed when it collides,
--  ^ requires collisiondetection = true to have any effect
    vertical = false,
--  ^ vertical: if true faces player using y axis only
    texture = "image.png",
--  ^ Uses texture (string)