Lua_api.txt: Re-order some sections. Alphabeticise class reference (#7487)
authorParamat <paramat@users.noreply.github.com>
Tue, 26 Jun 2018 01:34:27 +0000 (02:34 +0100)
committerGitHub <noreply@github.com>
Tue, 26 Jun 2018 01:34:27 +0000 (02:34 +0100)
doc/lua_api.txt

index 47931eb0076dc4eac142bf5fb05505ee5a0258f2..9fb22556bdc2d5f41f6a9641bcf0e06fea7ec1ff 100644 (file)
@@ -1147,1509 +1147,1957 @@ A box of a regular node would look like:
 
     {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
 
-Perlin noise
-------------
-Perlin noise creates a continuously-varying value depending on the input values.
-Usually in Minetest the input values are either 2D or 3D co-ordinates in nodes.
-The result is used during map generation to create the terrain shape, vary heat
-and humidity to distribute biomes, vary the density of decorations or vary the
-structure of ores.
 
-### Structure of perlin noise
-An 'octave' is a simple noise generator that outputs a value between -1 and 1.
-The smooth wavy noise it generates has a single characteristic scale, almost
-like a 'wavelength', so on its own does not create fine detail.
-Due to this perlin noise combines several octaves to create variation on
-multiple scales. Each additional octave has a smaller 'wavelength' than the
-previous.
 
-This combination results in noise varying very roughly between -2.0 and 2.0 and
-with an average value of 0.0, so `scale` and `offset` are then used to multiply
-and offset the noise variation.
+HUD element types
+-----------------
+The position field is used for all element types.
 
-The final perlin noise variation is created as follows:
+To account for differing resolutions, the position coordinates are the
+percentage of the screen, ranging in value from `0` to `1`.
 
-noise = offset + scale * (octave1 +
-                          octave2 * persistence +
-                          octave3 * persistence ^ 2 +
-                          octave4 * persistence ^ 3 +
-                          ...)
+The name field is not yet used, but should contain a description of what the
+HUD element represents. The direction field is the direction in which something
+is drawn.
 
-Noise Parameters
-----------------
-Noise Parameters are commonly called `NoiseParams`.
+`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.
 
-### `offset`
-After the multiplication by `scale` this is added to the result and is the final
-step in creating the noise value.
-Can be positive or negative.
+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.
 
-### `scale`
-Once all octaves have been combined, the result is multiplied by this.
-Can be positive or negative.
+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
+precisely positioned items in the HUD.
 
-### `spread`
-For octave1, this is roughly the change of input value needed for a very large
-variation in the noise value generated by octave1. It is almost like a
-'wavelength' for the wavy noise variation.
-Each additional octave has a 'wavelength' that is smaller than the previous
-octave, to create finer detail. `spread` will therefore roughly be the typical
-size of the largest structures in the final noise variation.
+**Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling
+factor!
 
-`spread` is a vector with values for x, y, z to allow the noise variation to be
-stretched or compressed in the desired axes.
-Values are positive numbers.
+Below are the specific uses for fields in each type; fields not listed for that
+type are ignored.
 
-### `seed`
-This is a whole number that determines the entire pattern of the noise
-variation. Altering it enables different noise patterns to be created.
-With other parameters equal, different seeds produce different noise patterns
-and identical seeds produce identical noise patterns.
+### `image`
+Displays an image on the HUD.
 
-For this parameter you can randomly choose any whole number. Usually it is
-preferable for this to be different from other seeds, but sometimes it is useful
-to be able to create identical noise patterns.
+* `scale`: The scale of the image, with 1 being the original texture size.
+  Only the X coordinate scale is used (positive values).
+  Negative values represent that percentage of the screen it
+  should take; e.g. `x=-100` means 100% (width).
+* `text`: The name of the texture that is displayed.
+* `alignment`: The alignment of the image.
+* `offset`: offset in pixels from position.
 
-When used in mapgen this is actually a 'seed offset', it is added to the
-'world seed' to create the seed used by the noise, to ensure the noise has a
-different pattern in different worlds.
+### `text`
+Displays text on the HUD.
 
-### `octaves`
-The number of simple noise generators that are combined.
-A whole number, 1 or more.
-Each additional octave adds finer detail to the noise but also increases the
-noise calculation load.
-3 is a typical minimum for a high quality, complex and natural-looking noise
-variation. 1 octave has a slight 'gridlike' appearence.
+* `scale`: Defines the bounding rectangle of the text.
+  A value such as `{x=100, y=100}` should work.
+* `text`: The text to be displayed in the HUD element.
+* `number`: An integer containing the RGB value of the color used to draw the
+  text. Specify `0xFFFFFF` for white text, `0xFF0000` for red, and so on.
+* `alignment`: The alignment of the text.
+* `offset`: offset in pixels from position.
 
-Choose the number of octaves according to the `spread` and `lacunarity`, and the
-size of the finest detail you require. For example:
-if `spread` is 512 nodes, `lacunarity` is 2.0 and finest detail required is 16
-nodes, octaves will be 6 because the 'wavelengths' of the octaves will be
-512, 256, 128, 64, 32, 16 nodes.
-Warning: If the 'wavelength' of any octave falls below 1 an error will occur.
+### `statbar`
+Displays a horizontal bar made up of half-images.
 
-### `persistence`
-Each additional octave has an amplitude that is the amplitude of the previous
-octave multiplied by `persistence`, to reduce the amplitude of finer details,
-as is often helpful and natural to do so.
-Since this controls the balance of fine detail to large-scale detail
-`persistence` can be thought of as the 'roughness' of the noise.
+* `text`: The name of the texture that is used.
+* `number`: The number of half-textures that are displayed.
+  If odd, will end with a vertically center-split texture.
+* `direction`
+* `offset`: offset in pixels from position.
+* `size`: If used, will force full-image size to this value (override texture
+  pack image size)
 
-A positive or negative non-zero number, often between 0.3 and 1.0.
-A common medium value is 0.5, such that each octave has half the amplitude of
-the previous octave.
-This may need to be tuned when altering `lacunarity`; when doing so consider
-that a common medium value is 1 / lacunarity.
+### `inventory`
+* `text`: The name of the inventory list to be displayed.
+* `number`: Number of items in the inventory to be displayed.
+* `item`: Position of item that is selected.
+* `direction`
+* `offset`: offset in pixels from position.
 
-### `lacunarity`
-Each additional octave has a 'wavelength' that is the 'wavelength' of the
-previous octave multiplied by 1 / lacunarity, to create finer detail.
-'lacunarity' is often 2.0 so 'wavelength' often halves per octave.
+### `waypoint`
+Displays distance to selected world position.
 
-A positive number no smaller than 1.0.
-Values below 2.0 create higher quality noise at the expense of requiring more
-octaves to cover a paticular range of 'wavelengths'.
+* `name`: The name of the waypoint.
+* `text`: Distance suffix. Can be blank.
+* `number:` An integer containing the RGB value of the color used to draw the
+  text.
+* `world_pos`: World position of the waypoint.
 
-### `flags`
-Leave this field unset for no special handling.
-Currently supported are `defaults`, `eased` and `absvalue`:
+Representations of simple things
+--------------------------------
 
-#### `defaults`
-Specify this if you would like to keep auto-selection of eased/not-eased while
-specifying some other flags.
+### Position/vector
 
-#### `eased`
-Maps noise gradient values onto a quintic S-curve before performing
-interpolation. This results in smooth, rolling noise.
-Disable this (`noeased`) for sharp-looking noise with a slightly gridded
-appearence.
-If no flags are specified (or defaults is), 2D noise is eased and 3D noise is
-not eased.
-Easing a 3D noise significantly increases the noise calculation load, so use
-with restraint.
+    {x=num, y=num, z=num}
 
-#### `absvalue`
-The absolute value of each octave's noise variation is used when combining the
-octaves. The final perlin noise variation is created as follows:
+For helper functions see "Spatial Vectors".
 
-noise = offset + scale * (abs(octave1) +
-                          abs(octave2) * persistence +
-                          abs(octave3) * persistence ^ 2 +
-                          abs(octave4) * persistence ^ 3 +
-                          ...)
+### `pointed_thing`
+* `{type="nothing"}`
+* `{type="node", under=pos, above=pos}`
+* `{type="object", ref=ObjectRef}`
 
-###Format example
-For 2D or 3D perlin noise or perlin noise maps:
+Flag Specifier Format
+---------------------
+Flags using the standardized flag specifier format can be specified in either
+of two ways, by string or table.
 
-    np_terrain = {
-        offset = 0,
-        scale = 1,
-        spread = {x = 500, y = 500, z = 500},
-        seed = 571347,
-        octaves = 5,
-        persist = 0.63,
-        lacunarity = 2.0,
-        flags = "defaults, absvalue",
-    }
+The string format is a comma-delimited set of flag names; whitespace and
+unrecognized flag fields are ignored. Specifying a flag in the string sets the
+flag, and specifying a flag prefixed by the string `"no"` explicitly
+clears the flag from whatever the default may be.
 
-For 2D noise the Z component of `spread` is still defined but is ignored.
-A single noise parameter table can be used for 2D or 3D noise.
+In addition to the standard string flag format, the schematic flags field can
+also be a table of flag names to boolean values representing whether or not the
+flag is set. Additionally, if a field with the flag name prefixed with `"no"`
+is present, mapped to a boolean of any value, the specified flag is unset.
 
-Ore types
----------
-These tell in what manner the ore is generated.
+E.g. A flag field of value
 
-All default ores are of the uniformly-distributed scatter type.
+    {place_center_x = true, place_center_y=false, place_center_z=true}
 
-### `scatter`
-Randomly chooses a location and generates a cluster of ore.
+is equivalent to
 
-If `noise_params` is specified, the ore will be placed if the 3D perlin noise
-at that point is greater than the `noise_threshold`, giving the ability to
-create a non-equal distribution of ore.
+    {place_center_x = true, noplace_center_y=true, place_center_z=true}
 
-### `sheet`
-Creates a sheet of ore in a blob shape according to the 2D perlin noise
-described by `noise_params` and `noise_threshold`. This is essentially an
-improved version of the so-called "stratus" ore seen in some unofficial mods.
+which is equivalent to
 
-This sheet consists of vertical columns of uniform randomly distributed height,
-varying between the inclusive range `column_height_min` and `column_height_max`.
-If `column_height_min` is not specified, this parameter defaults to 1.
-If `column_height_max` is not specified, this parameter defaults to `clust_size`
-for reverse compatibility. New code should prefer `column_height_max`.
+    "place_center_x, noplace_center_y, place_center_z"
 
-The `column_midpoint_factor` parameter controls the position of the column at
-which ore emanates from.
-If 1, columns grow upward. If 0, columns grow downward. If 0.5, columns grow
-equally starting from each direction.
-`column_midpoint_factor` is a decimal number ranging in value from 0 to 1. If
-this parameter is not specified, the default is 0.5.
+or even
 
-The ore parameters `clust_scarcity` and `clust_num_ores` are ignored for this
-ore type.
+    "place_center_x, place_center_z"
 
-### `puff`
-Creates a sheet of ore in a cloud-like puff shape.
+since, by default, no schematic attributes are set.
 
-As with the `sheet` ore type, the size and shape of puffs are described by
-`noise_params` and `noise_threshold` and are placed at random vertical
-positions within the currently generated chunk.
+Items
+-----
 
-The vertical top and bottom displacement of each puff are determined by the
-noise parameters `np_puff_top` and `np_puff_bottom`, respectively.
+### Item types
+There are three kinds of items: nodes, tools and craftitems.
 
-### `blob`
-Creates a deformed sphere of ore according to 3d perlin noise described by
-`noise_params`. The maximum size of the blob is `clust_size`, and
-`clust_scarcity` has the same meaning as with the `scatter` type.
+* Node (`register_node`): A node from the world.
+* Tool (`register_tool`): A tool/weapon that can dig and damage
+  things according to `tool_capabilities`.
+* Craftitem (`register_craftitem`): A miscellaneous item.
 
-### `vein`
-Creates veins of ore varying in density by according to the intersection of two
-instances of 3d perlin noise with different seeds, both described by
-`noise_params`.
-
-`random_factor` varies the influence random chance has on placement of an ore
-inside the vein, which is `1` by default. Note that modifying this parameter
-may require adjusting `noise_threshold`.
+### Amount and wear
+All item stacks have an amount between 0 to 65535. It is 1 by
+default. Tool item stacks can not have an amount greater than 1.
 
-The parameters `clust_scarcity`, `clust_num_ores`, and `clust_size` are ignored
-by this ore type.
+Tools use a wear (=damage) value ranging from 0 to 65535. The
+value 0 is the default and used is for unworn tools. The values
+1 to 65535 are used for worn tools, where a higher value stands for
+a higher wear. Non-tools always have a wear value of 0.
 
-This ore type is difficult to control since it is sensitive to small changes.
-The following is a decent set of parameters to work from:
+### Item formats
+Items and item stacks can exist in three formats: Serializes, table format
+and `ItemStack`.
 
-    noise_params = {
-        offset  = 0,
-        scale   = 3,
-        spread  = {x=200, y=200, z=200},
-        seed    = 5390,
-        octaves = 4,
-        persist = 0.5,
-        lacunarity = 2.0,
-        flags = "eased",
-    },
-    noise_threshold = 1.6
+#### Serialized
+This is called "stackstring" or "itemstring". It is a simple string with
+1-3 components: the full item identifier, an optional amount and an optional
+wear value. Syntax:
 
-**WARNING**: Use this ore type *very* sparingly since it is ~200x more
-computationally expensive than any other ore.
+    <identifier> [<amount>[ <wear>]]
 
-### `stratum`
-Creates a single undulating ore stratum that is continuous across mapchunk
-borders and horizontally spans the world.
+Examples:
 
-The 2D perlin noise described by `noise_params` defines the Y co-ordinate of
-the stratum midpoint. The 2D perlin noise described by `np_stratum_thickness`
-defines the stratum's vertical thickness (in units of nodes). Due to being
-continuous across mapchunk borders the stratum's vertical thickness is
-unlimited.
+* `'default:apple'`: 1 apple
+* `'default:dirt 5'`: 5 dirt
+* `'default:pick_stone'`: a new stone pickaxe
+* `'default:pick_wood 1 21323'`: a wooden pickaxe, ca. 1/3 worn out
 
-If the noise parameter `noise_params` is omitted the ore will occur from y_min
-to y_max in a simple horizontal stratum.
+#### Table format
+Examples:
 
-A parameter `stratum_thickness` can be provided instead of the noise parameter
-`np_stratum_thickness`, to create a constant thickness.
+5 dirt nodes:
 
-Leaving out one or both noise parameters makes the ore generation less
-intensive, useful when adding multiple strata.
+    {name="default:dirt", count=5, wear=0, metadata=""}
 
-`y_min` and `y_max` define the limits of the ore generation and for performance
-reasons should be set as close together as possible but without clipping the
-stratum's Y variation.
+A wooden pick about 1/3 worn out:
 
-Each node in the stratum has a 1-in-`clust_scarcity` chance of being ore, so a
-solid-ore stratum would require a `clust_scarcity` of 1.
+    {name="default:pick_wood", count=1, wear=21323, metadata=""}
 
-The parameters `clust_num_ores`, `clust_size`, `noise_threshold` and
-`random_factor` are ignored by this ore type.
+An apple:
 
-Ore attributes
---------------
-See section "Flag Specifier Format".
+    {name="default:apple", count=1, wear=0, metadata=""}
 
-Currently supported flags:
-`puff_cliffs`, `puff_additive_composition`.
+#### `ItemStack`
+A native C++ format with many helper methods. Useful for converting
+between formats. See the Class reference section for details.
 
-### `puff_cliffs`
-If set, puff ore generation will not taper down large differences in
-displacement when approaching the edge of a puff. This flag has no effect for
-ore types other than `puff`.
+When an item must be passed to a function, it can usually be in any of
+these formats.
 
-### `puff_additive_composition`
-By default, when noise described by `np_puff_top` or `np_puff_bottom` results
-in a negative displacement, the sub-column at that point is not generated. With
-this attribute set, puff ore generation will instead generate the absolute
-difference in noise displacement values. This flag has no effect for ore types
-other than `puff`.
 
-Decoration types
-----------------
-The varying types of decorations that can be placed.
+Groups
+------
+In a number of places, there is a group table. Groups define the
+properties of a thing (item, node, armor of entity, capabilities of
+tool) in such a way that the engine and other mods can can interact with
+the thing without actually knowing what the thing is.
 
-### `simple`
-Creates a 1 times `H` times 1 column of a specified node (or a random node from
-a list, if a decoration list is specified). Can specify a certain node it must
-spawn next to, such as water or lava, for example. Can also generate a
-decoration of random height between a specified lower and upper bound.
-This type of decoration is intended for placement of grass, flowers, cacti,
-papyri, waterlilies and so on.
+### Usage
+Groups are stored in a table, having the group names with keys and the
+group ratings as values. For example:
 
-### `schematic`
-Copies a box of `MapNodes` from a specified schematic file (or raw description).
-Can specify a probability of a node randomly appearing when placed.
-This decoration type is intended to be used for multi-node sized discrete
-structures, such as trees, cave spikes, rocks, and so on.
+    groups = {crumbly=3, soil=1}
+    -- ^ Default dirt
 
+    groups = {crumbly=2, soil=1, level=2, outerspace=1}
+    -- ^ A more special dirt-kind of thing
 
-Schematic specifier
---------------------
-A schematic specifier identifies a schematic by either a filename to a
-Minetest Schematic file (`.mts`) or through raw data supplied through Lua,
-in the form of a table.  This table specifies the following fields:
+Groups always have a rating associated with them. If there is no
+useful meaning for a rating for an enabled group, it shall be `1`.
 
-* The `size` field is a 3D vector containing the dimensions of the provided
-  schematic. (required)
-* The `yslice_prob` field is a table of {ypos, prob} which sets the `ypos`th
-  vertical slice of the schematic to have a `prob / 256 * 100` chance of
-  occurring. (default: 255)
-* The `data` field is a flat table of MapNode tables making up the schematic,
-  in the order of `[z [y [x]]]`. (required)
-  Each MapNode table contains:
-    * `name`: the name of the map node to place (required)
-    * `prob` (alias `param1`): the probability of this node being placed
-      (default: 255)
-    * `param2`: the raw param2 value of the node being placed onto the map
-      (default: 0)
-    * `force_place`: boolean representing if the node should forcibly overwrite
-      any previous contents (default: false)
+When not defined, the rating of a group defaults to `0`. Thus when you
+read groups, you must interpret `nil` and `0` as the same value, `0`.
 
-About probability values:
+You can read the rating of a group for an item or a node by using
 
-* A probability value of `0` or `1` means that node will never appear
-  (0% chance).
-* A probability value of `254` or `255` means the node will always appear
-  (100% chance).
-* If the probability value `p` is greater than `1`, then there is a
-  `(p / 256 * 100)` percent chance that node will appear when the schematic is
-  placed on the map.
+    minetest.get_item_group(itemname, groupname)
 
+### Groups of items
+Groups of items can define what kind of an item it is (e.g. wool).
 
-Schematic attributes
---------------------
-See section "Flag Specifier Format".
+### Groups of nodes
+In addition to the general item things, groups are used to define whether
+a node is destroyable and how long it takes to destroy by a tool.
 
-Currently supported flags: `place_center_x`, `place_center_y`, `place_center_z`,
-                           `force_placement`.
+### Groups of entities
+For entities, groups are, as of now, used only for calculating damage.
+The rating is the percentage of damage caused by tools with this damage group.
+See "Entity damage mechanism".
 
-* `place_center_x`: Placement of this decoration is centered along the X axis.
-* `place_center_y`: Placement of this decoration is centered along the Y axis.
-* `place_center_z`: Placement of this decoration is centered along the Z axis.
-* `force_placement`: Schematic nodes other than "ignore" will replace existing
-  nodes.
+    object.get_armor_groups() --> a group-rating table (e.g. {fleshy=100})
+    object.set_armor_groups({fleshy=30, cracky=80})
 
+### Groups of tools
+Groups in tools define which groups of nodes and entities they are
+effective towards.
 
-HUD element types
------------------
-The position field is used for all element types.
+### Groups in crafting recipes
+An example: Make meat soup from any meat, any water and any bowl:
 
-To account for differing resolutions, the position coordinates are the
-percentage of the screen, ranging in value from `0` to `1`.
+    {
+        output = 'food:meat_soup_raw',
+        recipe = {
+            {'group:meat'},
+            {'group:water'},
+            {'group:bowl'},
+        },
+        -- preserve = {'group:bowl'}, -- Not implemented yet (TODO)
+    }
 
-The name field is not yet used, but should contain a description of what the
-HUD element represents. The direction field is the direction in which something
-is drawn.
+Another example: Make red wool from white wool and red dye:
 
-`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.
+    {
+        type = 'shapeless',
+        output = 'wool:red',
+        recipe = {'wool:white', 'group:dye,basecolor_red'},
+    }
 
-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.
+### 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
+* `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
+* `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
+* `slippery`: Players and items will slide on the node.
+  Slipperiness rises steadily with `slippery` value, starting at 1.
 
-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
-precisely positioned items in the HUD.
 
-**Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling
-factor!
+### Known damage and digging time defining groups
+* `crumbly`: dirt, sand
+* `cracky`: tough but crackable stuff like stone.
+* `snappy`: something that can be cut using fine tools; e.g. leaves, small
+  plants, wire, sheets of metal
+* `choppy`: something that can be cut using force; e.g. trees, wooden planks
+* `fleshy`: Living things like animals and the player. This could imply
+  some blood effects when hitting.
+* `explody`: Especially prone to explosions
+* `oddly_breakable_by_hand`:
+   Can be added to nodes that shouldn't logically be breakable by the
+   hand but are. Somewhat similar to `dig_immediate`, but times are more
+   like `{[1]=3.50,[2]=2.00,[3]=0.70}` and this does not override the
+   speed of a tool if the tool can dig at a faster speed than this
+   suggests for the hand.
 
-Below are the specific uses for fields in each type; fields not listed for that
-type are ignored.
+### Examples of custom groups
+Item groups are often used for defining, well, _groups of items_.
 
-### `image`
-Displays an image on the HUD.
+* `meat`: any meat-kind of a thing (rating might define the size or healing
+  ability or be irrelevant -- it is not defined as of yet)
+* `eatable`: anything that can be eaten. Rating might define HP gain in half
+  hearts.
+* `flammable`: can be set on fire. Rating might define the intensity of the
+  fire, affecting e.g. the speed of the spreading of an open fire.
+* `wool`: any wool (any origin, any color)
+* `metal`: any metal
+* `weapon`: any weapon
+* `heavy`: anything considerably heavy
 
-* `scale`: The scale of the image, with 1 being the original texture size.
-  Only the X coordinate scale is used (positive values).
-  Negative values represent that percentage of the screen it
-  should take; e.g. `x=-100` means 100% (width).
-* `text`: The name of the texture that is displayed.
-* `alignment`: The alignment of the image.
-* `offset`: offset in pixels from position.
+### Digging time calculation specifics
+Groups such as `crumbly`, `cracky` and `snappy` are used for this
+purpose. Rating is `1`, `2` or `3`. A higher rating for such a group implies
+faster digging time.
 
-### `text`
-Displays text on the HUD.
+The `level` group is used to limit the toughness of nodes a tool can dig
+and to scale the digging times / damage to a greater extent.
 
-* `scale`: Defines the bounding rectangle of the text.
-  A value such as `{x=100, y=100}` should work.
-* `text`: The text to be displayed in the HUD element.
-* `number`: An integer containing the RGB value of the color used to draw the
-  text. Specify `0xFFFFFF` for white text, `0xFF0000` for red, and so on.
-* `alignment`: The alignment of the text.
-* `offset`: offset in pixels from position.
+**Please do understand this**, otherwise you cannot use the system to it's
+full potential.
 
-### `statbar`
-Displays a horizontal bar made up of half-images.
+Tools define their properties by a list of parameters for groups. They
+cannot dig other groups; thus it is important to use a standard bunch of
+groups to enable interaction with tools.
 
-* `text`: The name of the texture that is used.
-* `number`: The number of half-textures that are displayed.
-  If odd, will end with a vertically center-split texture.
-* `direction`
-* `offset`: offset in pixels from position.
-* `size`: If used, will force full-image size to this value (override texture
-  pack image size)
+#### Tools definition
+Tools define:
 
-### `inventory`
-* `text`: The name of the inventory list to be displayed.
-* `number`: Number of items in the inventory to be displayed.
-* `item`: Position of item that is selected.
-* `direction`
-* `offset`: offset in pixels from position.
+* Full punch interval
+* Maximum drop level
+* For an arbitrary list of groups:
+    * Uses (until the tool breaks)
+        * Maximum level (usually `0`, `1`, `2` or `3`)
+        * Digging times
+        * Damage groups
 
-### `waypoint`
-Displays distance to selected world position.
+#### Full punch interval
+When used as a weapon, the tool will do full damage if this time is spent
+between punches. If e.g. half the time is spent, the tool will do half
+damage.
 
-* `name`: The name of the waypoint.
-* `text`: Distance suffix. Can be blank.
-* `number:` An integer containing the RGB value of the color used to draw the
-  text.
-* `world_pos`: World position of the waypoint.
+#### Maximum drop level
+Suggests the maximum level of node, when dug with the tool, that will drop
+it's useful item. (e.g. iron ore to drop a lump of iron).
 
-Representations of simple things
---------------------------------
+This is not automated; it is the responsibility of the node definition
+to implement this.
 
-### Position/vector
+#### Uses
+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`.
 
-    {x=num, y=num, z=num}
+* `uses=10, leveldiff=0`: actual uses: 10
+* `uses=10, leveldiff=1`: actual uses: 30
+* `uses=10, leveldiff=2`: actual uses: 90
 
-For helper functions see "Spatial Vectors".
+#### Maximum level
+Tells what is the maximum level of a node of this group that the tool will
+be able to dig.
 
-### `pointed_thing`
-* `{type="nothing"}`
-* `{type="node", under=pos, above=pos}`
-* `{type="object", ref=ObjectRef}`
+#### Digging times
+List of digging times for different ratings of the group, for nodes of the
+maximum level.
 
-Flag Specifier Format
----------------------
-Flags using the standardized flag specifier format can be specified in either
-of two ways, by string or table.
+For example, as a Lua table, `times={2=2.00, 3=0.70}`. This would
+result in the tool to be able to dig nodes that have a rating of `2` or `3`
+for this group, and unable to dig the rating `1`, which is the toughest.
+Unless there is a matching group that enables digging otherwise.
 
-The string format is a comma-delimited set of flag names; whitespace and
-unrecognized flag fields are ignored. Specifying a flag in the string sets the
-flag, and specifying a flag prefixed by the string `"no"` explicitly
-clears the flag from whatever the default may be.
+If the result digging time is 0, a delay of 0.15 seconds is added between
+digging nodes; If the player releases LMB after digging, this delay is set to 0,
+i.e. players can more quickly click the nodes away instead of holding LMB.
 
-In addition to the standard string flag format, the schematic flags field can
-also be a table of flag names to boolean values representing whether or not the
-flag is set. Additionally, if a field with the flag name prefixed with `"no"`
-is present, mapped to a boolean of any value, the specified flag is unset.
+#### Damage groups
+List of damage for groups of entities. See "Entity damage mechanism".
 
-E.g. A flag field of value
+#### Example definition of the capabilities of a tool
 
-    {place_center_x = true, place_center_y=false, place_center_z=true}
+    tool_capabilities = {
+        full_punch_interval=1.5,
+        max_drop_level=1,
+        groupcaps={
+            crumbly={maxlevel=2, uses=20, times={[1]=1.60, [2]=1.20, [3]=0.80}}
+        }
+        damage_groups = {fleshy=2},
+    }
 
-is equivalent to
+This makes the tool be able to dig nodes that fulfil both of these:
 
-    {place_center_x = true, noplace_center_y=true, place_center_z=true}
+* Have the `crumbly` group
+* Have a `level` group less or equal to `2`
 
-which is equivalent to
+Table of resulting digging times:
 
-    "place_center_x, noplace_center_y, place_center_z"
+    crumbly        0     1     2     3     4  <- level
+         ->  0     -     -     -     -     -
+             1  0.80  1.60  1.60     -     -
+             2  0.60  1.20  1.20     -     -
+             3  0.40  0.80  0.80     -     -
 
-or even
+    level diff:    2     1     0    -1    -2
 
-    "place_center_x, place_center_z"
+Table of resulting tool uses:
 
-since, by default, no schematic attributes are set.
+    ->  0     -     -     -     -     -
+        1   180    60    20     -     -
+        2   180    60    20     -     -
+        3   180    60    20     -     -
 
-Items
------
+**Notes**:
 
-### Item types
-There are three kinds of items: nodes, tools and craftitems.
+* At `crumbly==0`, the node is not diggable.
+* At `crumbly==3`, the level difference digging time divider kicks in and makes
+  easy nodes to be quickly breakable.
+* At `level > 2`, the node is not diggable, because it's `level > maxlevel`
 
-* Node (`register_node`): A node from the world.
-* Tool (`register_tool`): A tool/weapon that can dig and damage
-  things according to `tool_capabilities`.
-* Craftitem (`register_craftitem`): A miscellaneous item.
+Entity damage mechanism
+-----------------------
+Damage calculation:
 
-### Amount and wear
-All item stacks have an amount between 0 to 65535. It is 1 by
-default. Tool item stacks can not have an amount greater than 1.
+    damage = 0
+    foreach group in cap.damage_groups:
+        damage += cap.damage_groups[group] * limit(actual_interval /
+               cap.full_punch_interval, 0.0, 1.0)
+            * (object.armor_groups[group] / 100.0)
+            -- Where object.armor_groups[group] is 0 for inexistent values
+    return damage
 
-Tools use a wear (=damage) value ranging from 0 to 65535. The
-value 0 is the default and used is for unworn tools. The values
-1 to 65535 are used for worn tools, where a higher value stands for
-a higher wear. Non-tools always have a wear value of 0.
+Client predicts damage based on damage groups. Because of this, it is able to
+give an immediate response when an entity is damaged or dies; the response is
+pre-defined somehow (e.g. by defining a sprite animation) (not implemented;
+TODO).
+Currently a smoke puff will appear when an entity dies.
 
-### Item formats
-Items and item stacks can exist in three formats: Serializes, table format
-and `ItemStack`.
+The group `immortal` completely disables normal damage.
 
-#### Serialized
-This is called "stackstring" or "itemstring". It is a simple string with
-1-3 components: the full item identifier, an optional amount and an optional
-wear value. Syntax:
+Entities can define a special armor group, which is `punch_operable`. This
+group 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.
 
-    <identifier> [<amount>[ <wear>]]
+On the Lua side, every punch calls:
 
-Examples:
+  entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction, damage)
 
-* `'default:apple'`: 1 apple
-* `'default:dirt 5'`: 5 dirt
-* `'default:pick_stone'`: a new stone pickaxe
-* `'default:pick_wood 1 21323'`: a wooden pickaxe, ca. 1/3 worn out
+This should never be called directly, because damage is usually not handled by
+the entity itself.
 
-#### Table format
-Examples:
+* `puncher` is the object performing the punch. Can be `nil`. Should never be
+  accessed unless absolutely required, to encourage interoperability.
+* `time_from_last_punch` is time from last punch (by `puncher`) or `nil`.
+* `tool_capabilities` can be `nil`.
+* `direction` is a unit vector, pointing from the source of the punch to
+   the punched object.
+* `damage` damage that will be done to entity
+Return value of this function will determine if damage is done by this function
+(retval true) or shall be done by engine (retval false)
 
-5 dirt nodes:
+To punch an entity/object in Lua, call:
 
-    {name="default:dirt", count=5, wear=0, metadata=""}
+  object:punch(puncher, time_from_last_punch, tool_capabilities, direction)
 
-A wooden pick about 1/3 worn out:
+* Return value is tool wear.
+* Parameters are equal to the above callback.
+* If `direction` equals `nil` and `puncher` does not equal `nil`, `direction`
+  will be automatically filled in based on the location of `puncher`.
 
-    {name="default:pick_wood", count=1, wear=21323, metadata=""}
+Node Metadata
+-------------
+The instance of a node in the world normally only contains the three values
+mentioned in "Nodes". However, it is possible to insert extra data into a
+node. It is called "node metadata"; See `NodeMetaRef`.
 
-An apple:
+Node metadata contains two things:
 
-    {name="default:apple", count=1, wear=0, metadata=""}
+* A key-value store
+* An inventory
 
-#### `ItemStack`
-A native C++ format with many helper methods. Useful for converting
-between formats. See the Class reference section for details.
+Some of the values in the key-value store are handled specially:
 
-When an item must be passed to a function, it can usually be in any of
-these formats.
+* `formspec`: Defines a right-click inventory menu. See "Formspec".
+* `infotext`: Text shown on the screen when the node is pointed at
 
+Example stuff:
 
-Groups
-------
-In a number of places, there is a group table. Groups define the
-properties of a thing (item, node, armor of entity, capabilities of
-tool) in such a way that the engine and other mods can can interact with
-the thing without actually knowing what the thing is.
-
-### Usage
-Groups are stored in a table, having the group names with keys and the
-group ratings as values. For example:
+    local meta = minetest.get_meta(pos)
+    meta:set_string("formspec",
+            "size[8,9]"..
+            "list[context;main;0,0;8,4;]"..
+            "list[current_player;main;0,5;8,4;]")
+    meta:set_string("infotext", "Chest");
+    local inv = meta:get_inventory()
+    inv:set_size("main", 8*4)
+    print(dump(meta:to_table()))
+    meta:from_table({
+        inventory = {
+            main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "",
+                    [5] = "", [6] = "", [7] = "", [8] = "", [9] = "",
+                    [10] = "", [11] = "", [12] = "", [13] = "",
+                    [14] = "default:cobble", [15] = "", [16] = "", [17] = "",
+                    [18] = "", [19] = "", [20] = "default:cobble", [21] = "",
+                    [22] = "", [23] = "", [24] = "", [25] = "", [26] = "",
+                    [27] = "", [28] = "", [29] = "", [30] = "", [31] = "",
+                    [32] = ""}
+        },
+        fields = {
+            formspec = "size[8,9]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]",
+            infotext = "Chest"
+        }
+    })
 
-    groups = {crumbly=3, soil=1}
-    -- ^ Default dirt
+Item Metadata
+-------------
+Item stacks can store metadata too. See `ItemStackMetaRef`.
 
-    groups = {crumbly=2, soil=1, level=2, outerspace=1}
-    -- ^ A more special dirt-kind of thing
+Item metadata only contains a key-value store.
 
-Groups always have a rating associated with them. If there is no
-useful meaning for a rating for an enabled group, it shall be `1`.
+Some of the values in the key-value store are handled specially:
 
-When not defined, the rating of a group defaults to `0`. Thus when you
-read groups, you must interpret `nil` and `0` as the same value, `0`.
+* `description`: Set the item stack's description. Defaults to
+  `idef.description`.
+* `color`: A `ColorString`, which sets the stack's color.
+* `palette_index`: If the item has a palette, this is used to get the
+  current color from the palette.
 
-You can read the rating of a group for an item or a node by using
+Example stuff:
 
-    minetest.get_item_group(itemname, groupname)
+    local meta = stack:get_meta()
+    meta:set_string("key", "value")
+    print(dump(meta:to_table()))
 
-### Groups of items
-Groups of items can define what kind of an item it is (e.g. wool).
+Formspec
+--------
+Formspec defines a menu. Currently not much else than inventories are
+supported. It is a string, with a somewhat strange format.
 
-### Groups of nodes
-In addition to the general item things, groups are used to define whether
-a node is destroyable and how long it takes to destroy by a tool.
+Spaces and newlines can be inserted between the blocks, as is used in the
+examples.
 
-### Groups of entities
-For entities, groups are, as of now, used only for calculating damage.
-The rating is the percentage of damage caused by tools with this damage group.
-See "Entity damage mechanism".
+WARNING: Minetest allows you to add elements to every single formspec instance
+using player:set_formspec_prepend(), which may be the reason backgrounds are
+appearing when you don't expect them to. See `no_prepend[]`
 
-    object.get_armor_groups() --> a group-rating table (e.g. {fleshy=100})
-    object.set_armor_groups({fleshy=30, cracky=80})
+### Examples
 
-### Groups of tools
-Groups in tools define which groups of nodes and entities they are
-effective towards.
+#### Chest
 
-### Groups in crafting recipes
-An example: Make meat soup from any meat, any water and any bowl:
+    size[8,9]
+    list[context;main;0,0;8,4;]
+    list[current_player;main;0,5;8,4;]
 
-    {
-        output = 'food:meat_soup_raw',
-        recipe = {
-            {'group:meat'},
-            {'group:water'},
-            {'group:bowl'},
-        },
-        -- preserve = {'group:bowl'}, -- Not implemented yet (TODO)
-    }
+#### Furnace
 
-Another example: Make red wool from white wool and red dye:
+    size[8,9]
+    list[context;fuel;2,3;1,1;]
+    list[context;src;2,1;1,1;]
+    list[context;dst;5,1;2,2;]
+    list[current_player;main;0,5;8,4;]
 
-    {
-        type = 'shapeless',
-        output = 'wool:red',
-        recipe = {'wool:white', 'group:dye,basecolor_red'},
-    }
+#### Minecraft-like player inventory
 
-### 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
-* `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
-* `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
-* `slippery`: Players and items will slide on the node.
-  Slipperiness rises steadily with `slippery` value, starting at 1.
+    size[8,7.5]
+    image[1,0.6;1,2;player.png]
+    list[current_player;main;0,3.5;8,4;]
+    list[current_player;craft;3,0;3,3;]
+    list[current_player;craftpreview;7,1;1,1;]
 
+### Elements
 
-### Known damage and digging time defining groups
-* `crumbly`: dirt, sand
-* `cracky`: tough but crackable stuff like stone.
-* `snappy`: something that can be cut using fine tools; e.g. leaves, small
-  plants, wire, sheets of metal
-* `choppy`: something that can be cut using force; e.g. trees, wooden planks
-* `fleshy`: Living things like animals and the player. This could imply
-  some blood effects when hitting.
-* `explody`: Especially prone to explosions
-* `oddly_breakable_by_hand`:
-   Can be added to nodes that shouldn't logically be breakable by the
-   hand but are. Somewhat similar to `dig_immediate`, but times are more
-   like `{[1]=3.50,[2]=2.00,[3]=0.70}` and this does not override the
-   speed of a tool if the tool can dig at a faster speed than this
-   suggests for the hand.
+#### `size[<W>,<H>,<fixed_size>]`
+* Define the size of the menu in inventory slots
+* `fixed_size`: `true`/`false` (optional)
+* deprecated: `invsize[<W>,<H>;]`
 
-### Examples of custom groups
-Item groups are often used for defining, well, _groups of items_.
+#### `position[<X>,<Y>]`
+* Must be used after `size` element.
+* Defines the position on the game window of the formspec's `anchor` point.
+* For X and Y, 0.0 and 1.0 represent opposite edges of the game window,
+  for example:
+    * [0.0, 0.0] sets the position to the top left corner of the game window.
+    * [1.0, 1.0] sets the position to the bottom right of the game window.
+* Defaults to the center of the game window [0.5, 0.5].
 
-* `meat`: any meat-kind of a thing (rating might define the size or healing
-  ability or be irrelevant -- it is not defined as of yet)
-* `eatable`: anything that can be eaten. Rating might define HP gain in half
-  hearts.
-* `flammable`: can be set on fire. Rating might define the intensity of the
-  fire, affecting e.g. the speed of the spreading of an open fire.
-* `wool`: any wool (any origin, any color)
-* `metal`: any metal
-* `weapon`: any weapon
-* `heavy`: anything considerably heavy
+#### `anchor[<X>,<Y>]`
+* Must be used after both `size` and `position` (if present) elements.
+* Defines the location of the anchor point within the formspec.
+* For X and Y, 0.0 and 1.0 represent opposite edges of the formspec,
+  for example:
+    * [0.0, 1.0] sets the anchor to the bottom left corner of the formspec.
+    * [1.0, 0.0] sets the anchor to the top right of the formspec.
+* Defaults to the center of the formspec [0.5, 0.5].
 
-### Digging time calculation specifics
-Groups such as `crumbly`, `cracky` and `snappy` are used for this
-purpose. Rating is `1`, `2` or `3`. A higher rating for such a group implies
-faster digging time.
+* `position` and `anchor` elements need suitable values to avoid a formspec
+  extending off the game window due to particular game window sizes.
 
-The `level` group is used to limit the toughness of nodes a tool can dig
-and to scale the digging times / damage to a greater extent.
+#### `no_prepend[]`
+* Must be used after the `size`, `position`, and `anchor` elements (if present).
+* Disables player:set_formspec_prepend() from applying to this formspec.
 
-**Please do understand this**, otherwise you cannot use the system to it's
-full potential.
+#### `container[<X>,<Y>]`
+* Start of a container block, moves all physical elements in the container by
+  (X, Y).
+* Must have matching `container_end`
+* Containers can be nested, in which case the offsets are added
+  (child containers are relative to parent containers)
 
-Tools define their properties by a list of parameters for groups. They
-cannot dig other groups; thus it is important to use a standard bunch of
-groups to enable interaction with tools.
+#### `container_end[]`
+* End of a container, following elements are no longer relative to this
+  container.
 
-#### Tools definition
-Tools define:
+#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]`
+* Show an inventory list
 
-* Full punch interval
-* Maximum drop level
-* For an arbitrary list of groups:
-    * Uses (until the tool breaks)
-        * Maximum level (usually `0`, `1`, `2` or `3`)
-        * Digging times
-        * Damage groups
+#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
+* Show an inventory list
 
-#### Full punch interval
-When used as a weapon, the tool will do full damage if this time is spent
-between punches. If e.g. half the time is spent, the tool will do half
-damage.
+#### `listring[<inventory location>;<list name>]`
+* Allows to create a ring of inventory lists
+* Shift-clicking on items in one element of the ring
+  will send them to the next inventory list inside the ring
+* The first occurrence of an element inside the ring will
+  determine the inventory where items will be sent to
 
-#### Maximum drop level
-Suggests the maximum level of node, when dug with the tool, that will drop
-it's useful item. (e.g. iron ore to drop a lump of iron).
+#### `listring[]`
+* Shorthand for doing `listring[<inventory location>;<list name>]`
+  for the last two inventory lists added by list[...]
 
-This is not automated; it is the responsibility of the node definition
-to implement this.
+#### `listcolors[<slot_bg_normal>;<slot_bg_hover>]`
+* Sets background color of slots as `ColorString`
+* Sets background color of slots on mouse hovering
 
-#### Uses
-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`.
+#### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]`
+* Sets background color of slots as `ColorString`
+* Sets background color of slots on mouse hovering
+* Sets color of slots border
 
-* `uses=10, leveldiff=0`: actual uses: 10
-* `uses=10, leveldiff=1`: actual uses: 30
-* `uses=10, leveldiff=2`: actual uses: 90
+#### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]`
+* Sets background color of slots as `ColorString`
+* Sets background color of slots on mouse hovering
+* Sets color of slots border
+* Sets default background color of tooltips
+* Sets default font color of tooltips
 
-#### Maximum level
-Tells what is the maximum level of a node of this group that the tool will
-be able to dig.
+#### `tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>;<fontcolor>]`
+* Adds tooltip for an element
+* `<bgcolor>` tooltip background color as `ColorString` (optional)
+* `<fontcolor>` tooltip font color as `ColorString` (optional)
 
-#### Digging times
-List of digging times for different ratings of the group, for nodes of the
-maximum level.
+#### `image[<X>,<Y>;<W>,<H>;<texture name>]`
+* Show an image
+* Position and size units are inventory slots
 
-For example, as a Lua table, `times={2=2.00, 3=0.70}`. This would
-result in the tool to be able to dig nodes that have a rating of `2` or `3`
-for this group, and unable to dig the rating `1`, which is the toughest.
-Unless there is a matching group that enables digging otherwise.
+#### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
+* Show an inventory image of registered item/node
+* Position and size units are inventory slots
 
-If the result digging time is 0, a delay of 0.15 seconds is added between
-digging nodes; If the player releases LMB after digging, this delay is set to 0,
-i.e. players can more quickly click the nodes away instead of holding LMB.
+#### `bgcolor[<color>;<fullscreen>]`
+* Sets background color of formspec as `ColorString`
+* If `true`, the background color is drawn fullscreen (does not effect the size
+  of the formspec).
 
-#### Damage groups
-List of damage for groups of entities. See "Entity damage mechanism".
+#### `background[<X>,<Y>;<W>,<H>;<texture name>]`
+* Use a background. Inventory rectangles are not drawn then.
+* Position and size units are inventory slots
+* Example for formspec 8x4 in 16x resolution: image shall be sized
+  8 times 16px  times  4 times 16px.
 
-#### Example definition of the capabilities of a tool
+#### `background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]`
+* Use a background. Inventory rectangles are not drawn then.
+* Position and size units are inventory slots
+* Example for formspec 8x4 in 16x resolution:
+  image shall be sized 8 times 16px  times  4 times 16px
+* If `true` the background is clipped to formspec size
+  (`x` and `y` are used as offset values, `w` and `h` are ignored)
 
-    tool_capabilities = {
-        full_punch_interval=1.5,
-        max_drop_level=1,
-        groupcaps={
-            crumbly={maxlevel=2, uses=20, times={[1]=1.60, [2]=1.20, [3]=0.80}}
-        }
-        damage_groups = {fleshy=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.
+* `x` and `y` position the field relative to the top left of the menu
+* `w` and `h` are the size of the field
+* Fields are a set height, but will be vertically centred on `h`
+* Position and size units are inventory slots
+* `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
 
-This makes the tool be able to dig nodes that fulfil both of these:
+#### `field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
+* 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.
+* `x` and `y` position the field relative to the top left of the menu
+* `w` and `h` are the size of the field
+* Fields are a set height, but will be vertically centred on `h`
+* Position and size units are inventory slots
+* `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
+    * `default` may contain variable references such as `${text}'` which
+      will fill the value from the metadata value `text`
+    * **Note**: no extra text or more than a single variable is supported ATM.
+* See `field_close_on_enter` to stop enter closing the formspec
 
-* Have the `crumbly` group
-* Have a `level` group less or equal to `2`
+#### `field[<name>;<label>;<default>]`
+* As above, but without position/size units
+* When enter is pressed in field, `fields.key_enter_field` will be sent with
+  the name of this field.
+* Special field for creating simple forms, such as sign text input
+* Must be used without a `size[]` element
+* A "Proceed" button will be added automatically
+* See `field_close_on_enter` to stop enter closing the formspec
 
-Table of resulting digging times:
+#### `field_close_on_enter[<name>;<close_on_enter>]`
+* <name> is the name of the field
+* if <close_on_enter> is false, pressing enter in the field will submit the
+  form but not close it.
+* defaults to true when not specified (ie: no tag for a field)
 
-    crumbly        0     1     2     3     4  <- level
-         ->  0     -     -     -     -     -
-             1  0.80  1.60  1.60     -     -
-             2  0.60  1.20  1.20     -     -
-             3  0.40  0.80  0.80     -     -
+#### `textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
+* Same as fields above, but with multi-line input
+* if the text overflows a vertical scrollbar is added
+* if the name is empty the textarea is readonly, the label is not displayed.
 
-    level diff:    2     1     0    -1    -2
+#### `label[<X>,<Y>;<label>]`
+* `x` and `y` work as per field
+* `label` is the text on the label
+* Position and size units are inventory slots
 
-Table of resulting tool uses:
+#### `vertlabel[<X>,<Y>;<label>]`
+* Textual label drawn vertically
+* `x` and `y` work as per field
+* `label` is the text on the label
+* Position and size units are inventory slots
 
-    ->  0     -     -     -     -     -
-        1   180    60    20     -     -
-        2   180    60    20     -     -
-        3   180    60    20     -     -
+#### `button[<X>,<Y>;<W>,<H>;<name>;<label>]`
+* Clickable button. When clicked, fields will be sent.
+* `x`, `y` and `name` work as per field
+* `w` and `h` are the size of the button
+* Fixed button height. It will be vertically centred on `h`
+* `label` is the text on the button
+* Position and size units are inventory slots
 
-**Notes**:
+#### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
+* `x`, `y`, `w`, `h`, and `name` work as per button
+* `texture name` is the filename of an image
+* Position and size units are inventory slots
 
-* At `crumbly==0`, the node is not diggable.
-* At `crumbly==3`, the level difference digging time divider kicks in and makes
-  easy nodes to be quickly breakable.
-* At `level > 2`, the node is not diggable, because it's `level > maxlevel`
+#### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]`
+* `x`, `y`, `w`, `h`, and `name` work as per button
+* `texture name` is the filename of an image
+* Position and size units are inventory slots
+* `noclip=true` means the image button doesn't need to be within specified
+  formsize.
+* `drawborder`: draw button border or not
+* `pressed texture name` is the filename of an image on pressed state
 
-Entity damage mechanism
------------------------
-Damage calculation:
+#### `item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]`
+* `x`, `y`, `w`, `h`, `name` and `label` work as per button
+* `item name` is the registered name of an item/node,
+  tooltip will be made out of its description
+  to override it use tooltip element
+* Position and size units are inventory slots
 
-    damage = 0
-    foreach group in cap.damage_groups:
-        damage += cap.damage_groups[group] * limit(actual_interval /
-               cap.full_punch_interval, 0.0, 1.0)
-            * (object.armor_groups[group] / 100.0)
-            -- Where object.armor_groups[group] is 0 for inexistent values
-    return damage
+#### `button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]`
+* When clicked, fields will be sent and the form will quit.
 
-Client predicts damage based on damage groups. Because of this, it is able to
-give an immediate response when an entity is damaged or dies; the response is
-pre-defined somehow (e.g. by defining a sprite animation) (not implemented;
-TODO).
-Currently a smoke puff will appear when an entity dies.
+#### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
+* When clicked, fields will be sent and the form will quit.
 
-The group `immortal` completely disables normal damage.
+#### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]`
+* Scrollable item list showing arbitrary text elements
+* `x` and `y` position the itemlist relative to the top left of the menu
+* `w` and `h` are the size of the itemlist
+* `name` fieldname sent to server on doubleclick value is current selected
+  element.
+* `listelements` can be prepended by #color in hexadecimal format RRGGBB
+  (only).
+    * if you want a listelement to start with "#" write "##".
 
-Entities can define a special armor group, which is `punch_operable`. This
-group 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.
+#### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]`
+* Scrollable itemlist showing arbitrary text elements
+* `x` and `y` position the item list relative to the top left of the menu
+* `w` and `h` are the size of the item list
+* `name` fieldname sent to server on doubleclick value is current selected
+  element.
+* `listelements` can be prepended by #RRGGBB (only) in hexadecimal format
+    * if you want a listelement to start with "#" write "##"
+* Index to be selected within textlist
+* `true`/`false`: draw transparent background
+* See also `minetest.explode_textlist_event`
+  (main menu: `core.explode_textlist_event`).
 
-On the Lua side, every punch calls:
+#### `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 the itemlist relative to the top left of the menu
+* `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
 
-  entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction, damage)
+#### `box[<X>,<Y>;<W>,<H>;<color>]`
+* Simple colored box
+* `x` and `y` position the box relative to the top left of the menu
+* `w` and `h` are the size of box
+* `color` is color specified as a `ColorString`.
+  If the alpha component is left blank, the box will be semitransparent.
 
-This should never be called directly, because damage is usually not handled by
-the entity itself.
+#### `dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]`
+* Show a dropdown field
+* **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
+* Fieldname data is transferred to Lua
+* Items to be shown in dropdown
+* Index of currently selected dropdown item
 
-* `puncher` is the object performing the punch. Can be `nil`. Should never be
-  accessed unless absolutely required, to encourage interoperability.
-* `time_from_last_punch` is time from last punch (by `puncher`) or `nil`.
-* `tool_capabilities` can be `nil`.
-* `direction` is a unit vector, pointing from the source of the punch to
-   the punched object.
-* `damage` damage that will be done to entity
-Return value of this function will determine if damage is done by this function
-(retval true) or shall be done by engine (retval false)
+#### `checkbox[<X>,<Y>;<name>;<label>;<selected>]`
+* Show a checkbox
+* `x` and `y`: position of checkbox
+* `name` fieldname data is transferred to Lua
+* `label` to be shown left of checkbox
+* `selected` (optional): `true`/`false`
 
-To punch an entity/object in Lua, call:
+#### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]`
+* Show a scrollbar
+* 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)
+* `x` and `y`: position of trackbar
+* `w` and `h`: width and height
+* `orientation`:  `vertical`/`horizontal`
+* Fieldname data is transferred to Lua
+* Value this trackbar is set to (`0`-`1000`)
+* See also `minetest.explode_scrollbar_event`
+  (main menu: `core.explode_scrollbar_event`).
 
-  object:punch(puncher, time_from_last_punch, tool_capabilities, direction)
-
-* Return value is tool wear.
-* Parameters are equal to the above callback.
-* If `direction` equals `nil` and `puncher` does not equal `nil`, `direction`
-  will be automatically filled in based on the location of `puncher`.
-
-Node Metadata
--------------
-The instance of a node in the world normally only contains the three values
-mentioned in "Nodes". However, it is possible to insert extra data into a
-node. It is called "node metadata"; See `NodeMetaRef`.
-
-Node metadata contains two things:
+#### `table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]`
+* Show scrollable table using options defined by the previous `tableoptions[]`
+* Displays cells as defined by the previous `tablecolumns[]`
+* `x` and `y`: position the itemlist relative to the top left of the menu
+* `w` and `h` are the size of the itemlist
+* `name`: fieldname sent to server on row select or doubleclick
+* `cell 1`...`cell n`: cell contents given in row-major order
+* `selected idx`: index of row to be selected within table (first row = `1`)
+* See also `minetest.explode_table_event`
+  (main menu: `core.explode_table_event`).
 
-* A key-value store
-* An inventory
+#### `tableoptions[<opt 1>;<opt 2>;...]`
+* Sets options for `table[]`
+* `color=#RRGGBB`
+    * default text color (`ColorString`), defaults to `#FFFFFF`
+* `background=#RRGGBB`
+    * table background color (`ColorString`), defaults to `#000000`
+* `border=<true/false>`
+    * should the table be drawn with a border? (default: `true`)
+* `highlight=#RRGGBB`
+    * highlight background color (`ColorString`), defaults to `#466432`
+* `highlight_text=#RRGGBB`
+    * highlight text color (`ColorString`), defaults to `#FFFFFF`
+* `opendepth=<value>`
+    * all subtrees up to `depth < value` are open (default value = `0`)
+    * only useful when there is a column of type "tree"
 
-Some of the values in the key-value store are handled specially:
+#### `tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]`
+* Sets columns for `table[]`
+* Types: `text`, `image`, `color`, `indent`, `tree`
+    * `text`:   show cell contents as text
+    * `image`:  cell contents are an image index, use column options to define
+                images.
+    * `color`:  cell contents are a ColorString and define color of following
+                cell.
+    * `indent`: cell contents are a number and define indentation of following
+                cell.
+    * `tree`:   same as indent, but user can open and close subtrees
+                (treeview-like).
+* Column options:
+    * `align=<value>`
+        * for `text` and `image`: content alignment within cells.
+          Available values: `left` (default), `center`, `right`, `inline`
+    * `width=<value>`
+        * for `text` and `image`: minimum width in em (default: `0`)
+        * for `indent` and `tree`: indent width in em (default: `1.5`)
+    * `padding=<value>`: padding left of the column, in em (default `0.5`).
+      Exception: defaults to 0 for indent columns
+    * `tooltip=<value>`: tooltip text (default: empty)
+    * `image` column options:
+        * `0=<value>` sets image for image index 0
+        * `1=<value>` sets image for image index 1
+        * `2=<value>` sets image for image index 2
+        * and so on; defined indices need not be contiguous empty or
+          non-numeric cells are treated as `0`.
+    * `color` column options:
+        * `span=<value>`: number of following columns to affect
+          (default: infinite).
 
-* `formspec`: Defines a right-click inventory menu. See "Formspec".
-* `infotext`: Text shown on the screen when the node is pointed at
+**Note**: do _not_ use a element name starting with `key_`; those names are
+reserved to pass key press events to formspec!
 
-Example stuff:
+Inventory locations
+-------------------
+* `"context"`: Selected node metadata (deprecated: `"current_name"`)
+* `"current_player"`: Player to whom the menu is shown
+* `"player:<name>"`: Any player
+* `"nodemeta:<X>,<Y>,<Z>"`: Any node metadata
+* `"detached:<name>"`: A detached inventory
 
-    local meta = minetest.get_meta(pos)
-    meta:set_string("formspec",
-            "size[8,9]"..
-            "list[context;main;0,0;8,4;]"..
-            "list[current_player;main;0,5;8,4;]")
-    meta:set_string("infotext", "Chest");
-    local inv = meta:get_inventory()
-    inv:set_size("main", 8*4)
-    print(dump(meta:to_table()))
-    meta:from_table({
-        inventory = {
-            main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "",
-                    [5] = "", [6] = "", [7] = "", [8] = "", [9] = "",
-                    [10] = "", [11] = "", [12] = "", [13] = "",
-                    [14] = "default:cobble", [15] = "", [16] = "", [17] = "",
-                    [18] = "", [19] = "", [20] = "default:cobble", [21] = "",
-                    [22] = "", [23] = "", [24] = "", [25] = "", [26] = "",
-                    [27] = "", [28] = "", [29] = "", [30] = "", [31] = "",
-                    [32] = ""}
-        },
-        fields = {
-            formspec = "size[8,9]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]",
-            infotext = "Chest"
-        }
-    })
+Player Inventory lists
+----------------------
+* `main`: list containing the default inventory
+* `craft`: list containing the craft input
+* `craftpreview`: list containing the craft output
+* `hand`: list containing an override for the empty hand
 
-Item Metadata
+`ColorString`
 -------------
-Item stacks can store metadata too. See `ItemStackMetaRef`.
-
-Item metadata only contains a key-value store.
-
-Some of the values in the key-value store are handled specially:
-
-* `description`: Set the item stack's description. Defaults to
-  `idef.description`.
-* `color`: A `ColorString`, which sets the stack's color.
-* `palette_index`: If the item has a palette, this is used to get the
-  current color from the palette.
-
-Example stuff:
-
-    local meta = stack:get_meta()
-    meta:set_string("key", "value")
-    print(dump(meta:to_table()))
-
-Formspec
---------
-Formspec defines a menu. Currently not much else than inventories are
-supported. It is a string, with a somewhat strange format.
-
-Spaces and newlines can be inserted between the blocks, as is used in the
-examples.
+`#RGB` defines a color in hexadecimal format.
 
-WARNING: Minetest allows you to add elements to every single formspec instance
-using player:set_formspec_prepend(), which may be the reason backgrounds are
-appearing when you don't expect them to. See `no_prepend[]`
+`#RGBA` defines a color in hexadecimal format and alpha channel.
 
-### Examples
+`#RRGGBB` defines a color in hexadecimal format.
 
-#### Chest
+`#RRGGBBAA` defines a color in hexadecimal format and alpha channel.
 
-    size[8,9]
-    list[context;main;0,0;8,4;]
-    list[current_player;main;0,5;8,4;]
+Named colors are also supported and are equivalent to
+[CSS Color Module Level 4](http://dev.w3.org/csswg/css-color/#named-colors).
+To specify the value of the alpha channel, append `#AA` to the end of the color
+name (e.g. `colorname#08`). For named colors the hexadecimal string
+representing the alpha value must (always) be two hexadecimal digits.
 
-#### Furnace
+`ColorSpec`
+-----------
+A ColorSpec specifies a 32-bit color.  It can be written in either:
+table form, each element ranging from 0..255 (a, if absent, defaults to 255):
+    `colorspec = {a=255, r=0, g=255, b=0}`
+numerical form, the raw integer value of an ARGB8 quad:
+    `colorspec = 0xFF00FF00`
+or string form, a ColorString (defined above):
+    `colorspec = "green"`
 
-    size[8,9]
-    list[context;fuel;2,3;1,1;]
-    list[context;src;2,1;1,1;]
-    list[context;dst;5,1;2,2;]
-    list[current_player;main;0,5;8,4;]
+Escape sequences
+----------------
+Most text can contain escape sequences, that can for example color the text.
+There are a few exceptions: tab headers, dropdowns and vertical labels can't.
+The following functions provide escape sequences:
 
-#### Minecraft-like player inventory
+* `minetest.get_color_escape_sequence(color)`:
+    * `color` is a ColorString
+    * The escape sequence sets the text color to `color`
+* `minetest.colorize(color, message)`:
+    * Equivalent to:
+      `minetest.get_color_escape_sequence(color) ..
+      message ..
+      minetest.get_color_escape_sequence("#ffffff")`
+* `minetest.get_background_escape_sequence(color)`
+    * `color` is a ColorString
+    * The escape sequence sets the background of the whole text element to
+      `color`. Only defined for item descriptions and tooltips.
+* `minetest.strip_foreground_colors(str)`
+    * Removes foreground colors added by `get_color_escape_sequence`.
+* `minetest.strip_background_colors(str)`
+    * Removes background colors added by `get_background_escape_sequence`.
+* `minetest.strip_colors(str)`
+    * Removes all color escape sequences.
 
-    size[8,7.5]
-    image[1,0.6;1,2;player.png]
-    list[current_player;main;0,3.5;8,4;]
-    list[current_player;craft;3,0;3,3;]
-    list[current_player;craftpreview;7,1;1,1;]
+Spatial Vectors
+---------------
+For the following functions, `v`, `v1`, `v2` are vectors,
+`p1`, `p2` are positions:
 
-### Elements
+* `vector.new(a[, b, c])`:
+    * Returns a vector.
+    * A copy of `a` if `a` is a vector.
+    * `{x = a, y = b, z = c}`, if all of `a`, `b`, `c` are defined numbers.
+* `vector.direction(p1, p2)`:
+    * Returns a vector of length 1 with direction `p1` to `p2`.
+    * If `p1` and `p2` are identical, returns `{x = 0, y = 0, z = 0}`.
+* `vector.distance(p1, p2)`:
+    * Returns zero or a positive number, the distance between `p1` and `p2`.
+* `vector.length(v)`:
+    * Returns zero or a positive number, the length of vector `v`.
+* `vector.normalize(v)`:
+    * Returns a vector of length 1 with direction of vector `v`.
+    * If `v` has zero length, returns `{x = 0, y = 0, z = 0}`.
+* `vector.floor(v)`:
+    * Returns a vector, each dimension rounded down.
+* `vector.round(v)`:
+    * Returns a vector, each dimension rounded to nearest integer.
+* `vector.apply(v, func)`:
+    * Returns a vector where the function `func` has been applied to each
+      component.
+* `vector.equals(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`.
 
-#### `size[<W>,<H>,<fixed_size>]`
-* Define the size of the menu in inventory slots
-* `fixed_size`: `true`/`false` (optional)
-* deprecated: `invsize[<W>,<H>;]`
+For the following functions `x` can be either a vector or a number:
 
-#### `position[<X>,<Y>]`
-* Must be used after `size` element.
-* Defines the position on the game window of the formspec's `anchor` point.
-* For X and Y, 0.0 and 1.0 represent opposite edges of the game window,
-  for example:
-    * [0.0, 0.0] sets the position to the top left corner of the game window.
-    * [1.0, 1.0] sets the position to the bottom right of the game window.
-* Defaults to the center of the game window [0.5, 0.5].
+* `vector.add(v, x)`:
+    * Returns a vector.
+* `vector.subtract(v, x)`:
+    * Returns a vector.
+* `vector.multiply(v, x)`:
+    * Returns a scaled vector or Schur product.
+* `vector.divide(v, x)`:
+    * Returns a scaled vector or Schur quotient.
 
-#### `anchor[<X>,<Y>]`
-* Must be used after both `size` and `position` (if present) elements.
-* Defines the location of the anchor point within the formspec.
-* For X and Y, 0.0 and 1.0 represent opposite edges of the formspec,
-  for example:
-    * [0.0, 1.0] sets the anchor to the bottom left corner of the formspec.
-    * [1.0, 0.0] sets the anchor to the top right of the formspec.
-* Defaults to the center of the formspec [0.5, 0.5].
+Helper functions
+----------------
+* `dump2(obj, name, dumped)`: returns a string which makes `obj`
+  human-readable, handles reference loops.
+    * `obj`: arbitrary variable
+    * `name`: string, default: `"_"`
+    * `dumped`: table, default: `{}`
+* `dump(obj, dumped)`: returns a string which makes `obj` human-readable
+    * `obj`: arbitrary variable
+    * `dumped`: table, default: `{}`
+* `math.hypot(x, y)`
+    * Get the hypotenuse of a triangle with legs x and y.
+      Useful for distance calculation.
+* `math.sign(x, tolerance)`: returns `-1`, `0` or `1`
+    * Get the sign of a number.
+    * tolerance: number, default: `0.0`
+    * If the absolute value of `x` is within the `tolerance` or `x` is NaN,
+      `0` is returned.
+* `string.split(str, separator, include_empty, max_splits, sep_is_pattern)`
+    * `separator`: string, default: `","`
+    * `include_empty`: boolean, default: `false`
+    * `max_splits`: number, if it's positive, splits aren't limited,
+      default: `-1`
+    * `sep_is_pattern`: boolean, it specifies whether separator is a plain
+      string or a pattern (regex), default: `false`
+    * e.g. `"a,b":split","` returns `{"a","b"}`
+* `string:trim()`: returns the string without whitespace pre- and suffixes
+    * e.g. `"\n \t\tfoo bar\t ":trim()` returns `"foo bar"`
+* `minetest.wrap_text(str, limit, as_table)`: returns a string or table
+    * Adds newlines to the string to keep it within the specified character
+      limit
+    * Note that the returned lines may be longer than the limit since it only
+      splits at word borders.
+    * `limit`: number, maximal amount of characters in one line
+    * `as_table`: boolean, if set to true, a table of lines instead of a string
+      is returned, default: `false`
+* `minetest.pos_to_string(pos, decimal_places)`: returns string `"(X,Y,Z)"`
+    * `pos`: table {x=X, y=Y, z=Z}
+    * Converts the position `pos` to a human-readable, printable string
+    * `decimal_places`: number, if specified, the x, y and z values of
+      the position are rounded to the given decimal place.
+* `minetest.string_to_pos(string)`: returns a position or `nil`
+    * Same but in reverse.
+    * If the string can't be parsed to a position, nothing is returned.
+* `minetest.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)")`: returns two positions
+    * Converts a string representing an area box into two positions
+* `minetest.formspec_escape(string)`: returns a string
+    * escapes the characters "[", "]", "\", "," and ";", which can not be used
+      in formspecs.
+* `minetest.is_yes(arg)`
+    * returns true if passed 'y', 'yes', 'true' or a number that isn't zero.
+* `minetest.is_nan(arg)`
+    * returns true when the passed number represents NaN.
+* `minetest.get_us_time()`
+    * returns time with microsecond precision. May not return wall time.
+* `table.copy(table)`: returns a table
+    * returns a deep copy of `table`
+* `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
 
-* `position` and `anchor` elements need suitable values to avoid a formspec
-  extending off the game window due to particular game window sizes.
+Translations
+------------
 
-#### `no_prepend[]`
-* Must be used after the `size`, `position`, and `anchor` elements (if present).
-* Disables player:set_formspec_prepend() from applying to this formspec.
+Texts can be translated client-side with the help of `minetest.translate` and
+translation files.
 
-#### `container[<X>,<Y>]`
-* Start of a container block, moves all physical elements in the container by
-  (X, Y).
-* Must have matching `container_end`
-* Containers can be nested, in which case the offsets are added
-  (child containers are relative to parent containers)
+### Translating a string
+Two functions are provided to translate strings: `minetest.translate` and
+`minetest.get_translator`.
 
-#### `container_end[]`
-* End of a container, following elements are no longer relative to this
-  container.
+* `minetest.get_translator(textdomain)` is a simple wrapper around
+  `minetest.translate`, and `minetest.get_translator(textdomain)(str, ...)` is
+  equivalent to `minetest.translate(textdomain, str, ...)`.
+  It is intended to be used in the following way, so that it avoids verbose
+  repetitions of `minetest.translate`:
 
-#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]`
-* Show an inventory list
+    local S = minetest.get_translator(textdomain)
+    S(str, ...)
 
-#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
-* Show an inventory list
+  As an extra commodity, if `textdomain` is nil, it is assumed to be "" instead.
 
-#### `listring[<inventory location>;<list name>]`
-* Allows to create a ring of inventory lists
-* Shift-clicking on items in one element of the ring
-  will send them to the next inventory list inside the ring
-* The first occurrence of an element inside the ring will
-  determine the inventory where items will be sent to
+* `minetest.translate(textdomain, str, ...)` translates the string `str` with
+  the given `textdomain` for disambiguation. The textdomain must match the
+  textdomain specified in the translation file in order to get the string
+  translated. This can be used so that a string is translated differently in
+  different contexts.
+  It is advised to use the name of the mod as textdomain whenever possible, to
+  avoid clashes with other mods.
+  This function must be given a number of arguments equal to the number of
+  arguments the translated string expects.
+  Arguments are literal strings -- they will not be translated, so if you want
+  them to be, they need to come as outputs of `minetest.translate` as well.
 
-#### `listring[]`
-* Shorthand for doing `listring[<inventory location>;<list name>]`
-  for the last two inventory lists added by list[...]
+  For instance, suppose we want to translate "@1 Wool" with "@1" being replaced
+  by the translation of "Red". We can do the following:
 
-#### `listcolors[<slot_bg_normal>;<slot_bg_hover>]`
-* Sets background color of slots as `ColorString`
-* Sets background color of slots on mouse hovering
+    local S = minetest.get_translator()
+    S("@1 Wool", S("Red"))
 
-#### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]`
-* Sets background color of slots as `ColorString`
-* Sets background color of slots on mouse hovering
-* Sets color of slots border
+  This will be displayed as "Red Wool" on old clients and on clients that do
+  not have localization enabled. However, if we have for instance a translation
+  file named `wool.fr.tr` containing the following:
 
-#### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]`
-* Sets background color of slots as `ColorString`
-* Sets background color of slots on mouse hovering
-* Sets color of slots border
-* Sets default background color of tooltips
-* Sets default font color of tooltips
+    @1 Wool=Laine @1
+    Red=Rouge
 
-#### `tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>;<fontcolor>]`
-* Adds tooltip for an element
-* `<bgcolor>` tooltip background color as `ColorString` (optional)
-* `<fontcolor>` tooltip font color as `ColorString` (optional)
+  this will be displayed as "Laine Rouge" on clients with a French locale.
 
-#### `image[<X>,<Y>;<W>,<H>;<texture name>]`
-* Show an image
-* Position and size units are inventory slots
+### Operations on translated strings
 
-#### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
-* Show an inventory image of registered item/node
-* Position and size units are inventory slots
+The output of `minetest.translate` is a string, with escape sequences adding
+additional information to that string so that it can be translated on the
+different clients. In particular, you can't expect operations like string.length
+to work on them like you would expect them to, or string.gsub to work in the
+expected manner. However, string concatenation will still work as expected
+(note that you should only use this for things like formspecs; do not translate
+sentences by breaking them into parts; arguments should be used instead), and
+operations such as `minetest.colorize` which are also concatenation.
 
-#### `bgcolor[<color>;<fullscreen>]`
-* Sets background color of formspec as `ColorString`
-* If `true`, the background color is drawn fullscreen (does not effect the size
-  of the formspec).
+### Translation file format
+A translation file has the suffix `.[lang].tr`, where `[lang]` is the language
+it corresponds to. It must be put into the `locale` subdirectory of the mod.
+The file should be a text file, with the following format:
 
-#### `background[<X>,<Y>;<W>,<H>;<texture name>]`
-* Use a background. Inventory rectangles are not drawn then.
-* Position and size units are inventory slots
-* Example for formspec 8x4 in 16x resolution: image shall be sized
-  8 times 16px  times  4 times 16px.
+* Lines beginning with `# textdomain:` (the space is significant) can be used
+  to specify the text domain of all following translations in the file.
+* All other empty lines or lines beginning with `#` are ignored.
+* Other lines should be in the format `original=translated`. Both `original`
+  and `translated` can contain escape sequences beginning with `@` to insert
+  arguments, literal `@`, `=` or newline (See ### Escapes below).
+  There must be no extraneous whitespace around the `=` or at the beginning or
+  the end of the line.
 
-#### `background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]`
-* Use a background. Inventory rectangles are not drawn then.
-* Position and size units are inventory slots
-* Example for formspec 8x4 in 16x resolution:
-  image shall be sized 8 times 16px  times  4 times 16px
-* If `true` the background is clipped to formspec size
-  (`x` and `y` are used as offset values, `w` and `h` are ignored)
+### Escapes
+Strings that need to be translated can contain several escapes, preceded by `@`.
 
-#### `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.
-* `x` and `y` position the field relative to the top left of the menu
-* `w` and `h` are the size of the field
-* Fields are a set height, but will be vertically centred on `h`
-* Position and size units are inventory slots
-* `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
+* `@@` acts as a literal `@`.
+* `@n`, where `n` is a digit between 1 and 9, is an argument for the translated
+  string that will be inlined when translation. Due to how translations are
+  implemented, the original translation string **must** have its arguments in
+  increasing order, without gaps or repetitions, starting from 1.
+* `@=` acts as a literal `=`. It is not required in strings given to
+  `minetest.translate`, but is in translation files to avoid being confused
+  with the `=` separating the original from the translation.
+* `@\n` (where the `\n` is a literal newline) acts as a literal newline.
+  As with `@=`, this escape is not required in strings given to
+  `minetest.translate`, but is in translation files.
+* `@n` acts as a literal newline as well.
 
-#### `field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
-* 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.
-* `x` and `y` position the field relative to the top left of the menu
-* `w` and `h` are the size of the field
-* Fields are a set height, but will be vertically centred on `h`
-* Position and size units are inventory slots
-* `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
-    * `default` may contain variable references such as `${text}'` which
-      will fill the value from the metadata value `text`
-    * **Note**: no extra text or more than a single variable is supported ATM.
-* See `field_close_on_enter` to stop enter closing the formspec
+Perlin noise
+------------
+Perlin noise creates a continuously-varying value depending on the input values.
+Usually in Minetest the input values are either 2D or 3D co-ordinates in nodes.
+The result is used during map generation to create the terrain shape, vary heat
+and humidity to distribute biomes, vary the density of decorations or vary the
+structure of ores.
 
-#### `field[<name>;<label>;<default>]`
-* As above, but without position/size units
-* When enter is pressed in field, `fields.key_enter_field` will be sent with
-  the name of this field.
-* Special field for creating simple forms, such as sign text input
-* Must be used without a `size[]` element
-* A "Proceed" button will be added automatically
-* See `field_close_on_enter` to stop enter closing the formspec
+### Structure of perlin noise
+An 'octave' is a simple noise generator that outputs a value between -1 and 1.
+The smooth wavy noise it generates has a single characteristic scale, almost
+like a 'wavelength', so on its own does not create fine detail.
+Due to this perlin noise combines several octaves to create variation on
+multiple scales. Each additional octave has a smaller 'wavelength' than the
+previous.
 
-#### `field_close_on_enter[<name>;<close_on_enter>]`
-* <name> is the name of the field
-* if <close_on_enter> is false, pressing enter in the field will submit the
-  form but not close it.
-* defaults to true when not specified (ie: no tag for a field)
+This combination results in noise varying very roughly between -2.0 and 2.0 and
+with an average value of 0.0, so `scale` and `offset` are then used to multiply
+and offset the noise variation.
 
-#### `textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
-* Same as fields above, but with multi-line input
-* if the text overflows a vertical scrollbar is added
-* if the name is empty the textarea is readonly, the label is not displayed.
+The final perlin noise variation is created as follows:
 
-#### `label[<X>,<Y>;<label>]`
-* `x` and `y` work as per field
-* `label` is the text on the label
-* Position and size units are inventory slots
+noise = offset + scale * (octave1 +
+                          octave2 * persistence +
+                          octave3 * persistence ^ 2 +
+                          octave4 * persistence ^ 3 +
+                          ...)
 
-#### `vertlabel[<X>,<Y>;<label>]`
-* Textual label drawn vertically
-* `x` and `y` work as per field
-* `label` is the text on the label
-* Position and size units are inventory slots
+Noise Parameters
+----------------
+Noise Parameters are commonly called `NoiseParams`.
 
-#### `button[<X>,<Y>;<W>,<H>;<name>;<label>]`
-* Clickable button. When clicked, fields will be sent.
-* `x`, `y` and `name` work as per field
-* `w` and `h` are the size of the button
-* Fixed button height. It will be vertically centred on `h`
-* `label` is the text on the button
-* Position and size units are inventory slots
+### `offset`
+After the multiplication by `scale` this is added to the result and is the final
+step in creating the noise value.
+Can be positive or negative.
 
-#### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
-* `x`, `y`, `w`, `h`, and `name` work as per button
-* `texture name` is the filename of an image
-* Position and size units are inventory slots
+### `scale`
+Once all octaves have been combined, the result is multiplied by this.
+Can be positive or negative.
 
-#### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]`
-* `x`, `y`, `w`, `h`, and `name` work as per button
-* `texture name` is the filename of an image
-* Position and size units are inventory slots
-* `noclip=true` means the image button doesn't need to be within specified
-  formsize.
-* `drawborder`: draw button border or not
-* `pressed texture name` is the filename of an image on pressed state
+### `spread`
+For octave1, this is roughly the change of input value needed for a very large
+variation in the noise value generated by octave1. It is almost like a
+'wavelength' for the wavy noise variation.
+Each additional octave has a 'wavelength' that is smaller than the previous
+octave, to create finer detail. `spread` will therefore roughly be the typical
+size of the largest structures in the final noise variation.
 
-#### `item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]`
-* `x`, `y`, `w`, `h`, `name` and `label` work as per button
-* `item name` is the registered name of an item/node,
-  tooltip will be made out of its description
-  to override it use tooltip element
-* Position and size units are inventory slots
+`spread` is a vector with values for x, y, z to allow the noise variation to be
+stretched or compressed in the desired axes.
+Values are positive numbers.
 
-#### `button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]`
-* When clicked, fields will be sent and the form will quit.
+### `seed`
+This is a whole number that determines the entire pattern of the noise
+variation. Altering it enables different noise patterns to be created.
+With other parameters equal, different seeds produce different noise patterns
+and identical seeds produce identical noise patterns.
 
-#### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
-* When clicked, fields will be sent and the form will quit.
+For this parameter you can randomly choose any whole number. Usually it is
+preferable for this to be different from other seeds, but sometimes it is useful
+to be able to create identical noise patterns.
 
-#### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]`
-* Scrollable item list showing arbitrary text elements
-* `x` and `y` position the itemlist relative to the top left of the menu
-* `w` and `h` are the size of the itemlist
-* `name` fieldname sent to server on doubleclick value is current selected
-  element.
-* `listelements` can be prepended by #color in hexadecimal format RRGGBB
-  (only).
-    * if you want a listelement to start with "#" write "##".
+When used in mapgen this is actually a 'seed offset', it is added to the
+'world seed' to create the seed used by the noise, to ensure the noise has a
+different pattern in different worlds.
 
-#### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]`
-* Scrollable itemlist showing arbitrary text elements
-* `x` and `y` position the item list relative to the top left of the menu
-* `w` and `h` are the size of the item list
-* `name` fieldname sent to server on doubleclick value is current selected
-  element.
-* `listelements` can be prepended by #RRGGBB (only) in hexadecimal format
-    * if you want a listelement to start with "#" write "##"
-* Index to be selected within textlist
-* `true`/`false`: draw transparent background
-* See also `minetest.explode_textlist_event`
-  (main menu: `core.explode_textlist_event`).
+### `octaves`
+The number of simple noise generators that are combined.
+A whole number, 1 or more.
+Each additional octave adds finer detail to the noise but also increases the
+noise calculation load.
+3 is a typical minimum for a high quality, complex and natural-looking noise
+variation. 1 octave has a slight 'gridlike' appearence.
 
-#### `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 the itemlist relative to the top left of the menu
-* `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
+Choose the number of octaves according to the `spread` and `lacunarity`, and the
+size of the finest detail you require. For example:
+if `spread` is 512 nodes, `lacunarity` is 2.0 and finest detail required is 16
+nodes, octaves will be 6 because the 'wavelengths' of the octaves will be
+512, 256, 128, 64, 32, 16 nodes.
+Warning: If the 'wavelength' of any octave falls below 1 an error will occur.
 
-#### `box[<X>,<Y>;<W>,<H>;<color>]`
-* Simple colored box
-* `x` and `y` position the box relative to the top left of the menu
-* `w` and `h` are the size of box
-* `color` is color specified as a `ColorString`.
-  If the alpha component is left blank, the box will be semitransparent.
+### `persistence`
+Each additional octave has an amplitude that is the amplitude of the previous
+octave multiplied by `persistence`, to reduce the amplitude of finer details,
+as is often helpful and natural to do so.
+Since this controls the balance of fine detail to large-scale detail
+`persistence` can be thought of as the 'roughness' of the noise.
 
-#### `dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]`
-* Show a dropdown field
-* **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
-* Fieldname data is transferred to Lua
-* Items to be shown in dropdown
-* Index of currently selected dropdown item
+A positive or negative non-zero number, often between 0.3 and 1.0.
+A common medium value is 0.5, such that each octave has half the amplitude of
+the previous octave.
+This may need to be tuned when altering `lacunarity`; when doing so consider
+that a common medium value is 1 / lacunarity.
 
-#### `checkbox[<X>,<Y>;<name>;<label>;<selected>]`
-* Show a checkbox
-* `x` and `y`: position of checkbox
-* `name` fieldname data is transferred to Lua
-* `label` to be shown left of checkbox
-* `selected` (optional): `true`/`false`
+### `lacunarity`
+Each additional octave has a 'wavelength' that is the 'wavelength' of the
+previous octave multiplied by 1 / lacunarity, to create finer detail.
+'lacunarity' is often 2.0 so 'wavelength' often halves per octave.
 
-#### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]`
-* Show a scrollbar
-* 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)
-* `x` and `y`: position of trackbar
-* `w` and `h`: width and height
-* `orientation`:  `vertical`/`horizontal`
-* Fieldname data is transferred to Lua
-* Value this trackbar is set to (`0`-`1000`)
-* See also `minetest.explode_scrollbar_event`
-  (main menu: `core.explode_scrollbar_event`).
+A positive number no smaller than 1.0.
+Values below 2.0 create higher quality noise at the expense of requiring more
+octaves to cover a paticular range of 'wavelengths'.
 
-#### `table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]`
-* Show scrollable table using options defined by the previous `tableoptions[]`
-* Displays cells as defined by the previous `tablecolumns[]`
-* `x` and `y`: position the itemlist relative to the top left of the menu
-* `w` and `h` are the size of the itemlist
-* `name`: fieldname sent to server on row select or doubleclick
-* `cell 1`...`cell n`: cell contents given in row-major order
-* `selected idx`: index of row to be selected within table (first row = `1`)
-* See also `minetest.explode_table_event`
-  (main menu: `core.explode_table_event`).
+### `flags`
+Leave this field unset for no special handling.
+Currently supported are `defaults`, `eased` and `absvalue`:
 
-#### `tableoptions[<opt 1>;<opt 2>;...]`
-* Sets options for `table[]`
-* `color=#RRGGBB`
-    * default text color (`ColorString`), defaults to `#FFFFFF`
-* `background=#RRGGBB`
-    * table background color (`ColorString`), defaults to `#000000`
-* `border=<true/false>`
-    * should the table be drawn with a border? (default: `true`)
-* `highlight=#RRGGBB`
-    * highlight background color (`ColorString`), defaults to `#466432`
-* `highlight_text=#RRGGBB`
-    * highlight text color (`ColorString`), defaults to `#FFFFFF`
-* `opendepth=<value>`
-    * all subtrees up to `depth < value` are open (default value = `0`)
-    * only useful when there is a column of type "tree"
+#### `defaults`
+Specify this if you would like to keep auto-selection of eased/not-eased while
+specifying some other flags.
 
-#### `tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]`
-* Sets columns for `table[]`
-* Types: `text`, `image`, `color`, `indent`, `tree`
-    * `text`:   show cell contents as text
-    * `image`:  cell contents are an image index, use column options to define
-                images.
-    * `color`:  cell contents are a ColorString and define color of following
-                cell.
-    * `indent`: cell contents are a number and define indentation of following
-                cell.
-    * `tree`:   same as indent, but user can open and close subtrees
-                (treeview-like).
-* Column options:
-    * `align=<value>`
-        * for `text` and `image`: content alignment within cells.
-          Available values: `left` (default), `center`, `right`, `inline`
-    * `width=<value>`
-        * for `text` and `image`: minimum width in em (default: `0`)
-        * for `indent` and `tree`: indent width in em (default: `1.5`)
-    * `padding=<value>`: padding left of the column, in em (default `0.5`).
-      Exception: defaults to 0 for indent columns
-    * `tooltip=<value>`: tooltip text (default: empty)
-    * `image` column options:
-        * `0=<value>` sets image for image index 0
-        * `1=<value>` sets image for image index 1
-        * `2=<value>` sets image for image index 2
-        * and so on; defined indices need not be contiguous empty or
-          non-numeric cells are treated as `0`.
-    * `color` column options:
-        * `span=<value>`: number of following columns to affect
-          (default: infinite).
+#### `eased`
+Maps noise gradient values onto a quintic S-curve before performing
+interpolation. This results in smooth, rolling noise.
+Disable this (`noeased`) for sharp-looking noise with a slightly gridded
+appearence.
+If no flags are specified (or defaults is), 2D noise is eased and 3D noise is
+not eased.
+Easing a 3D noise significantly increases the noise calculation load, so use
+with restraint.
 
-**Note**: do _not_ use a element name starting with `key_`; those names are
-reserved to pass key press events to formspec!
+#### `absvalue`
+The absolute value of each octave's noise variation is used when combining the
+octaves. The final perlin noise variation is created as follows:
 
-Inventory locations
--------------------
-* `"context"`: Selected node metadata (deprecated: `"current_name"`)
-* `"current_player"`: Player to whom the menu is shown
-* `"player:<name>"`: Any player
-* `"nodemeta:<X>,<Y>,<Z>"`: Any node metadata
-* `"detached:<name>"`: A detached inventory
+noise = offset + scale * (abs(octave1) +
+                          abs(octave2) * persistence +
+                          abs(octave3) * persistence ^ 2 +
+                          abs(octave4) * persistence ^ 3 +
+                          ...)
 
-Player Inventory lists
-----------------------
-* `main`: list containing the default inventory
-* `craft`: list containing the craft input
-* `craftpreview`: list containing the craft output
-* `hand`: list containing an override for the empty hand
+### Format example
+For 2D or 3D perlin noise or perlin noise maps:
 
-`ColorString`
--------------
-`#RGB` defines a color in hexadecimal format.
+    np_terrain = {
+        offset = 0,
+        scale = 1,
+        spread = {x = 500, y = 500, z = 500},
+        seed = 571347,
+        octaves = 5,
+        persist = 0.63,
+        lacunarity = 2.0,
+        flags = "defaults, absvalue",
+    }
 
-`#RGBA` defines a color in hexadecimal format and alpha channel.
+For 2D noise the Z component of `spread` is still defined but is ignored.
+A single noise parameter table can be used for 2D or 3D noise.
 
-`#RRGGBB` defines a color in hexadecimal format.
+Ore types
+---------
+These tell in what manner the ore is generated.
 
-`#RRGGBBAA` defines a color in hexadecimal format and alpha channel.
+All default ores are of the uniformly-distributed scatter type.
 
-Named colors are also supported and are equivalent to
-[CSS Color Module Level 4](http://dev.w3.org/csswg/css-color/#named-colors).
-To specify the value of the alpha channel, append `#AA` to the end of the color
-name (e.g. `colorname#08`). For named colors the hexadecimal string
-representing the alpha value must (always) be two hexadecimal digits.
+### `scatter`
+Randomly chooses a location and generates a cluster of ore.
 
-`ColorSpec`
------------
-A ColorSpec specifies a 32-bit color.  It can be written in either:
-table form, each element ranging from 0..255 (a, if absent, defaults to 255):
-    `colorspec = {a=255, r=0, g=255, b=0}`
-numerical form, the raw integer value of an ARGB8 quad:
-    `colorspec = 0xFF00FF00`
-or string form, a ColorString (defined above):
-    `colorspec = "green"`
+If `noise_params` is specified, the ore will be placed if the 3D perlin noise
+at that point is greater than the `noise_threshold`, giving the ability to
+create a non-equal distribution of ore.
 
-Escape sequences
-----------------
-Most text can contain escape sequences, that can for example color the text.
-There are a few exceptions: tab headers, dropdowns and vertical labels can't.
-The following functions provide escape sequences:
+### `sheet`
+Creates a sheet of ore in a blob shape according to the 2D perlin noise
+described by `noise_params` and `noise_threshold`. This is essentially an
+improved version of the so-called "stratus" ore seen in some unofficial mods.
 
-* `minetest.get_color_escape_sequence(color)`:
-    * `color` is a ColorString
-    * The escape sequence sets the text color to `color`
-* `minetest.colorize(color, message)`:
-    * Equivalent to:
-      `minetest.get_color_escape_sequence(color) ..
-      message ..
-      minetest.get_color_escape_sequence("#ffffff")`
-* `minetest.get_background_escape_sequence(color)`
-    * `color` is a ColorString
-    * The escape sequence sets the background of the whole text element to
-      `color`. Only defined for item descriptions and tooltips.
-* `minetest.strip_foreground_colors(str)`
-    * Removes foreground colors added by `get_color_escape_sequence`.
-* `minetest.strip_background_colors(str)`
-    * Removes background colors added by `get_background_escape_sequence`.
-* `minetest.strip_colors(str)`
-    * Removes all color escape sequences.
+This sheet consists of vertical columns of uniform randomly distributed height,
+varying between the inclusive range `column_height_min` and `column_height_max`.
+If `column_height_min` is not specified, this parameter defaults to 1.
+If `column_height_max` is not specified, this parameter defaults to `clust_size`
+for reverse compatibility. New code should prefer `column_height_max`.
 
-Spatial Vectors
----------------
-For the following functions, `v`, `v1`, `v2` are vectors,
-`p1`, `p2` are positions:
+The `column_midpoint_factor` parameter controls the position of the column at
+which ore emanates from.
+If 1, columns grow upward. If 0, columns grow downward. If 0.5, columns grow
+equally starting from each direction.
+`column_midpoint_factor` is a decimal number ranging in value from 0 to 1. If
+this parameter is not specified, the default is 0.5.
 
-* `vector.new(a[, b, c])`:
-    * Returns a vector.
-    * A copy of `a` if `a` is a vector.
-    * `{x = a, y = b, z = c}`, if all of `a`, `b`, `c` are defined numbers.
-* `vector.direction(p1, p2)`:
-    * Returns a vector of length 1 with direction `p1` to `p2`.
-    * If `p1` and `p2` are identical, returns `{x = 0, y = 0, z = 0}`.
-* `vector.distance(p1, p2)`:
-    * Returns zero or a positive number, the distance between `p1` and `p2`.
-* `vector.length(v)`:
-    * Returns zero or a positive number, the length of vector `v`.
-* `vector.normalize(v)`:
-    * Returns a vector of length 1 with direction of vector `v`.
-    * If `v` has zero length, returns `{x = 0, y = 0, z = 0}`.
-* `vector.floor(v)`:
-    * Returns a vector, each dimension rounded down.
-* `vector.round(v)`:
-    * Returns a vector, each dimension rounded to nearest integer.
-* `vector.apply(v, func)`:
-    * Returns a vector where the function `func` has been applied to each
-      component.
-* `vector.equals(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`.
+The ore parameters `clust_scarcity` and `clust_num_ores` are ignored for this
+ore type.
 
-For the following functions `x` can be either a vector or a number:
+### `puff`
+Creates a sheet of ore in a cloud-like puff shape.
 
-* `vector.add(v, x)`:
-    * Returns a vector.
-* `vector.subtract(v, x)`:
-    * Returns a vector.
-* `vector.multiply(v, x)`:
-    * Returns a scaled vector or Schur product.
-* `vector.divide(v, x)`:
-    * Returns a scaled vector or Schur quotient.
+As with the `sheet` ore type, the size and shape of puffs are described by
+`noise_params` and `noise_threshold` and are placed at random vertical
+positions within the currently generated chunk.
 
-Helper functions
-----------------
-* `dump2(obj, name, dumped)`: returns a string which makes `obj`
-  human-readable, handles reference loops.
-    * `obj`: arbitrary variable
-    * `name`: string, default: `"_"`
-    * `dumped`: table, default: `{}`
-* `dump(obj, dumped)`: returns a string which makes `obj` human-readable
-    * `obj`: arbitrary variable
-    * `dumped`: table, default: `{}`
-* `math.hypot(x, y)`
-    * Get the hypotenuse of a triangle with legs x and y.
-      Useful for distance calculation.
-* `math.sign(x, tolerance)`: returns `-1`, `0` or `1`
-    * Get the sign of a number.
-    * tolerance: number, default: `0.0`
-    * If the absolute value of `x` is within the `tolerance` or `x` is NaN,
-      `0` is returned.
-* `string.split(str, separator, include_empty, max_splits, sep_is_pattern)`
-    * `separator`: string, default: `","`
-    * `include_empty`: boolean, default: `false`
-    * `max_splits`: number, if it's positive, splits aren't limited,
-      default: `-1`
-    * `sep_is_pattern`: boolean, it specifies whether separator is a plain
-      string or a pattern (regex), default: `false`
-    * e.g. `"a,b":split","` returns `{"a","b"}`
-* `string:trim()`: returns the string without whitespace pre- and suffixes
-    * e.g. `"\n \t\tfoo bar\t ":trim()` returns `"foo bar"`
-* `minetest.wrap_text(str, limit, as_table)`: returns a string or table
-    * Adds newlines to the string to keep it within the specified character
-      limit
-    * Note that the returned lines may be longer than the limit since it only
-      splits at word borders.
-    * `limit`: number, maximal amount of characters in one line
-    * `as_table`: boolean, if set to true, a table of lines instead of a string
-      is returned, default: `false`
-* `minetest.pos_to_string(pos, decimal_places)`: returns string `"(X,Y,Z)"`
-    * `pos`: table {x=X, y=Y, z=Z}
-    * Converts the position `pos` to a human-readable, printable string
-    * `decimal_places`: number, if specified, the x, y and z values of
-      the position are rounded to the given decimal place.
-* `minetest.string_to_pos(string)`: returns a position or `nil`
-    * Same but in reverse.
-    * If the string can't be parsed to a position, nothing is returned.
-* `minetest.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)")`: returns two positions
-    * Converts a string representing an area box into two positions
-* `minetest.formspec_escape(string)`: returns a string
-    * escapes the characters "[", "]", "\", "," and ";", which can not be used
-      in formspecs.
-* `minetest.is_yes(arg)`
-    * returns true if passed 'y', 'yes', 'true' or a number that isn't zero.
-* `minetest.is_nan(arg)`
-    * returns true when the passed number represents NaN.
-* `minetest.get_us_time()`
-    * returns time with microsecond precision. May not return wall time.
-* `table.copy(table)`: returns a table
-    * returns a deep copy of `table`
-* `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
+The vertical top and bottom displacement of each puff are determined by the
+noise parameters `np_puff_top` and `np_puff_bottom`, respectively.
 
-Translations
-------------
+### `blob`
+Creates a deformed sphere of ore according to 3d perlin noise described by
+`noise_params`. The maximum size of the blob is `clust_size`, and
+`clust_scarcity` has the same meaning as with the `scatter` type.
 
-Texts can be translated client-side with the help of `minetest.translate` and
-translation files.
+### `vein`
+Creates veins of ore varying in density by according to the intersection of two
+instances of 3d perlin noise with different seeds, both described by
+`noise_params`.
 
-### Translating a string
-Two functions are provided to translate strings: `minetest.translate` and
-`minetest.get_translator`.
+`random_factor` varies the influence random chance has on placement of an ore
+inside the vein, which is `1` by default. Note that modifying this parameter
+may require adjusting `noise_threshold`.
 
-* `minetest.get_translator(textdomain)` is a simple wrapper around
-  `minetest.translate`, and `minetest.get_translator(textdomain)(str, ...)` is
-  equivalent to `minetest.translate(textdomain, str, ...)`.
-  It is intended to be used in the following way, so that it avoids verbose
-  repetitions of `minetest.translate`:
+The parameters `clust_scarcity`, `clust_num_ores`, and `clust_size` are ignored
+by this ore type.
 
-    local S = minetest.get_translator(textdomain)
-    S(str, ...)
+This ore type is difficult to control since it is sensitive to small changes.
+The following is a decent set of parameters to work from:
 
-  As an extra commodity, if `textdomain` is nil, it is assumed to be "" instead.
+    noise_params = {
+        offset  = 0,
+        scale   = 3,
+        spread  = {x=200, y=200, z=200},
+        seed    = 5390,
+        octaves = 4,
+        persist = 0.5,
+        lacunarity = 2.0,
+        flags = "eased",
+    },
+    noise_threshold = 1.6
 
-* `minetest.translate(textdomain, str, ...)` translates the string `str` with
-  the given `textdomain` for disambiguation. The textdomain must match the
-  textdomain specified in the translation file in order to get the string
-  translated. This can be used so that a string is translated differently in
-  different contexts.
-  It is advised to use the name of the mod as textdomain whenever possible, to
-  avoid clashes with other mods.
-  This function must be given a number of arguments equal to the number of
-  arguments the translated string expects.
-  Arguments are literal strings -- they will not be translated, so if you want
-  them to be, they need to come as outputs of `minetest.translate` as well.
+**WARNING**: Use this ore type *very* sparingly since it is ~200x more
+computationally expensive than any other ore.
 
-  For instance, suppose we want to translate "@1 Wool" with "@1" being replaced
-  by the translation of "Red". We can do the following:
+### `stratum`
+Creates a single undulating ore stratum that is continuous across mapchunk
+borders and horizontally spans the world.
 
-    local S = minetest.get_translator()
-    S("@1 Wool", S("Red"))
+The 2D perlin noise described by `noise_params` defines the Y co-ordinate of
+the stratum midpoint. The 2D perlin noise described by `np_stratum_thickness`
+defines the stratum's vertical thickness (in units of nodes). Due to being
+continuous across mapchunk borders the stratum's vertical thickness is
+unlimited.
 
-  This will be displayed as "Red Wool" on old clients and on clients that do
-  not have localization enabled. However, if we have for instance a translation
-  file named `wool.fr.tr` containing the following:
+If the noise parameter `noise_params` is omitted the ore will occur from y_min
+to y_max in a simple horizontal stratum.
+
+A parameter `stratum_thickness` can be provided instead of the noise parameter
+`np_stratum_thickness`, to create a constant thickness.
+
+Leaving out one or both noise parameters makes the ore generation less
+intensive, useful when adding multiple strata.
+
+`y_min` and `y_max` define the limits of the ore generation and for performance
+reasons should be set as close together as possible but without clipping the
+stratum's Y variation.
+
+Each node in the stratum has a 1-in-`clust_scarcity` chance of being ore, so a
+solid-ore stratum would require a `clust_scarcity` of 1.
+
+The parameters `clust_num_ores`, `clust_size`, `noise_threshold` and
+`random_factor` are ignored by this ore type.
+
+Ore attributes
+--------------
+See section "Flag Specifier Format".
+
+Currently supported flags:
+`puff_cliffs`, `puff_additive_composition`.
+
+### `puff_cliffs`
+If set, puff ore generation will not taper down large differences in
+displacement when approaching the edge of a puff. This flag has no effect for
+ore types other than `puff`.
+
+### `puff_additive_composition`
+By default, when noise described by `np_puff_top` or `np_puff_bottom` results
+in a negative displacement, the sub-column at that point is not generated. With
+this attribute set, puff ore generation will instead generate the absolute
+difference in noise displacement values. This flag has no effect for ore types
+other than `puff`.
+
+Decoration types
+----------------
+The varying types of decorations that can be placed.
+
+### `simple`
+Creates a 1 times `H` times 1 column of a specified node (or a random node from
+a list, if a decoration list is specified). Can specify a certain node it must
+spawn next to, such as water or lava, for example. Can also generate a
+decoration of random height between a specified lower and upper bound.
+This type of decoration is intended for placement of grass, flowers, cacti,
+papyri, waterlilies and so on.
+
+### `schematic`
+Copies a box of `MapNodes` from a specified schematic file (or raw description).
+Can specify a probability of a node randomly appearing when placed.
+This decoration type is intended to be used for multi-node sized discrete
+structures, such as trees, cave spikes, rocks, and so on.
+
+Schematic specifier
+--------------------
+A schematic specifier identifies a schematic by either a filename to a
+Minetest Schematic file (`.mts`) or through raw data supplied through Lua,
+in the form of a table.  This table specifies the following fields:
+
+* The `size` field is a 3D vector containing the dimensions of the provided
+  schematic. (required)
+* The `yslice_prob` field is a table of {ypos, prob} which sets the `ypos`th
+  vertical slice of the schematic to have a `prob / 256 * 100` chance of
+  occurring. (default: 255)
+* The `data` field is a flat table of MapNode tables making up the schematic,
+  in the order of `[z [y [x]]]`. (required)
+  Each MapNode table contains:
+    * `name`: the name of the map node to place (required)
+    * `prob` (alias `param1`): the probability of this node being placed
+      (default: 255)
+    * `param2`: the raw param2 value of the node being placed onto the map
+      (default: 0)
+    * `force_place`: boolean representing if the node should forcibly overwrite
+      any previous contents (default: false)
+
+About probability values:
+
+* A probability value of `0` or `1` means that node will never appear
+  (0% chance).
+* A probability value of `254` or `255` means the node will always appear
+  (100% chance).
+* If the probability value `p` is greater than `1`, then there is a
+  `(p / 256 * 100)` percent chance that node will appear when the schematic is
+  placed on the map.
+
+Schematic attributes
+--------------------
+See section "Flag Specifier Format".
+
+Currently supported flags: `place_center_x`, `place_center_y`, `place_center_z`,
+                           `force_placement`.
+
+* `place_center_x`: Placement of this decoration is centered along the X axis.
+* `place_center_y`: Placement of this decoration is centered along the Y axis.
+* `place_center_z`: Placement of this decoration is centered along the Z axis.
+* `force_placement`: Schematic nodes other than "ignore" will replace existing
+  nodes.
+
+Lua Voxel Manipulator
+---------------------
+### About VoxelManip
+VoxelManip is a scripting interface to the internal 'Map Voxel Manipulator'
+facility. The purpose of this object is for fast, low-level, bulk access to
+reading and writing Map content. As such, setting map nodes through VoxelManip
+will lack many of the higher level features and concepts you may be used to
+with other methods of setting nodes. For example, nodes will not have their
+construction and destruction callbacks run, and no rollback information is
+logged.
+
+It is important to note that VoxelManip is designed for speed, and *not* ease
+of use or flexibility. If your mod requires a map manipulation facility that
+will handle 100% of all edge cases, or the use of high level node placement
+features, perhaps `minetest.set_node()` is better suited for the job.
+
+In addition, VoxelManip might not be faster, or could even be slower, for your
+specific use case. VoxelManip is most effective when setting large areas of map
+at once - for example, if only setting a 3x3x3 node area, a
+`minetest.set_node()` loop may be more optimal. Always profile code using both
+methods of map manipulation to determine which is most appropriate for your
+usage.
+
+A recent simple test of setting cubic areas showed that `minetest.set_node()`
+is faster than a VoxelManip for a 3x3x3 node cube or smaller.
+
+### Using VoxelManip
+A VoxelManip object can be created any time using either:
+`VoxelManip([p1, p2])`, or `minetest.get_voxel_manip([p1, p2])`.
+
+If the optional position parameters are present for either of these routines,
+the specified region will be pre-loaded into the VoxelManip object on creation.
+Otherwise, the area of map you wish to manipulate must first be loaded into the
+VoxelManip object using `VoxelManip:read_from_map()`.
+
+Note that `VoxelManip:read_from_map()` returns two position vectors. The region
+formed by these positions indicate the minimum and maximum (respectively)
+positions of the area actually loaded in the VoxelManip, which may be larger
+than the area requested. For convenience, the loaded area coordinates can also
+be queried any time after loading map data with `VoxelManip:get_emerged_area()`.
+
+Now that the VoxelManip object is populated with map data, your mod can fetch a
+copy of this data using either of two methods. `VoxelManip:get_node_at()`,
+which retrieves an individual node in a MapNode formatted table at the position
+requested is the simplest method to use, but also the slowest.
+
+Nodes in a VoxelManip object may also be read in bulk to a flat array table
+using:
+
+* `VoxelManip:get_data()` for node content (in Content ID form, see section
+  'Content IDs'),
+* `VoxelManip:get_light_data()` for node light levels, and
+* `VoxelManip:get_param2_data()` for the node type-dependent "param2" values.
+
+See section 'Flat array format' for more details.
+
+It is very important to understand that the tables returned by any of the above
+three functions represent a snapshot of the VoxelManip's internal state at the
+time of the call. This copy of the data will not magically update itself if
+another function modifies the internal VoxelManip state.
+Any functions that modify a VoxelManip's contents work on the VoxelManip's
+internal state unless otherwise explicitly stated.
+
+Once the bulk data has been edited to your liking, the internal VoxelManip
+state can be set using:
+
+* `VoxelManip:set_data()` for node content (in Content ID form, see section
+  'Content IDs'),
+* `VoxelManip:set_light_data()` for node light levels, and
+* `VoxelManip:set_param2_data()` for the node type-dependent `param2` values.
+
+The parameter to each of the above three functions can use any table at all in
+the same flat array format as produced by `get_data()` etc. and is not required
+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()`
+
+
+#### Flat array format
+Let
+    `Nx = p2.X - p1.X + 1`,
+    `Ny = p2.Y - p1.Y + 1`, and
+    `Nz = p2.Z - p1.Z + 1`.
+
+Then, for a loaded region of p1..p2, this array ranges from `1` up to and
+including the value of the expression `Nx * Ny * Nz`.
+
+Positions offset from p1 are present in the array with the format of:
+
+```
+[
+    (0, 0, 0),   (1, 0, 0),   (2, 0, 0),   ... (Nx, 0, 0),
+    (0, 1, 0),   (1, 1, 0),   (2, 1, 0),   ... (Nx, 1, 0),
+    ...
+    (0, Ny, 0),  (1, Ny, 0),  (2, Ny, 0),  ... (Nx, Ny, 0),
+    (0, 0, 1),   (1, 0, 1),   (2, 0, 1),   ... (Nx, 0, 1),
+    ...
+    (0, Ny, 2),  (1, Ny, 2),  (2, Ny, 2),  ... (Nx, Ny, 2),
+    ...
+    (0, Ny, Nz), (1, Ny, Nz), (2, Ny, Nz), ... (Nx, Ny, Nz)
+]
+```
+
+and the array index for a position p contained completely in p1..p2 is:
+
+`(p.Z - p1.Z) * Ny * Nx + (p.Y - p1.Y) * Nx + (p.X - p1.X) + 1`
+
+Note that this is the same "flat 3D array" format as
+`PerlinNoiseMap:get3dMap_flat()`.
+VoxelArea objects (see section 'VoxelArea') can be used to simplify calculation
+of the index for a single point in a flat VoxelManip array.
+
+#### Content IDs
+A Content ID is a unique integer identifier for a specific node type.
+These IDs are used by VoxelManip in place of the node name string for
+`VoxelManip:get_data()` and `VoxelManip:set_data()`. You can use
+`minetest.get_content_id()` to look up the Content ID for the specified node
+name, and `minetest.get_name_from_content_id()` to look up the node name string
+for a given Content ID.
+After registration of a node, its Content ID will remain the same throughout
+execution of the mod.
+Note that the node being queried needs to have already been been registered.
+
+The following builtin node types have their Content IDs defined as constants:
+
+* `minetest.CONTENT_UNKNOWN`: ID for "unknown" nodes
+* `minetest.CONTENT_AIR`:     ID for "air" nodes
+* `minetest.CONTENT_IGNORE`:  ID for "ignore" nodes
+
+#### Mapgen VoxelManip objects
+Inside of `on_generated()` callbacks, it is possible to retrieve the same
+VoxelManip object used by the core's Map Generator (commonly abbreviated
+Mapgen). Most of the rules previously described still apply but with a few
+differences:
+
+* The Mapgen VoxelManip object is retrieved using:
+  `minetest.get_mapgen_object("voxelmanip")`
+* This VoxelManip object already has the region of map just generated loaded
+  into it; it's not necessary to call `VoxelManip:read_from_map()` before using
+  a Mapgen VoxelManip.
+* The `on_generated()` callbacks of some mods may place individual nodes in the
+  generated area using non-VoxelManip map modification methods. Because the
+  same Mapgen VoxelManip object is passed through each `on_generated()`
+  callback, it becomes necessary for the Mapgen VoxelManip object to maintain
+  consistency with the current map state. For this reason, calling any of the
+  following functions:
+  `minetest.add_node()`, `minetest.set_node()`, or `minetest.swap_node()`
+  will also update the Mapgen VoxelManip object's internal state active on the
+  current thread.
+* After modifying the Mapgen VoxelManip object's internal buffer, it may be
+  necessary to update lighting information using either:
+  `VoxelManip:calc_lighting()` or `VoxelManip:set_lighting()`.
+
+#### Other API functions operating on a VoxelManip
+If any VoxelManip contents were set to a liquid node,
+`VoxelManip:update_liquids()` must be called for these liquid nodes to begin
+flowing. It is recommended to call this function only after having written all
+buffered data back to the VoxelManip object, save for special situations where
+the modder desires to only have certain liquid nodes begin flowing.
+
+The functions `minetest.generate_ores()` and `minetest.generate_decorations()`
+will generate all registered decorations and ores throughout the full area
+inside of the specified VoxelManip object.
+
+`minetest.place_schematic_on_vmanip()` is otherwise identical to
+`minetest.place_schematic()`, except instead of placing the specified schematic
+directly on the map at the specified position, it will place the schematic
+inside the VoxelManip.
+
+#### Notes
+* Attempting to read data from a VoxelManip object before map is read will
+  result in a zero-length array table for `VoxelManip:get_data()`, and an
+  "ignore" node at any position for `VoxelManip:get_node_at()`.
+* If either a region of map has not yet been generated or is out-of-bounds of
+  the map, that region is filled with "ignore" nodes.
+* Other mods, or the core itself, could possibly modify the area of map
+  currently loaded into a VoxelManip object. With the exception of Mapgen
+  VoxelManips (see above section), the internal buffers are not updated. For
+  this reason, it is strongly encouraged to complete the usage of a particular
+  VoxelManip object in the same callback it had been created.
+* If a VoxelManip object will be used often, such as in an `on_generated()`
+  callback, consider passing a file-scoped table as the optional parameter to
+  `VoxelManip:get_data()`, which serves as a static buffer the function can use
+  to write map data to instead of returning a new table each call. This greatly
+  enhances performance by avoiding unnecessary memory allocations.
+
+### Methods
+* `read_from_map(p1, p2)`:  Loads a chunk of map into the VoxelManip object
+  containing the region formed by `p1` and `p2`.
+    * returns actual emerged `pmin`, actual emerged `pmax`
+* `write_to_map([light])`: Writes the data loaded from the `VoxelManip` back to
+  the map.
+    * **important**: data must be set using `VoxelManip:set_data()` before
+      calling this.
+    * if `light` is true, then lighting is automatically recalculated.
+      The default value is true.
+      If `light` is false, no light calculations happen, and you should correct
+      all modified blocks with `minetest.fix_light()` as soon as possible.
+      Keep in mind that modifying the map where light is incorrect can cause
+      more lighting bugs.
+* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded in
+  the `VoxelManip` at that position
+* `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at
+  that position.
+* `get_data([buffer])`: Retrieves the node content data loaded into the
+  `VoxelManip` object.
+    * returns raw node data in the form of an array of node content IDs
+    * if the param `buffer` is present, this table will be used to store the
+      result instead.
+* `set_data(data)`: Sets the data contents of the `VoxelManip` object
+* `update_map()`: Does nothing, kept for compatibility.
+* `set_lighting(light, [p1, p2])`: Set the lighting within the `VoxelManip` to
+  a uniform value.
+    * `light` is a table, `{day=<0...15>, night=<0...15>}`
+    * 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.
+* `get_light_data()`: Gets the light data read into the `VoxelManip` object
+    * Returns an array (indices 1 to volume) of integers ranging from `0` to
+      `255`.
+    * Each value is the bitwise combination of day and night light values
+      (`0` to `15` each).
+    * `light = day + (night * 16)`
+* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node
+  in the `VoxelManip`.
+    * expects lighting data in the same format that `get_light_data()` returns
+* `get_param2_data([buffer])`: Gets the raw `param2` data read into the
+  `VoxelManip` object.
+    * Returns an array (indices 1 to volume) of integers ranging from `0` to
+      `255`.
+    * If the param `buffer` is present, this table will be used to store the
+      result instead.
+* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in
+  the `VoxelManip`.
+* `calc_lighting([p1, p2], [propagate_shadow])`:  Calculate lighting within the
+  `VoxelManip`.
+    * 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.
+    * `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.
+* `update_liquids()`: Update liquid flow
+* `was_modified()`: Returns `true` or `false` if the data in the voxel
+  manipulator had been modified since the last read from map, due to a call to
+  `minetest.set_data()` on the loaded area elsewhere.
+* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
+
+### `VoxelArea`
+A helper class for voxel areas.
+It can be created via `VoxelArea:new{MinEdge=pmin, MaxEdge=pmax}`.
+The coordinates are *inclusive*, like most other things in Minetest.
+
+#### Methods
+* `getExtent()`: returns a 3D vector containing the size of the area formed by
+  `MinEdge` and `MaxEdge`.
+* `getVolume()`: returns the volume of the area formed by `MinEdge` and
+  `MaxEdge`.
+* `index(x, y, z)`: returns the index of an absolute position in a flat array
+  starting at `1`.
+    * `x`, `y` and `z` must be integers to avoid an incorrect index result.
+    * The position (x, y, z) is not checked for being inside the area volume,
+      being outside can cause an incorrect index result.
+    * Useful for things like `VoxelManip`, raw Schematic specifiers,
+      `PerlinNoiseMap:get2d`/`3dMap`, and so on.
+* `indexp(p)`: same functionality as `index(x, y, z)` but takes a vector.
+    * As with `index(x, y, z)`, the components of `p` must be integers, and `p`
+      is not checked for being inside the area volume.
+* `position(i)`: returns the absolute position vector corresponding to index
+  `i`.
+* `contains(x, y, z)`: check if (`x`,`y`,`z`) is inside area formed by
+  `MinEdge` and `MaxEdge`.
+* `containsp(p)`: same as above, except takes a vector
+* `containsi(i)`: same as above, except takes an index `i`
+* `iter(minx, miny, minz, maxx, maxy, maxz)`: returns an iterator that returns
+  indices.
+    * from (`minx`,`miny`,`minz`) to (`maxx`,`maxy`,`maxz`) in the order of
+      `[z [y [x]]]`.
+* `iterp(minp, maxp)`: same as above, except takes a vector
+
+Mapgen objects
+--------------
+A mapgen object is a construct used in map generation. Mapgen objects can be
+used by an `on_generate` callback to speed up operations by avoiding
+unnecessary recalculations, these can be retrieved using the
+`minetest.get_mapgen_object()` function. If the requested Mapgen object is
+unavailable, or `get_mapgen_object()` was called outside of an `on_generate()`
+callback, `nil` is returned.
+
+The following Mapgen objects are currently available:
+
+### `voxelmanip`
+This returns three values; the `VoxelManip` object to be used, minimum and
+maximum emerged position, in that order. All mapgens support this object.
+
+### `heightmap`
+Returns an array containing the y coordinates of the ground levels of nodes in
+the most recently generated chunk by the current mapgen.
+
+### `biomemap`
+Returns an array containing the biome IDs of nodes in the most recently
+generated chunk by the current mapgen.
+
+### `heatmap`
+Returns an array containing the temperature values of nodes in the most
+recently generated chunk by the current mapgen.
+
+### `humiditymap`
+Returns an array containing the humidity values of nodes in the most recently
+generated chunk by the current mapgen.
+
+### `gennotify`
+Returns a table mapping requested generation notification types to arrays of
+positions at which the corresponding generated structures are located within
+the current chunk. To set the capture of positions of interest to be recorded
+on generate, use `minetest.set_gen_notify()`.
+For decorations, the returned positions are the ground surface 'place_on'
+nodes, not the decorations themselves. A 'simple' type decoration is often 1
+node above the returned position and possibly displaced by 'place_offset_y'.
+
+Possible fields of the table returned are:
+
+* `dungeon`
+* `temple`
+* `cave_begin`
+* `cave_end`
+* `large_cave_begin`
+* `large_cave_end`
+* `decoration`
+
+Decorations have a key in the format of `"decoration#id"`, where `id` is the
+numeric unique decoration ID.
+
+Registered entities
+-------------------
+* Functions receive a "luaentity" as `self`:
+    * It has the member `.name`, which is the registered name `("mod:thing")`
+    * It has the member `.object`, which is an `ObjectRef` pointing to the
+      object.
+    * The original prototype stuff is visible directly via a metatable
+* Callbacks:
+    * `on_activate(self, staticdata, dtime_s)`
+        * Called when the object is instantiated.
+        * `dtime_s` is the time passed since the object was unloaded, which can
+          be used for updating the entity state.
+    * `on_step(self, dtime)`
+        * 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)`
+        * Called when somebody punches the object.
+        * Note that you probably want to handle most punches using the
+          automatic armor group system.
+        * `puncher`: an `ObjectRef` (can be `nil`)
+        * `time_from_last_punch`: Meant for disallowing spamming of clicks
+          (can be `nil`).
+        * `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.
+    * `on_death(self, killer)`
+        * Called when the object dies.
+        * `killer`: an `ObjectRef` (can be `nil`)
+    * `on_rightclick(self, clicker)`
+    * `on_attach_child(self, child)`
+        * `child`: an `ObjectRef` of the child that attaches
+    * `on_detach_child(self, child)`
+        * `child`: an `ObjectRef` of the child that detaches
+    * `on_detach(self, parent)`
+        * `parent`: an `ObjectRef` (can be `nil`) from where it got detached
+        * This happens before the parent object is removed from the world
+    * `get_staticdata(self)`
+        * Should return a string that will be passed to `on_activate` when
+          the object is instantiated the next time.
 
