]> git.lizzy.rs Git - minetest.git/blobdiff - doc/lua_api.txt
lua_api.txt: Explain what a float range is
[minetest.git] / doc / lua_api.txt
index 0f2fea4dba25456ae52231322d26eddceed5b9c5..c1e26c72eacc6ec0fbc99264f63c954354ec4c44 100644 (file)
@@ -85,6 +85,8 @@ The game directory can contain the following files:
       (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
@@ -396,7 +398,7 @@ Deprecated, define dungeon nodes in biome definitions instead.
 
 * `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
 
@@ -758,6 +760,17 @@ appropriate `paramtype2`:
       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).
@@ -908,13 +921,13 @@ Examples of sound parameter tables:
     {
         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
@@ -968,7 +981,7 @@ These sound files are played back by the engine if provided.
  * `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
@@ -983,7 +996,7 @@ existence before trying to access the fields.
 
 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:
@@ -1058,18 +1071,39 @@ The function of `param2` is determined by `paramtype2` in node definition.
     * 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:
@@ -1091,7 +1125,7 @@ The function of `param2` is determined by `paramtype2` in node definition.
       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
@@ -1112,6 +1146,10 @@ The function of `param2` is determined by `paramtype2` in node definition.
     * 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
@@ -1153,12 +1191,14 @@ Look for examples in `games/devtest` or `games/minetest_game`.
     * 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.
@@ -1285,7 +1325,7 @@ A nodebox is defined as any of:
         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, ...}
@@ -1296,7 +1336,7 @@ A nodebox is defined as any of:
         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, ...}
@@ -1304,9 +1344,9 @@ A nodebox is defined as any of:
         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:
@@ -1341,7 +1381,7 @@ clients and handled by many parts of the engine.
 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
 -----------
@@ -1571,6 +1611,8 @@ Exact pointing location (currently only `Raycast` supports these fields):
 * `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.
 
 
 
@@ -1626,7 +1668,7 @@ Item types
 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
@@ -1651,7 +1693,7 @@ Amount and wear
 ---------------
 
 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
@@ -1694,7 +1736,7 @@ Examples:
   * 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
@@ -1783,8 +1825,8 @@ For entities, groups are, as of now, used only for calculating damage.
 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
 ---------------------------
@@ -1795,7 +1837,24 @@ are effective towards.
 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",
@@ -1806,7 +1865,9 @@ An example: Make meat soup from any meat, any water and any bowl:
         },
     }
 
-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",
@@ -1829,10 +1890,19 @@ to games.
 
 ### 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
@@ -2037,7 +2107,7 @@ Example definition of the capabilities of an item
         },
     }
 
-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`
@@ -2260,7 +2330,7 @@ For colored text you can use `minetest.colorize`.
 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
@@ -2562,7 +2632,7 @@ Elements
 * 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
@@ -2573,7 +2643,7 @@ Elements
 * 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
@@ -2636,7 +2706,7 @@ Elements
 
 * 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>]`
@@ -3485,10 +3555,10 @@ Operators can be used if all of the involved vectors have metatables:
     * 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`:
@@ -3553,7 +3623,7 @@ Helper functions
 * `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`
@@ -3589,7 +3659,7 @@ Helper functions
     * 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.
@@ -3879,7 +3949,7 @@ previous octave multiplied by 1 / lacunarity, to create finer detail.
 
 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`
 
@@ -3896,7 +3966,7 @@ specifying some other 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
@@ -4426,7 +4496,8 @@ Methods
 -----------
 
 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
@@ -4474,7 +4545,7 @@ the axes in a voxel area:
 
 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`.
@@ -4589,7 +4660,7 @@ Callbacks:
     * `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
@@ -4647,7 +4718,7 @@ Tree definition
         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
@@ -4808,6 +4879,18 @@ Utilities
   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()`
@@ -4868,6 +4951,12 @@ Utilities
           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`
@@ -5112,7 +5201,7 @@ Call these functions only at load time!
     * 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)`
@@ -5125,7 +5214,7 @@ Call these functions only at load time!
                         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`
@@ -5255,6 +5344,13 @@ Call these functions only at load time!
 * `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,
@@ -5276,6 +5372,16 @@ Call these functions only at load time!
     * `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
 ---------------
@@ -5430,7 +5536,7 @@ Environment access
 * `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.
@@ -5532,6 +5638,13 @@ Environment access
       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:
