]> git.lizzy.rs Git - minetest.git/blobdiff - doc/lua_api.txt
Documementation: Add advice on lifetime of ObjectRefs
[minetest.git] / doc / lua_api.txt
index 2b05cff8c1db90ec8289f85ca560d86163b497f4..75ad07cadeb9d7f517ea277970c47076a85cbd6e 100644 (file)
@@ -3,10 +3,10 @@ Minetest Lua Modding API Reference
 
 * More information at <http://www.minetest.net/>
 * Developer Wiki: <http://dev.minetest.net/>
 
 * More information at <http://www.minetest.net/>
 * Developer Wiki: <http://dev.minetest.net/>
-
+* (Unofficial) Minetest Modding Book by rubenwardy: <https://rubenwardy.com/minetest_modding_book/>
 
 Introduction
 
 Introduction
-============
+------------
 
 Content and functionality can be added to Minetest using Lua scripting
 in run-time loaded mods.
 
 Content and functionality can be added to Minetest using Lua scripting
 in run-time loaded mods.
@@ -119,8 +119,14 @@ Modpacks
 --------
 
 Mods can be put in a subdirectory, if the parent directory, which otherwise
 --------
 
 Mods can be put in a subdirectory, if the parent directory, which otherwise
-should be a mod, contains a file named `modpack.txt`. This file shall be
-empty, except for lines starting with `#`, which are comments.
+should be a mod, contains a file named `modpack.conf`.
+The file is a key-value store of modpack details.
+
+* `name`: The modpack name.
+* `description`: Description of mod to be shown in the Mods tab of the main
+                 menu.
+
+Note: to support 0.4.x, please also create an empty modpack.txt file.
 
 Mod directory structure
 -----------------------
 
 Mod directory structure
 -----------------------
@@ -148,7 +154,7 @@ The location of this directory can be fetched by using
 
 ### mod.conf
 
 
 ### mod.conf
 
-A key-value store of mod details.
+A `Settings` file that provides meta information about the mod.
 
 * `name`: The mod name. Allows Minetest to determine the mod name even if the
           folder is wrongly named.
 
 * `name`: The mod name. Allows Minetest to determine the mod name even if the
           folder is wrongly named.
@@ -190,8 +196,9 @@ A file containing a description to be shown in the Mods tab of the main menu.
 
 ### `settingtypes.txt`
 
 
 ### `settingtypes.txt`
 
-A file in the same format as the one in builtin. It will be parsed by the
-settings menu and the settings will be displayed in the "Mods" category.
+The format is documented in `builtin/settingtypes.txt`.
+It is parsed by the main menu settings dialogue to list mod-specific
+settings in the "Mods" category.
 
 ### `init.lua`
 
 
 ### `init.lua`
 
@@ -252,13 +259,15 @@ dependency.
 Aliases
 =======
 
 Aliases
 =======
 
-Aliases can be added by using `minetest.register_alias(name, convert_to)` or
-`minetest.register_alias_force(name, convert_to)`.
+Aliases of itemnames can be added by using
+`minetest.register_alias(alias, original_name)` or
+`minetest.register_alias_force(alias, original_name)`.
 
 
-This converts anything called `name` to `convert_to`.
+This adds an alias `alias` for the item called `original_name`.
+From now on, you can use `alias` to refer to the item `original_name`.
 
 The only difference between `minetest.register_alias` and
 
 The only difference between `minetest.register_alias` and
-`minetest.register_alias_force` is that if an item called `name` exists,
+`minetest.register_alias_force` is that if an item named `alias` already exists,
 `minetest.register_alias` will do nothing while
 `minetest.register_alias_force` will unregister it.
 
 `minetest.register_alias` will do nothing while
 `minetest.register_alias_force` will unregister it.
 
@@ -275,40 +284,35 @@ Mapgen aliases
 --------------
 
 In a game, a certain number of these must be set to tell core mapgens which
 --------------
 
 In a game, a certain number of these must be set to tell core mapgens which
-of the game's nodes are to be used by the core mapgens. For example:
+of the game's nodes are to be used for core mapgen generation. For example:
 
     minetest.register_alias("mapgen_stone", "default:stone")
 
 
     minetest.register_alias("mapgen_stone", "default:stone")
 
-### Aliases needed for all mapgens except Mapgen V6
+### Aliases for non-V6 mapgens
 
 
-#### Base terrain
+#### Essential aliases
 
 * mapgen_stone
 * mapgen_water_source
 * mapgen_river_water_source
 
 
 * mapgen_stone
 * mapgen_water_source
 * mapgen_river_water_source
 
-#### Caves
+`mapgen_river_water_source` is required for mapgens with sloping rivers where
+it is necessary to have a river liquid node with a short `liquid_range` and
+`liquid_renewable = false` to avoid flooding.
 
 
-Not required if cave liquid nodes are set in biome definitions.
+#### Optional aliases
 
 * mapgen_lava_source
 
 
 * mapgen_lava_source
 
-#### Dungeons
-
-Not required if dungeon nodes are set in biome definitions.
+Fallback lava node used if cave liquids are not defined in biome definitions.
+Deprecated for non-V6 mapgens, define cave liquids in biome definitions instead.
 
 * mapgen_cobble
 
 * mapgen_cobble
-* mapgen_stair_cobble
-* mapgen_mossycobble
-* mapgen_desert_stone
-* mapgen_stair_desert_stone
-* mapgen_sandstone
-* mapgen_sandstonebrick
-* mapgen_stair_sandstone_block
 
 
-### Aliases needed for Mapgen V6
+Fallback node used if dungeon nodes are not defined in biome definitions.
+Deprecated for non-V6 mapgens, define dungeon nodes in biome definitions instead.
 
 
-#### Terrain and biomes
+### Aliases needed for Mapgen V6
 
 * mapgen_stone
 * mapgen_water_source
 
 * mapgen_stone
 * mapgen_water_source
@@ -324,8 +328,6 @@ Not required if dungeon nodes are set in biome definitions.
 * mapgen_snow
 * mapgen_ice
 
 * mapgen_snow
 * mapgen_ice
 
-#### Flora
-
 * mapgen_tree
 * mapgen_leaves
 * mapgen_apple
 * mapgen_tree
 * mapgen_leaves
 * mapgen_apple
@@ -335,8 +337,6 @@ Not required if dungeon nodes are set in biome definitions.
 * mapgen_pine_tree
 * mapgen_pine_needles
 
 * mapgen_pine_tree
 * mapgen_pine_needles
 
-#### Dungeons
-
 * mapgen_cobble
 * mapgen_stair_cobble
 * mapgen_mossycobble
 * mapgen_cobble
 * mapgen_stair_cobble
 * mapgen_mossycobble
@@ -826,7 +826,7 @@ Examples of sound parameter tables:
         gain = 1.0,  -- default
         loop = true,
     }
         gain = 1.0,  -- default
         loop = true,
     }
-    -- Play in a location
+    -- Play at a location
     {
         pos = {x = 1, y = 2, z = 3},
         gain = 1.0,  -- default
     {
         pos = {x = 1, y = 2, z = 3},
         gain = 1.0,  -- default
@@ -839,94 +839,75 @@ Examples of sound parameter tables:
         max_hear_distance = 32,  -- default, uses an euclidean metric
         loop = true,
     }
         max_hear_distance = 32,  -- default, uses an euclidean metric
         loop = true,
     }
+    -- Play at a location, heard by anyone *but* the given player
+    {
+        pos = {x = 32, y = 0, z = 100},
+        max_hear_distance = 40,
+        exclude_player = name,
+    }
 
 Looped sounds must either be connected to an object or played locationless to
 
 Looped sounds must either be connected to an object or played locationless to
-one player using `to_player = name,`
-
-`SimpleSoundSpec`
------------------
+one player using `to_player = name`.
 
 
-* e.g. `""`
-* e.g. `"default_place_node"`
-* e.g. `{}`
-* e.g. `{name = "default_place_node"}`
-* e.g. `{name = "default_place_node", gain = 1.0}`
-* e.g. `{name = "default_place_node", gain = 1.0, pitch = 1.0}`
+A positional sound will only be heard by players that are within
+`max_hear_distance` of the sound position, at the start of the sound.
 
 
+`exclude_player = name` can be applied to locationless, positional and object-
+bound sounds to exclude a single player from hearing them.
 
 
+`SimpleSoundSpec`
+-----------------
 
 
+Specifies a sound name, gain (=volume) and pitch.
+This is either a string or a table.
 
 
-Registered definitions
-======================
+In string form, you just specify the sound name or
+the empty string for no sound.
 
 
-Anything added using certain `minetest.register_*` functions gets added to
-the global `minetest.registered_*` tables.
+Table form has the following fields:
 
 
-* `minetest.register_entity(name, entity definition)`
-    * added to `minetest.registered_entities[name]`
+* `name`: Sound name
+* `gain`: Volume (`1.0` = 100%)
+* `pitch`: Pitch (`1.0` = 100%)
 
 
-* `minetest.register_node(name, node definition)`
-    * added to `minetest.registered_items[name]`
-    * added to `minetest.registered_nodes[name]`
+`gain` and `pitch` are optional and default to `1.0`.
 
 
-* `minetest.register_tool(name, item definition)`
-    * added to `minetest.registered_items[name]`
-
-* `minetest.register_craftitem(name, item definition)`
-    * added to `minetest.registered_items[name]`
-
-* `minetest.unregister_item(name)`
-    * Unregisters the item name from engine, and deletes the entry with key
-      `name` from `minetest.registered_items` and from the associated item
-      table according to its nature: `minetest.registered_nodes[]` etc
-
-* `minetest.register_biome(biome definition)`
-    * returns an integer uniquely identifying the registered biome
-    * added to `minetest.registered_biome` with the key of `biome.name`
-    * if `biome.name` is nil, the key is the returned ID
-
-* `minetest.unregister_biome(name)`
-    * Unregisters the biome name from engine, and deletes the entry with key
-      `name` from `minetest.registered_biome`
-
-* `minetest.register_ore(ore definition)`
-    * returns an integer uniquely identifying the registered ore
-    * added to `minetest.registered_ores` with the key of `ore.name`
-    * if `ore.name` is nil, the key is the returned ID
+Examples:
 
 
-* `minetest.register_decoration(decoration definition)`
-    * returns an integer uniquely identifying the registered decoration
-    * added to `minetest.registered_decorations` with the key of
-      `decoration.name`.
-    * if `decoration.name` is nil, the key is the returned ID
+* `""`: No sound
+* `{}`: No sound
+* `"default_place_node"`: Play e.g. `default_place_node.ogg`
+* `{name = "default_place_node"}`: Same as above
+* `{name = "default_place_node", gain = 0.5}`: 50% volume
+* `{name = "default_place_node", gain = 0.9, pitch = 1.1}`: 90% volume, 110% pitch
 
 
-* `minetest.register_schematic(schematic definition)`
-    * returns an integer uniquely identifying the registered schematic
-    * added to `minetest.registered_schematic` with the key of `schematic.name`
-    * if `schematic.name` is nil, the key is the returned ID
-    * if the schematic is loaded from a file, schematic.name is set to the
-      filename.
-    * if the function is called when loading the mod, and schematic.name is a
-      relative path, then the current mod path will be prepended to the
-      schematic filename.
+Special sound files
+-------------------
 
 
-* `minetest.clear_registered_biomes()`
-    * clears all biomes currently registered
+These sound files are played back by the engine if provided.
 
 
-* `minetest.clear_registered_ores()`
-    * clears all ores currently registered
+ * `player_damage`: Played when the local player takes damage (gain = 0.5)
+ * `player_falling_damage`: Played when the local player takes
+   damage by falling (gain = 0.5)
+ * `default_dig_<groupname>`: Default node digging sound
+   (see node sound definition for details)
 
 
-* `minetest.clear_registered_decorations()`
-    * clears all decorations currently registered
+Registered definitions
+======================
 
 
-* `minetest.clear_registered_schematics()`
-    * clears all schematics currently registered
+Anything added using certain [Registration functions] gets added to one or more
+of the global [Registered definition tables].
 
 Note that in some cases you will stumble upon things that are not contained
 in these tables (e.g. when a mod has been removed). Always check for
 existence before trying to access the fields.
 
 
 Note that in some cases you will stumble upon things that are not contained
 in these tables (e.g. when a mod has been removed). Always check for
 existence before trying to access the fields.
 
-Example: If you want to check the drawtype of a node, you could do:
+Example:
+
+All nodes register 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:
 
     local function get_nodedef_field(nodename, fieldname)
         if not minetest.registered_nodes[nodename] then
 
     local function get_nodedef_field(nodename, fieldname)
         if not minetest.registered_nodes[nodename] then
@@ -967,7 +948,8 @@ Node paramtypes
 The functions of `param1` and `param2` are determined by certain fields in the
 node definition.
 
 The functions of `param1` and `param2` are determined by certain fields in the
 node definition.
 
-`param1` is reserved for the engine when `paramtype != "none"`:
+The function of `param1` is determined by `paramtype` in node definition.
+`param1` is reserved for the engine when `paramtype != "none"`.
 
 * `paramtype = "light"`
     * The value stores light with and without sun in its upper and lower 4 bits
 
 * `paramtype = "light"`
     * The value stores light with and without sun in its upper and lower 4 bits
@@ -984,19 +966,27 @@ node definition.
         * mesh
         * plantlike
         * plantlike_rooted
         * mesh
         * plantlike
         * plantlike_rooted
-
-`param2` is reserved for the engine when any of these are used:
-
-* `liquidtype = "flowing"`
-    * The level and some flags of the liquid is stored in `param2`
-* `drawtype = "flowingliquid"`
-    * The drawn liquid level is read from `param2`
-* `drawtype = "torchlike"`
-* `drawtype = "signlike"`
+* `paramtype = "none"`
+    * `param1` will not be used by the engine and can be used to store
+      an arbitrary value
+
+The function of `param2` is determined by `paramtype2` in node definition.
+`param2` is reserved for the engine when `paramtype2 != "none"`.
+
+* `paramtype2 = "flowingliquid"`
+    * Used by `drawtype = "flowingliquid"` and `liquidtype = "flowing"`
+    * The liquid level and a flag of the liquid are stored in `param2`
+    * Bits 0-2: Liquid level (0-7). The higher, the more liquid is in this node
+    * Bit 3: If set, liquid is flowing downwards (no graphical effect)
 * `paramtype2 = "wallmounted"`
 * `paramtype2 = "wallmounted"`
