Add multiple element selection to `style` and `style_type` (#9380)
[oweals/minetest.git] / doc / lua_api.txt
index cb92ea7b85c3f63e9e0ea2f070ba73dfce3128df..4b7132828bb0ab1a663727bbd7e1781ed072aa26 100644 (file)
@@ -826,7 +826,7 @@ Examples of sound parameter tables:
         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
@@ -839,34 +839,58 @@ Examples of sound parameter tables:
         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
-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.
 
+`exclude_player = name` can be applied to locationless, positional and object-
+bound sounds to exclude a single player from hearing them.
+
 `SimpleSoundSpec`
 -----------------
 
-* e.g. `""`
-* e.g. `"default_place_node"`
-* e.g. `{}`
-* e.g. `{name = "default_place_node"}`
-* e.g. `{name = "default_place_node", gain = 1.0}`
-* e.g. `{name = "default_place_node", gain = 1.0, pitch = 1.0}`
+Specifies a sound name, gain (=volume) and pitch.
+This is either a string or a table.
+
+In string form, you just specify the sound name or
+the empty string for no sound.
+
+Table form has the following fields:
+
+* `name`: Sound name
+* `gain`: Volume (`1.0` = 100%)
+* `pitch`: Pitch (`1.0` = 100%)
 
+`gain` and `pitch` are optional and default to `1.0`.
+
+Examples:
+
+* `""`: 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
 
 Special sound files
 -------------------
 
 These sound files are played back by the engine if provided.
 
- * `main_menu`: Looped sound in the main menu (gain = 1.0)
  * `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)
 
 Registered definitions
 ======================
@@ -924,7 +948,8 @@ Node paramtypes
 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
@@ -941,19 +966,27 @@ node definition.
         * 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"`
-    * 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"`
+    * 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
@@ -972,13 +1005,13 @@ node definition.
             * 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"`
-    * 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)
@@ -1010,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"}`
+* `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].
 
@@ -1481,7 +1517,8 @@ Usage
 -----
 
 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}
@@ -1930,8 +1967,6 @@ For coloured text you can use `minetest.colorize`.
 
 Since formspec version 3, elements drawn in the order they are defined. All
 background elements are drawn before all other elements.
-`list` elements are an exception here. They are drawn last. This, however, might
-be changed at any time.
 
 **WARNING**: do _not_ use a element name starting with `key_`; those names are
 reserved to pass key press events to formspec!
@@ -2042,7 +2077,6 @@ Elements
   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.
-* **Note**: Lists are drawn after every other element. This might change at any time.
 
 ### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
 
@@ -2050,7 +2084,6 @@ Elements
   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.
-* **Note**: Lists are drawn after every other element. This might change at any time.
 
 ### `listring[<inventory location>;<list name>]`
 
@@ -2100,6 +2133,15 @@ Elements
 
 * 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
@@ -2210,7 +2252,7 @@ Elements
   an inventory slot.
 
 ### `hypertext[<X>,<Y>;<W>,<H>;<name>;<text>]`
-* Displays a static formated text with hyperlinks.
+* Displays a static formatted 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.
@@ -2453,16 +2495,16 @@ Elements
         * `span=<value>`: number of following columns to affect
           (default: infinite).
 
-### `style[<name>;<prop1>;<prop2>;...]`
+### `style[<name 1>,<name 2>,...;<prop1>;<prop2>;...]`
 
-* Set the style for the named element `name`.
+* Set the style for the named element(s) `name`.
 * Note: this **must** be before the element is defined.
 * See [Styling Formspecs].
 
 
-### `style_type[<type>;<prop1>;<prop2>;...]`
+### `style_type[<type 1>,<type 2>,...;<prop1>;<prop2>;...]`
 
-* Sets the style for all elements of type `type` which appear after this element.
+* Sets the style for all elements of type(s) `type` which appear after this element.
 * See [Styling Formspecs].
 
 Migrating to Real Coordinates
@@ -2505,13 +2547,18 @@ Styling Formspecs
 
 Formspec elements can be themed using the style elements:
 
-    style[<name>;<prop1>;<prop2>;...]
-    style_type[<type>;<prop1>;<prop2>;...]
+    style[<name 1>,<name 2>,...;<prop1>;<prop2>;...]
+    style_type[<type 1>,<type 2>,...;<prop1>;<prop2>;...]
 
 Where a prop is:
 
     property_name=property_value
 
+A name/type can optionally be a comma separated list of names/types, like so:
+
+    world_delete,world_create,world_configure
+    button,image_button
+
 For example:
 
     style_type[button;bgcolor=#006699]
@@ -2547,6 +2594,11 @@ Some types may inherit styles from parent types.
 
 ### 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.
@@ -2554,6 +2606,8 @@ Some types may inherit styles from parent types.
     * 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.
@@ -2570,6 +2624,11 @@ Some types may inherit styles from parent types.
     * 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)
@@ -2901,6 +2960,15 @@ Helper functions
 * `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
