X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=doc%2Flua_api.txt;h=56dc84d24aea13f73bdca4ba2d6866f907da3982;hb=9a5a538e8d1981fb3c2dd69ca3d37e4f9c426cf5;hp=f771a360d0d0eecb94063edb3669e62d79450ce6;hpb=be9024a397506dff1151b16e5f7a91e393b00d7e;p=minetest.git diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f771a360d..56dc84d24 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1,4 +1,4 @@ -Minetest Lua Modding API Reference 0.4.12 +Minetest Lua Modding API Reference 0.4.13 ========================================= * More information at * Developer Wiki: @@ -64,6 +64,8 @@ e.g. The game directory can contain the file minetest.conf, which will be used to set default settings when running the particular game. +It can also contain a settingtypes.txt in the same format as the one in builtin. +This settingtypes.txt will be parsed by the menu and the settings will be displayed in the "Games" category in the settings tab. ### Menu images @@ -125,6 +127,7 @@ Mod directory structure | |-- depends.txt | |-- screenshot.png | |-- description.txt + | |-- settingtypes.txt | |-- init.lua | |-- models | |-- textures @@ -155,6 +158,10 @@ A screenshot shown in modmanager within mainmenu. ### `description.txt` A File containing description to be shown within mainmenu. +### `settingtypes.txt` +A file in the same format as the one in builtin. It will be parsed by the +settings menu and the settings will be displayed in the "Mods" category. + ### `init.lua` The main Lua script. Running this script should register everything it wants to register. Subsequent execution depends on minetest calling the @@ -393,13 +400,13 @@ Examples of sound parameter tables: { pos = {x=1,y=2,z=3}, gain = 1.0, -- default - max_hear_distance = 32, -- default + max_hear_distance = 32, -- default, uses an euclidean metric } -- Play connected to an object, looped { object = , gain = 1.0, -- default - max_hear_distance = 32, -- default + max_hear_distance = 32, -- default, uses an euclidean metric loop = true, -- only sounds connected to objects can be looped } @@ -538,6 +545,10 @@ node definition: 0 = y+ 1 = z+ 2 = z- 3 = x+ 4 = x- 5 = y- facedir's two less significant bits are rotation around the axis paramtype2 == "leveled" + paramtype2 == "degrotate" + ^ The rotation of this node is stored in param2. Plants are rotated this way. + Values range 0 - 179. The value stored in param2 is multiplied by two to + get the actual rotation of the node. collision_box = { type = "fixed", fixed = { @@ -714,29 +725,45 @@ a non-equal distribution of ore. ### `sheet` Creates a sheet of ore in a blob shape according to the 2D perlin noise -described by `noise_params`. The relative height of the sheet can be -controlled by the same perlin noise as well, by specifying a non-zero -`scale` parameter in `noise_params`. +described by `noise_params` and `noise_threshold`. This is essentially an +improved version of the so-called "stratus" ore seen in some unofficial mods. + +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`. + +The `column_midpoint_factor` parameter controls the position of the column at which +ore eminates 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. -**IMPORTANT**: The noise is not transformed by `offset` or `scale` when comparing -against the noise threshold, but scale is used to determine relative height. -The height of the blob is randomly scattered, with a maximum height of `clust_size`. +The ore parameters `clust_scarcity` and `clust_num_ores` are ignored for this ore type. -`clust_scarcity` and `clust_num_ores` are ignored. +### `puff` +Creates a sheet of ore in a cloud-like puff shape. + +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. + +The vertical top and bottom displacement of each puff are determined by the noise +parameters `np_puff_top` and `np_puff_bottom`, respectively. -This is essentially an improved version of the so-called "stratus" ore seen in -some unofficial mods. ### `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. -### `vein + +### `vein` Creates veins of ore varying in density by according to the intersection of two instances of 3d perlin noise with diffferent 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_threshhold`. +modifying this parameter may require adjusting `noise_threshold`. The parameters `clust_scarcity`, `clust_num_ores`, and `clust_size` are ignored by this ore type. 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: @@ -750,7 +777,7 @@ to small changes. The following is a decent set of parameters to work from: persist = 0.5, flags = "eased", }, - noise_threshhold = 1.6 + noise_threshold = 1.6 WARNING: Use this ore type *very* sparingly since it is ~200x more computationally expensive than any other ore. @@ -766,19 +793,28 @@ Also produce this same ore between the height range of `-y_max` and `-y_min`. Useful for having ore in sky realms without having to duplicate ore entries. +### `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. -The default value is `simple`, and is currently the only type supported. - ### `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, and so on. +papyri, waterlilies and so on. ### `schematic` Copies a box of `MapNodes` from a specified schematic file (or raw description). @@ -817,8 +853,8 @@ Schematic attributes -------------------- See section "Flag Specifier Format". -Currently supported flags: `place_center_x`, `place_center_y`, - `place_center_z`, `force_placement`. +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. @@ -1269,10 +1305,12 @@ mentioned in "Nodes". However, it is possible to insert extra data into a node. It is called "node metadata"; See "`NodeMetaRef`". Metadata contains two things: + * A key-value store * An inventory Some of the values in the key-value store are handled specially: + * `formspec`: Defines a right-click inventory menu. See "Formspec". * `infotext`: Text shown on the screen when the node is pointed at @@ -1637,7 +1675,7 @@ numerical form, the raw integer value of an ARGB8 quad: or string form, a ColorString (defined above): `colorspec = "green"` -Vector helpers +Spatial Vectors -------------- * `vector.new([x[, y, z]])`: returns a vector. @@ -1655,8 +1693,8 @@ For the following functions `x` can be either a vector or a number: * `vector.add(v, x)`: returns a vector * `vector.subtract(v, x)`: returns a vector -* `vector.multiply(v, x)`: returns a vector -* `vector.divide(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 Helper functions ----------------- @@ -1681,6 +1719,8 @@ Helper functions * Convert position to a printable string * `minetest.string_to_pos(string)`: returns a position * Same but in reverse. Returns `nil` if the string can't be parsed to a position. +* `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)` @@ -1741,11 +1781,11 @@ Helper functions * false: return only file names. ### Logging -* `minetest.debug(line)` - * Always printed to `stderr` and logfile (`print()` is redirected here) -* `minetest.log(line)` -* `minetest.log(loglevel, line)` - * `loglevel` is one of `"error"`, `"action"`, `"info"`, `"verbose"` +* `minetest.debug(...)` + * Equivalent to `minetest.log(table.concat({...}, "\t"))` +* `minetest.log([level,] text)` + * `level` is one of `"none"`, `"error"`, `"warning"`, `"action"`, + `"info"`, or `"verbose"`. Default is `"none"`. ### Registration functions Call these functions only at load time! @@ -1883,7 +1923,11 @@ Call these functions only at load time! * Should be called by the authentication handler if privileges changes. * To report everybody, set `name=nil`. * `minetest.get_password_hash(name, raw_password)` - * Convert a name-password pair to a password hash that Minetest can use + * Convert a name-password pair to a password hash that Minetest can use. + * The returned value alone is not a good basis for password checks based + * on comparing the password hash in the database with the password hash + * from the function, with an externally provided password, as the hash + * in the db might use the new SRP verifier format. * `minetest.string_to_privs(str)`: returns `{priv1=true,...}` * `minetest.privs_to_string(privs)`: returns `"priv1,priv2,..."` * Convert between two privilege representations @@ -1891,8 +1935,11 @@ Call these functions only at load time! * `minetest.set_player_privs(name, {priv1=true,...})` * `minetest.get_player_privs(name) -> {priv1=true,...}` * `minetest.auth_reload()` -* `minetest.check_player_privs(name, {priv1=true,...})`: returns `bool, missing_privs` - * A quickhand for checking privileges +* `minetest.check_player_privs(player_or_name, ...)`: returns `bool, missing_privs` + * A quickhand for checking privileges. + * `player_or_name`: Either a Player object or the name of a player. + * `...` is either a list of strings, e.g. `"priva", "privb"` or + a table, e.g. `{ priva = true, privb = true }`. * `minetest.get_player_ip(name)`: returns an IP address string `minetest.set_player_password`, `minetest_set_player_privs`, `minetest_get_player_privs` @@ -1914,9 +1961,13 @@ and `minetest.auth_reload` call the authetification handler. * Returns `{name="ignore", ...}` for unloaded area * `minetest.get_node_or_nil(pos)` * Returns `nil` for unloaded area -* `minetest.get_node_light(pos, timeofday)` returns a number between `0` and `15` or `nil` +* `minetest.get_node_light(pos, timeofday)` + * Gets the light value at the given position. Note that the light value + "inside" the node at the given position is returned, so you usually want + to get the light value of a neighbor. + * `pos`: The position where to measure the light. * `timeofday`: `nil` for current time, `0` for night, `0.5` for day - + * Returns a number between `0` and `15` or `nil` * `minetest.place_node(pos, node)` * Place node with the same effects that a player would cause * `minetest.dig_node(pos)` @@ -1938,11 +1989,13 @@ and `minetest.auth_reload` call the authetification handler. * Returns `ObjectRef`, or `nil` if failed * `minetest.get_player_by_name(name)`: Get an `ObjectRef` to a player * `minetest.get_objects_inside_radius(pos, radius)` + * `radius`: using an euclidean metric * `minetest.set_timeofday(val)` * `val` is between `0` and `1`; `0` for midnight, `0.5` for midday * `minetest.get_timeofday()` * `minetest.get_gametime()`: returns the time, in seconds, since the world was created * `minetest.find_node_near(pos, radius, nodenames)`: returns pos or `nil` + * `radius`: using a maximum metric * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` * `minetest.find_nodes_in_area(minp, maxp, nodenames)`: returns a list of positions * returns as second value a table with the count of the individual nodes found @@ -1964,6 +2017,9 @@ and `minetest.auth_reload` call the authetification handler. * `get_gen_notify()`: returns a flagstring and a table with the deco_ids * `minetest.get_mapgen_object(objectname)` * Return requested mapgen object if available (see "Mapgen objects") +* `minetest.get_biome_id(biome_name)` + * Returns the biome id, as used in the biomemap Mapgen object, for a + given biome_name string. * `minetest.get_mapgen_params()` Returns mapgen parameters, a table containing `mgname`, `seed`, `chunksize`, `water_level`, and `flags`. * `minetest.set_mapgen_params(MapgenParams)` @@ -1989,6 +2045,19 @@ and `minetest.auth_reload` call the authetification handler. * `pos1` and `pos2` are optional and default to mapchunk minp and maxp. * `minetest.clear_objects()` * clear all objects in the environments +* `minetest.emerge_area(pos1, pos2, [callback], [param])` + * Queue all blocks in the area from `pos1` to `pos2`, inclusive, to be asynchronously + * fetched from memory, loaded from disk, or if inexistent, generates them. + * If `callback` is a valid Lua function, this will be called for each block emerged. + * The function signature of callback is: + * `function EmergeAreaCallback(blockpos, action, calls_remaining, param)` + * - `blockpos` is the *block* coordinates of the block that had been emerged + * - `action` could be one of the following constant values: + * `core.EMERGE_CANCELLED`, `core.EMERGE_ERRORED`, `core.EMERGE_FROM_MEMORY`, + * `core.EMERGE_FROM_DISK`, `core.EMERGE_GENERATED` + * - `calls_remaining` is the number of callbacks to be expected after this one + * - `param` is the user-defined parameter passed to emerge_area (or nil if the + * parameter was absent) * `minetest.delete_area(pos1, pos2)` * delete all mapblocks in the area from pos1 to pos2, inclusive * `minetest.line_of_sight(pos1, pos2, stepsize)`: returns `boolean, pos` @@ -2003,7 +2072,7 @@ and `minetest.auth_reload` call the authetification handler. * returns a table of 3D points representing a path from `pos1` to `pos2` or `nil` * `pos1`: start position * `pos2`: end position - * `searchdistance`: number of blocks to search in each direction + * `searchdistance`: number of blocks to search in each direction using a maximum metric * `max_jump`: maximum height difference to consider walkable * `max_drop`: maximum height difference to consider droppable * `algorithm`: One of `"A*_noprefetch"` (default), `"A*"`, `"Dijkstra"` @@ -2231,6 +2300,15 @@ These functions return the leftover itemstack. * `replacements` = `{["old_name"] = "convert_to", ...}` * `force_placement` is a boolean indicating whether nodes other than `air` and `ignore` are replaced by the schematic + * Returns nil if the schematic could not be loaded. + +* `minetest.place_schematic_on_vmanip(vmanip, pos, schematic, rotation, replacement, force_placement)`: + * This function is analagous to minetest.place_schematic, but places a schematic onto the + specified VoxelManip object `vmanip` instead of the whole map. + * Returns false if any part of the schematic was cut-off due to the VoxelManip not + containing the full area required, and true if the whole schematic was able to fit. + * Returns nil if the schematic could not be loaded. + * After execution, any external copies of the VoxelManip contents are invalidated. * `minetest.serialize_schematic(schematic, format, options)` * Return the serialized schematic specified by schematic (see: Schematic specifier) @@ -2403,7 +2481,7 @@ Can be gotten via `minetest.get_meta(pos)`. * `from_table(nil or {})` * See "Node Metadata" -### `NoteTimerRef` +### `NodeTimerRef` Node Timers: a high resolution persistent per-node timer. Can be gotten via `minetest.get_node_timer(pos)`. @@ -2693,6 +2771,15 @@ It can be created via `PcgRandom(seed)` or `PcgRandom(seed, sequence)`. * This is only a rough approximation of a normal distribution with mean=(max-min)/2 and variance=1 * 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 +be found on the system. + +#### Methods +* `next_bytes([count])`: return next `count` (default 1, capped at 2048) many random bytes, as a string. + ### `PerlinNoise` A perlin noise generator. It can be created via `PerlinNoise(seed, octaves, persistence, scale)` @@ -2740,29 +2827,179 @@ nil, this table will be used to store the result instead of creating a new table `noisevals = noise:getMapSlice({x=24, z=1}, {x=1, z=1})` ### `VoxelManip` -An interface to the `MapVoxelManipulator` for Lua. -It can be created via `VoxelManip()` or `minetest.get_voxel_manip()`. -The map will be pre-loaded if two positions are passed to either. +#### 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 very large areas of map at once - for example, if only +setting a 5x5x5 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. + +#### 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() et al. 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()`. + +Finally, a call to `VoxelManip:update_map()` is required to re-calculate lighting and set the blocks +as being modified so that connected clients are sent the updated parts of 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: +``` +core.CONTENT_UNKNOWN (ID for "unknown" nodes) +core.CONTENT_AIR (ID for "air" nodes) +core.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()`. +* `VoxelManip:update_map()` does not need to be called after `write_to_map()`. The map update is performed + automatically after all on_generated callbacks have been run for that generated block. + +##### 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 of 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)`: Reads a chunk of map from the map containing the - region formed by `p1` and `p2`. +* `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()`: Writes the data loaded from the `VoxelManip` back to the map. - * **important**: data must be set using `VoxelManip:set_data` before calling this + * **important**: data must be set using `VoxelManip:set_data()` before calling this * `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)`: Gets the data read into the `VoxelManip` object +* `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()`: Update map after writing chunk back to map. * To be used only by `VoxelManip` objects created by the mod itself; not a `VoxelManip` that was retrieved from `minetest.get_mapgen_object` -* `set_lighting(light, p1, p2)`: Set the lighting within the `VoxelManip` to a uniform value +* `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; @@ -2776,10 +3013,12 @@ The map will be pre-loaded if two positions are passed to either. * expects lighting data in the same format that `get_light_data()` returns * `get_param2_data()`: Gets the raw `param2` data read into the `VoxelManip` object * `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip` -* `calc_lighting(p1, p2)`: Calculate lighting within 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 + 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 @@ -2992,6 +3231,7 @@ Definition tables stepheight = 0, automatic_face_movement_dir = 0.0, -- ^ automatically set yaw to movement direction; offset in degrees; false to disable + backface_culling = true, -- false to disable backface_culling for model } ### Entity definition (`register_entity`) @@ -3018,10 +3258,14 @@ Definition tables { -- In the following two fields, also group:groupname will work. nodenames = {"default:lava_source"}, - neighbors = {"default:water_source", "default:water_flowing"}, -- (any of these) - -- ^ If left out or empty, any neighbor will do - interval = 1.0, -- (operation interval) - chance = 1, -- (chance of trigger is 1.0/this) + neighbors = {"default:water_source", "default:water_flowing"}, -- Any of these --[[ + ^ If left out or empty, any neighbor will do ]] + interval = 1.0, -- Operation interval in seconds + chance = 1, -- Chance of trigger per-node per-interval is 1.0 / this + catch_up = true, -- If true, catch-up behaviour is enabled --[[ + ^ The chance value is temporarily reduced when returning to + an area to simulate time lost by the area being unattended. + ^ Note chance value can often be reduced to 1 ]] action = func(pos, node, active_object_count, active_object_count_wider), } @@ -3068,6 +3312,11 @@ Definition tables --[[ ^ Shall place item and return the leftover itemstack ^ default: minetest.item_place ]] + on_secondary_use = func(itemstack, user, pointed_thing), + --[[ + ^ Same as on_place but called when pointing at nothing. + ^ pointed_thing : always { type = "nothing" } + ]] on_drop = func(itemstack, dropper, pos), --[[ ^ Shall drop item and return the leftover itemstack @@ -3164,6 +3413,7 @@ Definition tables dig = , -- "__group" = group-based sound (default) dug = , place = , + place_failed = , }, drop = "", -- Name of dropped node when dug. Default is the node itself. -- Alternatively: @@ -3178,14 +3428,17 @@ Definition tables }, on_construct = func(pos), --[[ - ^ Node constructor; always called after adding node + ^ Node constructor; called after adding node ^ Can set up metadata and stuff like that + ^ Not called for bulk node placement (i.e. schematics and VoxelManip) ^ default: nil ]] on_destruct = func(pos), --[[ - ^ Node destructor; always called before removing node + ^ Node destructor; called before removing node + ^ Not called for bulk node placement (i.e. schematics and VoxelManip) ^ default: nil ]] after_destruct = func(pos, oldnode), --[[ - ^ Node destructor; always called after removing node + ^ Node destructor; called after removing node + ^ Not called for bulk node placement (i.e. schematics and VoxelManip) ^ default: nil ]] after_place_node = func(pos, placer, itemstack, pointed_thing) --[[ @@ -3324,7 +3577,7 @@ Definition tables y_max = 64, flags = "", -- ^ Attributes for this ore generation - noise_threshhold = 0.5, + noise_threshold = 0.5, -- ^ If noise is above this threshold, ore is placed. Not needed for a uniform distribution noise_params = {offset=0, scale=1, spread={x=100, y=100, z=100}, seed=23, octaves=3, persist=0.70} -- ^ NoiseParams structure describing the perlin noise used for ore distribution. @@ -3339,6 +3592,51 @@ Definition tables -- ^ Can be a list of (or a single) biome names, IDs, or definitions. } +### Biome definition (`register_biome`) + + { + name = "tundra", + node_dust = "default:snow", + -- ^ Node dropped onto upper surface after all else is generated. + node_top = "default:dirt_with_snow", + depth_top = 1, + -- ^ Node forming surface layer of biome and thickness of this layer. + node_filler = "default:permafrost", + depth_filler = 3, + -- ^ Node forming lower layer of biome and thickness of this layer. + node_stone = "default:bluestone", + -- ^ Node that replaces all stone nodes between roughly y_min and y_max. + node_water_top = "default:ice", + depth_water_top = 10, + -- ^ Node forming a surface layer in seawater with the defined thickness. + node_water = "", + -- ^ Node that replaces all seawater nodes not in the defined surface layer. + node_river_water = "default:ice", + -- ^ Node that replaces river water in mapgens that use default:river_water. + y_min = 1, + y_max = 31000, + -- ^ Lower and upper limits for biome. + -- ^ Because biome is not recalculated for every node in a node column + -- ^ some biome materials can exceed their limits, especially stone. + -- ^ For each node column in a mapchunk, biome is only recalculated at column + -- ^ top and at each of these surfaces: + -- ^ Ground below air, water below air, ground below water. + -- ^ The selected biome then stays in effect for all nodes below until + -- ^ column base or the next biome recalculation. + heat_point = 0, + humidity_point = 50, + -- ^ Characteristic average temperature and humidity for the biome. + -- ^ These values create 'biome points' on a voronoi diagram that has heat + -- ^ and humidity as axes. The resulting voronoi cells determine which + -- ^ heat/humidity points belong to which biome, and therefore determine + -- ^ the area and location of each biome in the world. + -- ^ The biome points need to be carefully and evenly spaced on the voronoi + -- ^ diagram to result in roughly equal size biomes. + -- ^ Heat and humidity have average values of 50, vary mostly between + -- ^ 0 and 100 but also often exceed these values. + -- ^ Heat is not in degrees celcius, both values are abstract. + } + ### Decoration definition (`register_decoration`) { @@ -3363,6 +3661,11 @@ Definition tables -- ^ Minimum and maximum `y` positions these decorations can be generated at. -- ^ This parameter refers to the `y` position of the decoration base, so -- the actual maximum height would be `height_max + size.Y`. + flags = "liquid_surface", + -- ^ Flags for all decoration types. + -- ^ "liquid_surface": Instead of placement on the highest solid surface + -- ^ in a mapchunk column, placement is on the highest liquid surface. + -- ^ Placement is disabled if solid nodes are found above the liquid surface. ----- Simple-type parameters decoration = "default:grass",