-    * The rotation of the node is stored in `param2`. You can make this value
-      by using `minetest.dir_to_wallmounted()`.
+    * Supported drawtypes: "torchlike", "signlike", "normal", "nodebox", "mesh"
+    * The rotation of the node is stored in `param2`
+    * 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-
 * `paramtype2 = "facedir"`
 * `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()`.
     * Values range 0 - 23
     * 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()`.
     * Values range 0 - 23
@@ -1015,13 +1005,13 @@ node definition.
             * The height of the 'plantlike' section is stored in `param2`.
             * The height is (`param2` / 16) nodes.
 * `paramtype2 = "degrotate"`
             * The height of the 'plantlike' section is stored in `param2`.
             * The height is (`param2` / 16) nodes.
 * `paramtype2 = "degrotate"`
-    * Only valid for "plantlike". The rotation of the node is stored in
+    * Only valid for "plantlike" drawtype. The rotation of the node is stored in
       `param2`.
     * Values range 0 - 179. The value stored in `param2` is multiplied by two to
       get the actual rotation in degrees of the node.
 * `paramtype2 = "meshoptions"`
       `param2`.
     * Values range 0 - 179. The value stored in `param2` is multiplied by two to
       get the actual rotation in degrees of the node.
 * `paramtype2 = "meshoptions"`
-    * Only valid for "plantlike". The value of `param2` becomes a bitfield which
-      can be used to change how the client draws plantlike nodes.
+    * Only valid for "plantlike" drawtype. The value of `param2` becomes a
+      bitfield which can be used to change how the client draws plantlike nodes.
     * Bits 0, 1 and 2 form a mesh selector.
       Currently the following meshes are choosable:
         * 0 = a "x" shaped plant (ordinary plant)
     * Bits 0, 1 and 2 form a mesh selector.
       Currently the following meshes are choosable:
         * 0 = a "x" shaped plant (ordinary plant)
@@ -1053,6 +1043,9 @@ node definition.
     * `param2` values 0-63 define 64 levels of internal liquid, 0 being empty
       and 63 being full.
     * Liquid texture is defined using `special_tiles = {"modname_tilename.png"}`
     * `param2` values 0-63 define 64 levels of internal liquid, 0 being empty
       and 63 being full.
     * Liquid texture is defined using `special_tiles = {"modname_tilename.png"}`
+* `paramtype2 = "none"`
+    * `param2` will not be used by the engine and can be used to store
+      an arbitrary value
 
 Nodes can also contain extra data. See [Node Metadata].
 
 
 Nodes can also contain extra data. See [Node Metadata].
 
@@ -1077,16 +1070,11 @@ Look for examples in `games/minimal` or `games/minetest_game`.
 * `glasslike_framed`
     * All face-connected nodes are drawn as one volume within a surrounding
       frame.
 * `glasslike_framed`
     * All face-connected nodes are drawn as one volume within a surrounding
       frame.
-    * The frame appearence is generated from the edges of the first texture
+    * The frame appearance is generated from the edges of the first texture
       specified in `tiles`. The width of the edges used are 1/16th of texture
       size: 1 pixel for 16x16, 2 pixels for 32x32 etc.
     * The glass 'shine' (or other desired detail) on each node face is supplied
       by the second texture specified in `tiles`.
       specified in `tiles`. The width of the edges used are 1/16th of texture
       size: 1 pixel for 16x16, 2 pixels for 32x32 etc.
     * The glass 'shine' (or other desired detail) on each node face is supplied
       by the second texture specified in `tiles`.
-    * If a third texture is specified in `tiles` it will be used for the top and
-      base of the glass volume.
-    * If third and fourth textures are specified in `tiles`, the third will be
-      used for the top of the glass volume and the fourth will be used for the
-      base of the glass volume.
 * `glasslike_framed_optional`
     * This switches between the above 2 drawtypes according to the menu setting
       'Connected Glass'.
 * `glasslike_framed_optional`
     * This switches between the above 2 drawtypes according to the menu setting
       'Connected Glass'.
@@ -1220,6 +1208,64 @@ A box of a regular node would look like:
 
 
 
 
 
 
+Map terminology and coordinates
+===============================
+
+Nodes, mapblocks, mapchunks
+---------------------------
+
+A 'node' is the fundamental cubic unit of a world and appears to a player as
+roughly 1x1x1 meters in size.
+
+A 'mapblock' (often abbreviated to 'block') is 16x16x16 nodes and is the
+fundamental region of a world that is stored in the world database, sent to
+clients and handled by many parts of the engine.
+'mapblock' is preferred terminology to 'block' to help avoid confusion with
+'node', however 'block' often appears in the API.
+
+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.
+
+Coordinates
+-----------
+
+### Orientation of axes
+
+For node and mapblock coordinates, +X is East, +Y is up, +Z is North.
+
+### Node coordinates
+
+Almost all positions used in the API use node coordinates.
+
+### Mapblock coordinates
+
+Occasionally the API uses 'blockpos' which refers to mapblock coordinates that
+specify a particular mapblock.
+For example blockpos (0,0,0) specifies the mapblock that extends from
+node position (0,0,0) to node position (15,15,15).
+
+#### Converting node position to the containing blockpos
+
+To calculate the blockpos of the mapblock that contains the node at 'nodepos',
+for each axis:
+
+* blockpos = math.floor(nodepos / 16)
+
+#### Converting blockpos to min/max node positions
+
+To calculate the min/max node positions contained in the mapblock at 'blockpos',
+for each axis:
+
+* Minimum:
+  nodepos = blockpos * 16
+* Maximum:
+  nodepos = blockpos * 16 + 15
+
+
+
+
 HUD
 ===
 
 HUD
 ===
 
@@ -1238,9 +1284,10 @@ is drawn.
 `0` draws from left to right, `1` draws from right to left, `2` draws from
 top to bottom, and `3` draws from bottom to top.
 
 `0` draws from left to right, `1` draws from right to left, `2` draws from
 top to bottom, and `3` draws from bottom to top.
 
-The `alignment` field specifies how the item will be aligned. It ranges from
-`-1` to `1`, with `0` being the center. `-1` is moved to the left/up, and `1`
-is to the right/down. Fractional values can be used.
+The `alignment` field specifies how the item will be aligned. It is a table
+where `x` and `y` range from `-1` to `1`, with `0` being central. `-1` is
+moved to the left/up, and `1` is to the right/down. Fractional values can be
+used.
 
 The `offset` field specifies a pixel offset from the position. Contrary to
 position, the offset is not scaled to screen size. This allows for some
 
 The `offset` field specifies a pixel offset from the position. Contrary to
 position, the offset is not scaled to screen size. This allows for some
@@ -1249,10 +1296,16 @@ precisely positioned items in the HUD.
 **Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling
 factor!
 
 **Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling
 factor!
 
+The `z_index` field specifies the order of HUD elements from back to front.
+Lower z-index elements are displayed behind higher z-index elements. Elements
+with same z-index are displayed in an arbitrary order. Default 0.
+Supports negative values.
+
 Below are the specific uses for fields in each type; fields not listed for that
 type are ignored.
 
 ### `image`
 Below are the specific uses for fields in each type; fields not listed for that
 type are ignored.
 
 ### `image`
+
 Displays an image on the HUD.
 
 * `scale`: The scale of the image, with 1 being the original texture size.
 Displays an image on the HUD.
 
 * `scale`: The scale of the image, with 1 being the original texture size.
@@ -1323,9 +1376,13 @@ For helper functions see [Spatial Vectors].
 
 * `{type="nothing"}`
 * `{type="node", under=pos, above=pos}`
 
 * `{type="nothing"}`
 * `{type="node", under=pos, above=pos}`
+    * Indicates a pointed node selection box.
+    * `under` refers to the node position behind the pointed face.
+    * `above` refers to the node position in front of the pointed face.
 * `{type="object", ref=ObjectRef}`
 
 Exact pointing location (currently only `Raycast` supports these fields):
 * `{type="object", ref=ObjectRef}`
 
 Exact pointing location (currently only `Raycast` supports these fields):
+
 * `pointed_thing.intersection_point`: The absolute world coordinates of the
   point on the selection box which is pointed at. May be in the selection box
   if the pointer is in the box too.
 * `pointed_thing.intersection_point`: The absolute world coordinates of the
   point on the selection box which is pointed at. May be in the selection box
   if the pointer is in the box too.
@@ -1460,7 +1517,8 @@ Usage
 -----
 
 Groups are stored in a table, having the group names with keys and the
 -----
 
 Groups are stored in a table, having the group names with keys and the
-group ratings as values. For example:
+group ratings as values. Group ratings are integer values within the
+range [-32767, 32767]. For example:
 
     -- Default dirt
     groups = {crumbly=3, soil=1}
 
     -- Default dirt
     groups = {crumbly=3, soil=1}
@@ -1531,35 +1589,59 @@ Another example: Make red wool from white wool and red dye:
 Special groups
 --------------
 
 Special groups
 --------------
 
-* `immortal`: Disables the group damage system for an entity
-* `punch_operable`: For entities; disables the regular damage mechanism for
-  players punching it by hand or a non-tool item, so that it can do something
-  else than take damage.
-* `level`: Can be used to give an additional sense of progression in the game.
-     * A larger level will cause e.g. a weapon of a lower level make much less
-       damage, and get worn out much faster, or not be able to get drops
-       from destroyed nodes.
-     * `0` is something that is directly accessible at the start of gameplay
-     * There is no upper limit
+The asterisk `(*)` after a group name describes that there is no engine
+functionality bound to it, and implementation is left up as a suggestion
+to games.
+
+### Node, item and tool groups
+
+* `not_in_creative_inventory`: (*) Special group for inventory mods to indicate
+  that the item should be hidden in item lists.
+
+
+### 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
+* `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
     * `2`: the node always gets the digging time 0.5 seconds (rail, sign)
     * `3`: the node always gets the digging time 0 seconds (torch)
 * `disable_jump`: Player (and possibly other things) cannot jump from node
 * `fall_damage_add_percent`: damage speed = `speed * (1 + value/100)`
 * `dig_immediate`: Player can always pick up node without reducing tool wear
     * `2`: the node always gets the digging time 0.5 seconds (rail, sign)
     * `3`: the node always gets the digging time 0 seconds (torch)
 * `disable_jump`: Player (and possibly other things) cannot jump from node
 * `fall_damage_add_percent`: damage speed = `speed * (1 + value/100)`
-* `bouncy`: value is bounce speed in percent
 * `falling_node`: if there is no walkable block under the node it will fall
 * `falling_node`: if there is no walkable block under the node it will fall
-* `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.
-* `soil`: saplings will grow on nodes in this group
-* `connect_to_raillike`: makes nodes of raillike drawtype with same group value
-  connect to each other
+* `float`: the node will not fall through liquids
+* `level`: Can be used to give an additional sense of progression in the game.
+     * A larger level will cause e.g. a weapon of a lower level make much less
+       damage, and get worn out much faster, or not be able to get drops
+       from destroyed nodes.
+     * `0` is something that is directly accessible at the start of gameplay
+     * There is no upper limit
+     * See also: `leveldiff` in [Tools]
 * `slippery`: Players and items will slide on the node.
   Slipperiness rises steadily with `slippery` value, starting at 1.
 * `slippery`: Players and items will slide on the node.
   Slipperiness rises steadily with `slippery` value, starting at 1.
+
+
+### Tool-only groups
+
 * `disable_repair`: If set to 1 for a tool, it cannot be repaired using the
   `"toolrepair"` crafting recipe
 
 
 * `disable_repair`: If set to 1 for a tool, it cannot be repaired using the
   `"toolrepair"` crafting recipe
 
 
+### `ObjectRef` groups
+
+* `immortal`: Skips all damage and breath handling for an object. This group
+  will also hide the integrated HUD status bars for players, and is
+  automatically set to all players when damage is disabled on the server.
+* `punch_operable`: For entities; disables the regular damage mechanism for
+  players punching it by hand or a non-tool item, so that it can do something
+  else than take damage.
+
+
+
 Known damage and digging time defining groups
 ---------------------------------------------
 
 Known damage and digging time defining groups
 ---------------------------------------------
 
@@ -1649,6 +1731,8 @@ to implement this.
 Determines how many uses the tool has when it is used for digging a node,
 of this group, of the maximum level. For lower leveled nodes, the use count
 is multiplied by `3^leveldiff`.
 Determines how many uses the tool has when it is used for digging a node,
 of this group, of the maximum level. For lower leveled nodes, the use count
 is multiplied by `3^leveldiff`.
+`leveldiff` is the difference of the tool's `maxlevel` `groupcaps` and the
+node's `level` group. The node cannot be dug if `leveldiff` is less than zero.
 
 * `uses=10, leveldiff=0`: actual uses: 10
 * `uses=10, leveldiff=1`: actual uses: 30
 
 * `uses=10, leveldiff=0`: actual uses: 10
 * `uses=10, leveldiff=1`: actual uses: 30
@@ -1851,22 +1935,46 @@ Example:
 Formspec
 ========
 
 Formspec
 ========
 
-Formspec defines a menu. Currently not much else than inventories are
-supported. It is a string, with a somewhat strange format.
+Formspec defines a menu. This supports inventories and some of the
+typical widgets like buttons, checkboxes, text input fields, etc.
+It is a string, with a somewhat strange format.
+
+A formspec is made out of formspec elements, which includes widgets
+like buttons but also can be used to set stuff like background color.
+
+Many formspec elements have a `name`, which is a unique identifier which
+is used when the server receives user input. You must not use the name
+"quit" for formspec elements.
 
 Spaces and newlines can be inserted between the blocks, as is used in the
 examples.
 
 
 Spaces and newlines can be inserted between the blocks, as is used in the
 examples.
 
-Position and size units are inventory slots, `X` and `Y` position the formspec
-element relative to the top left of the menu or container. `W` and `H` are its
-width and height values.
+Position and size units are inventory slots unless the new coordinate system
+is enabled. `X` and `Y` position the formspec element relative to the top left
+of the menu or container. `W` and `H` are its width and height values.
+
+If the new system is enabled, all elements have unified coordinates for all
+elements with no padding or spacing in between. This is highly recommended
+for new forms. See `real_coordinates[<bool>]` and `Migrating to Real
+Coordinates`.
+
+Inventories with a `player:<name>` inventory location are only sent to the
+player named `<name>`.
+
 When displaying text which can contain formspec code, e.g. text set by a player,
 use `minetest.formspec_escape`.
 For coloured text you can use `minetest.colorize`.
 
 When displaying text which can contain formspec code, e.g. text set by a player,
 use `minetest.formspec_escape`.
 For coloured text you can use `minetest.colorize`.
 
-WARNING: Minetest allows you to add elements to every single formspec instance
+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
+reserved to pass key press events to formspec!
+
+**WARNING**: Minetest allows you to add elements to every single formspec instance
 using `player:set_formspec_prepend()`, which may be the reason backgrounds are
 using `player:set_formspec_prepend()`, which may be the reason backgrounds are
-appearing when you don't expect them to. See [`no_prepend[]`].
+appearing when you don't expect them to, or why things are styled differently
+to normal. See [`no_prepend[]`] and [Styling Formspecs].
 
 Examples
 --------
 
 Examples
 --------
@@ -1896,6 +2004,15 @@ Examples
 Elements
 --------
 
 Elements
 --------
 
+### `formspec_version[<version>]`
+
+* Set the formspec version to a certain number. If not specified,
+  version 1 is assumed.
+* Must be specified before `size` element.
+* Clients older than this version can neither show newer elements nor display
+  elements with new arguments correctly.
+* Available since feature `formspec_version_element`.
+
 ### `size[<W>,<H>,<fixed_size>]`
 
 * Define the size of the menu in inventory slots
 ### `size[<W>,<H>,<fixed_size>]`
 
 * Define the size of the menu in inventory slots
@@ -1930,6 +2047,17 @@ Elements
 * Must be used after the `size`, `position`, and `anchor` elements (if present).
 * Disables player:set_formspec_prepend() from applying to this formspec.
 
 * Must be used after the `size`, `position`, and `anchor` elements (if present).
 * Disables player:set_formspec_prepend() from applying to this formspec.
 
+### `real_coordinates[<bool>]`
+
+* INFORMATION: Enable it automatically using `formspec_version` version 2 or newer.
+* When set to true, all following formspec elements will use the new coordinate system.
+* If used immediately after `size`, `position`, `anchor`, and `no_prepend` elements
+  (if present), the form size will use the new coordinate system.
+* **Note**: Formspec prepends are not affected by the coordinates in the main form.
+  They must enable it explicitly.
+* For information on converting forms to the new coordinate system, see `Migrating
+  to Real Coordinates`.
+
 ### `container[<X>,<Y>]`
 
 * Start of a container block, moves all physical elements in the container by
 ### `container[<X>,<Y>]`
 
 * Start of a container block, moves all physical elements in the container by
@@ -1945,11 +2073,17 @@ Elements
 
 ### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]`
 
 
 ### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]`
 
-* Show an inventory list
+* Show an inventory list if it has been sent to the client. Nothing will
+  be shown if the inventory list is of size 0.
+* **Note**: With the new coordinate system, the spacing between inventory
+  slots is one-fourth the size of an inventory slot.
 
 ### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
 
 
 ### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
 
-* Show an inventory list
+* Show an inventory list if it has been sent to the client. Nothing will
+  be shown if the inventory list is of size 0.
+* **Note**: With the new coordinate system, the spacing between inventory
+  slots is one-fourth the size of an inventory slot.
 
 ### `listring[<inventory location>;<list name>]`
 
 
 ### `listring[<inventory location>;<list name>]`
 
@@ -1990,6 +2124,7 @@ Elements
 * `<fontcolor>` tooltip font color as `ColorString` (optional)
 
 ### `tooltip[<X>,<Y>;<W>,<H>;<tooltip_text>;<bgcolor>;<fontcolor>]`
 * `<fontcolor>` tooltip font color as `ColorString` (optional)
 
 ### `tooltip[<X>,<Y>;<W>,<H>;<tooltip_text>;<bgcolor>;<fontcolor>]`
+
 * Adds tooltip for an area. Other tooltips will take priority when present.
 * `<bgcolor>` tooltip background color as `ColorString` (optional)
 * `<fontcolor>` tooltip font color as `ColorString` (optional)
 * Adds tooltip for an area. Other tooltips will take priority when present.
 * `<bgcolor>` tooltip background color as `ColorString` (optional)
 * `<fontcolor>` tooltip font color as `ColorString` (optional)
@@ -1998,36 +2133,68 @@ Elements
 
 * Show an image
 
 
 * Show an image
 
+### `animated_image[<X>,<Y>;<W>,<H>;<texture name>:<frame count>,<frame duration>]`
+
+* Show an animated image. The image is drawn like a "vertical_frames" tile
+    animation (See Tile animation definition), but uses a frame count/duration
+    for simplicity
+* `<texture name>` is the image to use
+* `<frame count>` is the number of frames animating the image
+* `<frame duration>` is in milliseconds
+
 ### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
 
 * Show an inventory image of registered item/node
 
 ### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
 
 * Show an inventory image of registered item/node
 
-### `bgcolor[<color>;<fullscreen>]`
+### `bgcolor[<bgcolor>;<fullscreen>;<fbgcolor>]`
 
 
-* Sets background color of formspec as `ColorString`
-* If `true`, the background color is drawn fullscreen (does not affect the size
-  of the formspec).
+* Sets background color of formspec.
+* `bgcolor` and `fbgcolor` (optional) are `ColorString`s, they define the color
+  of the non-fullscreen and the fullscreen background.
+* `fullscreen` (optional) can be one of the following:
+  * `false`: Only the non-fullscreen background color is drawn. (default)
+  * `true`: Only the fullscreen background color is drawn.
+  * `both`: The non-fullscreen and the fullscreen background color are drawn.
+  * `neither`: No background color is drawn.
+* Note: Leave a parameter empty to not modify the value.
+* Note: `fbgcolor`, leaving parameters empty and values for `fullscreen` that
+  are not bools are only available since formspec version 3.
 
 ### `background[<X>,<Y>;<W>,<H>;<texture name>]`
 
 
 ### `background[<X>,<Y>;<W>,<H>;<texture name>]`
 
-* Use a background. Inventory rectangles are not drawn then.
 * Example for formspec 8x4 in 16x resolution: image shall be sized
   8 times 16px  times  4 times 16px.
 
 ### `background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]`
 
 * Example for formspec 8x4 in 16x resolution: image shall be sized
   8 times 16px  times  4 times 16px.
 
 ### `background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]`
 
-* Use a background. Inventory rectangles are not drawn then.
 * Example for formspec 8x4 in 16x resolution:
   image shall be sized 8 times 16px  times  4 times 16px
 * If `auto_clip` is `true`, the background is clipped to the formspec size
   (`x` and `y` are used as offset values, `w` and `h` are ignored)
 
 * Example for formspec 8x4 in 16x resolution:
   image shall be sized 8 times 16px  times  4 times 16px
 * If `auto_clip` is `true`, the background is clipped to the formspec size
   (`x` and `y` are used as offset values, `w` and `h` are ignored)
 
+### `background9[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>;<middle>]`
+
+* 9-sliced background. See https://en.wikipedia.org/wiki/9-slice_scaling
+* Middle is a rect which defines the middle of the 9-slice.
+       * `x` - The middle will be x pixels from all sides.
+       * `x,y` - The middle will be x pixels from the horizontal and y from the vertical.
+       * `x,y,x2,y2` - The middle will start at x,y, and end at x2, y2. Negative x2 and y2 values
+               will be added to the width and height of the texture, allowing it to be used as the
+               distance from the far end.
+       * All numbers in middle are integers.
+* Example for formspec 8x4 in 16x resolution:
+  image shall be sized 8 times 16px  times  4 times 16px
+* If `auto_clip` is `true`, the background is clipped to the formspec size
+  (`x` and `y` are used as offset values, `w` and `h` are ignored)
+* Available since formspec version 2
+
 ### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]`
 
 * Textual password style field; will be sent to server when a button is clicked
 * When enter is pressed in field, fields.key_enter_field will be sent with the
   name of this field.
 ### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]`
 
 * Textual password style field; will be sent to server when a button is clicked
 * When enter is pressed in field, fields.key_enter_field will be sent with the
   name of this field.
-* Fields are a set height, but will be vertically centred on `H`
+* 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.
 * `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
 * `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
@@ -2037,7 +2204,8 @@ Elements
 * Textual field; will be sent to server when a button is clicked
 * When enter is pressed in field, `fields.key_enter_field` will be sent with
   the name of this field.
 * Textual field; will be sent to server when a button is clicked
 * When enter is pressed in field, `fields.key_enter_field` will be sent with
   the name of this field.
-* Fields are a set height, but will be vertically centred on `H`
+* 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.
 * `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
 * `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
@@ -2074,23 +2242,39 @@ Elements
 
 * The label formspec element displays the text set in `label`
   at the specified position.
 
 * The label formspec element displays the text set in `label`
   at the specified position.
+* **Note**: If the new coordinate system is enabled, labels are
+  positioned from the center of the text, not the top.
 * The text is displayed directly without automatic line breaking,
 * The text is displayed directly without automatic line breaking,
-  so label should not be used for big text chunks.
+  so label should not be used for big text chunks.  Newlines can be
+  used to make labels multiline.
+* **Note**: With the new coordinate system, newlines are spaced with
+  half a coordinate.  With the old system, newlines are spaced 2/5 of
+  an inventory slot.
+
+### `hypertext[<X>,<Y>;<W>,<H>;<name>;<text>]`
+* Displays a static formated text with hyperlinks.
+* `x`, `y`, `w` and `h` work as per field
+* `name` is the name of the field as returned in fields to `on_receive_fields` in case of action in text.
+* `text` is the formatted text using `markup language` described below.
 
 ### `vertlabel[<X>,<Y>;<label>]`
 
 ### `vertlabel[<X>,<Y>;<label>]`
-
 * Textual label drawn vertically
 * `label` is the text on the label
 * Textual label drawn vertically
 * `label` is the text on the label
