-Minetest Lua Client Modding API Reference 0.5.0
+Minetest Lua Client Modding API Reference 5.4.0
================================================
* More information at <http://www.minetest.net/>
* Developer Wiki: <http://dev.minetest.net/>
Mods are loaded during client startup from the mod load paths by running
the `init.lua` scripts in a shared environment.
+In order to load client-side mods, the following conditions need to be satisfied:
+
+1) `$path_user/minetest.conf` contains the setting `enable_client_modding = true`
+
+2) The client-side mod located in `$path_user/clientmods/<modname>` is added to
+ `$path_user/clientmods/mods.conf` as `load_mod_<modname> = true`.
+
+Note: Depending on the remote server's settings, client-side mods might not
+be loaded or have limited functionality. See setting `csm_restriction_flags` for reference.
+
Paths
-----
* `RUN_IN_PLACE=1` (Windows release, local build)
- * `$path_user`:
- * Linux: `<build directory>`
- * Windows: `<build directory>`
- * `$path_share`
- * Linux: `<build directory>`
- * Windows: `<build directory>`
+ * `$path_user`: `<build directory>`
+ * `$path_share`: `<build directory>`
* `RUN_IN_PLACE=0`: (Linux release)
- * `$path_share`
+ * `$path_share`:
* Linux: `/usr/share/minetest`
* Windows: `<install directory>/minetest-0.4.x`
* `$path_user`:
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.txt`. This file shall be
-empty, except for lines starting with `#`, which are comments.
+should be a mod, contains a file named `modpack.conf`.
+The file is a key-value store of modpack details.
+
+* `name`: The modpack name.
+* `description`: Description of mod to be shown in the Mods tab of the main
+ menu.
Mod directory structure
------------------------
clientmods
├── modname
- | ├── depends.txt
- | ├── init.lua
+ │ ├── mod.conf
+ │ ├── init.lua
└── another
### modname
+
The location of this directory.
-### depends.txt
-List of mods that have to be loaded before loading this mod.
+### mod.conf
+
+An (optional) settings file that provides meta information about the mod.
-A single line contains a single modname.
+* `name`: The mod name. Allows Minetest to determine the mod name even if the
+ folder is wrongly named.
+* `description`: Description of mod to be shown in the Mods tab of the main
+ menu.
+* `depends`: A comma separated list of dependencies. These are mods that must be
+ loaded before this mod.
+* `optional_depends`: A comma separated list of optional dependencies.
+ Like a dependency, but no error if the mod doesn't exist.
-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.
+### `init.lua`
-### init.lua
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.
-
-### `sounds`
-Media files (sounds) that will be transferred to the
-client and will be available for use by the mod.
+**NOTE**: Client mods currently can't provide textures, sounds, or models by
+themselves. Any media referenced in function calls must already be loaded
+(provided by mods that exist on the server).
Naming convention for registered textual names
----------------------------------------------
Sounds
------
-**NOTE: max_hear_distance and connecting to objects is not implemented.**
+**NOTE: Connecting sounds to objects is not implemented.**
Only Ogg Vorbis files are supported.
{
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,
}
* Converts a string representing an area box into two positions
* `minetest.is_yes(arg)`
* returns whether `arg` can be interpreted as yes
+* `minetest.is_nan(arg)`
+ * returns true true when the passed number represents NaN.
* `table.copy(table)`: returns a table
* returns a deep copy of `table`
### Utilities
* `minetest.get_current_modname()`: returns the currently loading mod's name, when we are loading a mod
-* `minetest.get_language()`: returns the currently set gettext language.
+* `minetest.get_modpath(modname)`: returns virtual path of given mod including
+ the trailing separator. This is useful to load additional Lua files
+ contained in your mod:
+ e.g. `dofile(minetest.get_modpath(minetest.get_current_modname()) .. "stuff.lua")`
+* `minetest.get_language()`: returns two strings
+ * the current gettext locale
+ * the current language code (the same as used for client-side translations)
* `minetest.get_version()`: returns a table containing components of the
engine version. Components:
* `project`: Name of the project, eg, "Minetest"
* `minetest.sha1(data, [raw])`: returns the sha1 hash of data
* `data`: string of data to hash
* `raw`: return raw bytes instead of hex digits, default: false
+* `minetest.get_csm_restrictions()`: returns a table of `Flags` indicating the
+ restrictions applied to the current mod.
+ * If a flag in this table is set to true, the feature is RESTRICTED.
+ * Possible flags: `load_client_mods`, `chat_messages`, `read_itemdefs`,
+ `read_nodedefs`, `lookup_nodes`, `read_playerinfo`
### Logging
* `minetest.debug(...)`
### Global callback registration functions
Call these functions only at load time!
-* `minetest.register_globalstep(func(dtime))`
+* `minetest.register_globalstep(function(dtime))`
* Called every client environment step, usually interval of 0.1s
-* `minetest.register_on_shutdown(func())`
+* `minetest.register_on_mods_loaded(function())`
+ * Called just after mods have finished loading.
+* `minetest.register_on_shutdown(function())`
* Called before client shutdown
* **Warning**: If the client terminates abnormally (i.e. crashes), the registered
callbacks **will likely not be run**. Data should be saved at
semi-frequent intervals as well as on server shutdown.
-* `minetest.register_on_connect(func())`
- * Called at the end of client connection (when player is loaded onto map)
-* `minetest.register_on_receiving_chat_message(func(message))`
+* `minetest.register_on_receiving_chat_message(function(message))`
* Called always when a client receive a message
* Return `true` to mark the message as handled, which means that it will not be shown to chat
-* `minetest.register_on_sending_chat_message(func(message))`
+* `minetest.register_on_sending_chat_message(function(message))`
* Called always when a client send a message from chat
* Return `true` to mark the message as handled, which means that it will not be sent to server
* `minetest.register_chatcommand(cmd, chatcommand definition)`
* Adds definition to minetest.registered_chatcommands
* `minetest.unregister_chatcommand(name)`
* Unregisters a chatcommands registered with register_chatcommand.
-* `minetest.register_on_death(func())`
+* `minetest.register_on_chatcommand(function(command, params))`
+ * Called always when a chatcommand is triggered, before `minetest.registered_chatcommands`
+ is checked to see if that the command exists, but after the input is parsed.
+ * Return `true` to mark the command as handled, which means that the default
+ handlers will be prevented.
+* `minetest.register_on_death(function())`
* Called when the local player dies
-* `minetest.register_on_hp_modification(func(hp))`
+* `minetest.register_on_hp_modification(function(hp))`
* Called when server modified player's HP
-* `minetest.register_on_damage_taken(func(hp))`
+* `minetest.register_on_damage_taken(function(hp))`
* Called when the local player take damages
-* `minetest.register_on_formspec_input(func(formname, fields))`
+* `minetest.register_on_formspec_input(function(formname, fields))`
* Called when a button is pressed in the local player's inventory form
* Newest functions are called first
* If function returns `true`, remaining functions are not called
-* `minetest.register_on_dignode(func(pos, node))`
+* `minetest.register_on_dignode(function(pos, node))`
* Called when the local player digs a node
* Newest functions are called first
* If any function returns true, the node isn't dug
-* `minetest.register_on_punchnode(func(pos, node))`
+* `minetest.register_on_punchnode(function(pos, node))`
* Called when the local player punches a node
* Newest functions are called first
* If any function returns true, the punch is ignored
* `minetest.register_on_placenode(function(pointed_thing, node))`
* Called when a node has been placed
-* `minetest.register_on_item_use(func(item, pointed_thing))`
+* `minetest.register_on_item_use(function(item, pointed_thing))`
* Called when the local player uses an item.
* Newest functions are called first.
* If any function returns true, the item use is not sent to server.
-* `minetest.register_on_modchannel_message(func(channel_name, sender, message))`
+* `minetest.register_on_modchannel_message(function(channel_name, sender, message))`
* Called when an incoming mod channel message is received
* You must have joined some channels before, and server must acknowledge the
join request.
* If message comes from a server mod, `sender` field is an empty string.
-* `minetest.register_on_modchannel_signal(func(channel_name, signal))`
+* `minetest.register_on_modchannel_signal(function(channel_name, signal))`
* Called when a valid incoming mod channel signal is received
* Signal id permit to react to server mod channel events
* Possible values are:
3: leave_failed
4: event_on_not_joined_channel
5: state_changed
-* `minetest.register_on_inventory_open(func(inventory))`
+* `minetest.register_on_inventory_open(function(inventory))`
* Called when the local player open inventory
* Newest functions are called first
* If any function returns true, inventory doesn't open
* `spec` is a `SimpleSoundSpec`
* `parameters` is a sound parameter table
* `minetest.sound_stop(handle)`
+ * `handle` is a handle returned by `minetest.sound_play`
+* `minetest.sound_fade(handle, step, gain)`
+ * `handle` is a handle returned by `minetest.sound_play`
+ * `step` determines how fast a sound will fade.
+ Negative step will lower the sound volume, positive step will increase
+ the sound volume.
+ * `gain` the target gain for the fade.
### Timing
* `minetest.after(time, func, ...)`
* Optional: Variable number of arguments that are passed to `func`
* `minetest.get_us_time()`
* Returns time with microsecond precision. May not return wall time.
-* `minetest.get_day_count()`
- * Returns number days elapsed since world was created, accounting for time changes.
* `minetest.get_timeofday()`
* Returns the time of day: `0` for midnight, `0.5` for midday
* Returns the node at the given position as table in the format
`{name="node_name", param1=0, param2=0}`, returns `nil`
for unloaded areas or flavor limited areas.
+* `minetest.get_node_light(pos, timeofday)`
+ * Gets the light value at the given position. Note that the light value
+ "inside" the node at the given position is returned, so you usually want
+ to get the light value of a neighbor.
+ * `pos`: The position where to measure the light.
+ * `timeofday`: `nil` for current time, `0` for night, `0.5` for day
+ * Returns a number between `0` and `15` or `nil`
* `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns pos or `nil`
* `radius`: using a maximum metric
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
* `search_center` is an optional boolean (default: `false`)
If true `pos` is also checked for the nodes
+* `minetest.find_nodes_in_area(pos1, pos2, nodenames, [grouped])`
+ * `pos1` and `pos2` are the min and max positions of the area to search.
+ * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
+ * If `grouped` is true the return value is a table indexed by node name
+ which contains lists of positions.
+ * If `grouped` is false or absent the return values are as follows:
+ first value: Table with all node positions
+ second value: Table with the count of each node with the node name
+ as index
+ * Area volume is limited to 4,096,000 nodes
+* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a
+ list of positions.
+ * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
+ * Return value: Table with all node positions with a node air above
+ * Area volume is limited to 4,096,000 nodes
+* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos`
+ * Checks if there is anything other than air between pos1 and pos2.
+ * Returns false if something is blocking the sight.
+ * Returns the position of the blocking node when `false`
+ * `pos1`: First position
+ * `pos2`: Second position
+* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast`
+ * Creates a `Raycast` object.
+ * `pos1`: start of the ray
+ * `pos2`: end of the ray
+ * `objects`: if false, only nodes will be returned. Default is `true`.
+ * `liquids`: if false, liquid nodes won't be returned. Default is `false`.
+
+* `minetest.find_nodes_with_meta(pos1, pos2)`
+ * Get a table of positions of nodes that have metadata within a region
+ {pos1, pos2}.
* `minetest.get_meta(pos)`
* Get a `NodeMetaRef` at that position
* `minetest.get_node_level(pos)`
* get max available level for leveled node
### Player
-* `minetest.get_wielded_item()`
- * Returns the itemstack the local player is holding
* `minetest.send_chat_message(message)`
* Act as if `message` was typed by the player into the terminal.
* `minetest.run_server_chatcommand(cmd, param)`
### Client Environment
* `minetest.get_player_names()`
- * Returns list of player names on server
+ * Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server)
* `minetest.disconnect()`
* Disconnect from the server and exit to main menu.
* Returns `false` if the client is already disconnecting otherwise returns `true`.
-* `minetest.take_screenshot()`
- * Take a screenshot.
* `minetest.get_server_info()`
* Returns [server info](#server-info).
* `minetest.send_respawn()`
* Client joins channel `channel_name`, and creates it, if necessary. You
should listen from incoming messages with `minetest.register_on_modchannel_message`
call to receive incoming messages. Warning, this function is asynchronous.
- * You should use a minetest.register_on_connect(function() ... end) to perform
- a successful channel join on client startup.
+
+### Particles
+* `minetest.add_particle(particle definition)`
+
+* `minetest.add_particlespawner(particlespawner definition)`
+ * Add a `ParticleSpawner`, an object that spawns an amount of particles over `time` seconds
+ * Returns an `id`, and -1 if adding didn't succeed
+
+* `minetest.delete_particlespawner(id)`
+ * Delete `ParticleSpawner` with `id` (return value from `minetest.add_particlespawner`)
### Misc.
* `minetest.parse_json(string[, nullvalue])`: returns something
* `get_camera_mode()`
* Returns 0, 1, or 2 as described above
* `get_fov()`
- * Returns:
+ * Returns a table with X, Y, maximum and actual FOV in degrees:
```lua
{
* Returns aspect ratio of screen
### LocalPlayer
-An interface to retrieve information about the player. The player is
-not accessible until the client is fully done loading and therefore
-not at module init time.
-
-To get the localplayer handle correctly, use `on_connect()` as follows:
-
-```lua
-local localplayer
-minetest.register_on_connect(function()
- localplayer = minetest.localplayer
-end)
-```
+An interface to retrieve information about the player.
Methods:
* returns player HP
* `get_name()`
* returns player name
+* `get_wield_index()`
+ * returns the index of the wielded item
+* `get_wielded_item()`
+ * returns the itemstack the player is holding
* `is_attached()`
* returns true if player is attached
* `is_touching_ground()`
jump = float,
gravity = float,
sneak = boolean,
- sneak_glitch = boolean
+ sneak_glitch = boolean,
+ new_move = boolean,
}
```
* returns last look horizontal angle
* `get_last_look_vertical()`:
* returns last look vertical angle
-* `get_key_pressed()`:
- * returns last key typed by the player
+* `get_control()`:
+ * returns pressed player controls
+
+```lua
+ {
+ up = boolean,
+ down = boolean,
+ left = boolean,
+ right = boolean,
+ jump = boolean,
+ aux1 = boolean,
+ sneak = boolean,
+ zoom = boolean,
+ dig = boolean,
+ place = boolean,
+ }
+```
+
+* `get_armor_groups()`
+ * returns a table with the armor group ratings
* `hud_add(definition)`
* add a HUD element described by HUD def, returns ID number on success and `nil` on failure.
* See [`HUD definition`](#hud-definition-hud_add-hud_get)
* `fields`: key-value storage
* `inventory`: `{list1 = {}, ...}}`
+### `Raycast`
+
+A raycast on the map. It works with selection boxes.
+Can be used as an iterator in a for loop as:
+
+ local ray = Raycast(...)
+ for pointed_thing in ray do
+ ...
+ end
+
+The map is loaded as the ray advances. If the map is modified after the
+`Raycast` is created, the changes may or may not have an effect on the object.
+
+It can be created via `Raycast(pos1, pos2, objects, liquids)` or
+`minetest.raycast(pos1, pos2, objects, liquids)` where:
+
+* `pos1`: start of the ray
+* `pos2`: end of the ray
+* `objects`: if false, only nodes will be returned. Default is true.
+* `liquids`: if false, liquid nodes won't be returned. Default is false.
+
+#### Methods
+
+* `next()`: returns a `pointed_thing` with exact pointing location
+ * Returns the next thing pointed by the ray or nil.
+
-----------------
### Definitions
* `minetest.get_node_def(nodename)`
* `offset`: offset in pixels from position.
### `waypoint`
+
Displays distance to selected world position.
* `name`: The name of the waypoint.
* `text`: Distance suffix. Can be blank.
-* `number:` An integer containing the RGB value of the color used to draw the text.
+* `precision`: Waypoint precision, integer >= 0. Defaults to 10.
+ If set to 0, distance is not shown. Shown value is `floor(distance*precision)/precision`.
+ When the precision is an integer multiple of 10, there will be `log_10(precision)` digits after the decimal point.
+ `precision = 1000`, for example, will show 3 decimal places (eg: `0.999`).
+ `precision = 2` will show multiples of `0.5`; precision = 5 will show multiples of `0.2` and so on:
+ `precision = n` will show multiples of `1/n`
+* `number:` An integer containing the RGB value of the color used to draw the
+ text.
+* `world_pos`: World position of the waypoint.
+* `offset`: offset in pixels from position.
+* `alignment`: The alignment of the waypoint.
+
+### `image_waypoint`
+
+Same as `image`, but does not accept a `position`; the position is instead determined by `world_pos`, the world position of the waypoint.
+
+* `scale`: The scale of the image, with 1 being the original texture size.
+ Only the X coordinate scale is used (positive values).
+ Negative values represent that percentage of the screen it
+ should take; e.g. `x=-100` means 100% (width).
+* `text`: The name of the texture that is displayed.
+* `alignment`: The alignment of the image.
* `world_pos`: World position of the waypoint.
+* `offset`: offset in pixels from 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)
+ }