-    @1 Wool=Laine @1
-    Red=Rouge
+L-system trees
+--------------
 
-  this will be displayed as "Laine Rouge" on clients with a French locale.
+### Tree definition
 
-### Operations on translated strings
+    treedef={
+        axiom,         --string  initial tree axiom
+        rules_a,       --string  rules set A
+        rules_b,       --string  rules set B
+        rules_c,       --string  rules set C
+        rules_d,       --string  rules set D
+        trunk,         --string  trunk node name
+        leaves,        --string  leaves node name
+        leaves2,       --string  secondary leaves node name
+        leaves2_chance,--num     chance (0-100) to replace leaves with leaves2
+        angle,         --num     angle in deg
+        iterations,    --num     max # of iterations, usually 2 -5
+        random_level,  --num     factor to lower nr of iterations, usually 0 - 3
+        trunk_type,    --string  single/double/crossed) type of trunk: 1 node,
+                       --        2x2 nodes or 3x3 in cross shape
+        thin_branches, --boolean true -> use thin (1 node) branches
+        fruit,         --string  fruit node name
+        fruit_chance,  --num     chance (0-100) to replace leaves with fruit node
+        seed,          --num     random seed, if no seed is provided, the engine
+                                 will create one.
+    }
 
-The output of `minetest.translate` is a string, with escape sequences adding
-additional information to that string so that it can be translated on the
-different clients. In particular, you can't expect operations like string.length
-to work on them like you would expect them to, or string.gsub to work in the
-expected manner. However, string concatenation will still work as expected
-(note that you should only use this for things like formspecs; do not translate
-sentences by breaking them into parts; arguments should be used instead), and
-operations such as `minetest.colorize` which are also concatenation.
+### Key for Special L-System Symbols used in Axioms
 