+* **Note**: If the new coordinate system is enabled, vertlabels are
+  positioned from the center of the text, not the left.
 
 ### `button[<X>,<Y>;<W>,<H>;<name>;<label>]`
 
 * Clickable button. When clicked, fields will be sent.
 
 ### `button[<X>,<Y>;<W>,<H>;<name>;<label>]`
 
 * Clickable button. When clicked, fields will be sent.
-* Fixed button height. It will be vertically centred on `H`
+* 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.
 * `label` is the text on the button
 
 ### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
 
 * `texture name` is the filename of an image
 * `label` is the text on the button
 
 ### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
 
 * `texture name` is the filename of an image
+* **Note**: Height is supported on both the old and new coordinate systems
+  for image_buttons.
 
 ### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]`
 
 
 ### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]`
 
@@ -2102,17 +2286,19 @@ Elements
 
 ### `item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]`
 
 
 ### `item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]`
 
-* `item name` is the registered name of an item/node,
-  tooltip will be made out of its description
-  to override it use tooltip element
+* `item name` is the registered name of an item/node
+* The item description will be used as the tooltip. This can be overridden with
+  a tooltip element.
 
 ### `button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]`
 
 * When clicked, fields will be sent and the form will quit.
 
 ### `button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]`
 
 * When clicked, fields will be sent and the form will quit.
+* Same as `button` in all other respects.
 
 ### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
 
 * When clicked, fields will be sent and the form will quit.
 
 ### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
 
 * When clicked, fields will be sent and the form will quit.
+* Same as `image_button` in all other respects.
 
 ### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]`
 
 
 ### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]`
 
@@ -2138,6 +2324,34 @@ Elements
 ### `tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]`
 
 * Show a tab**header** at specific position (ignores formsize)
 ### `tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]`
 
 * Show a tab**header** at specific position (ignores formsize)
+* `X` and `Y`: position of the tabheader
+* *Note*: Width and height are automatically chosen with this syntax
+* `name` fieldname data is transferred to Lua
+* `caption 1`...: name shown on top of tab
+* `current_tab`: index of selected tab 1...
+* `transparent` (optional): show transparent
+* `draw_border` (optional): draw border
+
+### `tabheader[<X>,<Y>;<H>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]`
+
+* Show a tab**header** at specific position (ignores formsize)
+* **Important note**: This syntax for tabheaders can only be used with the
+  new coordinate system.
+* `X` and `Y`: position of the tabheader
+* `H`: height of the tabheader. Width is automatically determined with this syntax.
+* `name` fieldname data is transferred to Lua
+* `caption 1`...: name shown on top of tab
+* `current_tab`: index of selected tab 1...
+* `transparent` (optional): show transparent
+* `draw_border` (optional): draw border
+
+### `tabheader[<X>,<Y>;<W>,<H>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]`
+
+* Show a tab**header** at specific position (ignores formsize)
+* **Important note**: This syntax for tabheaders can only be used with the
+  new coordinate system.
+* `X` and `Y`: position of the tabheader
+* `W` and `H`: width and height of the tabheader
 * `name` fieldname data is transferred to Lua
 * `caption 1`...: name shown on top of tab
 * `current_tab`: index of selected tab 1...
 * `name` fieldname data is transferred to Lua
 * `caption 1`...: name shown on top of tab
 * `current_tab`: index of selected tab 1...
@@ -2156,8 +2370,22 @@ Elements
 * **Important note**: There are two different operation modes:
     1. handle directly on change (only changed dropdown is submitted)
     2. read the value on pressing a button (all dropdown values are available)
 * **Important note**: There are two different operation modes:
     1. handle directly on change (only changed dropdown is submitted)
     2. read the value on pressing a button (all dropdown values are available)
-* `x` and `y` position of dropdown
-* Width of dropdown
+* `X` and `Y`: position of the dropdown
+* `W`: width of the dropdown. Height is automatically chosen with this syntax.
+* Fieldname data is transferred to Lua
+* Items to be shown in dropdown
+* Index of currently selected dropdown item
+
+### `dropdown[<X>,<Y>;<W>,<H>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]`
+
+* Show a dropdown field
+* **Important note**: This syntax for dropdowns can only be used with the
+  new coordinate system.
+* **Important note**: There are two different operation modes:
+    1. handle directly on change (only changed dropdown is submitted)
+    2. read the value on pressing a button (all dropdown values are available)
+* `X` and `Y`: position of the dropdown
+* `W` and `H`: width and height of the dropdown
 * Fieldname data is transferred to Lua
 * Items to be shown in dropdown
 * Index of currently selected dropdown item
 * Fieldname data is transferred to Lua
 * Items to be shown in dropdown
 * Index of currently selected dropdown item
@@ -2168,19 +2396,45 @@ Elements
 * `name` fieldname data is transferred to Lua
 * `label` to be shown left of checkbox
 * `selected` (optional): `true`/`false`
 * `name` fieldname data is transferred to Lua
 * `label` to be shown left of checkbox
 * `selected` (optional): `true`/`false`
+* **Note**: If the new coordinate system is enabled, checkboxes are
+  positioned from the center of the checkbox, not the top.
 
 ### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]`
 
 
 ### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]`
 
-* Show a scrollbar
+* Show a scrollbar using options defined by the previous `scrollbaroptions[]`
 * There are two ways to use it:
     1. handle the changed event (only changed scrollbar is available)
     2. read the value on pressing a button (all scrollbars are available)
 * `orientation`:  `vertical`/`horizontal`
 * Fieldname data is transferred to Lua
 * There are two ways to use it:
     1. handle the changed event (only changed scrollbar is available)
     2. read the value on pressing a button (all scrollbars are available)
 * `orientation`:  `vertical`/`horizontal`
 * Fieldname data is transferred to Lua
-* Value this trackbar is set to (`0`-`1000`)
+* Value of this trackbar is set to (`0`-`1000`) by default
 * See also `minetest.explode_scrollbar_event`
   (main menu: `core.explode_scrollbar_event`).
 
 * See also `minetest.explode_scrollbar_event`
   (main menu: `core.explode_scrollbar_event`).
 
+### `scrollbaroptions[opt1;opt2;...]`
+* Sets options for all following `scrollbar[]` elements
+* `min=<int>`
+    * Sets scrollbar minimum value, defaults to `0`.
+* `max=<int>`
+    * Sets scrollbar maximum value, defaults to `1000`.
+      If the max is equal to the min, the scrollbar will be disabled.
+* `smallstep=<int>`
+    * Sets scrollbar step value when the arrows are clicked or the mouse wheel is
+      scrolled.
+    * If this is set to a negative number, the value will be reset to `10`.
+* `largestep=<int>`
+    * Sets scrollbar step value used by page up and page down.
+    * If this is set to a negative number, the value will be reset to `100`.
+* `thumbsize=<int>`
+    * Sets size of the thumb on the scrollbar. Size is calculated in the number of
+      units the thumb spans out of the range of the scrollbar values.
+    * Example: If a scrollbar has a `min` of 1 and a `max` of 100, a thumbsize of 10
+      would span a tenth of the scrollbar space.
+    * If this is set to zero or less, the value will be reset to `1`.
+* `arrows=<show/hide/default>`
+    * Whether to show the arrow buttons on the scrollbar. `default` hides the arrows
+      when the scrollbar gets too small, but shows them otherwise.
+
 ### `table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]`
 
 * Show scrollable table using options defined by the previous `tableoptions[]`
 ### `table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]`
 
 * Show scrollable table using options defined by the previous `tableoptions[]`
@@ -2241,11 +2495,249 @@ Elements
         * `span=<value>`: number of following columns to affect
           (default: infinite).
 
         * `span=<value>`: number of following columns to affect
           (default: infinite).
 
