mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 14:42:24 +01:00
d52e4cdbdb
Co-authored-by: grorp <gregor.parzefall@posteo.de>
1026 lines
40 KiB
Markdown
1026 lines
40 KiB
Markdown
Luanti Lua Client Modding API Reference 5.10.0
|
|
==============================================
|
|
|
|
**WARNING**: if you're looking for the `minetest` namespace (e.g. `minetest.something`),
|
|
it's now called `core` due to the renaming of Luanti (formerly Minetest).
|
|
`minetest` will keep existing as an alias, so that old code won't break.
|
|
|
|
* More information at <http://www.minetest.net/>
|
|
* Developer Wiki: <http://dev.minetest.net/>
|
|
|
|
Introduction
|
|
------------
|
|
|
|
** WARNING: The client API is currently unstable, and may break/change without warning. **
|
|
|
|
Content and functionality can be added to Luanti 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 Luanti.
|
|
|
|
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 (https://github.com/minetest/minetest).
|
|
|
|
Programming in Lua
|
|
------------------
|
|
If you have any difficulty in understanding this, please read
|
|
[Programming in Lua](http://www.lua.org/pil/).
|
|
|
|
Startup
|
|
-------
|
|
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`: `<build directory>`
|
|
* `$path_share`: `<build directory>`
|
|
* `RUN_IN_PLACE=0`: (Linux release)
|
|
* `$path_share`:
|
|
* Linux: `/usr/share/minetest`
|
|
* Windows: `<install directory>/minetest-0.4.x`
|
|
* `$path_user`:
|
|
* Linux: `$HOME/.minetest`
|
|
* Windows: `C:/users/<user>/AppData/minetest` (maybe)
|
|
|
|
Mod load path
|
|
-------------
|
|
Generic:
|
|
|
|
* `$path_share/clientmods/`
|
|
* `$path_user/clientmods/` (User-installed mods)
|
|
|
|
In a run-in-place version (e.g. the distributed windows version):
|
|
|
|
* `minetest/clientmods/` (User-installed mods)
|
|
|
|
On an installed version on Linux:
|
|
|
|
* `/usr/share/minetest/clientmods/`
|
|
* `$HOME/.minetest/clientmods/` (User-installed mods)
|
|
|
|
Modpack support
|
|
----------------
|
|
|
|
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.
|
|
|
|
* `name`: The modpack name.
|
|
* `description`: Description of mod to be shown in the Mods tab of the main
|
|
menu.
|
|
|
|
Mod directory structure
|
|
------------------------
|
|
|
|
clientmods
|
|
├── modname
|
|
│ ├── mod.conf
|
|
│ ├── init.lua
|
|
└── another
|
|
|
|
### modname
|
|
|
|
The location of this directory.
|
|
|
|
### mod.conf
|
|
|
|
An (optional) settings file that provides meta information about the mod.
|
|
|
|
* `name`: The mod name. Allows Luanti 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.
|
|
|
|
### `init.lua`
|
|
|
|
The main Lua script. Running this script should register everything it
|
|
wants to register. Subsequent execution depends on Luanti calling the
|
|
registered callbacks.
|
|
|
|
**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
|
|
----------------------------------------------
|
|
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.
|
|
|
|
### Example
|
|
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
|
|
|
|
:experimental:tnt
|
|
|
|
when registering it.
|
|
(also that mod is required to have `experimental` as a dependency)
|
|
|
|
The `:` prefix can also be used for maintaining backwards compatibility.
|
|
|
|
Sounds
|
|
------
|
|
**NOTE: Connecting sounds 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:
|
|
|
|
foomod_foosound.ogg
|
|
|
|
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:
|
|
|
|
* `foomod_foosound.ogg`
|
|
* `foomod_foosound.0.ogg`
|
|
* `foomod_foosound.1.ogg`
|
|
* (...)
|
|
* `foomod_foosound.9.ogg`
|
|
|
|
Examples of sound parameter tables:
|
|
|
|
```lua
|
|
-- 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
|
|
}
|
|
```
|
|
|
|
Looped sounds must be played locationless.
|
|
|
|
### SimpleSoundSpec
|
|
* e.g. `""`
|
|
* e.g. `"default_place_node"`
|
|
* e.g. `{}`
|
|
* e.g. `{name = "default_place_node"}`
|
|
* e.g. `{name = "default_place_node", gain = 1.0}`
|
|
|
|
Representations of simple things
|
|
--------------------------------
|
|
|
|
### Position/vector
|
|
|
|
```lua
|
|
{x=num, y=num, z=num}
|
|
```
|
|
|
|
For helper functions see "Vector helpers".
|
|
|
|
### pointed_thing
|
|
* `{type="nothing"}`
|
|
* `{type="node", under=pos, above=pos}`
|
|
* `{type="object", id=ObjectID}`
|
|
|
|
Flag Specifier Format
|
|
---------------------
|
|
|
|
Refer to `lua_api.md`.
|
|
|
|
Formspec
|
|
--------
|
|
|
|
Formspec defines a menu. It is a string, with a somewhat strange format.
|
|
|
|
For details, refer to `lua_api.md`.
|
|
|
|
Spatial Vectors
|
|
---------------
|
|
|
|
Refer to `lua_api.md`.
|
|
|
|
Helper functions
|
|
----------------
|
|
* `dump2(obj, name="_", dumped={})`
|
|
* Return object serialized as a string, handles reference loops
|
|
* `dump(obj, dumped={})`
|
|
* Return object serialized as a string
|
|
* `math.hypot(x, y)`
|
|
* Get the hypotenuse of a triangle with legs x and y.
|
|
Useful for distance calculation.
|
|
* `math.sign(x, tolerance)`
|
|
* Get the sign of a number.
|
|
Optional: Also returns `0` when the absolute value is within the tolerance (default: `0`)
|
|
* `string.split(str, separator=",", include_empty=false, max_splits=-1, sep_is_pattern=false)`
|
|
* If `max_splits` is negative, do not limit splits.
|
|
* `sep_is_pattern` specifies if separator is a plain string or a pattern (regex).
|
|
* e.g. `string:split("a,b", ",") == {"a","b"}`
|
|
* `string:trim()`
|
|
* e.g. `string.trim("\n \t\tfoo bar\t ") == "foo bar"`
|
|
* `core.wrap_text(str, limit)`: returns a string
|
|
* Adds new lines to the string to keep it within the specified character limit
|
|
* limit: Maximal amount of characters in one line
|
|
* `core.pos_to_string({x=X,y=Y,z=Z}, decimal_places))`: returns string `"(X,Y,Z)"`
|
|
* Convert position to a printable string
|
|
Optional: 'decimal_places' will round the x, y and z of the pos to the given decimal place.
|
|
* `core.string_to_pos(string)`: returns a position
|
|
* Same but in reverse. Returns `nil` if the string can't be parsed to a position.
|
|
* `core.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)")`: returns two positions
|
|
* Converts a string representing an area box into two positions
|
|
* `core.is_yes(arg)`
|
|
* returns whether `arg` can be interpreted as yes
|
|
* `core.is_nan(arg)`
|
|
* returns true when the passed number represents NaN.
|
|
* `table.copy(table)`: returns a table
|
|
* returns a deep copy of `table`
|
|
|
|
'core' namespace reference
|
|
--------------------------
|
|
|
|
### Utilities
|
|
|
|
* `core.get_current_modname()`: returns the currently loading mod's name, when we are loading a mod
|
|
* `core.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(core.get_modpath(core.get_current_modname()) .. "stuff.lua")`
|
|
* `core.get_language()`: returns two strings
|
|
* the current gettext locale
|
|
* the current language code (the same as used for client-side translations)
|
|
* `core.get_version()`: returns a table containing components of the
|
|
engine version. Components:
|
|
* `project`: Name of the project, eg, "Luanti"
|
|
* `string`: Simple version, eg, "1.2.3-dev"
|
|
* `hash`: Full git version (only set if available), eg, "1.2.3-dev-01234567-dirty"
|
|
Use this for informational purposes only. The information in the returned
|
|
table does not represent the capabilities of the engine, nor is it
|
|
reliable or verifiable. Compatible forks will have a different name and
|
|
version entirely. To check for the presence of engine features, test
|
|
whether the functions exported by the wanted features exist. For example:
|
|
`if core.check_for_falling then ... end`.
|
|
* `core.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
|
|
* `core.colorspec_to_colorstring(colorspec)`: Converts a ColorSpec to a
|
|
ColorString. If the ColorSpec is invalid, returns `nil`.
|
|
* `colorspec`: The ColorSpec to convert
|
|
* `core.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`
|
|
* `core.urlencode(str)`: Encodes non-unreserved URI characters by a
|
|
percent sign followed by two hex digits. See
|
|
[RFC 3986, section 2.3](https://datatracker.ietf.org/doc/html/rfc3986#section-2.3).
|
|
|
|
### Logging
|
|
* `core.debug(...)`
|
|
* Equivalent to `core.log(table.concat({...}, "\t"))`
|
|
* `core.log([level,] text)`
|
|
* `level` is one of `"none"`, `"error"`, `"warning"`, `"action"`,
|
|
`"info"`, or `"verbose"`. Default is `"none"`.
|
|
|
|
### Global callback registration functions
|
|
Call these functions only at load time!
|
|
|
|
* `core.register_globalstep(function(dtime))`
|
|
* Called every client environment step
|
|
* `dtime` is the time since last execution in seconds.
|
|
* `core.register_on_mods_loaded(function())`
|
|
* Called just after mods have finished loading.
|
|
* `core.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.
|
|
* `core.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
|
|
* `core.register_on_sending_chat_message(function(message))`
|
|
* Called always when a client sends a message from chat
|
|
* Return `true` to mark the message as handled, which means that it will not be sent to server
|
|
* `core.register_chatcommand(cmd, chatcommand definition)`
|
|
* Adds definition to core.registered_chatcommands
|
|
* `core.unregister_chatcommand(name)`
|
|
* Unregisters a chatcommands registered with register_chatcommand.
|
|
* `core.register_on_chatcommand(function(command, params))`
|
|
* Called always when a chatcommand is triggered, before `core.registered_chatcommands`
|
|
is checked to see if 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.
|
|
* `core.register_on_hp_modification(function(hp))`
|
|
* Called when server modified player's HP
|
|
* `core.register_on_damage_taken(function(hp))`
|
|
* Called when the local player take damages
|
|
* `core.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
|
|
* `core.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
|
|
* `core.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
|
|
* `core.register_on_placenode(function(pointed_thing, node))`
|
|
* Called when a node has been placed
|
|
* `core.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.
|
|
* `core.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.
|
|
* `core.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:
|
|
0: join_ok
|
|
1: join_failed
|
|
2: leave_ok
|
|
3: leave_failed
|
|
4: event_on_not_joined_channel
|
|
5: state_changed
|
|
* `core.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
|
|
### Sounds
|
|
* `core.sound_play(spec, parameters)`: returns a handle
|
|
* `spec` is a `SimpleSoundSpec`
|
|
* `parameters` is a sound parameter table
|
|
* `handle:stop()` or `core.sound_stop(handle)`
|
|
* `handle` is a handle returned by `core.sound_play`
|
|
* `handle:fade(step, gain)` or `core.sound_fade(handle, step, gain)`
|
|
* `handle` is a handle returned by `core.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
|
|
* `core.after(time, func, ...)`
|
|
* Call the function `func` after `time` seconds, may be fractional
|
|
* Optional: Variable number of arguments that are passed to `func`
|
|
* Jobs set for earlier times are executed earlier. If multiple jobs expire
|
|
at exactly the same time, then they expire in the order in which they were
|
|
registered. This basically just applies to jobs registered on the same
|
|
step with the exact same delay.
|
|
* `core.get_us_time()`
|
|
* Returns time with microsecond precision. May not return wall time.
|
|
* `core.get_timeofday()`
|
|
* Returns the time of day: `0` for midnight, `0.5` for midday
|
|
|
|
### Map
|
|
* `core.get_node_or_nil(pos)`
|
|
* 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.
|
|
* `core.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`
|
|
* `core.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
|
|
* `core.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
|
|
* `core.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
|
|
* `core.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
|
|
* `core.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`.
|
|
|
|
* `core.find_nodes_with_meta(pos1, pos2)`
|
|
* Get a table of positions of nodes that have metadata within a region
|
|
{pos1, pos2}.
|
|
* `core.get_meta(pos)`
|
|
* Get a `NodeMetaRef` at that position
|
|
* `core.get_node_level(pos)`
|
|
* get level of leveled node (water, snow)
|
|
* `core.get_node_max_level(pos)`
|
|
* get max available level for leveled node
|
|
|
|
### Player
|
|
* `core.send_chat_message(message)`
|
|
* Act as if `message` was typed by the player into the terminal.
|
|
* `core.run_server_chatcommand(cmd, param)`
|
|
* Alias for `core.send_chat_message("/" .. cmd .. " " .. param)`
|
|
* `core.clear_out_chat_queue()`
|
|
* Clears the out chat queue
|
|
* `core.localplayer`
|
|
* Reference to the LocalPlayer object. See [`LocalPlayer`](#localplayer) class reference for methods.
|
|
|
|
### Privileges
|
|
* `core.get_privilege_list()`
|
|
* Returns a list of privileges the current player has in the format `{priv1=true,...}`
|
|
* `core.string_to_privs(str)`: returns `{priv1=true,...}`
|
|
* `core.privs_to_string(privs)`: returns `"priv1,priv2,..."`
|
|
* Convert between two privilege representations
|
|
|
|
### Client Environment
|
|
* `core.get_player_names()`
|
|
* Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server)
|
|
* `core.disconnect()`
|
|
* Disconnect from the server and exit to main menu.
|
|
* Returns `false` if the client is already disconnecting otherwise returns `true`.
|
|
* `core.get_server_info()`
|
|
* Returns [server info](#server-info).
|
|
|
|
### Storage API
|
|
* `core.get_mod_storage()`:
|
|
* returns reference to mod private `StorageRef`
|
|
* must be called during mod load time
|
|
|
|
### Mod channels
|
|
![Mod channels communication scheme](docs/mod channels.png)
|
|
|
|
* `core.mod_channel_join(channel_name)`
|
|
* Client joins channel `channel_name`, and creates it, if necessary. You
|
|
should listen from incoming messages with `core.register_on_modchannel_message`
|
|
call to receive incoming messages. Warning, this function is asynchronous.
|
|
|
|
### Particles
|
|
* `core.add_particle(particle definition)`
|
|
|
|
* `core.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
|
|
|
|
* `core.delete_particlespawner(id)`
|
|
* Delete `ParticleSpawner` with `id` (return value from `core.add_particlespawner`)
|
|
|
|
### Misc.
|
|
* `core.parse_json(string[, nullvalue])`: returns something
|
|
* Convert a string containing JSON data into the Lua equivalent
|
|
* `nullvalue`: returned in place of the JSON null; defaults to `nil`
|
|
* On success returns a table, a string, a number, a boolean or `nullvalue`
|
|
* On failure outputs an error message and returns `nil`
|
|
* Example: `parse_json("[10, {\"a\":false}]")`, returns `{10, {a = false}}`
|
|
* `core.write_json(data[, styled])`: returns a string or `nil` and an error message
|
|
* Convert a Lua table into a JSON string
|
|
* styled: Outputs in a human-readable format if this is set, defaults to false
|
|
* Unserializable things like functions and userdata are saved as null.
|
|
* **Warning**: JSON is more strict than the Lua table format.
|
|
1. You can only use strings and positive integers of at least one as keys.
|
|
2. You cannot mix string and integer keys.
|
|
This is due to the fact that JSON has two distinct array and object values.
|
|
* Example: `write_json({10, {a = false}})`, returns `"[10, {\"a\": false}]"`
|
|
* `core.serialize(table)`: returns a string
|
|
* Convert a table containing tables, strings, numbers, booleans and `nil`s
|
|
into string form readable by `core.deserialize`
|
|
* Example: `serialize({foo='bar'})`, returns `'return { ["foo"] = "bar" }'`
|
|
* `core.deserialize(string)`: returns a table
|
|
* Convert a string returned by `core.deserialize` into a table
|
|
* `string` is loaded in an empty sandbox environment.
|
|
* Will load functions, but they cannot access the global environment.
|
|
* Example: `deserialize('return { ["foo"] = "bar" }')`, returns `{foo='bar'}`
|
|
* Example: `deserialize('print("foo")')`, returns `nil` (function call fails)
|
|
* `error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value)`
|
|
* `core.compress(data, method, ...)`: returns `compressed_data`
|
|
* Compress a string of data.
|
|
* `method` is a string identifying the compression method to be used.
|
|
* Supported compression methods:
|
|
* Deflate (zlib): `"deflate"`
|
|
* Zstandard: `"zstd"`
|
|
* `...` indicates method-specific arguments. Currently defined arguments
|
|
are:
|
|
* Deflate: `level` - Compression level, `0`-`9` or `nil`.
|
|
* Zstandard: `level` - Compression level. Integer or `nil`. Default `3`.
|
|
Note any supported Zstandard compression level could be used here,
|
|
but these are subject to change between Zstandard versions.
|
|
* `core.decompress(compressed_data, method, ...)`: returns data
|
|
* Decompress a string of data using the algorithm specified by `method`.
|
|
* See documentation on `core.compress()` for supported compression
|
|
methods.
|
|
* `...` indicates method-specific arguments. Currently, no methods use this
|
|
* `core.rgba(red, green, blue[, alpha])`: returns a string
|
|
* Each argument is an 8 Bit unsigned integer
|
|
* Returns the ColorString from rgb or rgba values
|
|
* Example: `core.rgba(10, 20, 30, 40)`, returns `"#0A141E28"`
|
|
* `core.encode_base64(string)`: returns string encoded in base64
|
|
* Encodes a string in base64.
|
|
* `core.decode_base64(string)`: returns string or nil on failure
|
|
* Padding characters are only supported starting at version 5.4.0, where
|
|
5.5.0 and newer perform proper checks.
|
|
* Decodes a string encoded in base64.
|
|
* `core.gettext(string)` : returns string
|
|
* look up the translation of a string in the gettext message catalog
|
|
* `fgettext_ne(string, ...)`
|
|
* call core.gettext(string), replace "$1"..."$9" with the given
|
|
extra arguments and return the result
|
|
* `fgettext(string, ...)` : returns string
|
|
* same as fgettext_ne(), but calls core.formspec_escape before returning result
|
|
* `core.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a position
|
|
* returns the exact position on the surface of a pointed node
|
|
* `core.global_exists(name)`
|
|
* Checks if a global variable has been set, without triggering a warning.
|
|
|
|
### UI
|
|
* `core.ui.minimap`
|
|
* Reference to the minimap object. See [`Minimap`](#minimap) class reference for methods.
|
|
* If client disabled minimap (using enable_minimap setting) this reference will be nil.
|
|
* `core.camera`
|
|
* Reference to the camera object. See [`Camera`](#camera) class reference for methods.
|
|
* `core.show_formspec(formname, formspec)` : returns true on success
|
|
* Shows a formspec to the player
|
|
* `core.display_chat_message(message)` returns true on success
|
|
* Shows a chat message to the current player.
|
|
|
|
Setting-related
|
|
---------------
|
|
|
|
* `core.settings`: Settings object containing all of the settings from the
|
|
main config file (`minetest.conf`). Check lua_api.md for class reference.
|
|
* `core.setting_get_pos(name)`: Loads a setting from the main settings and
|
|
parses it as a position (in the format `(1,2,3)`). Returns a position or nil.
|
|
|
|
Class reference
|
|
---------------
|
|
|
|
### ModChannel
|
|
|
|
An interface to use mod channels on client and server
|
|
|
|
#### Methods
|
|
* `leave()`: leave the mod channel.
|
|
* Client leaves channel `channel_name`.
|
|
* No more incoming or outgoing messages can be sent to this channel from client mods.
|
|
* This invalidate all future object usage
|
|
* Ensure your set mod_channel to nil after that to free Lua resources
|
|
* `is_writeable()`: returns true if channel is writable and mod can send over it.
|
|
* `send_all(message)`: Send `message` though the mod channel.
|
|
* If mod channel is not writable or invalid, message will be dropped.
|
|
* Message size is limited to 65535 characters by protocol.
|
|
|
|
### Minimap
|
|
An interface to manipulate minimap on client UI
|
|
|
|
#### Methods
|
|
* `show()`: shows the minimap (if not disabled by server)
|
|
* `hide()`: hides the minimap
|
|
* `set_pos(pos)`: sets the minimap position on screen
|
|
* `get_pos()`: returns the minimap current position
|
|
* `set_angle(deg)`: sets the minimap angle in degrees
|
|
* `get_angle()`: returns the current minimap angle in degrees
|
|
* `set_mode(mode)`: sets the minimap mode (0 to 6)
|
|
* `get_mode()`: returns the current minimap mode
|
|
* `set_shape(shape)`: Sets the minimap shape. (0 = square, 1 = round)
|
|
* `get_shape()`: Gets the minimap shape. (0 = square, 1 = round)
|
|
|
|
### Camera
|
|
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.
|
|
|
|
#### Methods
|
|
* `set_camera_mode(mode)`
|
|
* Pass `0` for first-person, `1` for third person, and `2` for third person front
|
|
* `get_camera_mode()`
|
|
* Returns 0, 1, or 2 as described above
|
|
* `get_fov()`
|
|
* Returns a table with X, Y, maximum and actual FOV in degrees:
|
|
|
|
```lua
|
|
{
|
|
x = number,
|
|
y = number,
|
|
max = number,
|
|
actual = number
|
|
}
|
|
```
|
|
|
|
* `get_pos()`
|
|
* Returns position of camera with view bobbing
|
|
* `get_offset()`
|
|
* Returns eye offset vector
|
|
* `get_look_dir()`
|
|
* Returns eye direction unit vector
|
|
* `get_look_vertical()`
|
|
* Returns pitch in radians
|
|
* `get_look_horizontal()`
|
|
* Returns yaw in radians
|
|
* `get_aspect_ratio()`
|
|
* Returns aspect ratio of screen
|
|
|
|
### LocalPlayer
|
|
An interface to retrieve information about the player.
|
|
This object will only be available after the client is initialized. Earlier accesses will yield a `nil` value.
|
|
|
|
Methods:
|
|
|
|
* `get_pos()`
|
|
* returns current player current position
|
|
* `get_velocity()`
|
|
* returns player speed vector
|
|
* `get_hp()`
|
|
* 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()`
|
|
* returns true if player touching ground
|
|
* `is_in_liquid()`
|
|
* returns true if player is in a liquid (This oscillates so that the player jumps a bit above the surface)
|
|
* `is_in_liquid_stable()`
|
|
* returns true if player is in a stable liquid (This is more stable and defines the maximum speed of the player)
|
|
* `get_move_resistance()`
|
|
* returns move resistance of current node, the higher the slower the player moves
|
|
* `is_climbing()`
|
|
* returns true if player is climbing
|
|
* `swimming_vertical()`
|
|
* returns true if player is swimming in vertical
|
|
* `get_physics_override()`
|
|
* returns:
|
|
|
|
```lua
|
|
{
|
|
speed = float,
|
|
speed_climb = float,
|
|
speed_crouch = float,
|
|
speed_fast = float,
|
|
speed_walk = float,
|
|
acceleration_default = float,
|
|
acceleration_air = float,
|
|
acceleration_fast = float,
|
|
jump = float,
|
|
gravity = float,
|
|
liquid_fluidity = float,
|
|
liquid_fluidity_smooth = float,
|
|
liquid_sink = float,
|
|
sneak = boolean,
|
|
sneak_glitch = boolean,
|
|
new_move = boolean,
|
|
}
|
|
```
|
|
|
|
* `get_override_pos()`
|
|
* returns override position
|
|
* `get_last_pos()`
|
|
* returns last player position before the current client step
|
|
* `get_last_velocity()`
|
|
* returns last player speed
|
|
* `get_breath()`
|
|
* returns the player's breath
|
|
* `get_movement_acceleration()`
|
|
* returns acceleration of the player in different environments
|
|
(note: does not take physics overrides into account):
|
|
|
|
```lua
|
|
{
|
|
fast = float,
|
|
air = float,
|
|
default = float,
|
|
}
|
|
```
|
|
|
|
* `get_movement_speed()`
|
|
* returns player's speed in different environments
|
|
(note: does not take physics overrides into account):
|
|
|
|
```lua
|
|
{
|
|
walk = float,
|
|
jump = float,
|
|
crouch = float,
|
|
fast = float,
|
|
climb = float,
|
|
}
|
|
```
|
|
|
|
* `get_movement()`
|
|
* returns player's movement in different environments
|
|
(note: does not take physics overrides into account):
|
|
|
|
```lua
|
|
{
|
|
liquid_fluidity = float,
|
|
liquid_sink = float,
|
|
liquid_fluidity_smooth = float,
|
|
gravity = float,
|
|
}
|
|
```
|
|
|
|
* `get_last_look_horizontal()`:
|
|
* returns last look horizontal angle
|
|
* `get_last_look_vertical()`:
|
|
* returns last look vertical angle
|
|
* `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)
|
|
* `hud_get(id)`
|
|
* returns the [`definition`](#hud-definition-hud_add-hud_get) of the HUD with that ID number or `nil`, if non-existent.
|
|
* `hud_get_all()`:
|
|
* Returns a table in the form `{ [id] = HUD definition, [id] = ... }`.
|
|
* A mod should keep track of its introduced IDs and only use this to access foreign elements.
|
|
* It is discouraged to change foreign HUD elements.
|
|
* `hud_remove(id)`
|
|
* remove the HUD element of the specified id, returns `true` on success
|
|
* `hud_change(id, stat, value)`
|
|
* change a value of a previously added HUD element
|
|
* element `stat` values: `position`, `name`, `scale`, `text`, `number`, `item`, `dir`
|
|
* Returns `true` on success, otherwise returns `nil`
|
|
|
|
### Settings
|
|
An interface to read config files in the format of `minetest.conf`.
|
|
|
|
It can be created via `Settings(filename)`.
|
|
|
|
#### Methods
|
|
* `get(key)`: returns a value
|
|
* `get_bool(key)`: returns a boolean
|
|
* `set(key, value)`
|
|
* `remove(key)`: returns a boolean (`true` for success)
|
|
* `get_names()`: returns `{key1,...}`
|
|
* `write()`: returns a boolean (`true` for success)
|
|
* write changes to file
|
|
* `to_table()`: returns `{[key1]=value1,...}`
|
|
|
|
### NodeMetaRef
|
|
Node metadata: reference extra data and functionality stored in a node.
|
|
Can be obtained via `core.get_meta(pos)`.
|
|
|
|
#### Methods
|
|
* `get_string(name)`
|
|
* `get_int(name)`
|
|
* `get_float(name)`
|
|
* `to_table()`: returns `nil` or a table with keys:
|
|
* `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:
|
|
|
|
```lua
|
|
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
|
|
`core.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
|
|
* `core.get_node_def(nodename)`
|
|
* Returns [node definition](#node-definition) table of `nodename`
|
|
* `core.get_item_def(itemstring)`
|
|
* Returns item definition table of `itemstring`
|
|
|
|
#### Node Definition
|
|
|
|
```lua
|
|
{
|
|
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 existent
|
|
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
|
|
Color,
|
|
Color
|
|
}>,
|
|
waving = number, -- 0 of not waving, 1 if waving
|
|
connect_sides = number, -- Used for connected nodes
|
|
connects_to = { -- List of nodes to connect to
|
|
"node1",
|
|
"node2"
|
|
},
|
|
post_effect_color = Color, -- Color overlaid 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 slow 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
|
|
move_resistance = <number>, -- How slow players can move through the node *May not exist*
|
|
}
|
|
```
|
|
|
|
#### Item Definition
|
|
|
|
```lua
|
|
{
|
|
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`)
|
|
|
|
```lua
|
|
{
|
|
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
|
|
|
|
```lua
|
|
{
|
|
address = "luanti.example.org", -- The domain name/IP address of a remote server or "" for a local server.
|
|
ip = "203.0.113.156", -- 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`)
|
|
|
|
Refer to `lua_api.md`.
|
|
|
|
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:
|
|
* `core.get_color_escape_sequence(color)`:
|
|
* `color` is a [ColorString](#colorstring)
|
|
* The escape sequence sets the text color to `color`
|
|
* `core.colorize(color, message)`:
|
|
* Equivalent to:
|
|
`core.get_color_escape_sequence(color) ..
|
|
message ..
|
|
core.get_color_escape_sequence("#ffffff")`
|
|
* `core.get_background_escape_sequence(color)`
|
|
* `color` is a [ColorString](#colorstring)
|
|
* The escape sequence sets the background of the whole text element to
|
|
`color`. Only defined for item descriptions and tooltips.
|
|
* `core.strip_foreground_colors(str)`
|
|
* Removes foreground colors added by `get_color_escape_sequence`.
|
|
* `core.strip_background_colors(str)`
|
|
* Removes background colors added by `get_background_escape_sequence`.
|
|
* `core.strip_colors(str)`
|
|
* Removes all color escape sequences.
|
|
|
|
`ColorString`
|
|
-------------
|
|
|
|
Refer to `lua_api.md`.
|
|
|
|
`Color`
|
|
-------------
|
|
`{a = alpha, r = red, g = green, b = blue}` defines an ARGB8 color.
|
|
|
|
### Particle definition (`add_particle`)
|
|
|
|
As documented in `lua_api.md`, except for obvious reasons, the `playername` field is not supported.
|
|
|
|
### `ParticleSpawner` definition (`add_particlespawner`)
|
|
|
|
As documented in `lua_api.md`, except for obvious reasons, the `playername` field is not supported.
|