-### Translation file format
-A translation file has the suffix `.[lang].tr`, where `[lang]` is the language
-it corresponds to. It must be put into the `locale` subdirectory of the mod.
-The file should be a text file, with the following format:
+* `G`: move forward one unit with the pen up
+* `F`: move forward one unit with the pen down drawing trunks and branches
+* `f`: move forward one unit with the pen down drawing leaves (100% chance)
+* `T`: move forward one unit with the pen down drawing trunks only
+* `R`: move forward one unit with the pen down placing fruit
+* `A`: replace with rules set A
+* `B`: replace with rules set B
+* `C`: replace with rules set C
+* `D`: replace with rules set D
+* `a`: replace with rules set A, chance 90%
+* `b`: replace with rules set B, chance 80%
+* `c`: replace with rules set C, chance 70%
+* `d`: replace with rules set D, chance 60%
+* `+`: yaw the turtle right by `angle` parameter
+* `-`: yaw the turtle left by `angle` parameter
+* `&`: pitch the turtle down by `angle` parameter
+* `^`: pitch the turtle up by `angle` parameter
+* `/`: roll the turtle to the right by `angle` parameter
+* `*`: roll the turtle to the left by `angle` parameter
+* `[`: save in stack current state info
+* `]`: recover from stack state info
 