-**Note**: do _not_ use a element name starting with `key_`; those names are
-reserved to pass key press events to formspec!
+### `style[<name>;<prop1>;<prop2>;...]`
+
+* Set the style for the named element `name`.
+* Note: this **must** be before the element is defined.
+* See [Styling Formspecs].
+
+
+### `style_type[<type>;<prop1>;<prop2>;...]`
+
+* Sets the style for all elements of type `type` which appear after this element.
+* See [Styling Formspecs].
+
+Migrating to Real Coordinates
+-----------------------------
+
+In the old system, positions included padding and spacing. Padding is a gap between
+the formspec window edges and content, and spacing is the gaps between items. For
+example, two `1x1` elements at `0,0` and `1,1` would have a spacing of `5/4` between them,
+and a padding of `3/8` from the formspec edge. It may be easiest to recreate old layouts
+in the new coordinate system from scratch.
+
+To recreate an old layout with padding, you'll need to pass the positions and sizes
+through the following formula to re-introduce padding:
+
+```
+pos = (oldpos + 1)*spacing + padding
+where
+    padding = 3/8
+    spacing = 5/4
+```
+
+You'll need to change the `size[]` tag like this:
+
+```
+size = (oldsize-1)*spacing + padding*2 + 1
+```
+
+A few elements had random offsets in the old system. Here is a table which shows these
+offsets when migrating:
+
+| Element |  Position  |  Size   | Notes
+|---------|------------|---------|-------
+| box     | +0.3, +0.1 | 0, -0.4 |
+| button  |            |         | Buttons now support height, so set h = 2 * 15/13 * 0.35, and reposition if h ~= 15/13 * 0.35 before
+| list    |            |         | Spacing is now 0.25 for both directions, meaning lists will be taller in height
+| label   | 0, +0.3    |         | The first line of text is now positioned centered exactly at the position specified
+
+Styling Formspecs
+-----------------
+
+Formspec elements can be themed using the style elements:
+
+    style[<name>;<prop1>;<prop2>;...]
+    style_type[<type>;<prop1>;<prop2>;...]
+
+Where a prop is:
+
+    property_name=property_value
+
+For example:
+
+    style_type[button;bgcolor=#006699]
+    style[world_delete;bgcolor=red;textcolor=yellow]
+    button[4,3.95;2.6,1;world_delete;Delete]
+
+Setting a property to nothing will reset it to the default value. For example:
+
+    style_type[button;bgimg=button.png;bgimg_pressed=button_pressed.png;border=false]
+    style[btn_exit;bgimg=;bgimg_pressed=;border=;bgcolor=red]
+
+
+### Supported Element Types
+
+Some types may inherit styles from parent types.
+
+* button
+* button_exit, inherits from button
+* checkbox
+* scrollbar
+* table
+* textlist
+* dropdown
+* field
+* pwdfield, inherits from field
+* textarea
+* label
+* vertlabel, inherits from field
+* image_button
+* item_image_button
+* tabheader
+
+
+### Valid Properties
+
+* animated_image
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+* box
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+        * Default to false in formspec_version version 3 or higher
+* button, button_exit, image_button, item_image_button
+    * alpha - boolean, whether to draw alpha in bgimg. Default true.
+    * bgcolor - color, sets button tint.
+    * bgcolor_hovered - color when hovered. Defaults to a lighter bgcolor when not provided.
+    * bgcolor_pressed - color when pressed. Defaults to a darker bgcolor when not provided.
+    * bgimg - standard background image. Defaults to none.
+    * bgimg_hovered - background image when hovered. Defaults to bgimg when not provided.
+    * bgimg_middle - Makes the bgimg textures render in 9-sliced mode and defines the middle rect.
+                     See background9[] documentation for more details
+    * bgimg_pressed - background image when pressed. Defaults to bgimg when not provided.
+    * border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+    * textcolor - color, default white.
+* checkbox
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+* scrollbar
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+* table, textlist
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+* dropdown
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+* field, pwdfield, textarea
+    * border - set to false to hide the textbox background and border. Default true.
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+    * textcolor - color. Default white.
+* image
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+        * Default to false in formspec_version version 3 or higher
+* item_image
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds. Default to false.
+* label, vertlabel
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+* image_button (additional properties)
+    * fgimg - standard image. Defaults to none.
+    * fgimg_hovered - image when hovered. Defaults to fgimg when not provided.
+    * fgimg_pressed - image when pressed. Defaults to fgimg when not provided.
+    * NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed
+* tabheader
+    * noclip - boolean, set to true to allow the element to exceed formspec bounds.
+    * textcolor - color. Default white.
+
+Markup language
+---------------
+
+Markup language used in `hypertext[]` elements uses tag that look like HTML tags. Some
+tags can enclose text, they open with `<tagname>` and close with `</tagname>`.
+Tags can have attributes, in that case, attributes are in the opening tag in
+form of a key/value separated with equal signs. Attribute values should not be quoted.
+
+These are the technically basic tags but see below for usual tags. Base tags are:
+
+`<style color=... font=... size=...>...</style>`
+
+Changes the style of the text.
+
+* `color`: Text color. Given color is a `colorspec`.
+* `size`: Text size.
+* `font`: Text font (`mono` or `normal`).
+
+`<global background=... margin=... valign=... color=... hovercolor=... size=... font=... halign=... >`
+
+Sets global style.
+
+Global only styles:
+* `background`: Text background, a `colorspec` or `none`.
+* `margin`: Page margins in pixel.
+* `valign`: Text vertical alignment (`top`, `middle`, `bottom`).
+
+Inheriting styles (affects child elements):
+* `color`: Default text color. Given color is a `colorspec`.
+* `hovercolor`: Color of <action> tags when mouse is over.
+* `size`: Default text size.
+* `font`: Default text font (`mono` or `normal`).
+* `halign`: Default text horizontal alignment (`left`, `right`, `center`, `justify`).
+
+This tag needs to be placed only once as it changes the global settings of the
+text. Anyway, if several tags are placed, each changed will be made in the order
+tags appear.
+
+`<tag name=... color=... hovercolor=... font=... size=...>`
+
+Defines or redefines tag style. This can be used to define new tags.
+* `name`: Name of the tag to define or change.
+* `color`: Text color. Given color is a `colorspec`.
+* `hovercolor`: Text color when element hovered (only for `action` tags). Given color is a `colorspec`.
+* `size`: Text size.
+* `font`: Text font (`mono` or `normal`).
+
+Following tags are the usual tags for text layout. They are defined by default.
+Other tags can be added using `<tag ...>` tag.
+
+`<normal>...</normal>`: Normal size text
+
+`<big>...</big>`: Big text
+
+`<bigger>...</bigger>`: Bigger text
+
+`<center>...</center>`: Centered text
+
+`<left>...</left>`: Left-aligned text
+
+`<right>...</right>`: Right-aligned text
+
+`<justify>...</justify>`: Justified text
+
+`<mono>...</mono>`: Monospaced font
+
+`<b>...</b>`, `<i>...</i>`, `<u>...</u>`: Bold, italic, underline styles.
+
+`<action name=...>...</action>`
+
+Make that text a clickable text triggering an action.
 
 
+* `name`: Name of the action (mandatory).
 
 
+When clicked, the formspec is send to the server. The value of the text field
+sent to `on_player_receive_fields` will be "action:" concatenated to the action
+name.
 
 
+`<img name=... float=... width=... height=...>`
+
+Draws an image which is present in the client media cache.
+
+* `name`: Name of the texture (mandatory).
+* `float`: If present, makes the image floating (`left` or `right`).
+* `width`: Force image width instead of taking texture width.
+* `height`: Force image height instead of taking texture height.
+
+If only width or height given, texture aspect is kept.
+
+`<item name=... float=... width=... height=... rotate=...>`
+
+Draws an item image.
+
+* `name`: Item string of the item to draw (mandatory).
+* `float`: If present, makes the image floating (`left` or `right`).
+* `width`: Item image width.
+* `height`: Item image height.
+* `rotate`: Rotate item image if set to `yes` or `X,Y,Z`. X, Y and Z being
+rotation speeds in percent of standard speed (-1000 to 1000). Works only if
+`inventory_items_animations` is set to true.
+* `angle`: Angle in which the item image is shown. Value has `X,Y,Z` form.
+X, Y and Z being angles around each three axes. Works only if
+`inventory_items_animations` is set to true.
 
 Inventory
 =========
 
 Inventory
 =========
@@ -2268,9 +2760,7 @@ Player Inventory lists
 * `craftresult`: list containing the crafted output
 * `hand`: list containing an override for the empty hand
     * Is not created automatically, use `InvRef:set_size`
 * `craftresult`: list containing the crafted output
 * `hand`: list containing an override for the empty hand
     * Is not created automatically, use `InvRef:set_size`
-
-
-
+    * Is only used to enhance the empty hand's tool capabilities
 
 Colors
 ======
 
 Colors
 ======
@@ -2339,6 +2829,12 @@ The following functions provide escape sequences:
 
 Spatial Vectors
 ===============
 
 Spatial Vectors
 ===============
+A spatial vector is similar to a position, but instead using
+absolute world coordinates, it uses *relative* coordinates, relative to
+no particular point.
+
+Internally, it is implemented as a table with the 3 fields
+`x`, `y` and `z`. Example: `{x = 0, y = 1, z = 0}`.
 
 For the following functions, `v`, `v1`, `v2` are vectors,
 `p1`, `p2` are positions:
 
 For the following functions, `v`, `v1`, `v2` are vectors,
 `p1`, `p2` are positions:
@@ -2368,13 +2864,23 @@ For the following functions, `v`, `v1`, `v2` are vectors,
     * Returns a boolean, `true` if the vectors are identical.
 * `vector.sort(v1, v2)`:
     * Returns in order minp, maxp vectors of the cuboid defined by `v1`, `v2`.
     * Returns a boolean, `true` if the vectors are identical.
 * `vector.sort(v1, v2)`:
     * Returns in order minp, maxp vectors of the cuboid defined by `v1`, `v2`.
+* `vector.angle(v1, v2)`:
+    * Returns the angle between `v1` and `v2` in radians.
+* `vector.dot(v1, v2)`
+    * Returns the dot product of `v1` and `v2`
+* `vector.cross(v1, v2)`
+    * Returns the cross product of `v1` and `v2`
 
 For the following functions `x` can be either a vector or a number:
 
 * `vector.add(v, x)`:
     * Returns a vector.
 
 For the following functions `x` can be either a vector or a number:
 
 * `vector.add(v, x)`:
     * Returns a vector.
+    * If `x` is a vector: Returns the sum of `v` and `x`.
+    * If `x` is a number: Adds `x` to each component of `v`.
 * `vector.subtract(v, x)`:
     * Returns a vector.
 * `vector.subtract(v, x)`:
     * Returns a vector.
+    * If `x` is a vector: Returns the difference of `v` subtracted by `x`.
+    * If `x` is a number: Subtracts `x` from each component of `v`.
 * `vector.multiply(v, x)`:
     * Returns a scaled vector or Schur product.
 * `vector.divide(v, x)`:
 * `vector.multiply(v, x)`:
     * Returns a scaled vector or Schur product.
 * `vector.divide(v, x)`:
@@ -2402,6 +2908,7 @@ Helper functions
     * tolerance: number, default: `0.0`
     * If the absolute value of `x` is within the `tolerance` or `x` is NaN,
       `0` is returned.
     * tolerance: number, default: `0.0`
     * If the absolute value of `x` is within the `tolerance` or `x` is NaN,
       `0` is returned.
+* `math.factorial(x)`: returns the factorial of `x`
 * `string.split(str, separator, include_empty, max_splits, sep_is_pattern)`
     * `separator`: string, default: `","`
     * `include_empty`: boolean, default: `false`
 * `string.split(str, separator, include_empty, max_splits, sep_is_pattern)`
     * `separator`: string, default: `","`
     * `include_empty`: boolean, default: `false`
@@ -2441,12 +2948,44 @@ Helper functions
     * returns time with microsecond precision. May not return wall time.
 * `table.copy(table)`: returns a table
     * returns a deep copy of `table`
     * returns time with microsecond precision. May not return wall time.
 * `table.copy(table)`: returns a table
     * returns a deep copy of `table`
+* `table.indexof(list, val)`: returns the smallest numerical index containing
+      the value `val` in the table `list`. Non-numerical indices are ignored.
+      If `val` could not be found, `-1` is returned. `list` must not have
+      negative indices.
 * `table.insert_all(table, other_table)`:
     * Appends all values in `other_table` to `table` - uses `#table + 1` to
       find new indices.
 * `table.insert_all(table, other_table)`:
     * Appends all values in `other_table` to `table` - uses `#table + 1` to
       find new indices.
+* `table.key_value_swap(t)`: returns a table with keys and values swapped
+    * If multiple keys in `t` map to the same value, the result is undefined.
+* `table.shuffle(table, [from], [to], [random_func])`:
+    * Shuffles elements `from` to `to` in `table` in place
+    * `from` defaults to `1`
+    * `to` defaults to `#table`
+    * `random_func` defaults to `math.random`. This function receives two
+      integers as arguments and should return a random integer inclusively
+      between them.
 * `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a
   position.
     * returns the exact position on the surface of a pointed node
 * `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a
   position.
     * returns the exact position on the surface of a pointed node
+* `minetest.get_dig_params(groups, tool_capabilities)`: Simulates a tool
+    that digs a node.
+    Returns a table with the following fields:
+    * `diggable`: `true` if node can be dug, `false` otherwise.
+    * `time`: Time it would take to dig the node.
+    * `wear`: How much wear would be added to the tool.
+    `time` and `wear` are meaningless if node's not diggable
+    Parameters:
+    * `groups`: Table of the node groups of the node that would be dug
+    * `tool_capabilities`: Tool capabilities table of the tool
+* `minetest.get_hit_params(groups, tool_capabilities [, time_from_last_punch])`:
+    Simulates an item that punches an object.
+    Returns a table with the following fields:
+    * `hp`: How much damage the punch would cause.
+    * `wear`: How much wear would be added to the tool.
+    Parameters:
+    * `groups`: Damage groups of the object
+    * `tool_capabilities`: Tool capabilities table of the item
+    * `time_from_last_punch`: time in seconds since last punch action
 
 
 
 
 
 
@@ -3025,7 +3564,6 @@ to be a table retrieved from `get_data()`.
 Once the internal VoxelManip state has been modified to your liking, the
 changes can be committed back to the map by calling `VoxelManip:write_to_map()`
 
 Once the internal VoxelManip state has been modified to your liking, the
 changes can be committed back to the map by calling `VoxelManip:write_to_map()`
 
-
 ### Flat array format
 
 Let
 ### Flat array format
 
 Let
@@ -3193,7 +3731,8 @@ Methods
     * To be used only by a `VoxelManip` object from
       `minetest.get_mapgen_object`.
     * (`p1`, `p2`) is the area in which lighting is set, defaults to the whole
     * To be used only by a `VoxelManip` object from
       `minetest.get_mapgen_object`.
     * (`p1`, `p2`) is the area in which lighting is set, defaults to the whole
-      area if left out or nil.
+      area if left out or nil. For almost all uses these should be left out
+      or nil to use the default.
     * `propagate_shadow` is an optional boolean deciding whether shadows in a
       generated mapchunk above are propagated down into the mapchunk, defaults
       to `true` if left out.
     * `propagate_shadow` is an optional boolean deciding whether shadows in a
       generated mapchunk above are propagated down into the mapchunk, defaults
       to `true` if left out.
@@ -3207,7 +3746,7 @@ Methods
 -----------
 
 A helper class for voxel areas.
 -----------
 
 A helper class for voxel areas.
-It can be created via `VoxelArea:new{MinEdge=pmin, MaxEdge=pmax}`.
+It can be created via `VoxelArea:new{MinEdge = pmin, MaxEdge = pmax}`.
 The coordinates are *inclusive*, like most other things in Minetest.
 
 ### Methods
 The coordinates are *inclusive*, like most other things in Minetest.
 
 ### Methods
@@ -3238,6 +3777,28 @@ The coordinates are *inclusive*, like most other things in Minetest.
       `[z [y [x]]]`.
 * `iterp(minp, maxp)`: same as above, except takes a vector
 
       `[z [y [x]]]`.
 * `iterp(minp, maxp)`: same as above, except takes a vector
 
+### Y stride and z stride of a flat array
+
+For a particular position in a voxel area, whose flat array index is known,
+it is often useful to know the index of a neighboring or nearby position.
+The table below shows the changes of index required for 1 node movements along
+the axes in a voxel area:
+
+    Movement    Change of index
+    +x          +1
+    -x          -1
+    +y          +ystride
+    -y          -ystride
+    +z          +zstride
+    -z          -zstride
+
+If, for example:
+
+    local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
+
+The values of `ystride` and `zstride` can be obtained using `area.ystride` and
+`area.zstride`.
+
 
 
 
 
 
 
@@ -3299,7 +3860,7 @@ Possible fields of the table returned are:
 * `decoration`
 
 Decorations have a key in the format of `"decoration#id"`, where `id` is the
 * `decoration`
 
 Decorations have a key in the format of `"decoration#id"`, where `id` is the
-numeric unique decoration ID.
+numeric unique decoration ID as returned by `minetest.get_decoration_id`.
 
 
 
 
 
 
@@ -3323,7 +3884,7 @@ Callbacks:
     * Called on every server tick, after movement and collision processing.
       `dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting
       in `minetest.conf`.
     * Called on every server tick, after movement and collision processing.
       `dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting
       in `minetest.conf`.
-* `on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir)`
+* `on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)`
     * Called when somebody punches the object.
     * Note that you probably want to handle most punches using the automatic
       armor group system.
     * Called when somebody punches the object.
     * Note that you probably want to handle most punches using the automatic
       armor group system.
@@ -3333,6 +3894,7 @@ Callbacks:
     * `tool_capabilities`: capability table of used tool (can be `nil`)
     * `dir`: unit vector of direction of punch. Always defined. Points from the
       puncher to the punched.
     * `tool_capabilities`: capability table of used tool (can be `nil`)
     * `dir`: unit vector of direction of punch. Always defined. Points from the
       puncher to the punched.
+    * `damage`: damage that will be done to entity.
 * `on_death(self, killer)`
     * Called when the object dies.
     * `killer`: an `ObjectRef` (can be `nil`)
 * `on_death(self, killer)`
     * Called when the object dies.
     * `killer`: an `ObjectRef` (can be `nil`)
@@ -3448,28 +4010,36 @@ Utilities
 * `minetest.features`: Table containing API feature flags
 
       {
 * `minetest.features`: Table containing API feature flags
 
       {
-          glasslike_framed = true,
-          nodebox_as_selectionbox = true,
-          chat_send_player_param3 = true,
-          get_all_craft_recipes_works = true,
+          glasslike_framed = true,  -- 0.4.7
+          nodebox_as_selectionbox = true,  -- 0.4.7
+          get_all_craft_recipes_works = true,  -- 0.4.7
           -- The transparency channel of textures can optionally be used on
           -- The transparency channel of textures can optionally be used on
-          -- nodes
+          -- nodes (0.4.7)
           use_texture_alpha = true,
           use_texture_alpha = true,
-          -- Tree and grass ABMs are no longer done from C++
+          -- Tree and grass ABMs are no longer done from C++ (0.4.8)
           no_legacy_abms = true,
           no_legacy_abms = true,
-          -- Texture grouping is possible using parentheses
+          -- Texture grouping is possible using parentheses (0.4.11)
           texture_names_parens = true,
           texture_names_parens = true,
-          -- Unique Area ID for AreaStore:insert_area
+          -- Unique Area ID for AreaStore:insert_area (0.4.14)
           area_store_custom_ids = true,
           -- add_entity supports passing initial staticdata to on_activate
           area_store_custom_ids = true,
           -- add_entity supports passing initial staticdata to on_activate
+          -- (0.4.16)
           add_entity_with_staticdata = true,
           add_entity_with_staticdata = true,
-          -- Chat messages are no longer predicted
+          -- Chat messages are no longer predicted (0.4.16)
           no_chat_message_prediction = true,
           -- The transparency channel of textures can optionally be used on
           no_chat_message_prediction = true,
           -- The transparency channel of textures can optionally be used on
-          -- objects (ie: players and lua entities)
+          -- objects (ie: players and lua entities) (5.0.0)
           object_use_texture_alpha = true,
           -- Object selectionbox is settable independently from collisionbox
           object_use_texture_alpha = true,
           -- Object selectionbox is settable independently from collisionbox
+          -- (5.0.0)
           object_independent_selectionbox = true,
           object_independent_selectionbox = true,
+          -- Specifies whether binary data can be uploaded or downloaded using
+          -- the HTTP API (5.1.0)
+          httpfetch_binary_data = true,
+          -- Whether formspec_version[<version>] may be used (5.1.0)
+          formspec_version_element = true,
+          -- Whether AreaStore's IDs are kept on save/load (5.1.0)
+          area_store_persistent_ids = true,
       }
 
 * `minetest.has_feature(arg)`: returns `boolean, missing_features`
       }
 
 * `minetest.has_feature(arg)`: returns `boolean, missing_features`
@@ -3489,6 +4059,7 @@ Utilities
           avg_jitter = 0.03,         -- average packet time jitter
           connection_uptime = 200,   -- seconds since client connected
           protocol_version = 32,     -- protocol version used by client
           avg_jitter = 0.03,         -- average packet time jitter
           connection_uptime = 200,   -- seconds since client connected
           protocol_version = 32,     -- protocol version used by client
+          formspec_version = 2,      -- supported formspec version
           -- following information is available on debug build only!!!
           -- DO NOT USE IN MODS
           --ser_vers = 26,             -- serialization version used by client
           -- following information is available on debug build only!!!
           -- DO NOT USE IN MODS
           --ser_vers = 26,             -- serialization version used by client
@@ -3541,17 +4112,68 @@ Registration functions
 
 Call these functions only at load time!
 
 
 Call these functions only at load time!
 
-* `minetest.register_entity(name, entity definition)`
-* `minetest.register_abm(abm definition)`
-* `minetest.register_lbm(lbm definition)`
+### Environment
+
 * `minetest.register_node(name, node definition)`
 * `minetest.register_node(name, node definition)`
-* `minetest.register_tool(name, item definition)`
 * `minetest.register_craftitem(name, item definition)`
 * `minetest.register_craftitem(name, item definition)`
+* `minetest.register_tool(name, item definition)`
+* `minetest.override_item(name, redefinition)`
+    * Overrides fields of an item registered with register_node/tool/craftitem.
+    * Note: Item must already be defined, (opt)depend on the mod defining it.
+    * Example: `minetest.override_item("default:mese",
+      {light_source=minetest.LIGHT_MAX})`
 * `minetest.unregister_item(name)`
 * `minetest.unregister_item(name)`
-* `minetest.register_alias(name, convert_to)`
+    * Unregisters the item from the engine, and deletes the entry with key
+      `name` from `minetest.registered_items` and from the associated item table
+      according to its nature: `minetest.registered_nodes`, etc.
+* `minetest.register_entity(name, entity definition)`
+* `minetest.register_abm(abm definition)`
+* `minetest.register_lbm(lbm definition)`
+* `minetest.register_alias(alias, original_name)`
     * Also use this to set the 'mapgen aliases' needed in a game for the core
     * Also use this to set the 'mapgen aliases' needed in a game for the core
-    * mapgens. See [Mapgen aliases] section above.
-* `minetest.register_alias_force(name, convert_to)`
+      mapgens. See [Mapgen aliases] section above.
+* `minetest.register_alias_force(alias, original_name)`
+* `minetest.register_ore(ore definition)`
+    * Returns an integer object handle uniquely identifying the registered
+      ore on success.
+    * The order of ore registrations determines the order of ore generation.
+* `minetest.register_biome(biome definition)`
+    * Returns an integer object handle uniquely identifying the registered
+      biome on success. To get the biome ID, use `minetest.get_biome_id`.
+* `minetest.unregister_biome(name)`
+    * Unregisters the biome from the engine, and deletes the entry with key
+      `name` from `minetest.registered_biomes`.
+    * Warning: This alters the biome to biome ID correspondences, so any
+      decorations or ores using the 'biomes' field must afterwards be cleared
+      and re-registered.
+* `minetest.register_decoration(decoration definition)`
+    * Returns an integer object handle uniquely identifying the registered
+      decoration on success. To get the decoration ID, use
+      `minetest.get_decoration_id`.
+    * The order of decoration registrations determines the order of decoration
+      generation.
+* `minetest.register_schematic(schematic definition)`
+    * Returns an integer object handle uniquely identifying the registered
+      schematic on success.
+    * If the schematic is loaded from a file, the `name` field is set to the
+      filename.
+    * If the function is called when loading the mod, and `name` is a relative
+      path, then the current mod path will be prepended to the schematic
+      filename.
+* `minetest.clear_registered_biomes()`
+    * Clears all biomes currently registered.
+    * Warning: Clearing and re-registering biomes alters the biome to biome ID
+      correspondences, so any decorations or ores using the 'biomes' field must
+      afterwards be cleared and re-registered.
+* `minetest.clear_registered_decorations()`
+    * Clears all decorations currently registered.
+* `minetest.clear_registered_ores()`
+    * Clears all ores currently registered.
+* `minetest.clear_registered_schematics()`
+    * Clears all schematics currently registered.
+
+### Gameplay
+
 * `minetest.register_craft(recipe)`
     * Check recipe table syntax for different types below.
 * `minetest.clear_craft(recipe)`
 * `minetest.register_craft(recipe)`
     * Check recipe table syntax for different types below.
 * `minetest.clear_craft(recipe)`
@@ -3564,51 +4186,57 @@ Call these functions only at load time!
     * **Warning**! The type field ("shaped", "cooking" or any other) will be
       ignored if the recipe contains output. Erasing is then done independently
       from the crafting method.
     * **Warning**! The type field ("shaped", "cooking" or any other) will be
       ignored if the recipe contains output. Erasing is then done independently
       from the crafting method.
-* `minetest.register_ore(ore definition)`
-* `minetest.register_biome(biome definition)`
-* `minetest.register_decoration(decoration definition)`
-* `minetest.override_item(name, redefinition)`
-    * Overrides fields of an item registered with register_node/tool/craftitem.
-    * Note: Item must already be defined, (opt)depend on the mod defining it.
-    * Example: `minetest.override_item("default:mese", {light_source=LIGHT_MAX})`
-* `minetest.clear_registered_ores()`
-* `minetest.clear_registered_biomes()`
-* `minetest.clear_registered_decorations()`
+* `minetest.register_chatcommand(cmd, chatcommand definition)`
+* `minetest.override_chatcommand(name, redefinition)`
+    * Overrides fields of a chatcommand registered with `register_chatcommand`.
+* `minetest.unregister_chatcommand(name)`
+    * Unregisters a chatcommands registered with `register_chatcommand`.
+* `minetest.register_privilege(name, definition)`
+    * `definition` can be a description or a definition table (see [Privilege
+      definition]).
+    * If it is a description, the priv will be granted to singleplayer and admin
+      by default.
+    * To allow players with `basic_privs` to grant, see the `basic_privs`
+      minetest.conf setting.
+* `minetest.register_authentication_handler(authentication handler definition)`
+    * Registers an auth handler that overrides the builtin one.
+    * This function can be called by a single mod once only.
 
 Global callback registration functions
 --------------------------------------
 
 Call these functions only at load time!
 
 
 Global callback registration functions
 --------------------------------------
 
 Call these functions only at load time!
 
-* `minetest.register_globalstep(func(dtime))`
+* `minetest.register_globalstep(function(dtime))`
     * Called every server step, usually interval of 0.1s
     * Called every server step, usually interval of 0.1s
-* `minetest.register_on_mods_loaded(func())`
+* `minetest.register_on_mods_loaded(function())`
     * Called after mods have finished loading and before the media is cached or the
       aliases handled.
     * Called after mods have finished loading and before the media is cached or the
       aliases handled.
-* `minetest.register_on_shutdown(func())`
+* `minetest.register_on_shutdown(function())`
     * Called before server shutdown
     * **Warning**: If the server terminates abnormally (i.e. crashes), the
       registered callbacks **will likely not be run**. Data should be saved at
       semi-frequent intervals as well as on server shutdown.
     * Called before server shutdown
     * **Warning**: If the server terminates abnormally (i.e. crashes), the
       registered callbacks **will likely not be run**. Data should be saved at
       semi-frequent intervals as well as on server shutdown.
-* `minetest.register_on_placenode(func(pos, newnode, placer, oldnode, itemstack, pointed_thing))`
+* `minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing))`
     * Called when a node has been placed
     * If return `true` no item is taken from `itemstack`
     * `placer` may be any valid ObjectRef or nil.
     * **Not recommended**; use `on_construct` or `after_place_node` in node
       definition whenever possible.
     * Called when a node has been placed
     * If return `true` no item is taken from `itemstack`
     * `placer` may be any valid ObjectRef or nil.
     * **Not recommended**; use `on_construct` or `after_place_node` in node
       definition whenever possible.
-* `minetest.register_on_dignode(func(pos, oldnode, digger))`
+* `minetest.register_on_dignode(function(pos, oldnode, digger))`
     * Called when a node has been dug.
     * **Not recommended**; Use `on_destruct` or `after_dig_node` in node
       definition whenever possible.
     * Called when a node has been dug.
     * **Not recommended**; Use `on_destruct` or `after_dig_node` in node
       definition whenever possible.
-* `minetest.register_on_punchnode(func(pos, node, puncher, pointed_thing))`
+* `minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing))`
     * Called when a node is punched
     * Called when a node is punched
-* `minetest.register_on_generated(func(minp, maxp, blockseed))`
+* `minetest.register_on_generated(function(minp, maxp, blockseed))`
     * Called after generating a piece of world. Modifying nodes inside the area
       is a bit faster than usually.
     * Called after generating a piece of world. Modifying nodes inside the area
       is a bit faster than usually.
-* `minetest.register_on_newplayer(func(ObjectRef))`
+* `minetest.register_on_newplayer(function(ObjectRef))`
     * Called after a new player has been created
     * Called after a new player has been created
-* `minetest.register_on_punchplayer(func(player, hitter, time_from_last_punch, tool_capabilities, dir, damage))`
+* `minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage))`
     * Called when a player is punched
     * Called when a player is punched
+    * Note: This callback is invoked even if the punched player is dead.
     * `player`: ObjectRef - Player that was punched
     * `hitter`: ObjectRef - Player that hit
     * `time_from_last_punch`: Meant for disallowing spamming of clicks
     * `player`: ObjectRef - Player that was punched
     * `hitter`: ObjectRef - Player that hit
     * `time_from_last_punch`: Meant for disallowing spamming of clicks
@@ -3618,7 +4246,7 @@ Call these functions only at load time!
       the puncher to the punched.
     * `damage`: Number that represents the damage calculated by the engine
     * should return `true` to prevent the default damage mechanism
       the puncher to the punched.
     * `damage`: Number that represents the damage calculated by the engine
     * should return `true` to prevent the default damage mechanism
-* `minetest.register_on_player_hpchange(func(player, hp_change, reason), modifier)`
+* `minetest.register_on_player_hpchange(function(player, hp_change, reason), modifier)`
     * Called when the player gets damaged or healed
     * `player`: ObjectRef of the player
     * `hp_change`: the amount of change. Negative when it is damage.
     * Called when the player gets damaged or healed
     * `player`: ObjectRef of the player
     * `hp_change`: the amount of change. Negative when it is damage.
@@ -3628,37 +4256,38 @@ 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`
                         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 neighbouring node.
+                             `reason.node` will hold the node name or nil.
             * `drown`
             * `respawn`
         * Any of the above types may have additional fields from mods.
         * `reason.from` will be `mod` or `engine`.
     * `modifier`: when true, the function should return the actual `hp_change`.
             * `drown`
             * `respawn`
         * Any of the above types may have additional fields from mods.
         * `reason.from` will be `mod` or `engine`.
     * `modifier`: when true, the function should return the actual `hp_change`.
-       Note: modifiers only get a temporary hp_change that can be modified by later modifiers.
-       modifiers can return true as a second argument to stop the execution of further functions.
-       Non-modifiers receive the final hp change calculated by the modifiers.
-* `minetest.register_on_dieplayer(func(ObjectRef, reason))`
+       Note: modifiers only get a temporary `hp_change` that can be modified by later modifiers.
+       Modifiers can return true as a second argument to stop the execution of further functions.
+       Non-modifiers receive the final HP change calculated by the modifiers.
+* `minetest.register_on_dieplayer(function(ObjectRef, reason))`
     * Called when a player dies
     * `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange
     * Called when a player dies
     * `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange
-* `minetest.register_on_respawnplayer(func(ObjectRef))`
+* `minetest.register_on_respawnplayer(function(ObjectRef))`
     * Called when player is to be respawned
     * Called _before_ repositioning of player occurs
     * return true in func to disable regular player placement
     * Called when player is to be respawned
     * Called _before_ repositioning of player occurs
     * return true in func to disable regular player placement
-* `minetest.register_on_prejoinplayer(func(name, ip))`
+* `minetest.register_on_prejoinplayer(function(name, ip))`
     * Called before a player joins the game
     * If it returns a string, the player is disconnected with that string as
       reason.
     * Called before a player joins the game
     * If it returns a string, the player is disconnected with that string as
       reason.
-* `minetest.register_on_joinplayer(func(ObjectRef))`
+* `minetest.register_on_joinplayer(function(ObjectRef))`
     * Called when a player joins the game
     * Called when a player joins the game
-* `minetest.register_on_leaveplayer(func(ObjectRef, timed_out))`
+* `minetest.register_on_leaveplayer(function(ObjectRef, timed_out))`
     * Called when a player leaves the game
     * `timed_out`: True for timeout, false for other reasons.
     * Called when a player leaves the game
     * `timed_out`: True for timeout, false for other reasons.
-* `minetest.register_on_auth_fail(func(name, ip))`
+* `minetest.register_on_auth_fail(function(name, ip))`
     * Called when a client attempts to log into an account but supplies the
       wrong password.
     * `ip`: The IP address of the client.
     * `name`: The account the client attempted to log into.
     * Called when a client attempts to log into an account but supplies the
       wrong password.
     * `ip`: The IP address of the client.
     * `name`: The account the client attempted to log into.
-* `minetest.register_on_cheat(func(ObjectRef, cheat))`
+* `minetest.register_on_cheat(function(ObjectRef, cheat))`
     * Called when a player cheats
     * `cheat`: `{type=<cheat_type>}`, where `<cheat_type>` is one of:
         * `moved_too_fast`
     * Called when a player cheats
     * `cheat`: `{type=<cheat_type>}`, where `<cheat_type>` is one of:
         * `moved_too_fast`
@@ -3667,15 +4296,47 @@ Call these functions only at load time!
         * `finished_unknown_dig`
         * `dug_unbreakable`
         * `dug_too_fast`
         * `finished_unknown_dig`
         * `dug_unbreakable`
         * `dug_too_fast`
-* `minetest.register_on_chat_message(func(name, message))`
+* `minetest.register_on_chat_message(function(name, message))`
     * Called always when a player says something
     * Return `true` to mark the message as handled, which means that it will
       not be sent to other players.
     * Called always when a player says something
     * Return `true` to mark the message as handled, which means that it will
       not be sent to other players.
-* `minetest.register_on_player_receive_fields(func(player, formname, fields))`
-    * Called when a button is pressed in player's inventory form
+* `minetest.register_on_player_receive_fields(function(player, formname, fields))`
+    * Called when the server received input from `player` in a formspec with
+      the given `formname`. Specifically, this is called on any of the
+      following events:
+          * a button was pressed,
+          * Enter was pressed while the focus was on a text field
+          * a checkbox was toggled,
+          * something was selecteed in a drop-down list,
+          * a different tab was selected,
+          * selection was changed in a textlist or table,
+          * an entry was double-clicked in a textlist or table,
+          * a scrollbar was moved, or
+          * the form was actively closed by the player.
+    * Fields are sent for formspec elements which define a field. `fields`
+      is a table containing each formspecs element value (as string), with
+      the `name` parameter as index for each. The value depends on the
+      formspec element type:
+        * `button` and variants: If pressed, contains the user-facing button
+          text as value. If not pressed, is `nil`
+        * `field`, `textarea` and variants: Text in the field
+        * `dropdown`: Text of selected item
+        * `tabheader`: Tab index, starting with `"1"` (only if tab changed)
+        * `checkbox`: `"true"` if checked, `"false"` if unchecked
+        * `textlist`: See `minetest.explode_textlist_event`
+        * `table`: See `minetest.explode_table_event`
+        * `scrollbar`: See `minetest.explode_scrollbar_event`
+        * Special case: `["quit"]="true"` is sent when the user actively
+          closed the form by mouse click, keypress or through a button_exit[]
+          element.
+        * Special case: `["key_enter"]="true"` is sent when the user pressed
+          the Enter key and the focus was either nowhere (causing the formspec
+          to be closed) or on a button. If the focus was on a text field,
+          additionally, the index `key_enter_field` contains the name of the
+          text field. See also: `field_close_on_enter`.
     * Newest functions are called first
     * If function returns `true`, remaining functions are not called
     * Newest functions are called first
     * If function returns `true`, remaining functions are not called
-* `minetest.register_on_craft(func(itemstack, player, old_craft_grid, craft_inv))`
+* `minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv))`
     * Called when `player` crafts something
     * `itemstack` is the output
     * `old_craft_grid` contains the recipe (Note: the one in the inventory is
     * Called when `player` crafts something
     * `itemstack` is the output
     * `old_craft_grid` contains the recipe (Note: the one in the inventory is
@@ -3683,10 +4344,10 @@ Call these functions only at load time!
     * `craft_inv` is the inventory with the crafting grid
     * Return either an `ItemStack`, to replace the output, or `nil`, to not
       modify it.
     * `craft_inv` is the inventory with the crafting grid
     * Return either an `ItemStack`, to replace the output, or `nil`, to not
       modify it.
-* `minetest.register_craft_predict(func(itemstack, player, old_craft_grid, craft_inv))`
+* `minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv))`
     * The same as before, except that it is called before the player crafts, to
       make craft prediction, and it should not change anything.
     * The same as before, except that it is called before the player crafts, to
       make craft prediction, and it should not change anything.
-* `minetest.register_allow_player_inventory_action(func(player, inventory, action, inventory_info))`
+* `minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info))`
     * Determinates how much of a stack may be taken, put or moved to a
       player inventory.
     * `player` (type `ObjectRef`) is the player who modified the inventory
     * Determinates how much of a stack may be taken, put or moved to a
       player inventory.
     * `player` (type `ObjectRef`) is the player who modified the inventory
@@ -3698,11 +4359,11 @@ Call these functions only at load time!
         * `take`: Same as `put`
     * Return a numeric value to limit the amount of items to be taken, put or
       moved. A value of `-1` for `take` will make the source stack infinite.
         * `take`: Same as `put`
     * Return a numeric value to limit the amount of items to be taken, put or
       moved. A value of `-1` for `take` will make the source stack infinite.
-* `minetest.register_on_player_inventory_action(func(player, inventory, action, inventory_info))`
+* `minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info))`
     * Called after a take, put or move event from/to/in a player inventory
     * Function arguments: see `minetest.register_allow_player_inventory_action`
     * Does not accept or handle any return value.
     * Called after a take, put or move event from/to/in a player inventory
     * Function arguments: see `minetest.register_allow_player_inventory_action`
     * Does not accept or handle any return value.
-* `minetest.register_on_protection_violation(func(pos, name))`
+* `minetest.register_on_protection_violation(function(pos, name))`
     * Called by `builtin` and mods when a player violates protection at a
       position (eg, digs a node or punches a protected entity).
     * The registered functions can be called using
     * Called by `builtin` and mods when a player violates protection at a
       position (eg, digs a node or punches a protected entity).
     * The registered functions can be called using
@@ -3710,10 +4371,9 @@ Call these functions only at load time!
     * The provided function should check that the position is protected by the
       mod calling this function before it prints a message, if it does, to
       allow for multiple protection mods.
     * The provided function should check that the position is protected by the
       mod calling this function before it prints a message, if it does, to
       allow for multiple protection mods.
-* `minetest.register_on_item_eat(func(hp_change, replace_with_item, itemstack, user, pointed_thing))`
+* `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`
     * Called when an item is eaten, by `minetest.item_eat`
-    * Return `true` or `itemstack` to cancel the default item eat response
-      (i.e.: hp increase).
+    * Return `itemstack` to cancel the default item eat response (i.e.: hp increase).
 * `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,
 * `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,
@@ -3725,41 +4385,11 @@ Call these functions only at load time!
 * `minetest.register_can_bypass_userlimit(function(name, ip))`
     * Called when `name` user connects with `ip`.
     * Return `true` to by pass the player limit
 * `minetest.register_can_bypass_userlimit(function(name, ip))`
     * Called when `name` user connects with `ip`.
     * Return `true` to by pass the player limit
-* `minetest.register_on_modchannel_message(func(channel_name, sender, message))`
+* `minetest.register_on_modchannel_message(function(channel_name, sender, message))`
     * Called when an incoming mod channel message is received
     * You should have joined some channels to receive events.
     * If message comes from a server mod, `sender` field is an empty string.
 
     * Called when an incoming mod channel message is received
     * You should have joined some channels to receive events.
     * If message comes from a server mod, `sender` field is an empty string.
 
-Other registration functions
-----------------------------
-
-* `minetest.register_chatcommand(cmd, chatcommand definition)`
-    * Adds definition to `minetest.registered_chatcommands`
-* `minetest.override_chatcommand(name, redefinition)`
-    * Overrides fields of a chatcommand registered with `register_chatcommand`.
-* `minetest.unregister_chatcommand(name)`
-    * Unregisters a chatcommands registered with `register_chatcommand`.
-* `minetest.register_privilege(name, definition)`
-    * `definition`: `"description text"`
-    * `definition`:
-      `{description = "description text", give_to_singleplayer = boolean}`
-      the default of `give_to_singleplayer` is true.
-    * To allow players with `basic_privs` to grant, see `basic_privs`
-      minetest.conf setting.
-    * `on_grant(name, granter_name)`: Called when given to player `name` by
-      `granter_name`.
-      `granter_name` will be nil if the priv was granted by a mod.
-    * `on_revoke(name, revoker_name)`: Called when taken from player `name` by
-      `revoker_name`.
-      `revoker_name` will be nil if the priv was revoked by a mod
-    * Note that the above two callbacks will be called twice if a player is
-      responsible, once with the player name, and then with a nil player name.
-    * Return true in the above callbacks to stop register_on_priv_grant or
-      revoke being called.
-* `minetest.register_authentication_handler(authentication handler definition)`
-    * Registers an auth handler that overrides the builtin one
-    * This function can be called by a single mod once only.
-
 Setting-related
 ---------------
 
 Setting-related
 ---------------
 
@@ -3771,9 +4401,13 @@ Setting-related
 Authentication
 --------------
 
 Authentication
 --------------
 
-* `minetest.string_to_privs(str)`: returns `{priv1=true,...}`
-* `minetest.privs_to_string(privs)`: returns `"priv1,priv2,..."`
-    * Convert between two privilege representations
+* `minetest.string_to_privs(str[, delim])`:
+    * Converts string representation of privs into table form
+    * `delim`: String separating the privs. Defaults to `","`.
+    * Returns `{ priv1 = true, ... }`
+* `minetest.privs_to_string(privs[, delim])`:
+    * Returns the string representation of `privs`
+    * `delim`: String to delimit privs. Defaults to `","`.
 * `minetest.get_player_privs(name) -> {priv1=true,...}`
 * `minetest.check_player_privs(player_or_name, ...)`:
   returns `bool, missing_privs`
 * `minetest.get_player_privs(name) -> {priv1=true,...}`
 * `minetest.check_player_privs(player_or_name, ...)`:
   returns `bool, missing_privs`
@@ -3823,6 +4457,12 @@ Chat
 
 * `minetest.chat_send_all(text)`
 * `minetest.chat_send_player(name, text)`
 
 * `minetest.chat_send_all(text)`
 * `minetest.chat_send_player(name, text)`
+* `minetest.format_chat_message(name, message)`
+    * Used by the server to format a chat message, based on the setting `chat_message_format`.
+      Refer to the documentation of the setting for a list of valid placeholders.
+    * Takes player name and message, and returns the formatted string to be sent to players.
+    * Can be redefined by mods if required, for things like colored names or messages.
+    * **Only** the first occurrence of each placeholder will be replaced.
 
 Environment access
 ------------------
 
 Environment access
 ------------------
@@ -3915,7 +4555,7 @@ Environment access
     * Return value: Table with all node positions with a node air above
     * Area volume is limited to 4,096,000 nodes
 * `minetest.get_perlin(noiseparams)`
     * Return value: Table with all node positions with a node air above
     * Area volume is limited to 4,096,000 nodes
 * `minetest.get_perlin(noiseparams)`
-* `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
+* `minetest.get_perlin(seeddiff, octaves, persistence, spread)`
     * Return world-specific perlin noise (`int(worldseed)+seeddiff`)
 * `minetest.get_voxel_manip([pos1, pos2])`
     * Return voxel manipulator object.
     * Return world-specific perlin noise (`int(worldseed)+seeddiff`)
 * `minetest.get_voxel_manip([pos1, pos2])`
     * Return voxel manipulator object.