@@ -5571,7 +5684,7 @@ Environment access
 * `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
@@ -5669,11 +5782,11 @@ Environment access
 * `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)
@@ -5737,7 +5850,7 @@ Formspec
       `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}`
@@ -5776,6 +5889,12 @@ Item handling
 * `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"`.
@@ -5788,7 +5907,7 @@ Item handling
     * 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.
@@ -5895,6 +6014,11 @@ Defaults for the `on_place` and `on_drop` item definition functions
     * `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
@@ -5939,7 +6063,7 @@ Sounds
 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`
 
@@ -6035,7 +6159,7 @@ Server
       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
@@ -6076,11 +6200,11 @@ Bans
   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
 ---------
@@ -6243,11 +6367,25 @@ Misc.
     * 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
@@ -6279,7 +6417,7 @@ Misc.
     * **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}})`,
@@ -6308,16 +6446,20 @@ Misc.
     * `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
@@ -6362,7 +6504,7 @@ Misc.
       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
@@ -6377,7 +6519,7 @@ Misc.
     * `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
@@ -6396,16 +6538,20 @@ Misc.
     * 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`
@@ -6413,7 +6559,7 @@ Misc.
       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
@@ -6421,7 +6567,7 @@ Misc.
         * `"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
 
@@ -6552,7 +6698,7 @@ use the provided load and write functions for this.
     * 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.
@@ -6710,6 +6856,23 @@ an itemstring, a table or `nil`.
 * `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`
 ------------------
@@ -6731,6 +6894,11 @@ Can be obtained via `item:get_meta()`.
 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.
@@ -6742,6 +6910,7 @@ and [`PlayerMetaRef`].
 * `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)
@@ -6956,6 +7125,8 @@ child will follow movement and rotation of that bone.
 * `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
@@ -7046,7 +7217,7 @@ child will follow movement and rotation of that bone.
     * 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
@@ -7080,7 +7251,7 @@ child will follow movement and rotation of that bone.
           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
@@ -7294,8 +7465,22 @@ child will follow movement and rotation of that bone.
     * 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,
@@ -7435,6 +7620,22 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
 * `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
@@ -7551,11 +7752,15 @@ Player properties need to be saved manually.
         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
@@ -7736,12 +7941,11 @@ Used by `minetest.register_abm`.
         -- 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,
@@ -7749,7 +7953,7 @@ Used by `minetest.register_abm`.
         -- 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.
@@ -7760,7 +7964,7 @@ Used by `minetest.register_abm`.
         -- 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.
     }
 
@@ -7791,8 +7995,10 @@ gets activated (not loaded!)
         -- 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
@@ -7893,7 +8099,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         -- 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.
@@ -7931,7 +8137,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
             -- 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.
         },
@@ -7959,6 +8165,12 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
 
             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),
@@ -7981,6 +8193,19 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         -- 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.
@@ -8115,14 +8340,31 @@ Used by `minetest.register_node`.
         --              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).
@@ -8140,7 +8382,7 @@ Used by `minetest.register_node`.
         --   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,
@@ -8219,7 +8461,7 @@ Used by `minetest.register_node`.
             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)
@@ -8300,6 +8542,9 @@ Used by `minetest.register_node`.
         -- 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),
@@ -8357,7 +8602,7 @@ Used by `minetest.register_node`.
         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.
@@ -8415,50 +8660,194 @@ Used by `minetest.register_node`.
         -- 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'),
@@ -8466,32 +8855,90 @@ you want `additional_wear` to be negative.
 
 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
 --------------
@@ -8645,7 +9092,7 @@ performance and computing power the practical limit is much lower.
         -- 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",
@@ -8744,7 +9191,7 @@ See [Decoration types]. Used by `minetest.register_decoration`.
 
         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,
@@ -8766,7 +9213,7 @@ See [Decoration types]. Used by `minetest.register_decoration`.
         --   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.
 
@@ -8852,20 +9299,31 @@ Chat command definition
 
 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>`
@@ -8877,6 +9335,18 @@ Note that in params, use of symbols is as follows:
 * `()` 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
 --------------------
 
@@ -9105,7 +9575,7 @@ will be ignored.
 
         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)
 
@@ -9155,7 +9625,7 @@ a tween table.
 
 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).
 
@@ -9252,6 +9722,8 @@ section, along with the datatypes they accept.
 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
@@ -9362,7 +9834,7 @@ table contains options that allow simple animations to be applied to the texture
         -- 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
@@ -9532,3 +10004,17 @@ Bit Library
 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.