(this does not work for `enable_server`).
Only these settings are supported:
`enable_damage`, `creative_mode`, `enable_server`.
+ * `map_persistent`: Specifies whether newly created worlds should use
+ a persistent map backend. Defaults to `true` (= "sqlite3")
* `author`: The author of the game. It only appears when downloaded from
ContentDB.
* `release`: Ignore this: Should only ever be set by ContentDB, as it is
* `mapgen_stair_cobble` (falls back to cobble)
* `mapgen_mossycobble` (falls back to cobble)
-* `mapgen_stair_desert_stone` (falls backto desert_stone)
+* `mapgen_stair_desert_stone` (falls back to desert_stone)
### Setting the node used in Mapgen Singlenode
first (= 0 + 1) pixel will be picked from the palette.
* `param2 = 35` is 1 * 32 + 3, so the rotation is 3 and the
second (= 1 + 1) pixel will be picked from the palette.
+* `paramtype2 = "color4dir"` for nodes which use the first
+ six bits of `param2` for palette indexing. The remaining
+ two bits are describing rotation, as in `4dir` paramtype2.
+ Division by 4 yields the palette index (without stretching the
+ palette). These nodes can have 64 different colors, and the
+ palette should contain 64 pixels.
+ Examples:
+ * `param2 = 17` is 4 * 4 + 1, so the rotation is 1 and the
+ fifth (= 4 + 1) pixel will be picked from the palette.
+ * `param2 = 35` is 8 * 4 + 3, so the rotation is 3 and the
+ ninth (= 8 + 1) pixel will be picked from the palette.
To colorize a node on the map, set its `param2` value (according
to the node's paramtype2).
{
pos = {x = 1, y = 2, z = 3},
gain = 1.0, -- default
- max_hear_distance = 32, -- default, uses an euclidean metric
+ max_hear_distance = 32, -- default, uses a Euclidean metric
}
-- Play connected to an object, looped
{
object = <an ObjectRef>,
gain = 1.0, -- default
- max_hear_distance = 32, -- default, uses an euclidean metric
+ max_hear_distance = 32, -- default, uses a Euclidean metric
loop = true,
}
-- Play at a location, heard by anyone *but* the given player
* `player_falling_damage`: Played when the local player takes
damage by falling (gain = 0.5)
* `player_jump`: Played when the local player jumps
- * `default_dig_<groupname>`: Default node digging sound
+ * `default_dig_<groupname>`: Default node digging sound (gain = 0.5)
(see node sound definition for details)
Registered definitions
Example:
-All nodes register with `minetest.register_node` get added to the table
+All nodes registered with `minetest.register_node` get added to the table
`minetest.registered_nodes`.
If you want to check the drawtype of a node, you could do it like this:
* Supported drawtypes: "torchlike", "signlike", "plantlike",
"plantlike_rooted", "normal", "nodebox", "mesh"
* The rotation of the node is stored in `param2`
+ * Node is 'mounted'/facing towards one of 6 directions
* You can make this value by using `minetest.dir_to_wallmounted()`
* Values range 0 - 5
* The value denotes at which direction the node is "mounted":
0 = y+, 1 = y-, 2 = x+, 3 = x-, 4 = z+, 5 = z-
+ * By default, on placement the param2 is automatically set to the
+ appropriate rotation, depending on which side was pointed at
* `paramtype2 = "facedir"`
* Supported drawtypes: "normal", "nodebox", "mesh"
- * The rotation of the node is stored in `param2`. Furnaces and chests are
- rotated this way. Can be made by using `minetest.dir_to_facedir()`.
+ * The rotation of the node is stored in `param2`.
+ * Node is rotated around face and axis; 24 rotations in total.
+ * Can be made by using `minetest.dir_to_facedir()`.
+ * Chests and furnaces can be rotated that way, and also 'flipped'
* Values range 0 - 23
* facedir / 4 = axis direction:
0 = y+, 1 = z+, 2 = z-, 3 = x+, 4 = x-, 5 = y-
- * facedir modulo 4 = rotation around that axis
+ * The node is rotated 90 degrees around the X or Z axis so that its top face
+ points in the desired direction. For the y- direction, it's rotated 180
+ degrees around the Z axis.
+ * facedir modulo 4 = left-handed rotation around the specified axis, in 90° steps.
+ * By default, on placement the param2 is automatically set to the
+ horizontal direction the player was looking at (values 0-3)
+ * Special case: If the node is a connected nodebox, the nodebox
+ will NOT rotate, only the textures will.
+* `paramtype2 = "4dir"`
+ * Supported drawtypes: "normal", "nodebox", "mesh"
+ * The rotation of the node is stored in `param2`.
+ * Allows node to be rotated horizontally, 4 rotations in total
+ * Can be made by using `minetest.dir_to_fourdir()`.
+ * Chests and furnaces can be rotated that way, but not flipped
+ * Values range 0 - 3
+ * 4dir modulo 4 = rotation
+ * Otherwise, behavior is identical to facedir
* `paramtype2 = "leveled"`
* Only valid for "nodebox" with 'type = "leveled"', and "plantlike_rooted".
* Leveled nodebox:
optional modifiers of the "plant". `param2` is a bitfield.
* Bits 0 to 2 select the shape.
Use only one of the values below:
- * 0 = a "x" shaped plant (ordinary plant)
+ * 0 = an "x" shaped plant (ordinary plant)
* 1 = a "+" shaped plant (just rotated 45 degrees)
* 2 = a "*" shaped plant with 3 faces instead of 2
* 3 = a "#" shaped plant with 4 faces instead of 2
* Same as `facedir`, but with colors.
* The first three bits of `param2` tells which color is picked from the
palette. The palette should have 8 pixels.
+* `paramtype2 = "color4dir"`
+ * Same as `facedir`, but with colors.
+ * The first six bits of `param2` tells which color is picked from the
+ palette. The palette should have 64 pixels.
* `paramtype2 = "colorwallmounted"`
* Same as `wallmounted`, but with colors.
* The first five bits of `param2` tells which color is picked from the
* The cubic source node for a liquid.
* Faces bordering to the same node are never rendered.
* Connects to node specified in `liquid_alternative_flowing`.
+ * You *must* set `liquid_alternative_source` to the node's own name.
* Use `backface_culling = false` for the tiles you want to make
visible when inside the node.
* `flowingliquid`
* The flowing version of a liquid, appears with various heights and slopes.
* Faces bordering to the same node are never rendered.
* Connects to node specified in `liquid_alternative_source`.
+ * You *must* set `liquid_alternative_flowing` to the node's own name.
* Node textures are defined with `special_tiles` where the first tile
is for the top and bottom faces and the second tile is for the side
faces.
wall_side = box
}
{
- -- A node that has optional boxes depending on neighbouring nodes'
+ -- A node that has optional boxes depending on neighboring nodes'
-- presence and type. See also `connects_to`.
type = "connected",
fixed = box OR {box1, box2, ...}
connect_back = box OR {box1, box2, ...}
connect_right = box OR {box1, box2, ...}
-- The following `disconnected_*` boxes are the opposites of the
- -- `connect_*` ones above, i.e. when a node has no suitable neighbour
+ -- `connect_*` ones above, i.e. when a node has no suitable neighbor
-- on the respective side, the corresponding disconnected box is drawn.
disconnected_top = box OR {box1, box2, ...}
disconnected_bottom = box OR {box1, box2, ...}
disconnected_left = box OR {box1, box2, ...}
disconnected_back = box OR {box1, box2, ...}
disconnected_right = box OR {box1, box2, ...}
- disconnected = box OR {box1, box2, ...} -- when there is *no* neighbour
+ disconnected = box OR {box1, box2, ...} -- when there is *no* neighbor
disconnected_sides = box OR {box1, box2, ...} -- when there are *no*
- -- neighbours to the sides
+ -- neighbors to the sides
}
A `box` is defined as:
A 'mapchunk' (sometimes abbreviated to 'chunk') is usually 5x5x5 mapblocks
(80x80x80 nodes) and is the volume of world generated in one operation by
the map generator.
-The size in mapblocks has been chosen to optimise map generation.
+The size in mapblocks has been chosen to optimize map generation.
Coordinates
-----------
* `pointed_thing.intersection_normal`: Unit vector, points outwards of the
selected selection box. This specifies which face is pointed at.
Is a null vector `vector.zero()` when the pointer is inside the selection box.
+ For entities with rotated selection boxes, this will be rotated properly
+ by the entity's rotation - it will always be in absolute world space.
There are three kinds of items: nodes, tools and craftitems.
* Node: Placeable item form of a node in the world's voxel grid
-* Tool: Has a changable wear property but cannot be stacked
+* Tool: Has a changeable wear property but cannot be stacked
* Craftitem: Has no special properties
Every registered node (the voxel in the world) has a corresponding
---------------
All item stacks have an amount between 0 and 65535. It is 1 by
-default. Tool item stacks can not have an amount greater than 1.
+default. Tool item stacks cannot have an amount greater than 1.
Tools use a wear (damage) value ranging from 0 to 65535. The
value 0 is the default and is used for unworn tools. The values
* amount must be 1 (pickaxe is a tool), ca. 1/3 worn out (it's a tool),
* with the `description` field set to `"My worn out pick"` in its metadata
* `[[default:dirt 5 0 "\u0001description\u0002Special dirt\u0003"]]`:
- * analogeous to the above example
+ * analogous to the above example
* note how the wear is set to `0` as dirt is not a tool
You should ideally use the `ItemStack` format to build complex item strings
The rating is the percentage of damage caused by items with this damage group.
See [Entity damage mechanism].
- object.get_armor_groups() --> a group-rating table (e.g. {fleshy=100})
- object.set_armor_groups({fleshy=30, cracky=80})
+ object:get_armor_groups() --> a group-rating table (e.g. {fleshy=100})
+ object:set_armor_groups({fleshy=30, cracky=80})
Groups of tool capabilities
---------------------------
Groups in crafting recipes
--------------------------
-An example: Make meat soup from any meat, any water and any bowl:
+In crafting recipes, you can specify a group as an input item.
+This means that any item in that group will be accepted as input.
+
+The basic syntax is:
+
+ "group:<group_name>"
+
+For example, `"group:meat"` will accept any item in the `meat` group.
+
+It is also possible to require an input item to be in
+multiple groups at once. The syntax for that is:
+
+ "group:<group_name_1>,<group_name_2>,(...),<group_name_n>"
+
+For example, `"group:leaves,birch,trimmed"` accepts any item which is member
+of *all* the groups `leaves` *and* `birch` *and* `trimmed`.
+
+An example recipe: Craft a raw meat soup from any meat, any water and any bowl:
{
output = "food:meat_soup_raw",
},
}
-Another example: Make red wool from white wool and red dye:
+Another example: Craft red wool from white wool and red dye
+(here, "red dye" is defined as any item which is member of
+*both* the groups `dye` and `basecolor_red`).
{
type = "shapeless",
### Node-only groups
-* `attached_node`: if the node under it is not a walkable block the node will be
- dropped as an item. If the node is wallmounted the wallmounted direction is
- checked.
-* `bouncy`: value is bounce speed in percent
+* `attached_node`: the node is 'attached' to a neighboring node. It checks
+ whether the node it is attached to is walkable. If it
+ isn't, the node will drop as an item.
+ * `1`: if the node is wallmounted, the node is attached in the wallmounted
+ direction. Otherwise, the node is attached to the node below.
+ * `2`: if the node is facedir or 4dir, the facedir or 4dir direction is checked.
+ No effect for other nodes.
+ Note: The "attaching face" of this node is tile no. 5 (back face).
+ * `3`: the node is always attached to the node below.
+ * `4`: the node is always attached to the node above.
+* `bouncy`: value is bounce speed in percent.
+ If positive, jump/sneak on floor impact will increase/decrease bounce height.
+ Negative value is the same bounciness, but non-controllable.
* `connect_to_raillike`: makes nodes of raillike drawtype with same group value
connect to each other
* `dig_immediate`: Player can always pick up node without reducing tool wear
},
}
-This makes the item capable of digging nodes that fulfil both of these:
+This makes the item capable of digging nodes that fulfill both of these:
* Have the `crumbly` group
* Have a `level` group less or equal to `2`
Since formspec version 3, elements drawn in the order they are defined. All
background elements are drawn before all other elements.
-**WARNING**: do _not_ use a element name starting with `key_`; those names are
+**WARNING**: do _not_ use an element name starting with `key_`; those names are
reserved to pass key press events to formspec!
**WARNING**: Minetest allows you to add elements to every single formspec instance
* When enter is pressed in field, fields.key_enter_field will be sent with the
name of this field.
* With the old coordinate system, fields are a set height, but will be vertically
- centred on `H`. With the new coordinate system, `H` will modify the height.
+ centered on `H`. With the new coordinate system, `H` will modify the height.
* `name` is the name of the field as returned in fields to `on_receive_fields`
* `label`, if not blank, will be text printed on the top left above the field
* See `field_close_on_enter` to stop enter closing the formspec
* When enter is pressed in field, `fields.key_enter_field` will be sent with
the name of this field.
* With the old coordinate system, fields are a set height, but will be vertically
- centred on `H`. With the new coordinate system, `H` will modify the height.
+ centered on `H`. With the new coordinate system, `H` will modify the height.
* `name` is the name of the field as returned in fields to `on_receive_fields`
* `label`, if not blank, will be text printed on the top left above the field
* `default` is the default value of the field
* Clickable button. When clicked, fields will be sent.
* With the old coordinate system, buttons are a set height, but will be vertically
- centred on `H`. With the new coordinate system, `H` will modify the height.
+ centered on `H`. With the new coordinate system, `H` will modify the height.
* `label` is the text on the button
### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
* Returns the additive inverse of v.
* `v1 + v2`:
* Returns the sum of both vectors.
- * Note: `+` can not be used together with scalars.
+ * Note: `+` cannot be used together with scalars.
* `v1 - v2`:
* Returns the difference of `v1` subtracted by `v2`.
- * Note: `-` can not be used together with scalars.
+ * Note: `-` cannot be used together with scalars.
* `v * s` or `s * v`:
* Returns `v` scaled by `s`.
* `v / s`:
* `math.round(x)`: Returns `x` rounded to the nearest integer.
* At a multiple of 0.5, rounds away from zero.
* `string.split(str, separator, include_empty, max_splits, sep_is_pattern)`
- * `separator`: string, default: `","`
+ * `separator`: string, cannot be empty, default: `","`
* `include_empty`: boolean, default: `false`
* `max_splits`: number, if it's negative, splits aren't limited,
default: `-1`
* Example: `minetest.string_to_area("(1,2,3) (~5,~-5,~)", {x=10,y=10,z=10})`
returns `{x=1,y=2,z=3}, {x=15,y=5,z=10}`
* `minetest.formspec_escape(string)`: returns a string
- * escapes the characters "[", "]", "\", "," and ";", which can not be used
+ * escapes the characters "[", "]", "\", "," and ";", which cannot be used
in formspecs.
* `minetest.is_yes(arg)`
* returns true if passed 'y', 'yes', 'true' or a number that isn't zero.
A positive number no smaller than 1.0.
Values below 2.0 create higher quality noise at the expense of requiring more
-octaves to cover a paticular range of 'wavelengths'.
+octaves to cover a particular range of 'wavelengths'.
### `flags`
Maps noise gradient values onto a quintic S-curve before performing
interpolation. This results in smooth, rolling noise.
Disable this (`noeased`) for sharp-looking noise with a slightly gridded
-appearence.
+appearance.
If no flags are specified (or defaults is), 2D noise is eased and 3D noise is
not eased.
Easing a 3D noise significantly increases the noise calculation load, so use
-----------
A helper class for voxel areas.
-It can be created via `VoxelArea:new({MinEdge = pmin, MaxEdge = pmax})`.
+It can be created via `VoxelArea(pmin, pmax)` or
+`VoxelArea:new({MinEdge = pmin, MaxEdge = pmax})`.
The coordinates are *inclusive*, like most other things in Minetest.
### Methods
If, for example:
- local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
+ local area = VoxelArea(emin, emax)
The values of `ystride` and `zstride` can be obtained using `area.ystride` and
`area.zstride`.
* `killer`: an `ObjectRef` (can be `nil`)
* `on_rightclick(self, clicker)`
* Called when `clicker` pressed the 'place/use' key while pointing
- to the object (not neccessarily an actual rightclick)
+ to the object (not necessarily an actual rightclick)
* `clicker`: an `ObjectRef` (may or may not be a player)
* `on_attach_child(self, child)`
* `child`: an `ObjectRef` of the child that attaches
leaves2_chance,--num chance (0-100) to replace leaves with leaves2
angle, --num angle in deg
iterations, --num max # of iterations, usually 2 -5
- random_level, --num factor to lower nr of iterations, usually 0 - 3
+ random_level, --num factor to lower number of iterations, usually 0 - 3
trunk_type, --string single/double/crossed) type of trunk: 1 node,
-- 2x2 nodes or 3x3 in cross shape
thin_branches, --boolean true -> use thin (1 node) branches
or checking if a mod is enabled.
* `minetest.get_modnames()`: returns a list of enabled mods, sorted alphabetically.
* Does not include disabled mods, even if they are installed.
+* `minetest.get_game_info()`: returns a table containing information about the
+ current game. Note that other meta information (e.g. version/release number)
+ can be manually read from `game.conf` in the game's root directory.
+
+ {
+ id = string,
+ title = string,
+ author = string,
+ -- The root directory of the game
+ path = string,
+ }
+
* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"`
* Useful for storing custom data
* `minetest.is_singleplayer()`
get_sky_as_table = true,
-- VoxelManip:get_light_data accepts an optional buffer argument (5.7.0)
get_light_data_buffer = true,
+ -- When using a mod storage backend that is not "files" or "dummy",
+ -- the amount of data in mod storage is not constrained by
+ -- the amount of RAM available. (5.7.0)
+ mod_storage_on_disk = true,
+ -- "zstd" method for compress/decompress (5.7.0)
+ compress_zstd = true,
}
* `minetest.has_feature(arg)`: returns `boolean, missing_features`
* should return `true` to prevent the default damage mechanism
* `minetest.register_on_rightclickplayer(function(player, clicker))`
* Called when the 'place/use' key was used while pointing a player
- (not neccessarily an actual rightclick)
+ (not necessarily an actual rightclick)
* `player`: ObjectRef - Player that is acted upon
* `clicker`: ObjectRef - Object that acted upon `player`, may or may not be a player
* `minetest.register_on_player_hpchange(function(player, hp_change, reason), modifier)`
giving a type - use this for custom damage types.
* `punch`: Was punched. `reason.object` will hold the puncher, or nil if none.
* `fall`
- * `node_damage`: `damage_per_second` from a neighbouring node.
+ * `node_damage`: `damage_per_second` from a neighboring node.
`reason.node` will hold the node name or nil.
* `drown`
* `respawn`
* `minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing))`
* Called when an item is eaten, by `minetest.item_eat`
* Return `itemstack` to cancel the default item eat response (i.e.: hp increase).
+* `minetest.register_on_item_pickup(function(itemstack, picker, pointed_thing, time_from_last_punch, ...))`
+ * Called by `minetest.item_pickup` before an item is picked up.
+ * Function is added to `minetest.registered_on_item_pickups`.
+ * Oldest functions are called first.
+ * Parameters are the same as in the `on_pickup` callback.
+ * Return an itemstack to cancel the default item pick-up response (i.e.: adding
+ the item into inventory).
* `minetest.register_on_priv_grant(function(name, granter, priv))`
* Called when `granter` grants the priv `priv` to `name`.
* Note that the callback will be called twice if it's done by a player,
* `pos_list` is an array of all modified positions.
* `node_list` is an array of the old node that was previously at the position
with the corresponding index in pos_list.
+* `minetest.register_on_mapblocks_changed(function(modified_blocks, modified_block_count))`
+ * Called soon after any nodes or node metadata have been modified. No
+ modifications will be missed, but there may be false positives.
+ * Will never be called more than once per server step.
+ * `modified_blocks` is the set of modified mapblock position hashes. These
+ are in the same format as those produced by `minetest.hash_node_position`,
+ and can be converted to positions with `minetest.get_position_from_hash`.
+ The set is a table where the keys are hashes and the values are `true`.
+ * `modified_block_count` is the number of entries in the set.
+ * Note: callbacks must be registered at mod load time.
Setting-related
---------------
* `minetest.get_player_by_name(name)`: Get an `ObjectRef` to a player
* `minetest.get_objects_inside_radius(pos, radius)`: returns a list of
ObjectRefs.
- * `radius`: using an euclidean metric
+ * `radius`: using a Euclidean metric
* `minetest.get_objects_in_area(pos1, pos2)`: returns a list of
ObjectRefs.
* `pos1` and `pos2` are the min and max positions of the area to search.
prefix `"no"` is attached, clears instead.
* `flags` is in the same format and has the same options as `mg_flags` in
`minetest.conf`.
+* `minetest.get_mapgen_edges([mapgen_limit[, chunksize]])`
+ * Returns the minimum and maximum possible generated node positions
+ in that order.
+ * `mapgen_limit` is an optional number. If it is absent, its value is that
+ of the *active* mapgen setting `"mapgen_limit"`.
+ * `chunksize` is an optional number. If it is absent, its value is that
+ of the *active* mapgen setting `"chunksize"`.
* `minetest.get_mapgen_setting(name)`
* Gets the *active* mapgen setting (or nil if none exists) in string
format with the following order of precedence:
* `minetest.clear_objects([options])`
* Clear all objects in the environment
* Takes an optional table as an argument with the field `mode`.
- * mode = `"full"` : Load and go through every mapblock, clearing
+ * mode = `"full"`: Load and go through every mapblock, clearing
objects (default).
* mode = `"quick"`: Clear objects immediately in loaded mapblocks,
clear objects in unloaded mapblocks only when the
* `minetest.check_single_for_falling(pos)`
* causes an unsupported `group:falling_node` node to fall and causes an
unattached `group:attached_node` node to fall.
- * does not spread these updates to neighbours.
+ * does not spread these updates to neighbors.
* `minetest.check_for_falling(pos)`
* causes an unsupported `group:falling_node` node to fall and causes an
unattached `group:attached_node` node to fall.
- * spread these updates to neighbours and can cause a cascade
+ * spread these updates to neighbors and can cause a cascade
of nodes to fall.
* `minetest.get_spawn_level(x, z)`
* Returns a player spawn y co-ordinate for the provided (x, z)
`minetest.close_formspec(playername, "")`.
**USE THIS ONLY WHEN ABSOLUTELY NECESSARY!**
* `minetest.formspec_escape(string)`: returns a string
- * escapes the characters "[", "]", "\", "," and ";", which can not be used
+ * escapes the characters "[", "]", "\", "," and ";", which cannot be used
in formspecs.
* `minetest.explode_table_event(string)`: returns a table
* returns e.g. `{type="CHG", row=1, column=2}`
* `minetest.facedir_to_dir(facedir)`
* Convert a facedir back into a vector aimed directly out the "back" of a
node.
+* `minetest.dir_to_fourdir(dir)`
+ * Convert a vector to a 4dir value, used in `param2` for
+ `paramtype2="4dir"`.
+* `minetest.fourdir_to_dir(fourdir)`
+ * Convert a 4dir back into a vector aimed directly out the "back" of a
+ node.
* `minetest.dir_to_wallmounted(dir)`
* Convert a vector to a wallmounted value, used for
`paramtype2="wallmounted"`.
* Convert yaw (angle) to a vector
* `minetest.is_colored_paramtype(ptype)`
* Returns a boolean. Returns `true` if the given `paramtype2` contains
- color information (`color`, `colorwallmounted` or `colorfacedir`).
+ color information (`color`, `colorwallmounted`, `colorfacedir`, etc.).
* `minetest.strip_param2_color(param2, paramtype2)`
* Removes everything but the color information from the
given `param2` value.
* `param2` overrides facedir and wallmounted `param2`
* returns `itemstack, position`
* `position`: the location the node was placed to. `nil` if nothing was placed.
+* `minetest.item_pickup(itemstack, picker, pointed_thing, time_from_last_punch, ...)`
+ * Runs callbacks registered by `minetest.register_on_item_pickup` and adds
+ the item to the picker's `"main"` inventory list.
+ * Parameters are the same as in `on_pickup`.
+ * Returns the leftover itemstack.
* `minetest.item_drop(itemstack, dropper, pos)`
* Drop the item
* returns the leftover itemstack
Timing
------
-* `minetest.after(time, func, ...)` : returns job table to use as below.
+* `minetest.after(time, func, ...)`: returns job table to use as below.
* Call the function `func` after `time` seconds, may be fractional
* Optional: Variable number of arguments that are passed to `func`
data too.
* Returns a code (0: successful, 1: no such player, 2: player is connected)
* `minetest.remove_player_auth(name)`: remove player authentication data
- * Returns boolean indicating success (false if player nonexistant)
+ * Returns boolean indicating success (false if player nonexistent)
* `minetest.dynamic_add_media(options, callback)`
* `options`: table containing the following parameters
* `filepath`: path to a media file on the filesystem
IP address or name
* `minetest.kick_player(name, [reason])`: disconnect a player with an optional
reason.
- * Returns boolean indicating success (false if player nonexistant)
+ * Returns boolean indicating success (false if player nonexistent)
* `minetest.disconnect_player(name, [reason])`: disconnect a player with an
optional reason, this will not prefix with 'Kicked: ' like kick_player.
If no reason is given, it will default to 'Disconnected.'
- * Returns boolean indicating success (false if player nonexistant)
+ * Returns boolean indicating success (false if player nonexistent)
Particles
---------
* Replaces definition of a builtin hud element
* `name`: `"breath"` or `"health"`
* `hud_definition`: definition to replace builtin definition
+* `minetest.parse_relative_number(arg, relative_to)`: returns number or nil
+ * Helper function for chat commands.
+ * For parsing an optionally relative number of a chat command
+ parameter, using the chat command tilde notation.
+ * `arg`: String snippet containing the number; possible values:
+ * `"<number>"`: return as number
+ * `"~<number>"`: return `relative_to + <number>`
+ * `"~"`: return `relative_to`
+ * Anything else will return `nil`
+ * `relative_to`: Number to which the `arg` number might be relative to
+ * Examples:
+ * `minetest.parse_relative_number("5", 10)` returns 5
+ * `minetest.parse_relative_number("~5", 10)` returns 15
+ * `minetest.parse_relative_number("~", 10)` returns 10
* `minetest.send_join_message(player_name)`
* This function can be overridden by mods to change the join message.
* `minetest.send_leave_message(player_name, timed_out)`
* This function can be overridden by mods to change the leave message.
-* `minetest.hash_node_position(pos)`: returns an 48-bit integer
+* `minetest.hash_node_position(pos)`: returns a 48-bit integer
* `pos`: table {x=number, y=number, z=number},
* Gives a unique hash number for a node position (16+16+16=48bit)
* `minetest.get_position_from_hash(hash)`: returns a position
* **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 can not mix string and integer 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}})`,
* `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.
* `minetest.decompress(compressed_data, method, ...)`: returns data
- * Decompress a string of data (using ZLib).
+ * Decompress a string of data using the algorithm specified by `method`.
* See documentation on `minetest.compress()` for supported compression
methods.
* `...` indicates method-specific arguments. Currently, no methods use this
* `minetest.rgba(red, green, blue[, alpha])`: returns a string
- * Each argument is a 8 Bit unsigned integer
+ * Each argument is an 8 Bit unsigned integer
* Returns the ColorString from rgb or rgba values
* Example: `minetest.rgba(10, 20, 30, 40)`, returns `"#0A141E28"`
* `minetest.encode_base64(string)`: returns string encoded in base64
similar to, but no larger than, `interval`.
* All corners and edges of the defined volume are checked.
* `interval` defaults to 4.
- * `interval` should be carefully chosen and maximised to avoid an excessive
+ * `interval` should be carefully chosen and maximized to avoid an excessive
number of points being checked.
* Like `minetest.is_protected`, this function may be extended or
overwritten by mods to provide a faster implementation to check the
* `orient_flags`: Optional table containing extra tweaks to the placement code:
* `invert_wall`: if `true`, place wall-orientation on the ground and
ground-orientation on the wall.
- * `force_wall` : if `true`, always place the node in wall orientation.
+ * `force_wall`: if `true`, always place the node in wall orientation.
* `force_ceiling`: if `true`, always place on the ceiling.
* `force_floor`: if `true`, always place the node on the floor.
* `force_facedir`: if `true`, forcefully reset the facedir to north
* Returns the amount of knockback applied on the punched player.
* Arguments are equivalent to `register_on_punchplayer`, except the following:
* `distance`: distance between puncher and punched player
- * This function can be overriden by mods that wish to modify this behaviour.
+ * This function can be overridden by mods that wish to modify this behavior.
* You may want to cache and call the old function to allow multiple mods to
- change knockback behaviour.
+ change knockback behavior.
-* `minetest.forceload_block(pos[, transient])`
+* `minetest.forceload_block(pos[, transient[, limit]])`
* forceloads the position `pos`.
* returns `true` if area could be forceloaded
* If `transient` is `false` or absent, the forceload will be persistent
(saved between server runs). If `true`, the forceload will be transient
(not saved between server runs).
+ * `limit` is an optional limit on the number of blocks that can be
+ forceloaded at once. If `limit` is negative, there is no limit. If it is
+ absent, the limit is the value of the setting `"max_forceloaded_blocks"`.
+ If the call would put the number of blocks over the limit, the call fails.
* `minetest.forceload_free_block(pos[, transient])`
* stops forceloading the position `pos`
If `true`, frees a transient forceload.
* `minetest.compare_block_status(pos, condition)`
- * Checks whether the mapblock at positition `pos` is in the wanted condition.
+ * Checks whether the mapblock at position `pos` is in the wanted condition.
* `condition` may be one of the following values:
* `"unknown"`: not in memory
* `"emerging"`: in the queue for loading from disk or generating
* `"active"`: in memory and active
* Other values are reserved for future functionality extensions
* Return value, the comparison status:
- * `false`: Mapblock does not fulfil the wanted condition
+ * `false`: Mapblock does not fulfill the wanted condition
* `true`: Mapblock meets the requirement
* `nil`: Unsupported `condition` value
* Returns the new area's ID, or nil if the insertion failed.
* The (inclusive) positions `corner1` and `corner2` describe the area.
* `data` is a string stored with the area.
- * `id` (optional): will be used as the internal area ID if it is an unique
+ * `id` (optional): will be used as the internal area ID if it is a unique
number between 0 and 2^32-2.
* `reserve(count)`
* Requires SpatialIndex, no-op function otherwise.
* `peek_item(n)`: returns taken `ItemStack`
* Copy (don't remove) up to `n` items from this stack
* `n`: number, default: `1`
+* `equals(other)`:
+ * returns `true` if this stack is identical to `other`.
+ * Note: `stack1:to_string() == stack2:to_string()` is not reliable,
+ as stack metadata can be serialized in arbitrary order.
+ * Note: if `other` is an itemstring or table representation of an
+ ItemStack, this will always return false, even if it is
+ "equivalent".
+
+### Operators
+
+* `stack1 == stack2`:
+ * Returns whether `stack1` and `stack2` are identical.
+ * Note: `stack1:to_string() == stack2:to_string()` is not reliable,
+ as stack metadata can be serialized in arbitrary order.
+ * Note: if `stack2` is an itemstring or table representation of an
+ ItemStack, this will always return false, even if it is
+ "equivalent".
`ItemStackMetaRef`
------------------
Base class used by [`StorageRef`], [`NodeMetaRef`], [`ItemStackMetaRef`],
and [`PlayerMetaRef`].
+Note: If a metadata value is in the format `${k}`, an attempt to get the value
+will return the value associated with key `k`. There is a low recursion limit.
+This behavior is **deprecated** and will be removed in a future version. Usage
+of the `${k}` syntax in formspecs is not deprecated.
+
### Methods
* `contains(key)`: Returns true if key present, otherwise false.
* `get_int(key)`: Returns `0` if key not present.
* `set_float(key, value)`
* `get_float(key)`: Returns `0` if key not present.
+* `get_keys()`: returns a list of all keys in the metadata.
* `to_table()`: returns `nil` or a table with keys:
* `fields`: key-value storage
* `inventory`: `{list1 = {}, ...}}` (NodeMetaRef only)
* `set_rotation(rot)`
* `rot` is a vector (radians). X is pitch (elevation), Y is yaw (heading)
and Z is roll (bank).
+ * Does not reset rotation incurred through `automatic_rotate`.
+ Remove & readd your objects to force a certain rotation.
* `get_rotation()`: returns the rotation, a vector (radians)
* `set_yaw(yaw)`: sets the yaw in radians (heading).
* `get_yaw()`: returns number in radians
* the formspec string will be added to every formspec shown to the user,
except for those with a no_prepend[] tag.
* This should be used to set style elements such as background[] and
- bgcolor[], any non-style elements (eg: label) may result in weird behaviour.
+ bgcolor[], any non-style elements (eg: label) may result in weird behavior.
* Only affects formspecs shown after this is called.
* `get_formspec_prepend(formspec)`: returns a formspec string.
* `get_player_control()`: returns table with player pressed keys
of the old sneak side-effects: sneak ladders and 2 node sneak jump
(default: `false`)
* `new_move`: use new move/sneak code. When `false` the exact old code
- is used for the specific old sneak behaviour (default: `true`)
+ is used for the specific old sneak behavior (default: `true`)
* `get_physics_override()`: returns the table given to `set_physics_override`
* `hud_add(hud definition)`: add a HUD element described by HUD def, returns ID
number on success
* Resource intensive - use sparsely
* `set_lighting(light_definition)`: sets lighting for the player
* `light_definition` is a table with the following optional fields:
+ * `saturation` sets the saturation (vividness).
+ values > 1 increase the saturation
+ values in [0,1) decrease the saturation
+ * This value has no effect on clients who have the "Tone Mapping" shader disabled.
* `shadows` is a table that controls ambient shadows
* `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness)
+ * This value has no effect on clients who have the "Dynamic Shadows" shader disabled.
+ * `exposure` is a table that controls automatic exposure.
+ The basic exposure factor equation is `e = 2^exposure_correction / clamp(luminance, 2^luminance_min, 2^luminance_max)`
+ * `luminance_min` set the lower luminance boundary to use in the calculation
+ * `luminance_max` set the upper luminance boundary to use in the calculation
+ * `exposure_correction` correct observed exposure by the given EV value
+ * `speed_dark_bright` set the speed of adapting to bright light
+ * `speed_bright_dark` set the speed of adapting to dark scene
+ * `center_weight_power` set the power factor for center-weighted luminance measurement
+
* `get_lighting()`: returns the current state of lighting for the player.
* Result is a table with the same fields as `light_definition` in `set_lighting`.
* `respawn()`: Respawns the player using the same mechanism as the death screen,
* `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be
returned. Default is false.
+### Limitations
+
+Raycasts don't always work properly for attached objects as the server has no knowledge of models & bones.
+
+**Rotated selectionboxes paired with `automatic_rotate` are not reliable** either since the server
+can't reliably know the total rotation of the objects on different clients (which may differ on a per-client basis).
+The server calculates the total rotation incurred through `automatic_rotate` as a "best guess"
+assuming the object was active & rotating on the client all the time since its creation.
+This may be significantly out of sync with what clients see.
+Additionally, network latency and delayed property sending may create a mismatch of client- & server rotations.
+
+In singleplayer mode, raycasts on objects with rotated selectionboxes & automatic rotate will usually only be slightly off;
+toggling automatic rotation may however cause errors to add up.
+
+In multiplayer mode, the error may be arbitrarily large.
+
### Methods
* `next()`: returns a `pointed_thing` with exact pointing location
collide_with_objects = true,
-- Collide with other objects if physical = true
- collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
- selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
- -- Selection box uses collision box dimensions when not set.
- -- For both boxes: {xmin, ymin, zmin, xmax, ymax, zmax} in nodes from
- -- object position.
+ collisionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, -- default
+ selectionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, rotate = false },
+ -- { xmin, ymin, zmin, xmax, ymax, zmax } in nodes from object position.
+ -- Collision boxes cannot rotate, setting `rotate = true` on it has no effect.
+ -- If not set, the selection box copies the collision box, and will also not rotate.
+ -- If `rotate = false`, the selection box will not rotate with the object itself, remaining fixed to the axes.
+ -- If `rotate = true`, it will match the object's rotation and any attachment rotations.
+ -- Raycasts use the selection box and object's rotation, but do *not* obey attachment rotations.
+
pointable = true,
-- Whether the object can be pointed at
-- If left out or empty, any neighbor will do.
-- `group:groupname` can also be used here.
- interval = 1.0,
+ interval = 10.0,
-- Operation interval in seconds
- chance = 1,
- -- Chance of triggering `action` per-node per-interval is 1.0 / this
- -- value
+ chance = 50,
+ -- Chance of triggering `action` per-node per-interval is 1.0 / chance
min_y = -32768,
max_y = 32767,
-- can be used to reduce CPU usage
catch_up = true,
- -- If true, catch-up behaviour is enabled: The `chance` value is
+ -- If true, catch-up behavior is enabled: The `chance` value is
-- temporarily reduced when returning to an area to simulate time lost
-- by the area being unattended. Note that the `chance` value can often
-- be reduced to 1.
-- mapblock.
-- `active_object_count_wider` is number of active objects in the node's
-- mapblock plus all 26 neighboring mapblocks. If any neighboring
- -- mapblocks are unloaded an estmate is calculated for them based on
+ -- mapblocks are unloaded an estimate is calculated for them based on
-- loaded mapblocks.
}
-- and not only the first time the block gets activated after the LBM
-- was introduced.
- action = function(pos, node),
+ action = function(pos, node, dtime_s),
-- Function triggered for each qualifying node.
+ -- `dtime_s` is the in-game time (in seconds) elapsed since the block
+ -- was last active
}
Tile definition
-- You can set the currently used color as the "palette_index" field of
-- the item stack metadata.
-- The palette is always stretched to fit indices between 0 and 255, to
- -- ensure compatibility with "colorfacedir" and "colorwallmounted" nodes.
+ -- ensure compatibility with "colorfacedir" (and similar) nodes.
color = "#ffffffff",
-- Color the item is colorized with. The palette overrides this.
-- Amount of uses this tool has for attacking players and entities
-- by punching them (0 = infinite uses).
-- For compatibility, this is automatically set from the first
- -- suitable groupcap using the forumla "uses * 3^(maxlevel - 1)".
+ -- suitable groupcap using the formula "uses * 3^(maxlevel - 1)".
-- It is recommend to set this explicitly instead of relying on the
-- fallback behavior.
},
eat = <SimpleSoundSpec>,
-- When item is eaten with `minetest.do_item_eat`
+
+ punch_use = <SimpleSoundSpec>,
+ -- When item is used with the 'punch/mine' key pointing at a node or entity
+
+ punch_use_air = <SimpleSoundSpec>,
+ -- When item is used with the 'punch/mine' key pointing at nothing (air)
},
on_place = function(itemstack, placer, pointed_thing),
-- The dropper may be any ObjectRef or nil.
-- default: minetest.item_drop
+ on_pickup = function(itemstack, picker, pointed_thing, time_from_last_punch, ...),
+ -- Called when a dropped item is punched by a player.
+ -- Shall pick-up the item and return the leftover itemstack or nil to not
+ -- modify the dropped item.
+ -- Parameters:
+ -- * `itemstack`: The `ItemStack` to be picked up.
+ -- * `picker`: Any `ObjectRef` or `nil`.
+ -- * `pointed_thing` (optional): The dropped item (a `"__builtin:item"`
+ -- luaentity) as `type="object"` `pointed_thing`.
+ -- * `time_from_last_punch, ...` (optional): Other parameters from
+ -- `luaentity:on_punch`.
+ -- default: `minetest.item_pickup`
+
on_use = function(itemstack, user, pointed_thing),
-- default: nil
-- When user pressed the 'punch/mine' key with the item in hand.
-- around it until `liquid_range` is reached;
-- will drain out without a source;
-- recommended drawtype: "flowingliquid".
- -- If it's "source" or "flowing" and `liquid_range > 0`, then
- -- both `liquid_alternative_*` fields must be specified
+ -- If it's "source" or "flowing", then the
+ -- `liquid_alternative_*` fields _must_ be specified
liquid_alternative_flowing = "",
- -- Node that represents the flowing version of the liquid
-
liquid_alternative_source = "",
- -- Node that represents the source version of the liquid
+ -- These fields may contain node names that represent the
+ -- flowing version (`liquid_alternative_flowing`) and
+ -- source version (`liquid_alternative_source`) of a liquid.
+ --
+ -- Specifically, these fields are required if any of these is true:
+ -- * `liquidtype ~= "none" or
+ -- * `drawtype == "liquid" or
+ -- * `drawtype == "flowingliquid"
+ --
+ -- Liquids consist of up to two nodes: source and flowing.
+ --
+ -- There are two ways to define a liquid:
+ -- 1) Source node and flowing node. This requires both fields to be
+ -- specified for both nodes.
+ -- 2) Standalone source node (cannot flow). `liquid_alternative_source`
+ -- must be specified and `liquid_range` must be set to 0.
+ --
+ -- Example:
+ -- liquid_alternative_flowing = "example:water_flowing",
+ -- liquid_alternative_source = "example:water_source",
liquid_viscosity = 0,
-- Controls speed at which the liquid spreads/flows (max. 7).
-- ability to "swim" up/down, sinking slowly if not moving,
-- smoother speed change when falling into, etc. The `movement_liquid_*`
-- settings apply.
- -- * nil: Will be treated as true if `liquidype ~= "none"`
+ -- * nil: Will be treated as true if `liquidtype ~= "none"`
-- and as false otherwise.
leveled = 0,
dig = <SimpleSoundSpec> or "__group",
-- While digging node.
-- If `"__group"`, then the sound will be
- -- `default_dig_<groupname>`, where `<groupname>` is the
+ -- `{name = "default_dig_<groupname>", gain = 0.5}` , where `<groupname>` is the
-- name of the item's digging group with the fastest digging time.
-- In case of a tie, one of the sounds will be played (but we
-- cannot predict which one)
-- Node constructor; called after adding node.
-- Can set up metadata and stuff like that.
-- Not called for bulk node placement (i.e. schematics and VoxelManip).
+ -- Note: Within an on_construct callback, minetest.set_node can cause an
+ -- infinite loop if it invokes the same callback.
+ -- Consider using minetest.swap_node instead.
-- default: nil
on_destruct = function(pos),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing),
-- default: nil
-- Called when clicker (an ObjectRef) used the 'place/build' key
- -- (not neccessarily an actual rightclick)
+ -- (not necessarily an actual rightclick)
-- while pointing at the node at pos with 'node' being the node table.
-- itemstack will hold clicker's wielded item.
-- Shall return the leftover itemstack.
-- If the source could not be determined it contains "??"
-- Useful for getting which mod truly registered something
-- example: if a node is registered as ":othermodname:nodename",
- -- nodename will show "othermodname", but mod_orgin will say "modname"
+ -- nodename will show "othermodname", but mod_origin will say "modname"
}
Crafting recipes
----------------
-Used by `minetest.register_craft`.
+Crafting converts one or more inputs to one output itemstack of arbitrary
+count (except for fuels, which don't have an output). The conversion reduces
+each input ItemStack by 1.
+
+Craft recipes are registered by `minetest.register_craft` and use a
+table format. The accepted parameters are listed below.
+
+Recipe input items can either be specified by item name (item count = 1)
+or by group (see "Groups in crafting recipes" for details).
+
+The following sections describe the types and syntaxes of recipes.
### Shaped
+This is the default recipe type (when no `type` is specified).
+
+A shaped recipe takes one or multiple items as input and has
+a single item stack as output. The input items must be specified
+in a 2-dimensional matrix (see parameters below) to specify the
+exact arrangement (the "shape") in which the player must place them
+in the crafting grid.
+
+For example, for a 3x3 recipe, the `recipes` table must have
+3 rows and 3 columns.
+
+In order to craft the recipe, the players' crafting grid must
+have equal or larger dimensions (both width and height).
+
+Parameters:
+
+* `type = "shaped"`: (optional) specifies recipe type as shaped
+* `output`: Itemstring of output itemstack (item counts >= 1 are allowed)
+* `recipe`: A 2-dimensional matrix of items, with a width *w* and height *h*.
+ * *w* and *h* are chosen by you, they don't have to be equal but must be at least 1
+ * The matrix is specified as a table containing tables containing itemnames
+ * The inner tables are the rows. There must be *h* tables, specified from the top to the bottom row
+ * Values inside of the inner table are the columns.
+ Each inner table must contain a list of *w* items, specified from left to right
+ * Empty slots *must* be filled with the empty string
+* `replacements`: (optional) Allows you to replace input items with some other items
+ when something is crafted
+ * Provided as a list of item pairs of the form `{ old_item, new_item }` where
+ `old_item` is the input item to replace (same syntax as for a regular input
+ slot; groups are allowed) and `new_item` is an itemstring for the item stack
+ it will become
+ * When the output is crafted, Minetest iterates through the list
+ of input items if the crafting grid. For each input item stack, it checks if
+ it matches with an `old_item` in the item pair list.
+ * If it matches, the item will be replaced. Also, this item pair
+ will *not* be applied again for the remaining items
+ * If it does not match, the item is consumed (reduced by 1) normally
+ * The `new_item` will appear in one of 3 places:
+ * Crafting grid, if the input stack size was exactly 1
+ * Player inventory, if input stack size was larger
+ * Drops as item entity, if it fits neither in craft grid or inventory
+
+#### Examples
+
+A typical shaped recipe:
+
+ -- Stone pickaxe
{
- output = "default:pick_stone",
+ output = "example:stone_pickaxe",
+ -- A 3x3 recipe which needs 3 stone in the 1st row,
+ -- and 1 stick in the horizontal middle in each of the 2nd and 3nd row.
+ -- The 4 remaining slots have to be empty.
recipe = {
- {"default:cobble", "default:cobble", "default:cobble"},
- {"", "default:stick", ""},
- {"", "default:stick", ""}, -- Also groups; e.g. "group:crumbly"
+ {"example:stone", "example:stone", "example:stone"}, -- row 1
+ {"", "example:stick", "" }, -- row 2
+ {"", "example:stick", "" }, -- row 3
+ -- ^ column 1 ^ column 2 ^ column 3
+ },
+ -- There is no replacements table, so every input item
+ -- will be consumed.
+ }
+
+Simple replacement example:
+
+ -- Wet sponge
+ {
+ output = "example:wet_sponge",
+ -- 1x2 recipe with a water bucket above a dry sponge
+ recipe = {
+ {"example:water_bucket"},
+ {"example:dry_sponge"},
+ },
+ -- When the wet sponge is crafted, the water bucket
+ -- in the input slot is replaced with an empty
+ -- bucket
+ replacements = {
+ {"example:water_bucket", "example:empty_bucket"},
+ },
+ }
+
+Complex replacement example 1:
+
+ -- Very wet sponge
+ {
+ output = "example:very_wet_sponge",
+ -- 3x3 recipe with a wet sponge in the center
+ -- and 4 water buckets around it
+ recipe = {
+ {"","example:water_bucket",""},
+ {"example:water_bucket","example:wet_sponge","example:water_bucket"},
+ {"","example:water_bucket",""},
+ },
+ -- When the wet sponge is crafted, all water buckets
+ -- in the input slot become empty
+ replacements = {
+ -- Without these repetitions, only the first
+ -- water bucket would be replaced.
+ {"example:water_bucket", "example:empty_bucket"},
+ {"example:water_bucket", "example:empty_bucket"},
+ {"example:water_bucket", "example:empty_bucket"},
+ {"example:water_bucket", "example:empty_bucket"},
+ },
+ }
+
+Complex replacement example 2:
+
+ -- Magic book:
+ -- 3 magic orbs + 1 book crafts a magic book,
+ -- and the orbs will be replaced with 3 different runes.
+ {
+ output = "example:magic_book",
+ -- 3x2 recipe
+ recipe = {
+ -- 3 items in the group `magic_orb` on top of a book in the middle
+ {"group:magic_orb", "group:magic_orb", "group:magic_orb"},
+ {"", "example:book", ""},
+ },
+ -- When the book is crafted, the 3 magic orbs will be turned into
+ -- 3 runes: ice rune, earth rune and fire rune (from left to right)
+ replacements = {
+ {"group:magic_orb", "example:ice_rune"},
+ {"group:magic_orb", "example:earth_rune"},
+ {"group:magic_orb", "example:fire_rune"},
},
- replacements = <list of item pairs>,
- -- replacements: replace one input item with another item on crafting
- -- (optional).
}
### Shapeless
+Takes a list of input items (at least 1). The order or arrangement
+of input items does not matter.
+
+In order to craft the recipe, the players' crafting grid must have matching or
+larger *count* of slots. The grid dimensions do not matter.
+
+Parameters:
+
+* `type = "shapeless"`: Mandatory
+* `output`: Same as for shaped recipe
+* `recipe`: List of item names
+* `replacements`: Same as for shaped recipe
+
+#### Example
+
{
+ -- Craft a mushroom stew from a bowl, a brown mushroom and a red mushroom
+ -- (no matter where in the input grid the items are placed)
type = "shapeless",
- output = "mushrooms:mushroom_stew",
+ output = "example:mushroom_stew",
recipe = {
- "mushrooms:bowl",
- "mushrooms:mushroom_brown",
- "mushrooms:mushroom_red",
+ "example:bowl",
+ "example:mushroom_brown",
+ "example:mushroom_red",
},
- replacements = <list of item pairs>,
}
### Tool repair
+Syntax:
+
{
type = "toolrepair",
additional_wear = -0.02, -- multiplier of 65536
}
Adds a shapeless recipe for *every* tool that doesn't have the `disable_repair=1`
-group. Player can put 2 equal tools in the craft grid to get one "repaired" tool
+group. If this recipe is used, repairing is possible with any crafting grid
+with at least 2 slots.
+The player can put 2 equal tools in the craft grid to get one "repaired" tool
back.
The wear of the output is determined by the wear of both tools, plus a
'repair bonus' given by `additional_wear`. To reduce the wear (i.e. 'repair'),
The formula used to calculate the resulting wear is:
- 65536 * (1 - ( (1 - tool_1_wear) + (1 - tool_2_wear) + additional_wear ))
+ 65536 * (1 - ( (1 - tool_1_wear) + (1 - tool_2_wear) + additional_wear))
The result is rounded and can't be lower than 0. If the result is 65536 or higher,
no crafting is possible.
### Cooking
+A cooking recipe has a single input item, a single output item stack
+and a cooking time. It represents cooking/baking/smelting/etc. items in
+an oven, furnace, or something similar; the exact meaning is up for games
+to decide, if they choose to use cooking at all.
+
+The engine does not implement anything specific to cooking recipes, but
+the recipes can be retrieved later using `minetest.get_craft_result` to
+have a consistent interface across different games/mods.
+
+Parameters:
+
+* `type = "cooking"`: Mandatory
+* `output`: Same as for shaped recipe
+* `recipe`: An itemname of the single input item
+* `cooktime`: (optional) Time it takes to cook this item, in seconds.
+ A floating-point number. (default: 3.0)
+* `replacements`: Same meaning as for shaped recipes, but the mods
+ that utilize cooking recipes (e.g. for adding a furnace
+ node) need to implement replacements on their own
+
+Note: Games and mods are free to re-interpret the cooktime in special
+cases, e.g. for a super furnace that cooks items twice as fast.
+
+#### Example
+
+Cooking sand to glass in 3 seconds:
+
{
type = "cooking",
- output = "default:glass",
- recipe = "default:sand",
- cooktime = 3,
+ output = "example:glass",
+ recipe = "example:sand",
+ cooktime = 3.0,
}
-### Furnace fuel
+### Fuel
+
+A fuel recipe is an item associated with a "burning time" and an optional
+item replacement. There is no output. This is usually used as fuel for
+furnaces, ovens, stoves, etc.
+
+Like with cooking recipes, the engine does not do anything specific with
+fuel recipes and it's up to games and mods to use them by retrieving
+them via `minetest.get_craft_result`.
+
+Parameters:
+
+* `type = "fuel"`: Mandatory
+* `recipe`: Itemname of the item to be used as fuel
+* `burntime`: (optional) Burning time this item provides, in seconds.
+ A floating-point number. (default: 1.0)
+* `replacements`: Same meaning as for shaped recipes, but the mods
+ that utilize fuels need to implement replacements
+ on their own
+
+Note: Games and mods are free to re-interpret the burntime in special
+cases, e.g. for an efficient furnace in which fuels burn twice as
+long.
+
+#### Examples
+
+Coal lump with a burntime of 20 seconds. Will be consumed when used.
{
type = "fuel",
- recipe = "bucket:bucket_lava",
- burntime = 60,
- replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}},
+ recipe = "example:coal_lump",
+ burntime = 20.0,
}
-The engine does not implement anything specific to cooking or fuels, but the
-recpies can be retrieved later using `minetest.get_craft_result` to have a
-consistent interface across different games/mods.
+Lava bucket with a burn time of 60 seconds. Will become an empty bucket
+if used:
+
+ {
+ type = "fuel",
+ recipe = "example:lava_bucket",
+ burntime = 60.0,
+ replacements = {{"example:lava_bucket", "example:empty_bucket"}},
+ }
Ore definition
--------------
-- Multiple nodes can be specified, each cave will use a randomly
-- chosen node from the list.
-- If this field is left out or 'nil', cave liquids fall back to
- -- classic behaviour of lava and water distributed using 3D noise.
+ -- classic behavior of lava and water distributed using 3D noise.
-- For no cave liquid, specify "air".
node_dungeon = "default:cobble",
spawn_by = "default:water",
-- Node (or list of nodes) that the decoration only spawns next to.
- -- Checks the 8 neighbouring nodes on the same Y, and also the ones
+ -- Checks the 8 neighboring nodes on the same Y, and also the ones
-- at Y+1, excluding both center nodes.
num_spawn_by = 1,
-- Ceiling decorations act as an inversion of floor decorations so the
-- effect of 'place_offset_y' is inverted.
-- Y-slice probabilities do not function correctly for ceiling
- -- schematic decorations as the behaviour is unchanged.
+ -- schematic decorations as the behavior is unchanged.
-- If a single decoration registration has both flags the floor and
-- ceiling decorations will be aligned vertically.
Used by `minetest.register_chatcommand`.
+Specifies the function to be called and the privileges required when a player
+issues the command. A help message that is the concatenation of the params and
+description fields is shown when the "/help" chatcommand is issued.
+
{
- params = "<name> <privilege>", -- Short parameter description
+ params = "",
+ -- Short parameter description. See the below note.
- description = "Remove privilege from player", -- Full description
+ description = "",
+ -- General description of the command's purpose.
- privs = {privs=true}, -- Require the "privs" privilege to run
+ privs = {},
+ -- Required privileges to run. See `minetest.check_player_privs()` for
+ -- the format and see [Privileges] for an overview of privileges.
func = function(name, param),
- -- Called when command is run. Returns boolean success and text output.
- -- Special case: The help message is shown to the player if `func`
- -- returns false without a text output.
+ -- Called when command is run.
+ -- * `name` is the name of the player who issued the command.
+ -- * `param` is a string with the full arguments to the command.
+ -- Returns a boolean for success and a string value.
+ -- The string is shown to the issuing player upon exit of `func` or,
+ -- if `func` returns `false` and no string, the help message is shown.
}
-Note that in params, use of symbols is as follows:
+Note that in params, the conventional use of symbols is as follows:
* `<>` signifies a placeholder to be replaced when the command is used. For
example, when a player name is needed: `<name>`
* `()` signifies grouping. For example, when param1 and param2 are both
required, or only param3 is required: `(<param1> <param2>) | <param3>`
+Example:
+
+ {
+ params = "<name> <privilege>",
+
+ description = "Remove privilege from player",
+
+ privs = {privs=true}, -- Require the "privs" privilege to run
+
+ func = function(name, param),
+ }
+
Privilege definition
--------------------
animation = {Tile Animation definition},
-- Optional, specifies how to animate the particles' texture
- -- v5.6.0 and later: set length to -1 to sychronize the length
+ -- v5.6.0 and later: set length to -1 to synchronize the length
-- of the animation with the expiration time of individual particles.
-- (-2 causes the animation to be played twice, and so on)
The following definitions are all equivalent, listed in order of precedence from
lowest (the legacy syntax) to highest (tween tables). If multiple forms of a
-property definition are present, the highest-precidence form will be selected
+property definition are present, the highest-precedence form will be selected
and all lower-precedence fields will be ignored, allowing for graceful
degradation in older clients).
All of the properties in this list can be animated with `*_tween` tables
unless otherwise specified. For example, `jitter` can be tweened by setting
a `jitter_tween` table instead of (or in addition to) a `jitter` table/value.
+In this section, a float range is a table defined as so: { min = A, max = B }
+A and B are your supplemented values. For a vec3 range this means they are vectors.
Types used are defined in the previous section.
* vec3 range `pos`: the position at which particles can appear
-- adds the value of pixels to those underneath them, modulo the sources
-- alpha channel. useful for e.g. bright light effects like sparks or fire
blend = "screen",
- -- like "add" but less bright. useful for subtler light effecs. note that
+ -- like "add" but less bright. useful for subtler light effects. note that
-- this is NOT formally equivalent to the "screen" effect used in image
-- editors and compositors, as it does not respect the alpha channel of
-- of the image being blended
Functions: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap
See http://bitop.luajit.org/ for advanced information.
+
+Error Handling
+--------------
+
+When an error occurs that is not caught, Minetest calls the function
+`minetest.error_handler` with the error object as its first argument. The second
+argument is the stack level where the error occurred. The return value is the
+error string that should be shown. By default this is a backtrace from
+`debug.traceback`. If the error object is not a string, it is first converted
+with `tostring` before being displayed. This means that you can use tables as
+error objects so long as you give them `__tostring` metamethods.
+
+You can override `minetest.error_handler`. You should call the previous handler
+with the correct stack level in your implementation.