@@ -4025,6 +4665,10 @@ Environment access
         * mode = `"quick"`: Clear objects immediately in loaded mapblocks,
                             clear objects in unloaded mapblocks only when the
                             mapblocks are next activated.
         * mode = `"quick"`: Clear objects immediately in loaded mapblocks,
                             clear objects in unloaded mapblocks only when the
                             mapblocks are next activated.
+* `minetest.load_area(pos1[, pos2])`
+    * Load the mapblocks containing the area from `pos1` to `pos2`.
+      `pos2` defaults to `pos1` if not specified.
+    * This function does not trigger map generation.
 * `minetest.emerge_area(pos1, pos2, [callback], [param])`
     * Queue all blocks in the area from `pos1` to `pos2`, inclusive, to be
       asynchronously fetched from memory, loaded from disk, or if inexistent,
 * `minetest.emerge_area(pos1, pos2, [callback], [param])`
     * Queue all blocks in the area from `pos1` to `pos2`, inclusive, to be
       asynchronously fetched from memory, loaded from disk, or if inexistent,
@@ -4199,7 +4843,10 @@ Item handling
 * `minetest.inventorycube(img1, img2, img3)`
     * Returns a string for making an image of a cube (useful as an item image)
 * `minetest.get_pointed_thing_position(pointed_thing, above)`
 * `minetest.inventorycube(img1, img2, img3)`
     * Returns a string for making an image of a cube (useful as an item image)
 * `minetest.get_pointed_thing_position(pointed_thing, above)`
-    * Get position of a `pointed_thing` (that you can get from somewhere)
+    * Returns the position of a `pointed_thing` or `nil` if the `pointed_thing`
+      does not refer to a node or entity.
+    * If the optional `above` parameter is true and the `pointed_thing` refers
+      to a node, then it will return the `above` position of the `pointed_thing`.
 * `minetest.dir_to_facedir(dir, is6d)`
     * Convert a vector to a facedir value, used in `param2` for
       `paramtype2="facedir"`.
 * `minetest.dir_to_facedir(dir, is6d)`
     * Convert a vector to a facedir value, used in `param2` for
       `paramtype2="facedir"`.
@@ -4236,8 +4883,9 @@ Item handling
       `{stack1, stack2, stack3, stack4, stack 5, stack 6, stack 7, stack 8, stack 9}`
     * `output.item` = `ItemStack`, if unsuccessful: empty `ItemStack`
     * `output.time` = a number, if unsuccessful: `0`
       `{stack1, stack2, stack3, stack4, stack 5, stack 6, stack 7, stack 8, stack 9}`
     * `output.item` = `ItemStack`, if unsuccessful: empty `ItemStack`
     * `output.time` = a number, if unsuccessful: `0`
-    * `output.replacements` = list of `ItemStack`s that couldn't be placed in
-      `decremented_input.items`
+    * `output.replacements` = List of replacement `ItemStack`s that couldn't be
+      placed in `decremented_input.items`. Replacements can be placed in
+      `decremented_input` if the stack of the replaced item has a count of 1.
     * `decremented_input` = like `input`
 * `minetest.get_craft_recipe(output)`: returns input
     * returns last registered recipe for output item (node)
     * `decremented_input` = like `input`
 * `minetest.get_craft_recipe(output)`: returns input
     * returns last registered recipe for output item (node)
@@ -4298,33 +4946,36 @@ Rollback
     * Revert latest actions of someone
     * `actor`: `"player:<name>"`, also `"liquid"`.
 
     * Revert latest actions of someone
     * `actor`: `"player:<name>"`, also `"liquid"`.
 
-Defaults for the `on_*` item definition functions
--------------------------------------------------
-
-These functions return the leftover itemstack.
+Defaults for the `on_place` and `on_drop` item definition functions
+-------------------------------------------------------------------
 
 * `minetest.item_place_node(itemstack, placer, pointed_thing[, param2, prevent_after_place])`
     * Place item as a node
     * `param2` overrides `facedir` and wallmounted `param2`
     * `prevent_after_place`: if set to `true`, `after_place_node` is not called
       for the newly placed node to prevent a callback and placement loop
 
 * `minetest.item_place_node(itemstack, placer, pointed_thing[, param2, prevent_after_place])`
     * Place item as a node
     * `param2` overrides `facedir` and wallmounted `param2`
     * `prevent_after_place`: if set to `true`, `after_place_node` is not called
       for the newly placed node to prevent a callback and placement loop
-    * returns `itemstack, success`
+    * returns `itemstack, position`
+      * `position`: the location the node was placed to. `nil` if nothing was placed.
 * `minetest.item_place_object(itemstack, placer, pointed_thing)`
     * Place item as-is
 * `minetest.item_place_object(itemstack, placer, pointed_thing)`
     * Place item as-is
