{-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
------------------------------
* `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`.
* `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)`.
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)`.
* 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,
#### 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.
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.
* `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
-----------------