-* Lines beginning with `# textdomain:` (the space is significant) can be used
-  to specify the text domain of all following translations in the file.
-* All other empty lines or lines beginning with `#` are ignored.
-* Other lines should be in the format `original=translated`. Both `original`
-  and `translated` can contain escape sequences beginning with `@` to insert
-  arguments, literal `@`, `=` or newline (See ### Escapes below).
-  There must be no extraneous whitespace around the `=` or at the beginning or
-  the end of the line.
+### Example
+Spawn a small apple tree:
 
-### Escapes
-Strings that need to be translated can contain several escapes, preceded by `@`.
+    pos = {x=230,y=20,z=4}
+    apple_tree={
+        axiom="FFFFFAFFBF",
+        rules_a="[&&&FFFFF&&FFFF][&&&++++FFFFF&&FFFF][&&&----FFFFF&&FFFF]",
+        rules_b="[&&&++FFFFF&&FFFF][&&&--FFFFF&&FFFF][&&&------FFFFF&&FFFF]",
+        trunk="default:tree",
+        leaves="default:leaves",
+        angle=30,
+        iterations=2,
+        random_level=0,
+        trunk_type="single",
+        thin_branches=true,
+        fruit_chance=10,
+        fruit="default:apple"
+    }
+    minetest.spawn_tree(pos,apple_tree)
 
-* `@@` acts as a literal `@`.
-* `@n`, where `n` is a digit between 1 and 9, is an argument for the translated
-  string that will be inlined when translation. Due to how translations are
-  implemented, the original translation string **must** have its arguments in
-  increasing order, without gaps or repetitions, starting from 1.
-* `@=` acts as a literal `=`. It is not required in strings given to
-  `minetest.translate`, but is in translation files to avoid being confused
-  with the `=` separating the original from the translation.
-* `@\n` (where the `\n` is a literal newline) acts as a literal newline.
-  As with `@=`, this escape is not required in strings given to
-  `minetest.translate`, but is in translation files.
-* `@n` acts as a literal newline as well.
 
 `minetest` namespace reference
 ------------------------------
@@ -3898,25 +4346,159 @@ These functions return the leftover itemstack.
 * `minetest.registered_decorations`
     * List of registered decoration definitions.
 
+
 Class reference
 ---------------
 
-### ModChannel
+### `AreaStore`
+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
+`AreaStore(type_name)`.
+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.
+* `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.
+* `reserve(count)`: reserves resources for at most `count` many contained
+  areas.
+  Only needed for efficiency, and only some implementations profit.
+* `remove_area(id)`: removes the area with the given id from the store, returns
+  success.
+* `set_cache_params(params)`: sets params for the included prefiltering cache.
+  Calling invalidates the cache, so that its elements have to be newly
+  generated.
+    * `params`:
+      {
+        enabled = boolean,     -- whether to enable, default true
+        block_radius = number, -- the radius (in nodes) of the areas the cache
+                                  generates prefiltered lists for, minimum 16,
+                                  default 64.
+        limit = number,        -- the cache's size, minimum 20, default 1000
+      }
+* `to_string()`: Experimental. Returns area store serialized as a (binary)
+  string.
+* `to_file(filename)`: Experimental. Like `to_string()`, but writes the data to
+  a file.
+* `from_string(str)`: Experimental. Deserializes string and loads it into the
+  AreaStore.
+  Returns success and, optionally, an error message.
+* `from_file(filename)`: Experimental. Like `from_string()`, but reads the data
+  from a file.
+
+### `InvRef`
+An `InvRef` is a reference to an inventory.
+
+#### Methods
+* `is_empty(listname)`: return `true` if list is empty
+* `get_size(listname)`: get size of a list
+* `set_size(listname, size)`: set size of a list
+    * returns `false` on error (e.g. invalid `listname` or `size`)
+* `get_width(listname)`: get width of a list
+* `set_width(listname, width)`: set width of list; currently used for crafting
+* `get_stack(listname, i)`: get a copy of stack index `i` in list
+* `set_stack(listname, i, stack)`: copy `stack` to index `i` in list
+* `get_list(listname)`: return full list
+* `set_list(listname, list)`: set full list (size will not change)
+* `get_lists()`: returns list of inventory lists
+* `set_lists(lists)`: sets inventory lists (size will not change)
+* `add_item(listname, stack)`: add item somewhere in list, returns leftover
+  `ItemStack`.
+* `room_for_item(listname, stack):` returns `true` if the stack of items
+  can be fully added to the list
+* `contains_item(listname, stack, [match_meta])`: returns `true` if
+  the stack of items can be fully taken from the list.
+  If `match_meta` is false, only the items' names are compared
+  (default: `false`).
+* `remove_item(listname, stack)`: take as many items as specified from the
+  list, returns the items that were actually removed (as an `ItemStack`)
+  -- note that any item metadata is ignored, so attempting to remove a specific
+  unique item this way will likely remove the wrong one -- to do that use
+  `set_stack` with an empty `ItemStack`.
+* `get_location()`: returns a location compatible to
+  `minetest.get_inventory(location)`.
+    * returns `{type="undefined"}` in case location is not known
+
+### `ItemStack`
+An `ItemStack` is a stack of items.
+
+It can be created via `ItemStack(x)`, where x is an `ItemStack`,
+an itemstring, a table or `nil`.
+
+#### Methods
+* `is_empty()`: returns `true` if stack is empty.
+* `get_name()`: returns item name (e.g. `"default:stone"`).
+* `set_name(item_name)`: returns a boolean indicating whether the item was
+  cleared.
+* `get_count()`: Returns number of items on the stack.
+* `set_count(count)`: returns a boolean indicating whether the item was cleared
+    * `count`: number, unsigned 16 bit integer
+* `get_wear()`: returns tool wear (`0`-`65535`), `0` for non-tools.
+* `set_wear(wear)`: returns boolean indicating whether item was cleared
+    * `wear`: number, unsigned 16 bit integer
+* `get_meta()`: returns ItemStackMetaRef. See section for more details
+* `get_metadata()`: (DEPRECATED) Returns metadata (a string attached to an item
+  stack).
+* `set_metadata(metadata)`: (DEPRECATED) Returns true.
+* `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.
+* `to_string()`: returns the stack in itemstring form.
+* `to_table()`: returns the stack in Lua table form.
+* `get_stack_max()`: returns the maximum size of the stack (depends on the
+  item).
+* `get_free_space()`: returns `get_stack_max() - get_count()`.
+* `is_known()`: returns `true` if the item name refers to a defined item type.
+* `get_definition()`: returns the item definition table.
+* `get_tool_capabilities()`: returns the digging properties of the item,
+  or those of the hand if none are defined for this item type
+* `add_wear(amount)`
+    * Increases wear by `amount` if the item is a tool
+    * `amount`: number, integer
+* `add_item(item)`: returns leftover `ItemStack`
+    * Put some item or stack onto this stack
+* `item_fits(item)`: returns `true` if item or stack can be fully added to
+  this one.
+* `take_item(n)`: returns taken `ItemStack`
+    * Take (and remove) up to `n` items from this stack
+    * `n`: number, default: `1`
+* `peek_item(n)`: returns taken `ItemStack`
+    * Copy (don't remove) up to `n` items from this stack
+    * `n`: number, default: `1`
 
-An interface to use mod channels on client and server
+### `ItemStackMetaRef`
+ItemStack metadata: reference extra data and functionality stored in a stack.
+Can be obtained via `item:get_meta()`.
 
 #### Methods
-* `leave()`: leave the mod channel.
-    * Server leaves channel `channel_name`.
-    * No more incoming or outgoing messages can be sent to this channel from
-      server mods.
-    * This invalidate all future object usage.
-    * Ensure your set mod_channel to nil after that to free Lua resources.
-* `is_writeable()`: returns true if channel is writeable and mod can send over
-  it.
-* `send_all(message)`: Send `message` though the mod channel.
-    * If mod channel is not writeable or invalid, message will be dropped.
-    * Message size is limited to 65535 characters by protocol.
+* All methods in MetaDataRef
+* `set_tool_capabilities([tool_capabilities])`
+    * Overrides the item's tool capabilities
+    * A nil value will clear the override data and restore the original
+      behavior.
 
 ### `MetaDataRef`
 See `StorageRef`, `NodeMetaRef`, `ItemStackMetaRef`, and `PlayerMetaRef`.
@@ -3941,6 +4523,22 @@ See `StorageRef`, `NodeMetaRef`, `ItemStackMetaRef`, and `PlayerMetaRef`.
 * `equals(other)`
     * returns `true` if this metadata has the same key-value pairs as `other`
 
+### ModChannel
+An interface to use mod channels on client and server
+
+#### Methods
+* `leave()`: leave the mod channel.
+    * Server leaves channel `channel_name`.
+    * No more incoming or outgoing messages can be sent to this channel from
+      server mods.
+    * This invalidate all future object usage.
+    * Ensure your set mod_channel to nil after that to free Lua resources.
+* `is_writeable()`: returns true if channel is writeable and mod can send over
+  it.
+* `send_all(message)`: Send `message` though the mod channel.
+    * If mod channel is not writeable or invalid, message will be dropped.
+    * Message size is limited to 65535 characters by protocol.
+
 ### `NodeMetaRef`
 Node metadata: reference extra data and functionality stored in a node.
 Can be obtained via `minetest.get_meta(pos)`.
@@ -3954,33 +4552,6 @@ Can be obtained via `minetest.get_meta(pos)`.
   meaning it's best to call this when initializing all other meta (e.g.
   `on_construct`).
 
-### `ItemStackMetaRef`
-ItemStack metadata: reference extra data and functionality stored in a stack.
-Can be obtained via `item:get_meta()`.
-
-#### Methods
-* All methods in MetaDataRef
-* `set_tool_capabilities([tool_capabilities])`
-    * Overrides the item's tool capabilities
-    * A nil value will clear the override data and restore the original
-      behavior.
-
-### `StorageRef`
-Mod metadata: per mod metadata, saved automatically.
-Can be obtained via `minetest.get_mod_storage()` during load time.
-
-#### Methods
-* All methods in MetaDataRef
-
-### `PlayerMetaRef`
-Player metadata.
-Uses the same method of storage as the deprecated player attribute API, so
-data there will also be in player meta.
-Can be obtained using `player:get_meta()`.
-
-#### Methods
-* All methods in MetaDataRef
-
 ### `NodeTimerRef`
 Node Timers: a high resolution persistent per-node timer.
 Can be gotten via `minetest.get_node_timer(pos)`.
@@ -4244,157 +4815,6 @@ This is basically a reference to a C++ `ServerActiveObject`
     * in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
 * `get_eye_offset()`: returns `offset_first` and `offset_third`
 
-### `InvRef`
-An `InvRef` is a reference to an inventory.
-
-#### Methods
-* `is_empty(listname)`: return `true` if list is empty
-* `get_size(listname)`: get size of a list
-* `set_size(listname, size)`: set size of a list
-    * returns `false` on error (e.g. invalid `listname` or `size`)
-* `get_width(listname)`: get width of a list
-* `set_width(listname, width)`: set width of list; currently used for crafting
-* `get_stack(listname, i)`: get a copy of stack index `i` in list
-* `set_stack(listname, i, stack)`: copy `stack` to index `i` in list
-* `get_list(listname)`: return full list
-* `set_list(listname, list)`: set full list (size will not change)
-* `get_lists()`: returns list of inventory lists
-* `set_lists(lists)`: sets inventory lists (size will not change)
-* `add_item(listname, stack)`: add item somewhere in list, returns leftover
-  `ItemStack`.
-* `room_for_item(listname, stack):` returns `true` if the stack of items
-  can be fully added to the list
-* `contains_item(listname, stack, [match_meta])`: returns `true` if
-  the stack of items can be fully taken from the list.
-  If `match_meta` is false, only the items' names are compared
-  (default: `false`).
-* `remove_item(listname, stack)`: take as many items as specified from the
-  list, returns the items that were actually removed (as an `ItemStack`)
-  -- note that any item metadata is ignored, so attempting to remove a specific
-  unique item this way will likely remove the wrong one -- to do that use
-  `set_stack` with an empty `ItemStack`.
-* `get_location()`: returns a location compatible to
-  `minetest.get_inventory(location)`.
-    * returns `{type="undefined"}` in case location is not known
-
-### `AreaStore`
-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
-`AreaStore(type_name)`.
-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.
-* `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.
-* `reserve(count)`: reserves resources for at most `count` many contained
-  areas.
-  Only needed for efficiency, and only some implementations profit.
-* `remove_area(id)`: removes the area with the given id from the store, returns
-  success.
-* `set_cache_params(params)`: sets params for the included prefiltering cache.
-  Calling invalidates the cache, so that its elements have to be newly
-  generated.
-    * `params`:
-      {
-        enabled = boolean,     -- whether to enable, default true
-        block_radius = number, -- the radius (in nodes) of the areas the cache
-                                  generates prefiltered lists for, minimum 16,
-                                  default 64.
-        limit = number,        -- the cache's size, minimum 20, default 1000
-      }
-* `to_string()`: Experimental. Returns area store serialized as a (binary)
-  string.
-* `to_file(filename)`: Experimental. Like `to_string()`, but writes the data to
-  a file.
-* `from_string(str)`: Experimental. Deserializes string and loads it into the
-  AreaStore.
-  Returns success and, optionally, an error message.
-* `from_file(filename)`: Experimental. Like `from_string()`, but reads the data
-  from a file.
-
-### `ItemStack`
-An `ItemStack` is a stack of items.
-
-It can be created via `ItemStack(x)`, where x is an `ItemStack`,
-an itemstring, a table or `nil`.
-
-#### Methods
-* `is_empty()`: returns `true` if stack is empty.
-* `get_name()`: returns item name (e.g. `"default:stone"`).
-* `set_name(item_name)`: returns a boolean indicating whether the item was
-  cleared.
-* `get_count()`: Returns number of items on the stack.
-* `set_count(count)`: returns a boolean indicating whether the item was cleared
-    * `count`: number, unsigned 16 bit integer
-* `get_wear()`: returns tool wear (`0`-`65535`), `0` for non-tools.
-* `set_wear(wear)`: returns boolean indicating whether item was cleared
-    * `wear`: number, unsigned 16 bit integer
-* `get_meta()`: returns ItemStackMetaRef. See section for more details
-* `get_metadata()`: (DEPRECATED) Returns metadata (a string attached to an item
-  stack).
-* `set_metadata(metadata)`: (DEPRECATED) Returns true.
-* `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.
-* `to_string()`: returns the stack in itemstring form.
-* `to_table()`: returns the stack in Lua table form.
-* `get_stack_max()`: returns the maximum size of the stack (depends on the
-  item).
-* `get_free_space()`: returns `get_stack_max() - get_count()`.
-* `is_known()`: returns `true` if the item name refers to a defined item type.
-* `get_definition()`: returns the item definition table.
-* `get_tool_capabilities()`: returns the digging properties of the item,
-  or those of the hand if none are defined for this item type
-* `add_wear(amount)`
-    * Increases wear by `amount` if the item is a tool
-    * `amount`: number, integer
-* `add_item(item)`: returns leftover `ItemStack`
-    * Put some item or stack onto this stack
-* `item_fits(item)`: returns `true` if item or stack can be fully added to
-  this one.
-* `take_item(n)`: returns taken `ItemStack`
-    * Take (and remove) up to `n` items from this stack
-    * `n`: number, default: `1`
-* `peek_item(n)`: returns taken `ItemStack`
-    * Copy (don't remove) up to `n` items from this stack
-    * `n`: number, default: `1`
-
-### `PseudoRandom`
-A 16-bit pseudorandom number generator.
-Uses a well-known LCG algorithm introduced by K&R.
-
-It can be created via `PseudoRandom(seed)`.
-
-#### Methods
-* `next()`: return next integer random number [`0`...`32767`]
-* `next(min, max)`: return next integer random number [`min`...`max`]
-    * `((max - min) == 32767) or ((max-min) <= 6553))` must be true
-      due to the simple implementation making bad distribution otherwise.
-
 ### `PcgRandom`
 A 32-bit pseudorandom number generator.
 Uses PCG32, an algorithm of the permuted congruential generator family,
@@ -4404,23 +4824,13 @@ It can be created via `PcgRandom(seed)` or `PcgRandom(seed, sequence)`.
 
 #### Methods
 * `next()`: return next integer random number [`-2147483648`...`2147483647`]
-* `next(min, max)`: return next integer random number [`min`...`max`]
-* `rand_normal_dist(min, max, num_trials=6)`: return normally distributed
-  random number [`min`...`max`].
-    * This is only a rough approximation of a normal distribution with:
-    * `mean = (max - min) / 2`, and
-    * `variance = (((max - min + 1) ^ 2) - 1) / (12 * num_trials)`
-    * Increasing `num_trials` improves accuracy of the approximation
-
-### `SecureRandom`
-Interface for the operating system's crypto-secure PRNG.
-
-It can be created via `SecureRandom()`.  The constructor returns nil if a
-secure random device cannot be found on the system.
-
-#### Methods
-* `next_bytes([count])`: return next `count` (default 1, capped at 2048) many
-  random bytes, as a string.
+* `next(min, max)`: return next integer random number [`min`...`max`]
+* `rand_normal_dist(min, max, num_trials=6)`: return normally distributed
+  random number [`min`...`max`].
+    * This is only a rough approximation of a normal distribution with:
+    * `mean = (max - min) / 2`, and
+    * `variance = (((max - min + 1) ^ 2) - 1) / (12 * num_trials)`
+    * Increasing `num_trials` improves accuracy of the approximation
 
 ### `PerlinNoise`
 A perlin noise generator.
@@ -4471,317 +4881,28 @@ table.
   To grab a single vertical column of noise starting at map coordinates
   x = 1023, y=1000, z = 1000:
   `noise:calc_3d_map({x=1000, y=1000, z=1000})`
-  `noisevals = noise:get_map_slice({x=24, z=1}, {x=1, z=1})`
-
-### `VoxelManip`
-
-#### About VoxelManip
-VoxelManip is a scripting interface to the internal 'Map Voxel Manipulator'
-facility. The purpose of this object is for fast, low-level, bulk access to
-reading and writing Map content. As such, setting map nodes through VoxelManip
-will lack many of the higher level features and concepts you may be used to
-with other methods of setting nodes. For example, nodes will not have their
-construction and destruction callbacks run, and no rollback information is
-logged.
-
-It is important to note that VoxelManip is designed for speed, and *not* ease
-of use or flexibility. If your mod requires a map manipulation facility that
-will handle 100% of all edge cases, or the use of high level node placement
-features, perhaps `minetest.set_node()` is better suited for the job.
-
-In addition, VoxelManip might not be faster, or could even be slower, for your
-specific use case. VoxelManip is most effective when setting large areas of map
-at once - for example, if only setting a 3x3x3 node area, a
-`minetest.set_node()` loop may be more optimal. Always profile code using both
-methods of map manipulation to determine which is most appropriate for your
-usage.
-
-A recent simple test of setting cubic areas showed that `minetest.set_node()`
-is faster than a VoxelManip for a 3x3x3 node cube or smaller.
-
-#### Using VoxelManip
-A VoxelManip object can be created any time using either:
-`VoxelManip([p1, p2])`, or `minetest.get_voxel_manip([p1, p2])`.
-
-If the optional position parameters are present for either of these routines,
-the specified region will be pre-loaded into the VoxelManip object on creation.
-Otherwise, the area of map you wish to manipulate must first be loaded into the
-VoxelManip object using `VoxelManip:read_from_map()`.
-
-Note that `VoxelManip:read_from_map()` returns two position vectors. The region
-formed by these positions indicate the minimum and maximum (respectively)
-positions of the area actually loaded in the VoxelManip, which may be larger
-than the area requested. For convenience, the loaded area coordinates can also
-be queried any time after loading map data with `VoxelManip:get_emerged_area()`.
-
-Now that the VoxelManip object is populated with map data, your mod can fetch a
-copy of this data using either of two methods. `VoxelManip:get_node_at()`,
-which retrieves an individual node in a MapNode formatted table at the position
-requested is the simplest method to use, but also the slowest.
-
-Nodes in a VoxelManip object may also be read in bulk to a flat array table
-using:
-
-* `VoxelManip:get_data()` for node content (in Content ID form, see section
-  'Content IDs'),
-* `VoxelManip:get_light_data()` for node light levels, and
-* `VoxelManip:get_param2_data()` for the node type-dependent "param2" values.
-
-See section 'Flat array format' for more details.
-
-It is very important to understand that the tables returned by any of the above
-three functions represent a snapshot of the VoxelManip's internal state at the
-time of the call. This copy of the data will not magically update itself if
-another function modifies the internal VoxelManip state.
-Any functions that modify a VoxelManip's contents work on the VoxelManip's
-internal state unless otherwise explicitly stated.
-
-Once the bulk data has been edited to your liking, the internal VoxelManip
-state can be set using:
-
-* `VoxelManip:set_data()` for node content (in Content ID form, see section
-  'Content IDs'),
-* `VoxelManip:set_light_data()` for node light levels, and
-* `VoxelManip:set_param2_data()` for the node type-dependent `param2` values.
-
-The parameter to each of the above three functions can use any table at all in
-the same flat array format as produced by `get_data()` etc. and is not required
-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()`
-
-
-##### Flat array format
-Let
-    `Nx = p2.X - p1.X + 1`,
-    `Ny = p2.Y - p1.Y + 1`, and
-    `Nz = p2.Z - p1.Z + 1`.
-
-Then, for a loaded region of p1..p2, this array ranges from `1` up to and
-including the value of the expression `Nx * Ny * Nz`.
-
-Positions offset from p1 are present in the array with the format of:
-
-```
-[
-    (0, 0, 0),   (1, 0, 0),   (2, 0, 0),   ... (Nx, 0, 0),
-    (0, 1, 0),   (1, 1, 0),   (2, 1, 0),   ... (Nx, 1, 0),
-    ...
-    (0, Ny, 0),  (1, Ny, 0),  (2, Ny, 0),  ... (Nx, Ny, 0),
-    (0, 0, 1),   (1, 0, 1),   (2, 0, 1),   ... (Nx, 0, 1),
-    ...
-    (0, Ny, 2),  (1, Ny, 2),  (2, Ny, 2),  ... (Nx, Ny, 2),
-    ...
-    (0, Ny, Nz), (1, Ny, Nz), (2, Ny, Nz), ... (Nx, Ny, Nz)
-]
-```
-
-and the array index for a position p contained completely in p1..p2 is:
-
-`(p.Z - p1.Z) * Ny * Nx + (p.Y - p1.Y) * Nx + (p.X - p1.X) + 1`
-
-Note that this is the same "flat 3D array" format as
-`PerlinNoiseMap:get3dMap_flat()`.
-VoxelArea objects (see section 'VoxelArea') can be used to simplify calculation
-of the index for a single point in a flat VoxelManip array.
-
-##### Content IDs
-A Content ID is a unique integer identifier for a specific node type.
-These IDs are used by VoxelManip in place of the node name string for
-`VoxelManip:get_data()` and `VoxelManip:set_data()`. You can use
-`minetest.get_content_id()` to look up the Content ID for the specified node
-name, and `minetest.get_name_from_content_id()` to look up the node name string
-for a given Content ID.
-After registration of a node, its Content ID will remain the same throughout
-execution of the mod.
-Note that the node being queried needs to have already been been registered.
-
-The following builtin node types have their Content IDs defined as constants:
-
-* `minetest.CONTENT_UNKNOWN`: ID for "unknown" nodes
-* `minetest.CONTENT_AIR`:     ID for "air" nodes
-* `minetest.CONTENT_IGNORE`:  ID for "ignore" nodes
-
-##### Mapgen VoxelManip objects
-Inside of `on_generated()` callbacks, it is possible to retrieve the same
-VoxelManip object used by the core's Map Generator (commonly abbreviated
-Mapgen). Most of the rules previously described still apply but with a few
-differences:
-
-* The Mapgen VoxelManip object is retrieved using:
-  `minetest.get_mapgen_object("voxelmanip")`
-* This VoxelManip object already has the region of map just generated loaded
-  into it; it's not necessary to call `VoxelManip:read_from_map()` before using
-  a Mapgen VoxelManip.
-* The `on_generated()` callbacks of some mods may place individual nodes in the
-  generated area using non-VoxelManip map modification methods. Because the
-  same Mapgen VoxelManip object is passed through each `on_generated()`
-  callback, it becomes necessary for the Mapgen VoxelManip object to maintain
-  consistency with the current map state. For this reason, calling any of the
-  following functions:
-  `minetest.add_node()`, `minetest.set_node()`, or `minetest.swap_node()`
-  will also update the Mapgen VoxelManip object's internal state active on the
-  current thread.
-* After modifying the Mapgen VoxelManip object's internal buffer, it may be
-  necessary to update lighting information using either:
-  `VoxelManip:calc_lighting()` or `VoxelManip:set_lighting()`.
-
-##### Other API functions operating on a VoxelManip
-If any VoxelManip contents were set to a liquid node,
-`VoxelManip:update_liquids()` must be called for these liquid nodes to begin
-flowing. It is recommended to call this function only after having written all
-buffered data back to the VoxelManip object, save for special situations where
-the modder desires to only have certain liquid nodes begin flowing.
-
-The functions `minetest.generate_ores()` and `minetest.generate_decorations()`
-will generate all registered decorations and ores throughout the full area
-inside of the specified VoxelManip object.
-
-`minetest.place_schematic_on_vmanip()` is otherwise identical to
-`minetest.place_schematic()`, except instead of placing the specified schematic
-directly on the map at the specified position, it will place the schematic
-inside the VoxelManip.
-
-##### Notes
-* Attempting to read data from a VoxelManip object before map is read will
-  result in a zero-length array table for `VoxelManip:get_data()`, and an
-  "ignore" node at any position for `VoxelManip:get_node_at()`.
-* If either a region of map has not yet been generated or is out-of-bounds of
-  the map, that region is filled with "ignore" nodes.
-* Other mods, or the core itself, could possibly modify the area of map
-  currently loaded into a VoxelManip object. With the exception of Mapgen
-  VoxelManips (see above section), the internal buffers are not updated. For
-  this reason, it is strongly encouraged to complete the usage of a particular
-  VoxelManip object in the same callback it had been created.
-* If a VoxelManip object will be used often, such as in an `on_generated()`
-  callback, consider passing a file-scoped table as the optional parameter to
-  `VoxelManip:get_data()`, which serves as a static buffer the function can use
-  to write map data to instead of returning a new table each call. This greatly
-  enhances performance by avoiding unnecessary memory allocations.
-
-#### Methods
-* `read_from_map(p1, p2)`:  Loads a chunk of map into the VoxelManip object
-  containing the region formed by `p1` and `p2`.
-    * returns actual emerged `pmin`, actual emerged `pmax`
-* `write_to_map([light])`: Writes the data loaded from the `VoxelManip` back to
-  the map.
-    * **important**: data must be set using `VoxelManip:set_data()` before
-      calling this.
-    * if `light` is true, then lighting is automatically recalculated.
-      The default value is true.
-      If `light` is false, no light calculations happen, and you should correct
-      all modified blocks with `minetest.fix_light()` as soon as possible.
-      Keep in mind that modifying the map where light is incorrect can cause
-      more lighting bugs.
-* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded in
-  the `VoxelManip` at that position
-* `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at
-  that position.
-* `get_data([buffer])`: Retrieves the node content data loaded into the
-  `VoxelManip` object.
-    * returns raw node data in the form of an array of node content IDs
-    * if the param `buffer` is present, this table will be used to store the
-      result instead.
-* `set_data(data)`: Sets the data contents of the `VoxelManip` object
-* `update_map()`: Does nothing, kept for compatibility.
-* `set_lighting(light, [p1, p2])`: Set the lighting within the `VoxelManip` to
-  a uniform value.
-    * `light` is a table, `{day=<0...15>, night=<0...15>}`
-    * 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.
-* `get_light_data()`: Gets the light data read into the `VoxelManip` object
-    * Returns an array (indices 1 to volume) of integers ranging from `0` to
-      `255`.
-    * Each value is the bitwise combination of day and night light values
-      (`0` to `15` each).
-    * `light = day + (night * 16)`
-* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node
-  in the `VoxelManip`.
-    * expects lighting data in the same format that `get_light_data()` returns
-* `get_param2_data([buffer])`: Gets the raw `param2` data read into the
-  `VoxelManip` object.
-    * Returns an array (indices 1 to volume) of integers ranging from `0` to
-      `255`.
-    * If the param `buffer` is present, this table will be used to store the
-      result instead.
-* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in
-  the `VoxelManip`.
-* `calc_lighting([p1, p2], [propagate_shadow])`:  Calculate lighting within the
-  `VoxelManip`.
-    * 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.
-    * `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.
-* `update_liquids()`: Update liquid flow
-* `was_modified()`: Returns `true` or `false` if the data in the voxel
-  manipulator had been modified since the last read from map, due to a call to
-  `minetest.set_data()` on the loaded area elsewhere.
-* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
-
-### `VoxelArea`
-A helper class for voxel areas.
-It can be created via `VoxelArea:new{MinEdge=pmin, MaxEdge=pmax}`.
-The coordinates are *inclusive*, like most other things in Minetest.
+  `noisevals = noise:get_map_slice({x=24, z=1}, {x=1, z=1})`
+
+### `PlayerMetaRef`
+Player metadata.
+Uses the same method of storage as the deprecated player attribute API, so
+data there will also be in player meta.
+Can be obtained using `player:get_meta()`.
 
 #### Methods
-* `getExtent()`: returns a 3D vector containing the size of the area formed by
-  `MinEdge` and `MaxEdge`.
-* `getVolume()`: returns the volume of the area formed by `MinEdge` and
-  `MaxEdge`.
-* `index(x, y, z)`: returns the index of an absolute position in a flat array
-  starting at `1`.
-    * `x`, `y` and `z` must be integers to avoid an incorrect index result.
-    * The position (x, y, z) is not checked for being inside the area volume,
-      being outside can cause an incorrect index result.
-    * Useful for things like `VoxelManip`, raw Schematic specifiers,
-      `PerlinNoiseMap:get2d`/`3dMap`, and so on.
-* `indexp(p)`: same functionality as `index(x, y, z)` but takes a vector.
-    * As with `index(x, y, z)`, the components of `p` must be integers, and `p`
-      is not checked for being inside the area volume.
-* `position(i)`: returns the absolute position vector corresponding to index
-  `i`.
-* `contains(x, y, z)`: check if (`x`,`y`,`z`) is inside area formed by
-  `MinEdge` and `MaxEdge`.
-* `containsp(p)`: same as above, except takes a vector
-* `containsi(i)`: same as above, except takes an index `i`
-* `iter(minx, miny, minz, maxx, maxy, maxz)`: returns an iterator that returns
-  indices.
-    * from (`minx`,`miny`,`minz`) to (`maxx`,`maxy`,`maxz`) in the order of
-      `[z [y [x]]]`.
-* `iterp(minp, maxp)`: same as above, except takes a vector
+* All methods in MetaDataRef
 
-### `Settings`
-An interface to read config files in the format of `minetest.conf`.
+### `PseudoRandom`
+A 16-bit pseudorandom number generator.
+Uses a well-known LCG algorithm introduced by K&R.
 
-It can be created via `Settings(filename)`.
+It can be created via `PseudoRandom(seed)`.
 
 #### Methods
-* `get(key)`: returns a value
-* `get_bool(key, [default])`: returns a boolean
-    * `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
-* `set(key, value)`
-    * Setting names can't contain whitespace or any of `="{}#`.
-    * Setting values can't contain the sequence `\n"""`.
-    * Setting names starting with "secure." can't be set on the main settings
-      object (`minetest.settings`).
-* `set_bool(key, value)`
-    * See documentation for set() above.
-* `set_np_group(key, value)`
-    * `value` is a NoiseParams table.
-    * Also, see documentation for set() above.
-* `remove(key)`: returns a boolean (`true` for success)
-* `get_names()`: returns `{key1,...}`
-* `write()`: returns a boolean (`true` for success)
-    * Writes changes to file.
-* `to_table()`: returns `{[key1]=value1,...}`
+* `next()`: return next integer random number [`0`...`32767`]
+* `next(min, max)`: return next integer random number [`min`...`max`]
+    * `((max - min) == 32767) or ((max-min) <= 6553))` must be true
+      due to the simple implementation making bad distribution otherwise.
 
 ### `Raycast`
 A raycast on the map. It works with selection boxes.
@@ -4803,170 +4924,50 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
 * `next()`: returns a `pointed_thing`
     * Returns the next thing pointed by the ray or nil.
 
-Mapgen objects
---------------
-A mapgen object is a construct used in map generation. Mapgen objects can be
-used by an `on_generate` callback to speed up operations by avoiding
-unnecessary recalculations, these can be retrieved using the
-`minetest.get_mapgen_object()` function. If the requested Mapgen object is
-unavailable, or `get_mapgen_object()` was called outside of an `on_generate()`
-callback, `nil` is returned.
-
-The following Mapgen objects are currently available:
-
-### `voxelmanip`
-This returns three values; the `VoxelManip` object to be used, minimum and
-maximum emerged position, in that order. All mapgens support this object.
-
-### `heightmap`
-Returns an array containing the y coordinates of the ground levels of nodes in
-the most recently generated chunk by the current mapgen.
-
-### `biomemap`
-Returns an array containing the biome IDs of nodes in the most recently
-generated chunk by the current mapgen.
-
-### `heatmap`
-Returns an array containing the temperature values of nodes in the most
-recently generated chunk by the current mapgen.
-
-### `humiditymap`
-Returns an array containing the humidity values of nodes in the most recently
-generated chunk by the current mapgen.
-
-### `gennotify`
-Returns a table mapping requested generation notification types to arrays of
-positions at which the corresponding generated structures are located within
-the current chunk. To set the capture of positions of interest to be recorded
-on generate, use `minetest.set_gen_notify()`.
-For decorations, the returned positions are the ground surface 'place_on'
-nodes, not the decorations themselves. A 'simple' type decoration is often 1
-node above the returned position and possibly displaced by 'place_offset_y'.
-
-Possible fields of the table returned are:
-
-* `dungeon`
-* `temple`
-* `cave_begin`
-* `cave_end`
-* `large_cave_begin`
-* `large_cave_end`
-* `decoration`
-
-Decorations have a key in the format of `"decoration#id"`, where `id` is the
-numeric unique decoration ID.
+### `SecureRandom`
+Interface for the operating system's crypto-secure PRNG.
 
-Registered entities
--------------------
-* Functions receive a "luaentity" as `self`:
-    * It has the member `.name`, which is the registered name `("mod:thing")`
-    * It has the member `.object`, which is an `ObjectRef` pointing to the
-      object.
-    * The original prototype stuff is visible directly via a metatable
-* Callbacks:
-    * `on_activate(self, staticdata, dtime_s)`
-        * Called when the object is instantiated.
-        * `dtime_s` is the time passed since the object was unloaded, which can
-          be used for updating the entity state.
-    * `on_step(self, dtime)`
-        * 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)`
-        * Called when somebody punches the object.
-        * Note that you probably want to handle most punches using the
-          automatic armor group system.
-        * `puncher`: an `ObjectRef` (can be `nil`)
-        * `time_from_last_punch`: Meant for disallowing spamming of clicks
-          (can be `nil`).
-        * `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.
-    * `on_death(self, killer)`
-        * Called when the object dies.
-        * `killer`: an `ObjectRef` (can be `nil`)
-    * `on_rightclick(self, clicker)`
-    * `on_attach_child(self, child)`
-        * `child`: an `ObjectRef` of the child that attaches
-    * `on_detach_child(self, child)`
-        * `child`: an `ObjectRef` of the child that detaches
-    * `on_detach(self, parent)`
-        * `parent`: an `ObjectRef` (can be `nil`) from where it got detached
-        * This happens before the parent object is removed from the world
-    * `get_staticdata(self)`
-        * Should return a string that will be passed to `on_activate` when
-          the object is instantiated the next time.
+It can be created via `SecureRandom()`.  The constructor returns nil if a
+secure random device cannot be found on the system.
 
-L-system trees
---------------
+#### Methods
+* `next_bytes([count])`: return next `count` (default 1, capped at 2048) many
+  random bytes, as a string.
 
-### Tree definition
+### `Settings`
+An interface to read config files in the format of `minetest.conf`.
 
-    treedef={
-        axiom,         --string  initial tree axiom
-        rules_a,       --string  rules set A
-        rules_b,       --string  rules set B
-        rules_c,       --string  rules set C
-        rules_d,       --string  rules set D
-        trunk,         --string  trunk node name
-        leaves,        --string  leaves node name
-        leaves2,       --string  secondary leaves node name
-        leaves2_chance,--num     chance (0-100) to replace leaves with leaves2
-        angle,         --num     angle in deg
-        iterations,    --num     max # of iterations, usually 2 -5
-        random_level,  --num     factor to lower nr of iterations, usually 0 - 3
-        trunk_type,    --string  single/double/crossed) type of trunk: 1 node,
-                       --        2x2 nodes or 3x3 in cross shape
-        thin_branches, --boolean true -> use thin (1 node) branches
-        fruit,         --string  fruit node name
-        fruit_chance,  --num     chance (0-100) to replace leaves with fruit node
-        seed,          --num     random seed, if no seed is provided, the engine
-                                 will create one.
-    }
+It can be created via `Settings(filename)`.
 