-* `minetest.item_place(itemstack, placer, pointed_thing, param2)`
-    * Use one of the above based on what the item is.
+    * returns the leftover itemstack
+    * **Note**: This function is deprecated and will never be called.
+* `minetest.item_place(itemstack, placer, pointed_thing[, param2])`
+    * Wrapper that calls `minetest.item_place_node` if appropriate
     * Calls `on_rightclick` of `pointed_thing.under` if defined instead
     * **Note**: is not called when wielded item overrides `on_place`
     * Calls `on_rightclick` of `pointed_thing.under` if defined instead
     * **Note**: is not called when wielded item overrides `on_place`
-    * `param2` overrides `facedir` and wallmounted `param2`
-    * returns `itemstack, success`
+    * `param2` overrides facedir and wallmounted `param2`
+    * returns `itemstack, position`
+      * `position`: the location the node was placed to. `nil` if nothing was placed.
 * `minetest.item_drop(itemstack, dropper, pos)`
     * Drop the item
 * `minetest.item_drop(itemstack, dropper, pos)`
     * Drop the item
-* `minetest.item_eat(hp_change, replace_with_item)`
-    * Eat the item.
+    * returns the leftover itemstack
+* `minetest.item_eat(hp_change[, replace_with_item])`
+    * Returns `function(itemstack, user, pointed_thing)` as a
+      function wrapper for `minetest.do_item_eat`.
     * `replace_with_item` is the itemstring which is added to the inventory.
       If the player is eating a stack, then replace_with_item goes to a
     * `replace_with_item` is the itemstring which is added to the inventory.
       If the player is eating a stack, then replace_with_item goes to a
-      different spot. Can be `nil`
-    * See `minetest.do_item_eat`
+      different spot.
 
 Defaults for the `on_punch` and `on_dig` node definition callbacks
 ------------------------------------------------------------------
 
 Defaults for the `on_punch` and `on_dig` node definition callbacks
 ------------------------------------------------------------------
@@ -4338,10 +4989,15 @@ Defaults for the `on_punch` and `on_dig` node definition callbacks
 Sounds
 ------
 
 Sounds
 ------
 
-* `minetest.sound_play(spec, parameters)`: returns a handle
+* `minetest.sound_play(spec, parameters, [ephemeral])`: returns a handle
     * `spec` is a `SimpleSoundSpec`
     * `parameters` is a sound parameter table
     * `spec` is a `SimpleSoundSpec`
     * `parameters` is a sound parameter table
+    * `ephemeral` is a boolean (default: false)
+      Ephemeral sounds will not return a handle and can't be stopped or faded.
+      It is recommend to use this for short sounds that happen in response to
+      player actions (e.g. door closing).
 * `minetest.sound_stop(handle)`
 * `minetest.sound_stop(handle)`
+    * `handle` is a handle returned by `minetest.sound_play`
 * `minetest.sound_fade(handle, step, gain)`
     * `handle` is a handle returned by `minetest.sound_play`
     * `step` determines how fast a sound will fade.
 * `minetest.sound_fade(handle, step, gain)`
     * `handle` is a handle returned by `minetest.sound_play`
     * `step` determines how fast a sound will fade.
@@ -4386,13 +5042,16 @@ Server
 Bans
 ----
 
 Bans
 ----
 
-* `minetest.get_ban_list()`: returns the ban list
-  (same as `minetest.get_ban_description("")`).
-* `minetest.get_ban_description(ip_or_name)`: returns ban description (string)
-* `minetest.ban_player(name)`: ban a player
-* `minetest.unban_player_or_ip(name)`: unban player or IP address
-* `minetest.kick_player(name, [reason])`: disconnect a player with a optional
+* `minetest.get_ban_list()`: returns a list of all bans formatted as string
+* `minetest.get_ban_description(ip_or_name)`: returns list of bans matching
+  IP address or name formatted as string
+* `minetest.ban_player(name)`: ban the IP of a currently connected player
+    * Returns boolean indicating success
+* `minetest.unban_player_or_ip(ip_or_name)`: remove ban record matching
+  IP address or name
+* `minetest.kick_player(name, [reason])`: disconnect a player with an optional
   reason.
   reason.
+    * Returns boolean indicating success (false if player nonexistant)
 
 Particles
 ---------
 
 Particles
 ---------
@@ -4501,6 +5160,18 @@ Schematics
           the Lua code generated will use that number of spaces as indentation
           instead of a tab character.
 
           the Lua code generated will use that number of spaces as indentation
           instead of a tab character.
 
+* `minetest.read_schematic(schematic, options)`
+    * Returns a Lua table representing the schematic (see: [Schematic specifier])
+    * `schematic` is the schematic to read (see: [Schematic specifier])
+    * `options` is a table containing the following optional parameters:
+        * `write_yslice_prob`: string value:
+            * `none`: no `write_yslice_prob` table is inserted,
+            * `low`: only probabilities that are not 254 or 255 are written in
+              the `write_ylisce_prob` table,
+            * `all`: write all probabilities to the `write_yslice_prob` table.
+            * The default for this option is `all`.
+            * Any invalid value will be interpreted as `all`.
+
 HTTP Requests
 -------------
 
 HTTP Requests
 -------------
 
@@ -4619,15 +5290,13 @@ Misc.
 * `minetest.decode_base64(string)`: returns string
     * Decodes a string encoded in base64.
 * `minetest.is_protected(pos, name)`: returns boolean
 * `minetest.decode_base64(string)`: returns string
     * Decodes a string encoded in base64.
 * `minetest.is_protected(pos, name)`: returns boolean
-    * Returns true, if player `name` shouldn't be able to dig at `pos` or do
-      other actions, definable by mods, due to some mod-defined ownership-like
-      concept.
-    * Returns false or nil, if the player is allowed to do such actions.
-    * `name` will be "" for non-players or unknown players.
-    * This function should be overridden by protection mods and should be used
-      to check if a player can interact at a position.
-    * This function should call the old version of itself if the position is
-      not protected by the mod.
+    * Returning `true` restricts the player `name` from modifying (i.e. digging,
+       placing) the node at position `pos`.
+    * `name` will be `""` for non-players or unknown players.
+    * This function should be overridden by protection mods. It is highly
+      recommended to grant access to players with the `protection_bypass` privilege.
+    * Cache and call the old version of this function if the position is
+      not protected by the mod. This will allow using multiple protection mods.
     * Example:
 
           local old_is_protected = minetest.is_protected
     * Example:
 
           local old_is_protected = minetest.is_protected
@@ -4678,6 +5347,15 @@ Misc.
       of the creative mode setting, checks for "sneak" to set the `invert_wall`
       parameter and `prevent_after_place` set to `true`.
 
       of the creative mode setting, checks for "sneak" to set the `invert_wall`
       parameter and `prevent_after_place` set to `true`.
 
+* `minetest.calculate_knockback(player, hitter, time_from_last_punch,
+  tool_capabilities, dir, distance, damage)`
+    * 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.
+    * You may want to cache and call the old function to allow multiple mods to
+      change knockback behaviour.
+
 * `minetest.forceload_block(pos[, transient])`
     * forceloads the position `pos`.
     * returns `true` if area could be forceloaded
 * `minetest.forceload_block(pos[, transient])`
     * forceloads the position `pos`.
     * returns `true` if area could be forceloaded
@@ -4714,6 +5392,8 @@ Global objects
 Global tables
 -------------
 
 Global tables
 -------------
 
+### Registered definition tables
+
 * `minetest.registered_items`
     * Map of registered items, indexed by name
 * `minetest.registered_nodes`
 * `minetest.registered_items`
     * Map of registered items, indexed by name
 * `minetest.registered_nodes`
@@ -4728,14 +5408,37 @@ Global tables
     * Map of object references, indexed by active object id
 * `minetest.luaentities`
     * Map of Lua entities, indexed by active object id
     * Map of object references, indexed by active object id
 * `minetest.luaentities`
     * Map of Lua entities, indexed by active object id
-* `minetest.registered_chatcommands`
-    * Map of registered chat command definitions, indexed by name
+* `minetest.registered_abms`
+    * List of ABM definitions
+* `minetest.registered_lbms`
+    * List of LBM definitions
+* `minetest.registered_aliases`
+    * Map of registered aliases, indexed by name
 * `minetest.registered_ores`
 * `minetest.registered_ores`
-    * List of registered ore definitions.
+    * Map of registered ore definitions, indexed by the `name` field.
+    * If `name` is nil, the key is the object handle returned by
+      `minetest.register_ore`.
 * `minetest.registered_biomes`
 * `minetest.registered_biomes`
-    * List of registered biome definitions.
+    * Map of registered biome definitions, indexed by the `name` field.
+    * If `name` is nil, the key is the object handle returned by
+      `minetest.register_biome`.
 * `minetest.registered_decorations`
 * `minetest.registered_decorations`
-    * List of registered decoration definitions.
+    * Map of registered decoration definitions, indexed by the `name` field.
+    * If `name` is nil, the key is the object handle returned by
+      `minetest.register_decoration`.
+* `minetest.registered_schematics`
+    * Map of registered schematic definitions, indexed by the `name` field.
+    * If `name` is nil, the key is the object handle returned by
+      `minetest.register_schematic`.
+* `minetest.registered_chatcommands`
+    * Map of registered chat command definitions, indexed by name
+* `minetest.registered_privileges`
+    * Map of registered privilege definitions, indexed by name
+
+### Registered callback tables
+
+All callbacks registered with [Global callback registration functions] are added
+to corresponding `minetest.registered_*` tables.
 
 
 
 
 
 
@@ -4752,35 +5455,38 @@ A fast access data structure to store areas, and find areas near a given
 position or area.
 Every area has a `data` string attribute to store additional information.
 You can create an empty `AreaStore` by calling `AreaStore()`, or
 position or area.
 Every area has a `data` string attribute to store additional information.
 You can create an empty `AreaStore` by calling `AreaStore()`, or
-`AreaStore(type_name)`.
+`AreaStore(type_name)`. The mod decides where to save and load AreaStore.
 If you chose the parameter-less constructor, a fast implementation will be
 automatically chosen for you.
 
 ### Methods
 
 If you chose the parameter-less constructor, a fast implementation will be
 automatically chosen for you.
 
 ### Methods
 
-* `get_area(id, include_borders, include_data)`: returns the area with the id
-  `id`.
-  (optional) Boolean values `include_borders` and `include_data` control what's
-  copied.
-  Returns nil if specified area id does not exist.
-* `get_areas_for_pos(pos, include_borders, include_data)`: returns all areas
-  that contain the position `pos`.
-  (optional) Boolean values `include_borders` and `include_data` control what's
-  copied.
-* `get_areas_in_area(edge1, edge2, accept_overlap, include_borders, include_data)`:
-  returns all areas that contain all nodes inside the area specified by `edge1`
-  and `edge2` (inclusive).
-  If `accept_overlap` is true, also areas are returned that have nodes in
-  common with the specified area.
-  (optional) Boolean values `include_borders` and `include_data` control what's
-  copied.
+* `get_area(id, include_borders, include_data)`
+    * Returns the area information about the specified ID.
+    * Returned values are either of these:
+
+            nil  -- Area not found
+            true -- Without `include_borders` and `include_data`
+            {
+                min = pos, max = pos -- `include_borders == true`
+                data = string        -- `include_data == true`
+            }
+
+* `get_areas_for_pos(pos, include_borders, include_data)`
+    * Returns all areas as table, indexed by the area ID.
+    * Table values: see `get_area`.
+* `get_areas_in_area(edge1, edge2, accept_overlap, include_borders, include_data)`
+    * Returns all areas that contain all nodes inside the area specified by `edge1`
+      and `edge2` (inclusive).
+    * `accept_overlap`: if `true`, areas are returned that have nodes in
+      common (intersect) with the specified area.
+    * Returns the same values as `get_areas_for_pos`.
 * `insert_area(edge1, edge2, data, [id])`: inserts an area into the store.
 * `insert_area(edge1, edge2, data, [id])`: inserts an area into the store.
-  Returns the new area's ID, or nil if the insertion failed.
-  The (inclusive) positions `edge1` and `edge2` describe the area.
-  `data` is a string stored with the area.  If passed, `id` will be used as the
-  internal area ID, it must be a unique number between 0 and 2^32-2. If you use
-  the `id` parameter you must always use it, or insertions are likely to fail
-  due to conflicts.
+    * Returns the new area's ID, or nil if the insertion failed.
+    * The (inclusive) positions `edge1` and `edge2` 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
+      number between 0 and 2^32-2.
 * `reserve(count)`: reserves resources for at most `count` many contained
   areas.
   Only needed for efficiency, and only some implementations profit.
 * `reserve(count)`: reserves resources for at most `count` many contained
   areas.
   Only needed for efficiency, and only some implementations profit.
@@ -4866,6 +5572,7 @@ an itemstring, a table or `nil`.
 * `get_metadata()`: (DEPRECATED) Returns metadata (a string attached to an item
   stack).
 * `set_metadata(metadata)`: (DEPRECATED) Returns true.
 * `get_metadata()`: (DEPRECATED) Returns metadata (a string attached to an item
   stack).
 * `set_metadata(metadata)`: (DEPRECATED) Returns true.
+* `get_description()`: returns the description shown in inventory list tooltips.
 * `clear()`: removes all items from the stack, making it empty.
 * `replace(item)`: replace the contents of this stack.
     * `item` can also be an itemstring or table.
 * `clear()`: removes all items from the stack, making it empty.
 * `replace(item)`: replace the contents of this stack.
     * `item` can also be an itemstring or table.
@@ -4909,7 +5616,8 @@ Can be obtained via `item:get_meta()`.
 `MetaDataRef`
 -------------
 
 `MetaDataRef`
 -------------
 
-See [`StorageRef`], [`NodeMetaRef`], [`ItemStackMetaRef`], and [`PlayerMetaRef`].
+Base class used by [`StorageRef`], [`NodeMetaRef`], [`ItemStackMetaRef`],
+and [`PlayerMetaRef`].
 
 ### Methods
 
 
 ### Methods
 
@@ -4998,16 +5706,31 @@ Can be gotten via `minetest.get_node_timer(pos)`.
 -----------
 
 Moving things in the game are generally these.
 -----------
 
 Moving things in the game are generally these.
+This is basically a reference to a C++ `ServerActiveObject`.
+
+### Advice on handling `ObjectRefs`
+
+When you receive an `ObjectRef` as a callback argument or from another API
+function, it is possible to store the reference somewhere and keep it around.
+It will keep functioning until the object is unloaded or removed.
+
+However, doing this is **NOT** recommended as there is (intentionally) no method
+to test if a previously acquired `ObjectRef` is still valid.
+Instead, `ObjectRefs` should be "let go" of as soon as control is returned from
+Lua back to the engine.
+Doing so is much less error-prone and you will never need to wonder if the
+object you are working with still exists.
 
 
-This is basically a reference to a C++ `ServerActiveObject`
 
 ### Methods
 
 
 ### Methods
 
-* `remove()`: remove object (after returning from Lua)
-    * Note: Doesn't work on players, use `minetest.kick_player` instead
 * `get_pos()`: returns `{x=num, y=num, z=num}`
 * `set_pos(pos)`: `pos`=`{x=num, y=num, z=num}`
 * `get_pos()`: returns `{x=num, y=num, z=num}`
 * `set_pos(pos)`: `pos`=`{x=num, y=num, z=num}`
-* `move_to(pos, continuous=false)`: interpolated move
+* `move_to(pos, continuous=false)`
+    * Does an interpolated move for Lua entities for visually smooth transitions.
+    * If `continuous` is true, the Lua entity will not be moved to the current
+      position before starting the interpolated move.
+    * For players this does the same as `set_pos`,`continuous` is ignored.
 * `punch(puncher, time_from_last_punch, tool_capabilities, direction)`
     * `puncher` = another `ObjectRef`,
     * `time_from_last_punch` = time since last punch action of the puncher
 * `punch(puncher, time_from_last_punch, tool_capabilities, direction)`
     * `puncher` = another `ObjectRef`,
     * `time_from_last_punch` = time since last punch action of the puncher
@@ -5016,7 +5739,10 @@ This is basically a reference to a C++ `ServerActiveObject`
 * `get_hp()`: returns number of hitpoints (2 * number of hearts)
 * `set_hp(hp, reason)`: set number of hitpoints (2 * number of hearts).
     * See reason in register_on_player_hpchange
 * `get_hp()`: returns number of hitpoints (2 * number of hearts)
 * `set_hp(hp, reason)`: set number of hitpoints (2 * number of hearts).
     * See reason in register_on_player_hpchange
-* `get_inventory()`: returns an `InvRef`
+    * Is limited to the range of 0 ... 65535 (2^16 - 1)
+    * For players: HP are also limited by `hp_max` specified in the player's
+      object properties
+* `get_inventory()`: returns an `InvRef` for players, otherwise returns `nil`
 * `get_wield_list()`: returns the name of the inventory list the wielded item
    is in.
 * `get_wield_index()`: returns the index of the wielded item
 * `get_wield_list()`: returns the name of the inventory list the wielded item
    is in.
 * `get_wield_index()`: returns the index of the wielded item
@@ -5063,8 +5789,12 @@ This is basically a reference to a C++ `ServerActiveObject`
         text = "My Nametag",
       }
 
         text = "My Nametag",
       }
 
-#### LuaEntitySAO-only (no-op for other objects)
+#### Lua entity only (no-op for other objects)
 
 
+* `remove()`: remove object
+    * The object is removed after returning from Lua. However the `ObjectRef`
+      itself instantly becomes unusable with all further method calls having
+      no effect and returning `nil`.
 * `set_velocity(vel)`
     * `vel` is a vector, e.g. `{x=0.0, y=2.3, z=1.0}`
 * `add_velocity(vel)`
 * `set_velocity(vel)`
     * `vel` is a vector, e.g. `{x=0.0, y=2.3, z=1.0}`
 * `add_velocity(vel)`
@@ -5075,7 +5805,11 @@ This is basically a reference to a C++ `ServerActiveObject`
 * `set_acceleration(acc)`
     * `acc` is a vector
 * `get_acceleration()`: returns the acceleration, a vector
 * `set_acceleration(acc)`
     * `acc` is a vector
 * `get_acceleration()`: returns the acceleration, a vector
-* `set_yaw(radians)`
+* `set_rotation(rot)`
+    * `rot` is a vector (radians). X is pitch (elevation), Y is yaw (heading)
+      and Z is roll (bank).
+* `get_rotation()`: returns the rotation, a vector (radians)
+* `set_yaw(radians)`: sets the yaw (heading).
 * `get_yaw()`: returns number in radians
 * `set_texture_mod(mod)`
 * `get_texture_mod()` returns current texture modifier
 * `get_yaw()`: returns number in radians
 * `set_texture_mod(mod)`
 * `get_texture_mod()` returns current texture modifier
@@ -5091,11 +5825,19 @@ This is basically a reference to a C++ `ServerActiveObject`
 * `get_entity_name()` (**Deprecated**: Will be removed in a future version)
 * `get_luaentity()`
 
 * `get_entity_name()` (**Deprecated**: Will be removed in a future version)
 * `get_luaentity()`
 
-#### Player-only (no-op for other objects)
+#### Player only (no-op for other objects)
 
 * `get_player_name()`: returns `""` if is not a player
 * `get_player_velocity()`: returns `nil` if is not a player, otherwise a
   table {x, y, z} representing the player's instantaneous velocity in nodes/s
 
 * `get_player_name()`: returns `""` if is not a player
 * `get_player_velocity()`: returns `nil` if is not a player, otherwise a
   table {x, y, z} representing the player's instantaneous velocity in nodes/s