@@ -3683,7 +3751,7 @@ Methods
 -----------
 
 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
@@ -3714,6 +3782,28 @@ The coordinates are *inclusive*, like most other things in Minetest.
       `[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`.
+
 
 
 
@@ -4058,6 +4148,9 @@ Call these functions only at load time!
 * `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
@@ -4072,12 +4165,15 @@ Call these functions only at load time!
     * 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_ores()`
-    * Clears all ores currently registered.
 * `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.
 
@@ -4310,9 +4406,13 @@ Setting-related
 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`
@@ -4851,33 +4951,36 @@ Rollback
     * 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
-    * 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(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`
-    * `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_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
-      different spot. Can be `nil`
-    * See `minetest.do_item_eat`
+      different spot.
 
 Defaults for the `on_punch` and `on_dig` node definition callbacks
 ------------------------------------------------------------------
@@ -4891,10 +4994,15 @@ Defaults for the `on_punch` and `on_dig` node definition callbacks
 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
+    * `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)`
+    * `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.
@@ -5603,8 +5711,21 @@ Can be gotten via `minetest.get_node_timer(pos)`.
 -----------
 
 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
 
@@ -5675,7 +5796,10 @@ This is basically a reference to a C++ `ServerActiveObject`
 
 #### Lua entity only (no-op for other objects)
 
-* `remove()`: remove object (after returning from Lua)
+* `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)`
@@ -6036,6 +6160,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
+* `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"""`.
@@ -6110,12 +6238,11 @@ Player properties need to be saved manually.
         -- Defaults to 1.625.
 
         physical = true,
+        -- Collide with `walkable` nodes.
 
         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.
@@ -6149,7 +6276,8 @@ Player properties need to be saved manually.
         -- 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.
@@ -6179,14 +6307,20 @@ Player properties need to be saved manually.
         -- spritesheet.
 
         is_visible = true,
+        -- If false, object is invisible and can't be pointed.
 
         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,
+        -- 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.
@@ -6462,9 +6596,14 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         -- 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 = function(itemstack, placer, pointed_thing),
@@ -6522,8 +6661,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
-        -- 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
@@ -6633,7 +6773,8 @@ Used by `minetest.register_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",
@@ -6673,12 +6814,33 @@ Used by `minetest.register_node`.
         -- liquid, flowingliquid drawtypes can only wave like liquids.
 
         sounds = {
+            -- Definition of node sounds to be played at various events.
+            -- All fields in this table are optional.
+
             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>,
+            -- Node was dug
+
             place = <SimpleSoundSpec>,
+            -- Node was placed. Also played after falling
+
             place_failed = <SimpleSoundSpec>,
+            -- When node placement failed
+
             fall = <SimpleSoundSpec>,
+            -- When node starts to fall
         },
 
         drop = "",