-### Key for Special L-System Symbols used in Axioms
+#### Methods
+* `get(key)`: returns a value
+* `get_bool(key, [default])`: returns a boolean
+    * `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
+* `set(key, value)`
+    * Setting names can't contain whitespace or any of `="{}#`.
+    * Setting values can't contain the sequence `\n"""`.
+    * Setting names starting with "secure." can't be set on the main settings
+      object (`minetest.settings`).
+* `set_bool(key, value)`
+    * See documentation for set() above.
+* `set_np_group(key, value)`
+    * `value` is a NoiseParams table.
+    * Also, see documentation for set() above.
+* `remove(key)`: returns a boolean (`true` for success)
+* `get_names()`: returns `{key1,...}`
+* `write()`: returns a boolean (`true` for success)
+    * Writes changes to file.
+* `to_table()`: returns `{[key1]=value1,...}`
 
-* `G`: move forward one unit with the pen up
-* `F`: move forward one unit with the pen down drawing trunks and branches
-* `f`: move forward one unit with the pen down drawing leaves (100% chance)
-* `T`: move forward one unit with the pen down drawing trunks only
-* `R`: move forward one unit with the pen down placing fruit
-* `A`: replace with rules set A
-* `B`: replace with rules set B
-* `C`: replace with rules set C
-* `D`: replace with rules set D
-* `a`: replace with rules set A, chance 90%
-* `b`: replace with rules set B, chance 80%
-* `c`: replace with rules set C, chance 70%
-* `d`: replace with rules set D, chance 60%
-* `+`: yaw the turtle right by `angle` parameter
-* `-`: yaw the turtle left by `angle` parameter
-* `&`: pitch the turtle down by `angle` parameter
-* `^`: pitch the turtle up by `angle` parameter
-* `/`: roll the turtle to the right by `angle` parameter
-* `*`: roll the turtle to the left by `angle` parameter
-* `[`: save in stack current state info
-* `]`: recover from stack state info
+### `StorageRef`
+Mod metadata: per mod metadata, saved automatically.
+Can be obtained via `minetest.get_mod_storage()` during load time.
 
-### Example
-Spawn a small apple tree:
+#### Methods
+* All methods in MetaDataRef
 
-    pos = {x=230,y=20,z=4}
-    apple_tree={
-        axiom="FFFFFAFFBF",
-        rules_a="[&&&FFFFF&&FFFF][&&&++++FFFFF&&FFFF][&&&----FFFFF&&FFFF]",
-        rules_b="[&&&++FFFFF&&FFFF][&&&--FFFFF&&FFFF][&&&------FFFFF&&FFFF]",
-        trunk="default:tree",
-        leaves="default:leaves",
-        angle=30,
-        iterations=2,
-        random_level=0,
-        trunk_type="single",
-        thin_branches=true,
-        fruit_chance=10,
-        fruit="default:apple"
-    }
-    minetest.spawn_tree(pos,apple_tree)
 
 Definition tables
 -----------------