+* `add_player_velocity(vel)`
+    * Adds to player velocity, this happens client-side and only once.
+    * Does not apply during free_move.
+    * Note that since the player speed is normalized at each move step,
+      increasing e.g. Y velocity beyond what would usually be achieved
+      (see: physics overrides) will cause existing X/Z velocity to be reduced.
+    * Example: `add_player_velocity({x=0, y=6.5, z=0})` is equivalent to
+      pressing the jump key (assuming default settings)
 * `get_look_dir()`: get camera direction as a unit vector
 * `get_look_vertical()`: pitch in radians
     * Angle ranges between -pi/2 and pi/2, which are straight up and down
 * `get_look_dir()`: get camera direction as a unit vector
 * `get_look_vertical()`: pitch in radians
     * Angle ranges between -pi/2 and pi/2, which are straight up and down
@@ -5117,12 +5859,22 @@ This is basically a reference to a C++ `ServerActiveObject`
   `set_look_vertical`.
 * `set_look_yaw(radians)`: sets look yaw - Deprecated. Use
   `set_look_horizontal`.
   `set_look_vertical`.
 * `set_look_yaw(radians)`: sets look yaw - Deprecated. Use
   `set_look_horizontal`.
-* `get_breath()`: returns players breath
-* `set_breath(value)`: sets players breath
+* `get_breath()`: returns player's breath
+* `set_breath(value)`: sets player's breath
     * values:
         * `0`: player is drowning
         * max: bubbles bar is not shown
         * See [Object properties] for more information
     * values:
         * `0`: player is drowning
         * max: bubbles bar is not shown
         * See [Object properties] for more information
+    * Is limited to range 0 ... 65535 (2^16 - 1)
+* `set_fov(fov, is_multiplier)`: Sets player's FOV
+    * `fov`: FOV value.
+    * `is_multiplier`: Set to `true` if the FOV value is a multiplier.
+      Defaults to `false`.
+    * Set to 0 to clear FOV override.
+* `get_fov()`:
+    * Returns player's FOV override in degrees, and a boolean depending on whether
+      the value is a multiplier.
+    * Returns 0 as first value if player's FOV hasn't been overridden.
 * `set_attribute(attribute, value)`:  DEPRECATED, use get_meta() instead
     * Sets an extra attribute with value on player.
     * `value` must be a string, or a number which will be converted to a
 * `set_attribute(attribute, value)`:  DEPRECATED, use get_meta() instead
     * Sets an extra attribute with value on player.
     * `value` must be a string, or a number which will be converted to a
@@ -5188,7 +5940,7 @@ This is basically a reference to a C++ `ServerActiveObject`
 * `hud_get_flags()`: returns a table of player HUD flags with boolean values.
     * See `hud_set_flags` for a list of flags that can be toggled.
 * `hud_set_hotbar_itemcount(count)`: sets number of items in builtin hotbar
 * `hud_get_flags()`: returns a table of player HUD flags with boolean values.
     * See `hud_set_flags` for a list of flags that can be toggled.
 * `hud_set_hotbar_itemcount(count)`: sets number of items in builtin hotbar
-    * `count`: number of items, must be between `1` and `23`
+    * `count`: number of items, must be between `1` and `32`
 * `hud_get_hotbar_itemcount`: returns number of visible items
 * `hud_set_hotbar_image(texturename)`
     * sets background image for hotbar
 * `hud_get_hotbar_itemcount`: returns number of visible items
 * `hud_set_hotbar_image(texturename)`
     * sets background image for hotbar
@@ -5239,6 +5991,11 @@ This is basically a reference to a C++ `ServerActiveObject`
     * in first person view
     * in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
 * `get_eye_offset()`: returns `offset_first` and `offset_third`
     * in first person view
     * in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
 * `get_eye_offset()`: returns `offset_first` and `offset_third`
+* `send_mapblock(blockpos)`:
+    * Sends a server-side loaded mapblock to the player.
+    * Returns `false` if failed.
+    * Resource intensive - use sparsely
+    * To get blockpos, integer divide pos by 16
 
 `PcgRandom`
 -----------
 
 `PcgRandom`
 -----------
@@ -5264,9 +6021,9 @@ It can be created via `PcgRandom(seed)` or `PcgRandom(seed, sequence)`.
 -------------
 
 A perlin noise generator.
 -------------
 
 A perlin noise generator.
-It can be created via `PerlinNoise(seed, octaves, persistence, scale)`
+It can be created via `PerlinNoise(seed, octaves, persistence, spread)`
 or `PerlinNoise(noiseparams)`.
 or `PerlinNoise(noiseparams)`.
-Alternatively with `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
+Alternatively with `minetest.get_perlin(seeddiff, octaves, persistence, spread)`
 or `minetest.get_perlin(noiseparams)`.
 
 ### Methods
 or `minetest.get_perlin(noiseparams)`.
 
 ### Methods
@@ -5398,6 +6155,10 @@ It can be created via `Settings(filename)`.
     * `default` is the value returned if `key` is not found.
     * Returns `nil` if `key` is not found and `default` not specified.
 * `get_np_group(key)`: returns a NoiseParams table
     * `default` is the value returned if `key` is not found.
     * Returns `nil` if `key` is not found and `default` not specified.
 * `get_np_group(key)`: returns a NoiseParams table
+* `get_flags(key)`:
+    * Returns `{flag = true/false, ...}` according to the set flags.
+    * Is currently limited to mapgen flags `mg_flags` and mapgen-specific
+      flags like `mgv5_spflags`.
 * `set(key, value)`
     * Setting names can't contain whitespace or any of `="{}#`.
     * Setting values can't contain the sequence `\n"""`.
 * `set(key, value)`
     * Setting names can't contain whitespace or any of `="{}#`.
     * Setting values can't contain the sequence `\n"""`.
@@ -5414,12 +6175,26 @@ It can be created via `Settings(filename)`.
     * Writes changes to file.
 * `to_table()`: returns `{[key1]=value1,...}`
 
     * Writes changes to file.
 * `to_table()`: returns `{[key1]=value1,...}`
 
+### Format
+
+The settings have the format `key = value`. Example:
+
+    foo = example text
+    bar = """
+    Multiline
+    value
+    """
+
+
 `StorageRef`
 ------------
 
 Mod metadata: per mod metadata, saved automatically.
 Can be obtained via `minetest.get_mod_storage()` during load time.
 
 `StorageRef`
 ------------
 
 Mod metadata: per mod metadata, saved automatically.
 Can be obtained via `minetest.get_mod_storage()` during load time.
 
+WARNING: This storage backend is incaptable to save raw binary data due
+to restrictions of JSON.
+
 ### Methods
 
 * All methods in MetaDataRef
 ### Methods
 
 * All methods in MetaDataRef
@@ -5434,6 +6209,9 @@ Object properties
 -----------------
 
 Used by `ObjectRef` methods. Part of an Entity definition.
 -----------------
 
 Used by `ObjectRef` methods. Part of an Entity definition.
+These properties are not persistent, but are applied automatically to the
+corresponding Lua entity using the given registration fields.
+Player properties need to be saved manually.
 
     {
         hp_max = 1,
 
     {
         hp_max = 1,
@@ -5455,12 +6233,11 @@ Used by `ObjectRef` methods. Part of an Entity definition.
         -- Defaults to 1.625.
 
         physical = true,
         -- Defaults to 1.625.
 
         physical = true,
+        -- Collide with `walkable` nodes.
 
         collide_with_objects = true,
         -- Collide with other objects if physical = true
 
 
         collide_with_objects = true,
         -- Collide with other objects if physical = true
 
-        weight = 5,
-
         collisionbox = {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},  -- Default
         selectionbox = {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
         -- Selection box uses collision box dimensions when not set.
         collisionbox = {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},  -- Default
         selectionbox = {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
         -- Selection box uses collision box dimensions when not set.
@@ -5470,14 +6247,14 @@ Used by `ObjectRef` methods. Part of an Entity definition.
         pointable = true,
         -- Overrides selection box when false
 
         pointable = true,
         -- Overrides selection box when false
 
-        visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem",
+        visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item",
         -- "cube" is a node-sized cube.
         -- "sprite" is a flat texture always facing the player.
         -- "upright_sprite" is a vertical flat texture.
         -- "mesh" uses the defined mesh model.
         -- "wielditem" is used for dropped items.
         --   (see builtin/game/item_entity.lua).
         -- "cube" is a node-sized cube.
         -- "sprite" is a flat texture always facing the player.
         -- "upright_sprite" is a vertical flat texture.
         -- "mesh" uses the defined mesh model.
         -- "wielditem" is used for dropped items.
         --   (see builtin/game/item_entity.lua).
-        --   For this use 'textures = {itemname}'.
+        --   For this use 'wield_item = itemname' (Deprecated: 'textures = {itemname}').
         --   If the item has a 'wield_image' the object will be an extrusion of
         --   that, otherwise:
         --   If 'itemname' is a cubic node or nodebox the object will appear
         --   If the item has a 'wield_image' the object will be an extrusion of
         --   that, otherwise:
         --   If 'itemname' is a cubic node or nodebox the object will appear
@@ -5486,16 +6263,20 @@ Used by `ObjectRef` methods. Part of an Entity definition.
         --   of its texture.
         --   Otherwise for non-node items, the object will be an extrusion of
         --   'inventory_image'.
         --   of its texture.
         --   Otherwise for non-node items, the object will be an extrusion of
         --   'inventory_image'.
+        --   If 'itemname' contains a ColorString or palette index (e.g. from
+        --   `minetest.itemstring_with_palette()`), the entity will inherit the color.
+        -- "item" is similar to "wielditem" but ignores the 'wield_image' parameter.
 
 
-        visual_size = {x = 1, y = 1},
-        -- `x` multiplies horizontal (X and Z) visual size.
-        -- `y` multiplies vertical (Y) visual size.
+        visual_size = {x = 1, y = 1, z = 1},
+        -- Multipliers for the visual size. If `z` is not specified, `x` will be used
+        -- to scale the entity along both horizontal axes.
 
 
-        mesh = "model",
+        mesh = "model.obj",
+        -- File name of mesh when using "mesh" visual
 
         textures = {},
         -- Number of required textures depends on visual.
 
         textures = {},
         -- Number of required textures depends on visual.
-        -- "cube" uses 6 textures in the way a node does.
+        -- "cube" uses 6 textures just like a node, but all 6 must be defined.
         -- "sprite" uses 1 texture.
         -- "upright_sprite" uses 2 textures: {front, back}.
         -- "wielditem" expects 'textures = {itemname}' (see 'visual' above).
         -- "sprite" uses 1 texture.
         -- "upright_sprite" uses 2 textures: {front, back}.
         -- "wielditem" expects 'textures = {itemname}' (see 'visual' above).
@@ -5521,14 +6302,20 @@ Used by `ObjectRef` methods. Part of an Entity definition.
         -- spritesheet.
 
         is_visible = true,
         -- spritesheet.
 
         is_visible = true,
+        -- If false, object is invisible and can't be pointed.
 
         makes_footstep_sound = false,
 
         makes_footstep_sound = false,
+        -- If true, is able to make footstep sounds of nodes
+        -- (see node sound definition for details).
 
         automatic_rotate = 0,
         -- Set constant rotation in radians per second, positive or negative.
         -- Set to 0 to disable constant rotation.
 
         stepheight = 0,
 
         automatic_rotate = 0,
         -- Set constant rotation in radians per second, positive or negative.
         -- Set to 0 to disable constant rotation.
 
         stepheight = 0,
+        -- If positive number, object will climb upwards when it moves
+        -- horizontally against a `walkable` node, if the height difference
+        -- is within `stepheight`.
 
         automatic_face_movement_dir = 0.0,
         -- Automatically set yaw to movement direction, offset in degrees.
 
         automatic_face_movement_dir = 0.0,
         -- Automatically set yaw to movement direction, offset in degrees.
@@ -5536,7 +6323,7 @@ Used by `ObjectRef` methods. Part of an Entity definition.
 
         automatic_face_movement_max_rotation_per_sec = -1,
         -- Limit automatic rotation to this value in degrees per second.
 
         automatic_face_movement_max_rotation_per_sec = -1,
         -- Limit automatic rotation to this value in degrees per second.
-        -- No limit if value < 0.
+        -- No limit if value <= 0.
 
         backface_culling = true,
         -- Set to false to disable backface_culling for model
 
         backface_culling = true,
         -- Set to false to disable backface_culling for model
@@ -5644,6 +6431,10 @@ LBM (LoadingBlockModifier) definition
 
 Used by `minetest.register_lbm`.
 
 
 Used by `minetest.register_lbm`.
 
+A loading block modifier (LBM) is used to define a function that is called for
+specific nodes (defined by `nodenames`) when a mapblock which contains such nodes
+gets loaded.
+
     {
         label = "Upgrade legacy doors",
         -- Descriptive label for profiling purposes (optional).
     {
         label = "Upgrade legacy doors",
         -- Descriptive label for profiling purposes (optional).
@@ -5658,10 +6449,10 @@ Used by `minetest.register_lbm`.
 
         run_at_every_load = false,
         -- Whether to run the LBM's action every time a block gets loaded,
 
         run_at_every_load = false,
         -- Whether to run the LBM's action every time a block gets loaded,
-        -- and not just for blocks that were saved last time before LBMs were
-        -- introduced to the world.
+        -- and not only the first time the block gets loaded after the LBM
+        -- was introduced.
 
 
-        action = func(pos, node),
+        action = function(pos, node),
     }
 
 Tile definition
     }
 
 Tile definition
@@ -5764,7 +6555,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
 
         liquids_pointable = false,
 
 
         liquids_pointable = false,
 
-        -- See "Tools" section
+        -- See "Tools" section for an example including explanation
         tool_capabilities = {
             full_punch_interval = 1.0,
             max_drop_level = 0,
         tool_capabilities = {
             full_punch_interval = 1.0,
             max_drop_level = 0,
@@ -5774,6 +6565,15 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
                          uses = 20, maxlevel = 2},
             },
             damage_groups = {groupname = damage},
                          uses = 20, maxlevel = 2},
             },
             damage_groups = {groupname = damage},
+            -- Damage values must be between -32768 and 32767 (2^15)
+
+            punch_attack_uses = nil,
+            -- 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)".
+            -- It is recommend to set this explicitly instead of relying on the
+            -- fallback behavior.
         },
 
         node_placement_prediction = nil,
         },
 
         node_placement_prediction = nil,
@@ -5791,26 +6591,32 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         -- upon digging. Server will always update actual result shortly.
 
         sound = {
         -- upon digging. Server will always update actual result shortly.
 
         sound = {
-            breaks = "default_tool_break",  -- tools only
-            place = <SimpleSoundSpec>,
+            -- Definition of items sounds to be played at various events.
+            -- All fields in this table are optional.
+
+            breaks = <SimpleSoundSpec>,
+            -- When tool breaks due to wear. Ignored for non-tools
+
+            eat = <SimpleSoundSpec>,
+            -- When item is eaten with `minetest.do_item_eat`
         },
 
         },
 
-        on_place = func(itemstack, placer, pointed_thing),
+        on_place = function(itemstack, placer, pointed_thing),
         -- Shall place item and return the leftover itemstack.
         -- The placer may be any ObjectRef or nil.
         -- default: minetest.item_place
 
         -- Shall place item and return the leftover itemstack.
         -- The placer may be any ObjectRef or nil.
         -- default: minetest.item_place
 
-        on_secondary_use = func(itemstack, user, pointed_thing),
-        -- Same as on_place but called when pointing at nothing.
+        on_secondary_use = function(itemstack, user, pointed_thing),
+        -- Same as on_place but called when not pointing at a node.
         -- The user may be any ObjectRef or nil.
         -- The user may be any ObjectRef or nil.
-        -- pointed_thing: always { type = "nothing" }
+        -- default: nil
 
 
-        on_drop = func(itemstack, dropper, pos),
+        on_drop = function(itemstack, dropper, pos),
         -- Shall drop item and return the leftover itemstack.
         -- The dropper may be any ObjectRef or nil.
         -- default: minetest.item_drop
 
         -- Shall drop item and return the leftover itemstack.
         -- The dropper may be any ObjectRef or nil.
         -- default: minetest.item_drop
 
-        on_use = func(itemstack, user, pointed_thing),
+        on_use = function(itemstack, user, pointed_thing),
         -- default: nil
         -- Function must return either nil if no item shall be removed from
         -- inventory, or an itemstack to replace the original itemstack.
         -- default: nil
         -- Function must return either nil if no item shall be removed from
         -- inventory, or an itemstack to replace the original itemstack.
@@ -5819,7 +6625,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         -- The user may be any ObjectRef or nil.
         -- The default functions handle regular use cases.
 
         -- The user may be any ObjectRef or nil.
         -- The default functions handle regular use cases.
 
-        after_use = func(itemstack, user, node, digparams),
+        after_use = function(itemstack, user, node, digparams),
         -- default: nil
         -- If defined, should return an itemstack and will be called instead of
         -- wearing out the tool. If returns nil, does nothing.
         -- default: nil
         -- If defined, should return an itemstack and will be called instead of
         -- wearing out the tool. If returns nil, does nothing.
@@ -5850,8 +6656,9 @@ Used by `minetest.register_node`.
         -- Supported for drawtypes "plantlike", "signlike", "torchlike",
         -- "firelike", "mesh".
         -- For plantlike and firelike, the image will start at the bottom of the
         -- Supported for drawtypes "plantlike", "signlike", "torchlike",
         -- "firelike", "mesh".
         -- For plantlike and firelike, the image will start at the bottom of the
-        -- node, for the other drawtypes the image will be centered on the node.
-        -- Note that positioning for "torchlike" may still change.
+        -- node. For torchlike, the image will start at the surface to which the
+        -- node "attaches". For the other drawtypes the image will be centered
+        -- on the node.
 
         tiles = {tile definition 1, def2, def3, def4, def5, def6},
         -- Textures of node; +Y, -Y, +X, -X, +Z, -Z
 
         tiles = {tile definition 1, def2, def3, def4, def5, def6},
         -- Textures of node; +Y, -Y, +X, -X, +Z, -Z
@@ -5895,7 +6702,11 @@ Used by `minetest.register_node`.
         place_param2 = nil,  -- Force value for param2 when player places node
 
         is_ground_content = true,
         place_param2 = nil,  -- Force value for param2 when player places node
 
         is_ground_content = true,
-        -- If false, the cave generator will not carve through this node
+        -- If false, the cave generator and dungeon generator will not carve
+        -- through this node.
+        -- Specifically, this stops mod-added nodes being removed by caves and
+        -- dungeons when those generate in a neighbor mapchunk and extend out
+        -- beyond the edge of that mapchunk.
 
         sunlight_propagates = false,
         -- If true, sunlight will go infinitely through this node
 
         sunlight_propagates = false,
         -- If true, sunlight will go infinitely through this node
@@ -5957,7 +6768,8 @@ Used by `minetest.register_node`.
         -- Tells connected nodebox nodes to connect only to these sides of this
         -- node
 
         -- Tells connected nodebox nodes to connect only to these sides of this
         -- node
 
