]> git.lizzy.rs Git - minetest.git/blobdiff - doc/lua_api.txt
HTTP API: Allow binary downloads and headers (#8573)
[minetest.git] / doc / lua_api.txt
index 26d8a3d91d44213f98020ceb5f8a598c4b27df9d..352b04cb0d4347bd0387597f2d3003e8bd85aa64 100644 (file)
@@ -4,9 +4,8 @@ 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/>
 
-
 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.
@@ -258,13 +257,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.
 
@@ -847,7 +848,10 @@ Examples of sound parameter tables:
     }
 
 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,`
+one player using `to_player = name,`.
+
+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.
 
 `SimpleSoundSpec`
 -----------------
 
 `SimpleSoundSpec`
 -----------------
@@ -1166,6 +1170,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
 ===
 
@@ -1184,9 +1246,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
@@ -1496,6 +1559,7 @@ Special groups
 * `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
 * `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
+* `float`: the node will not fall through liquids
 * `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.
 * `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.
@@ -1797,8 +1861,16 @@ 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.
@@ -2291,6 +2363,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:
@@ -2320,13 +2398,19 @@ 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.
 
 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)`:
@@ -2354,6 +2438,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`
@@ -2393,12 +2478,35 @@ 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.
 * `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a
   position.
     * returns the exact position on the surface of a pointed node
 * `table.insert_all(table, other_table)`:
     * Appends all values in `other_table` to `table` - uses `#table + 1` to
       find new indices.
 * `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
 
 
 
 
 
 
@@ -3144,7 +3252,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.
@@ -3418,11 +3527,14 @@ Utilities
           -- Chat messages are no longer predicted (0.4.16)
           no_chat_message_prediction = true,
           -- The transparency channel of textures can optionally be used on
           -- Chat messages are no longer predicted (0.4.16)
           no_chat_message_prediction = true,
           -- The transparency channel of textures can optionally be used on
-          -- objects (ie: players and lua entities) (5.0)
+          -- 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)
+          -- (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,
       }
 
 * `minetest.has_feature(arg)`: returns `boolean, missing_features`
       }
 
 * `minetest.has_feature(arg)`: returns `boolean, missing_features`
@@ -3511,12 +3623,13 @@ Call these functions only at load time!
 * `minetest.register_entity(name, entity definition)`
 * `minetest.register_abm(abm definition)`
 * `minetest.register_lbm(lbm definition)`
 * `minetest.register_entity(name, entity definition)`
 * `minetest.register_abm(abm definition)`
 * `minetest.register_lbm(lbm definition)`
-* `minetest.register_alias(name, convert_to)`
+* `minetest.register_alias(alias, original_name)`
     * Also use this to set the 'mapgen aliases' needed in a game for the core
       mapgens. See [Mapgen aliases] section above.
     * 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)`
+* `minetest.register_alias_force(alias, original_name)`
 * `minetest.register_ore(ore definition)`
     * Returns an integer uniquely identifying the registered ore on success.
 * `minetest.register_ore(ore definition)`
     * Returns an integer 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 uniquely identifying the registered biome on success.
 * `minetest.unregister_biome(name)`
 * `minetest.register_biome(biome definition)`
     * Returns an integer uniquely identifying the registered biome on success.
 * `minetest.unregister_biome(name)`
@@ -3525,6 +3638,8 @@ Call these functions only at load time!
 * `minetest.register_decoration(decoration definition)`
     * Returns an integer uniquely identifying the registered decoration on
       success.
 * `minetest.register_decoration(decoration definition)`
     * Returns an integer uniquely identifying the registered decoration on
       success.
+    * The order of decoration registrations determines the order of decoration
+      generation.
 * `minetest.register_schematic(schematic definition)`
     * Returns an integer uniquely identifying the registered schematic on
       success.
 * `minetest.register_schematic(schematic definition)`
     * Returns an integer uniquely identifying the registered schematic on
       success.
@@ -3606,6 +3721,7 @@ Call these functions only at load time!
     * Called after a new player has been created
 * `minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage))`
     * Called when a player is punched
     * Called after a new player has been created
 * `minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage))`
     * 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
@@ -3625,15 +3741,16 @@ 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.
+       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
 * `minetest.register_on_dieplayer(function(ObjectRef, reason))`
     * Called when a player dies
     * `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange
@@ -3669,11 +3786,39 @@ Call these functions only at load time!
     * 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(function(player, formname, fields))`
     * 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(function(player, formname, fields))`
-    * Called when a button is pressed in player's inventory form, when form
-      values are submitted or when the form is actively closed by the player.
-    * Fields are sent for formspec elements which define a field, and the "quit"
-      field is sent when actively closing the form by mouse click, keypress or
-      through a button_exit[] element.
+    * 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
 * `minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv))`
     * Newest functions are called first
     * If function returns `true`, remaining functions are not called
 * `minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv))`
@@ -3886,7 +4031,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.
@@ -5241,6 +5386,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`
 -----------
@@ -5266,9 +5416,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
@@ -5498,7 +5648,7 @@ Used by `ObjectRef` methods. Part of an Entity definition.
 
         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).
@@ -5539,7 +5689,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
@@ -5899,7 +6049,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
@@ -5990,12 +6144,15 @@ 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 = {
             footstep = <SimpleSoundSpec>,
 
         sounds = {
             footstep = <SimpleSoundSpec>,
@@ -6003,20 +6160,48 @@ Used by `minetest.register_node`.
             dug = <SimpleSoundSpec>,
             place = <SimpleSoundSpec>,
             place_failed = <SimpleSoundSpec>,
             dug = <SimpleSoundSpec>,
             place = <SimpleSoundSpec>,
             place_failed = <SimpleSoundSpec>,
+            fall = <SimpleSoundSpec>,
         },
 
         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:
         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.
+                {
+                    -- 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,
+                },
                 {
                 {
-                    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
+                    -- Only drop if using a tool whose name contains
+                    -- "default:shovel_".
+                    tools = {"~default:shovel_"},
+                    rarity = 2,
+                    -- The item list dropped.
+                    items = {"default:sand", "default:desert_sand"},
                 },
             },
         },
                 },
             },
         },
@@ -6099,6 +6284,7 @@ Used by `minetest.register_node`.
         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.
         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.
+        -- See minetest.register_on_player_receive_fields for more info.
         -- default: nil
 
         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player),
         -- default: nil
 
         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player),
@@ -6327,10 +6513,14 @@ 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.