-        mesh = "model",
+        mesh = "model.obj",
+        -- File name of mesh when using "mesh" drawtype
 
         selection_box = {
             type = "fixed",
 
         selection_box = {
             type = "fixed",
@@ -5986,54 +6798,109 @@ Used by `minetest.register_node`.
         legacy_wallmounted = false,
 
         waving = 0,
         legacy_wallmounted = false,
 
         waving = 0,
-        -- Valid for mesh, nodebox, plantlike, allfaces_optional nodes.
-        -- 1 - wave node like plants (top of node moves, bottom is fixed)
+        -- Valid for drawtypes:
+        -- mesh, nodebox, plantlike, allfaces_optional, liquid, flowingliquid.
+        -- 1 - wave node like plants (node top moves side-to-side, bottom is fixed)
         -- 2 - wave node like leaves (whole node moves side-to-side)
         -- 2 - wave node like leaves (whole node moves side-to-side)
-        -- caveats: not all models will properly wave.
-        -- plantlike drawtype nodes can only wave like plants.
-        -- allfaces_optional drawtype nodes can only wave like leaves.
+        -- 3 - wave node like liquids (whole node moves up and down)
+        -- Not all models will properly wave.
+        -- plantlike drawtype can only wave like plants.
+        -- allfaces_optional drawtype can only wave like leaves.
+        -- liquid, flowingliquid drawtypes can only wave like liquids.
 
         sounds = {
 
         sounds = {
+            -- Definition of node sounds to be played at various events.
+            -- All fields in this table are optional.
+
             footstep = <SimpleSoundSpec>,
             footstep = <SimpleSoundSpec>,
-            dig = <SimpleSoundSpec>,  -- "__group" = group-based sound (default)
+            -- If walkable, played when object walks on it. If node is
+            -- climbable or a liquid, played when object moves through it
+
+            dig = <SimpleSoundSpec> or "__group",
+            -- While digging node.
+            -- If `"__group"`, then the sound will be
+            -- `default_dig_<groupname>`, where `<groupname>` is the
+            -- name of the tool'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)
+            -- Default value: `"__group"`
+
             dug = <SimpleSoundSpec>,
             dug = <SimpleSoundSpec>,
+            -- Node was dug
+
             place = <SimpleSoundSpec>,
             place = <SimpleSoundSpec>,
+            -- Node was placed. Also played after falling
+
             place_failed = <SimpleSoundSpec>,
             place_failed = <SimpleSoundSpec>,
+            -- When node placement failed
+
+            fall = <SimpleSoundSpec>,
+            -- When node starts to fall
         },
 
         drop = "",
         },
 
         drop = "",
-        -- Name of dropped node when dug. Default is the node itself.
-        -- Alternatively:
+        -- Name of dropped item when dug.
+        -- Default dropped item is the node itself.
+        -- Using a table allows multiple items, drop chances and tool filtering.
+        -- Tool filtering was undocumented until recently, tool filtering by string
+        -- matching is deprecated.
         drop = {
         drop = {
-            -- Maximum number of items to drop
             max_items = 1,
             max_items = 1,
-            -- Choose max_items randomly from this list
+            -- Maximum number of item lists to drop.
+            -- The entries in 'items' are processed in order. For each:
+            -- Tool filtering is applied, chance of drop is applied, if both are
+            -- successful the entire item list is dropped.
+            -- Entry processing continues until the number of dropped item lists
+            -- equals 'max_items'.
+            -- Therefore, entries should progress from low to high drop chance.
             items = {
             items = {
+                -- Entry examples.
                 {
                 {
-                    items = {"foo:bar", "baz:frob"},  -- Items to drop
-                    rarity = 1,  -- Probability of dropping is 1 / rarity
-                    inherit_color = true, -- Inherit palette color from the node
+                    -- 1 in 1000 chance of dropping a diamond.
+                    -- Default rarity is '1'.
+                    rarity = 1000,
+                    items = {"default:diamond"},
+                },
+                {
+                    -- Only drop if using a tool whose name is identical to one
+                    -- of these.
+                    tools = {"default:shovel_mese", "default:shovel_diamond"},
+                    rarity = 5,
+                    items = {"default:dirt"},
+                    -- Whether all items in the dropped item list inherit the
+                    -- hardware coloring palette color from the dug node.
+                    -- Default is 'false'.
+                    inherit_color = true,
+                },
+                {
+                    -- Only drop if using a tool whose name contains
+                    -- "default:shovel_" (this tool filtering by string matching
+                    -- is deprecated).
+                    tools = {"~default:shovel_"},
+                    rarity = 2,
+                    -- The item list dropped.
+                    items = {"default:sand", "default:desert_sand"},
                 },
             },
         },
 
                 },
             },
         },
 
-        on_construct = func(pos),
+        on_construct = function(pos),
         -- 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).
         -- default: nil
 
         -- 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).
         -- default: nil
 
-        on_destruct = func(pos),
+        on_destruct = function(pos),
         -- Node destructor; called before removing node.
         -- Not called for bulk node placement.
         -- default: nil
 
         -- Node destructor; called before removing node.
         -- Not called for bulk node placement.
         -- default: nil
 
-        after_destruct = func(pos, oldnode),
+        after_destruct = function(pos, oldnode),
         -- Node destructor; called after removing node.
         -- Not called for bulk node placement.
         -- default: nil
 
         -- Node destructor; called after removing node.
         -- Not called for bulk node placement.
         -- default: nil
 
-        on_flood = func(pos, oldnode, newnode),
+        on_flood = function(pos, oldnode, newnode),
         -- Called when a liquid (newnode) is about to flood oldnode, if it has
         -- `floodable = true` in the nodedef. Not called for bulk node placement
         -- (i.e. schematics and VoxelManip) or air nodes. If return true the
         -- Called when a liquid (newnode) is about to flood oldnode, if it has
         -- `floodable = true` in the nodedef. Not called for bulk node placement
         -- (i.e. schematics and VoxelManip) or air nodes. If return true the
@@ -6042,7 +6909,7 @@ Used by `minetest.register_node`.
         -- Default: nil
         -- Warning: making a liquid node 'floodable' will cause problems.
 
         -- Default: nil
         -- Warning: making a liquid node 'floodable' will cause problems.
 
-        preserve_metadata = func(pos, oldnode, oldmeta, drops),
+        preserve_metadata = function(pos, oldnode, oldmeta, drops),
         -- Called when oldnode is about be converted to an item, but before the
         -- node is deleted from the world or the drops are added. This is
         -- generally the result of either the node being dug or an attached node
         -- Called when oldnode is about be converted to an item, but before the
         -- node is deleted from the world or the drops are added. This is
         -- generally the result of either the node being dug or an attached node
@@ -6052,28 +6919,28 @@ Used by `minetest.register_node`.
         -- "ItemStackMetaRef".
         -- default: nil
 
         -- "ItemStackMetaRef".
         -- default: nil
 
-        after_place_node = func(pos, placer, itemstack, pointed_thing),
+        after_place_node = function(pos, placer, itemstack, pointed_thing),
         -- Called after constructing node when node was placed using
         -- minetest.item_place_node / minetest.place_node.
         -- If return true no item is taken from itemstack.
         -- `placer` may be any valid ObjectRef or nil.
         -- default: nil
 
         -- Called after constructing node when node was placed using
         -- minetest.item_place_node / minetest.place_node.
         -- If return true no item is taken from itemstack.
         -- `placer` may be any valid ObjectRef or nil.
         -- default: nil
 
-        after_dig_node = func(pos, oldnode, oldmetadata, digger),
+        after_dig_node = function(pos, oldnode, oldmetadata, digger),
         -- oldmetadata is in table format.
         -- Called after destructing node when node was dug using
         -- minetest.node_dig / minetest.dig_node.
         -- default: nil
 
         can_dig = function(pos, [player]),
         -- oldmetadata is in table format.
         -- Called after destructing node when node was dug using
         -- minetest.node_dig / minetest.dig_node.
         -- default: nil
 
         can_dig = function(pos, [player]),
-
-        on_punch = func(pos, node, puncher, pointed_thing),
         -- Returns true if node can be dug, or false if not.
         -- default: nil
         -- Returns true if node can be dug, or false if not.
         -- default: nil
+
+        on_punch = function(pos, node, puncher, pointed_thing),
         -- default: minetest.node_punch
         -- By default calls minetest.register_on_punchnode callbacks.
 
         -- default: minetest.node_punch
         -- By default calls minetest.register_on_punchnode callbacks.
 
-        on_rightclick = func(pos, node, clicker, itemstack, pointed_thing),
+        on_rightclick = function(pos, node, clicker, itemstack, pointed_thing),
         -- default: nil
         -- itemstack will hold clicker's wielded item.
         -- Shall return the leftover itemstack.
         -- default: nil
         -- itemstack will hold clicker's wielded item.
         -- Shall return the leftover itemstack.
@@ -6081,7 +6948,7 @@ Used by `minetest.register_node`.
         -- This function does not get triggered by clients <=0.4.16 if the
         -- "formspec" node metadata field is set.
 
         -- This function does not get triggered by clients <=0.4.16 if the
         -- "formspec" node metadata field is set.
 
-        on_dig = func(pos, node, digger),
+        on_dig = function(pos, node, digger),
         -- default: minetest.node_dig
         -- By default checks privileges, wears out tool and removes node.
 
         -- default: minetest.node_dig
         -- By default checks privileges, wears out tool and removes node.
 
@@ -6092,33 +6959,34 @@ Used by `minetest.register_node`.
         -- return true to run the timer for another cycle with the same timeout
         -- value.
 
         -- return true to run the timer for another cycle with the same timeout
         -- value.
 
-        on_receive_fields = func(pos, formname, fields, sender),
+        on_receive_fields = function(pos, formname, fields, sender),
         -- fields = {name1 = value1, name2 = value2, ...}
         -- Called when an UI form (e.g. sign text input) returns data.
         -- fields = {name1 = value1, name2 = value2, ...}
         -- Called when an UI form (e.g. sign text input) returns data.
+        -- See minetest.register_on_player_receive_fields for more info.
         -- default: nil
 
         -- default: nil
 
-        allow_metadata_inventory_move = func(pos, from_list, from_index, to_list, to_index, count, player),
+        allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player),
         -- Called when a player wants to move items inside the inventory.
         -- Return value: number of items allowed to move.
 
         -- Called when a player wants to move items inside the inventory.
         -- Return value: number of items allowed to move.
 
-        allow_metadata_inventory_put = func(pos, listname, index, stack, player),
+        allow_metadata_inventory_put = function(pos, listname, index, stack, player),
         -- Called when a player wants to put something into the inventory.
         -- Return value: number of items allowed to put.
         -- Return value -1: Allow and don't modify item count in inventory.
 
         -- Called when a player wants to put something into the inventory.
         -- Return value: number of items allowed to put.
         -- Return value -1: Allow and don't modify item count in inventory.
 
-        allow_metadata_inventory_take = func(pos, listname, index, stack, player),
+        allow_metadata_inventory_take = function(pos, listname, index, stack, player),
         -- Called when a player wants to take something out of the inventory.
         -- Return value: number of items allowed to take.
         -- Return value -1: Allow and don't modify item count in inventory.
 
         -- Called when a player wants to take something out of the inventory.
         -- Return value: number of items allowed to take.
         -- Return value -1: Allow and don't modify item count in inventory.
 
-        on_metadata_inventory_move = func(pos, from_list, from_index, to_list, to_index, count, player),
-        on_metadata_inventory_put = func(pos, listname, index, stack, player),
-        on_metadata_inventory_take = func(pos, listname, index, stack, player),
+        on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player),
+        on_metadata_inventory_put = function(pos, listname, index, stack, player),
+        on_metadata_inventory_take = function(pos, listname, index, stack, player),
         -- Called after the actual action has happened, according to what was
         -- allowed.
         -- No return value.
 
         -- Called after the actual action has happened, according to what was
         -- allowed.
         -- No return value.
 
-        on_blast = func(pos, intensity),
+        on_blast = function(pos, intensity),
         -- intensity: 1.0 = mid range of regular TNT.
         -- If defined, called when an explosion touches the node, instead of
         -- removing the node.
         -- intensity: 1.0 = mid range of regular TNT.
         -- If defined, called when an explosion touches the node, instead of
         -- removing the node.
@@ -6323,14 +7191,20 @@ Used by `minetest.register_biome`.
         depth_riverbed = 2,
         -- Node placed under river water and thickness of this layer
 
         depth_riverbed = 2,
         -- Node placed under river water and thickness of this layer
 
-        node_cave_liquid = "default:water_source",
-        -- Nodes placed as a blob of liquid in 50% of large caves.
-        -- If absent, cave liquids fall back to classic behaviour of lava or
-        -- water distributed according to a hardcoded 3D noise.
+        node_cave_liquid = "default:lava_source",
+        node_cave_liquid = {"default:water_source", "default:lava_source"},
+        -- Nodes placed inside 50% of the medium size caves.
+        -- 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.
+        -- For no cave liquid, specify "air".
 
         node_dungeon = "default:cobble",
         -- Node used for primary dungeon structure.
 
         node_dungeon = "default:cobble",
         -- Node used for primary dungeon structure.
-        -- If absent, dungeon materials fall back to classic behaviour.
+        -- If absent, dungeon nodes fall back to the 'mapgen_cobble' mapgen
+        -- alias, if that is also absent, dungeon nodes fall back to the biome
+        -- 'node_stone'.
         -- If present, the following two nodes are also used.
 
         node_dungeon_alt = "default:mossycobble",
         -- If present, the following two nodes are also used.
 
         node_dungeon_alt = "default:mossycobble",
@@ -6553,29 +7427,60 @@ 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>`
 
 * `()` signifies grouping. For example, when param1 and param2 are both
   required, or only param3 is required: `(<param1> <param2>) | <param3>`
 
+Privilege definition
+--------------------
+
+Used by `minetest.register_privilege`.
+
+    {
+        description = "",
+        -- Privilege description
+
+        give_to_singleplayer = true,
+        -- Whether to grant the privilege to singleplayer.
+
+        give_to_admin = true,
+        -- Whether to grant the privilege to the server admin.
+        -- Uses value of 'give_to_singleplayer' by default.
+
+        on_grant = function(name, granter_name),
+        -- Called when given to player 'name' by 'granter_name'.
+        -- 'granter_name' will be nil if the priv was granted by a mod.
+
+        on_revoke = function(name, revoker_name),
+        -- Called when taken from player 'name' by 'revoker_name'.
+        -- 'revoker_name' will be nil if the priv was revoked by a mod.
+
+        -- Note that the above two callbacks will be called twice if a player is
+        -- responsible, once with the player name, and then with a nil player
+        -- name.
+        -- Return true in the above callbacks to stop register_on_priv_grant or
+        -- revoke being called.
+    }
+
 Detached inventory callbacks
 ----------------------------
 
 Used by `minetest.create_detached_inventory`.
 
     {
 Detached inventory callbacks
 ----------------------------
 
 Used by `minetest.create_detached_inventory`.
 
     {
-        allow_move = func(inv, from_list, from_index, to_list, to_index, count, player),
+        allow_move = function(inv, from_list, from_index, to_list, to_index, count, player),
         -- Called when a player wants to move items inside the inventory.
         -- Return value: number of items allowed to move.
 
         -- Called when a player wants to move items inside the inventory.
         -- Return value: number of items allowed to move.
 
-        allow_put = func(inv, listname, index, stack, player),
+        allow_put = function(inv, listname, index, stack, player),
         -- Called when a player wants to put something into the inventory.
         -- Return value: number of items allowed to put.
         -- Return value -1: Allow and don't modify item count in inventory.
 
         -- Called when a player wants to put something into the inventory.
         -- Return value: number of items allowed to put.
         -- Return value -1: Allow and don't modify item count in inventory.
 
-        allow_take = func(inv, listname, index, stack, player),
+        allow_take = function(inv, listname, index, stack, player),
         -- Called when a player wants to take something out of the inventory.
         -- Return value: number of items allowed to take.
         -- Return value -1: Allow and don't modify item count in inventory.
 
         -- Called when a player wants to take something out of the inventory.
         -- Return value: number of items allowed to take.
         -- Return value -1: Allow and don't modify item count in inventory.
 
-        on_move = func(inv, from_list, from_index, to_list, to_index, count, player),
-        on_put = func(inv, listname, index, stack, player),
-        on_take = func(inv, listname, index, stack, player),
+        on_move = function(inv, from_list, from_index, to_list, to_index, count, player),
+        on_put = function(inv, listname, index, stack, player),
+        on_take = function(inv, listname, index, stack, player),
         -- Called after the actual action has happened, according to what was
         -- allowed.
         -- No return value.
         -- Called after the actual action has happened, according to what was
         -- allowed.
         -- No return value.
@@ -6615,6 +7520,9 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`.
 
         size = { x=100, y=100 },
         -- Size of element in pixels
 
         size = { x=100, y=100 },
         -- Size of element in pixels
+
+        z_index = 0,
+        -- Z index : lower z-index HUDs are displayed behind higher z-index HUDs
     }
 
 Particle definition
     }
 
 Particle definition
@@ -6785,38 +7693,38 @@ Authentication handler definition
 Used by `minetest.register_authentication_handler`.
 
     {
 Used by `minetest.register_authentication_handler`.
 
     {
-        get_auth = func(name),
+        get_auth = function(name),
         -- Get authentication data for existing player `name` (`nil` if player
         -- doesn't exist).
         -- Returns following structure:
         -- `{password=<string>, privileges=<table>, last_login=<number or nil>}`
 
         -- Get authentication data for existing player `name` (`nil` if player
         -- doesn't exist).
         -- Returns following structure:
         -- `{password=<string>, privileges=<table>, last_login=<number or nil>}`
 
-        create_auth = func(name, password),
+        create_auth = function(name, password),
         -- Create new auth data for player `name`.
         -- Note that `password` is not plain-text but an arbitrary
         -- representation decided by the engine.
 
         -- Create new auth data for player `name`.
         -- Note that `password` is not plain-text but an arbitrary
         -- representation decided by the engine.
 
-        delete_auth = func(name),
+        delete_auth = function(name),
         -- Delete auth data of player `name`.
         -- Returns boolean indicating success (false if player is nonexistent).
 
         -- Delete auth data of player `name`.
         -- Returns boolean indicating success (false if player is nonexistent).
 
-        set_password = func(name, password),
+        set_password = function(name, password),
         -- Set password of player `name` to `password`.
         -- Auth data should be created if not present.
 
         -- Set password of player `name` to `password`.
         -- Auth data should be created if not present.
 
-        set_privileges = func(name, privileges),
+        set_privileges = function(name, privileges),
         -- Set privileges of player `name`.
         -- `privileges` is in table form, auth data should be created if not
         -- present.
 
         -- Set privileges of player `name`.
         -- `privileges` is in table form, auth data should be created if not
         -- present.
 
-        reload = func(),
+        reload = function(),
         -- Reload authentication data from the storage location.
         -- Returns boolean indicating success.
 
         -- Reload authentication data from the storage location.
         -- Returns boolean indicating success.
 
-        record_login = func(name),
+        record_login = function(name),
         -- Called when player joins, used for keeping track of last_login
 
         -- Called when player joins, used for keeping track of last_login
 
-        iterate = func(),
+        iterate = function(),
         -- Returns an iterator (use with `for` loops) for all player names
         -- currently in the auth database
     }
         -- Returns an iterator (use with `for` loops) for all player names
         -- currently in the auth database
     }