From 94218fb5a98d97ca19039b755f78cd9b64154448 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sun, 9 Aug 2015 10:15:16 -0400 Subject: Initial commit: split plants_lib off from plantlife modpack renamed it to biome_lib adapt all functions and references accordingly. --- API.txt | 579 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 579 insertions(+) create mode 100644 API.txt (limited to 'API.txt') diff --git a/API.txt b/API.txt new file mode 100644 index 0000000..73e310f --- /dev/null +++ b/API.txt @@ -0,0 +1,579 @@ +This document describes the Plantlife mod API. + +Last revision: 2015-02-16 + + +========= +Functions +========= + +There are three main functions defined by the main "biome_lib" mod: + +spawn_on_surfaces() +register_generate_plant() +grow_plants() + +There are also several internal, helper functions that can be called if so +desired, but they are not really intended for use by other mods and may change +at any time. They are briefly described below these main functions, but see +init.lua for details. + +Most functions in plants lib are declared locally to avoid namespace +collisions with other mods. They are accessible via the "biome_lib" method, +e.g. biome_lib:spawn_on_surfaces() and so forth. + +===== +spawn_on_surfaces(biome) +spawn_on_surfaces(sdelay, splant, sradius, schance, ssurface, savoid) + +This first function is an ABM-based spawner function originally created as +part of Ironzorg's flowers mod. It has since been largely extended and +expanded. There are two ways to call this function: You can either pass it +several individual string and number parameters to use the legacy interface, +or you can pass a single biome definition as a table, with all of your options +spelled out nicely. This is the preferred method. + +When used with the legacy interface, you must specify the parameters exactly +in order, with the first five being mandatory (even if some are set to nil), +and the last one being optional: + +sdelay: The value passed to the ABM's interval parameter, in seconds. +splant: The node name of the item to spawn (e.g. + "flowers:flower_rose"). A plant will of course only be + spawned if the node about to be replaced is air. +sradius: Don't spawn within this many nodes of the avoid items + mentioned below. If set to nil, this check is skipped. +schance: The value passed to the ABM's chance parameter, normally in + the 10-100 range (1-in-X chance of operating on a given node) +ssurface: String with the name of the node on which to spawn the plant + in question, such as "default:sand" or + "default:dirt_with_grass". It is not recommended to put air, + stone, or plain dirt here if you can use some other node, as + doing so will cause the engine to process potentially large + numbers of such nodes when deciding when to execute the ABM + and where it should operate. +savoid: Table with a list of groups and/or node names to avoid when + spawning the plant, such as {"group:flowers", "default:tree"}. + +When passed a table as the argument, and thus using the modern calling method, +you must pass a number of arguments in the form of an ordinary keyed-value +table. Below is a list of everything supported by this function: + +biome = { + spawn_plants = something, -- [*] String or table; see below. + spawn_delay = number, -- same as sdelay, above. + spawn_chance = number, -- same as schance, above. + spawn_surfaces = {table}, -- List of node names on which the plants + -- should be spawned. As with the single-node "ssurface" + -- option in the legacy API, you should not put stone, air, + -- etc. here. + + ---- From here down are a number of optional parameters. You will + ---- most likely want to use at least some of these to limit how and + ---- where your objects are spawned. + + avoid_nodes = {table}, -- same meaning as savoid, above + avoid_radius = num, -- same as sradius + seed_diff = num, -- The Perlin seed difference value passed to the + -- minetest.get_perlin() function. Used along with + -- the global Perlin controls below to create the + -- "biome" in which the plants will spawn. Defaults + -- to 0 if not provided. + light_min = num, -- Minimum amount of light necessary to make a plant + -- spawn. Defaults to 0. + light_max = num, -- Maximum amount of light needed to spawn. Defaults + -- to the engine's MAX_LIGHT value of 14. + neighbors = {table}, -- List of neighboring nodes that need to be + -- immediately next to the node the plant is about to + -- spawn on. Can also be a string with a single node + -- name. It is both passed to the ABM as the + -- "neighbors" parameter, and is used to manually + -- check the adjacent nodes. It only takes one of + -- these for the spawn routine to mark the target as + -- spawnable. Defaults to nil (ignored). + ncount = num, -- There must be at least this many of the above + -- neighbors in the eight spaces immediately + -- surrounding the node the plant is about to spawn on + -- for it to happen. If not provided, this check is + -- disabled. + facedir = num, -- The value passed to the param2 variable when adding + -- the node to the map. Defaults to 0. Be sure that + -- the value you use here (and the range thereof) is + -- appropriate for the type of node you're spawning. + random_facedir = {table}, -- If set, the table should contain two values. + -- If they're both provided, the spawned plant will be + -- given a random facedir value in the range specified + -- by these two numbers. Overrides the facedir + -- parameter above, if it exists. Use {0,3} if you + -- want the full range for wallmounted nodes, or {2,5} + -- for most everything else, or any other pair of + -- numbers appropriate for the node you want to spawn. + depth_max = num, -- If the object spawns on top of a water source, the + -- water must be at most this deep. Defaults to 1. + min_elevation = num, -- Surface must be at this altitude or higher to + -- spawn at all. Defaults to -31000... + max_elevation = num, -- ...but must be no higher than this altitude. + -- Defaults to +31000. + near_nodes = {table}, -- List of nodes that must be somewhere in the + -- vicinity in order for the plant to spawn. Can also + -- be a string with a single node name. If not + -- provided, this check is disabled. + near_nodes_size = num, -- How large of an area to check for the above + -- node. Specifically, this checks a flat, horizontal + -- area centered on the node to be spawned on. + -- Defaults to 0, but is ignored if the above + -- near_nodes value is not set. + near_nodes_vertical = num, -- Used with the size value above, this extends + -- the vertical range of the near nodes search. + -- Basically, this turns the flat region described + -- above into a cuboid region. The area to be checked + -- will extend this high and this low above/below the + -- target node, centered thereon. Defaults to 1 (only + -- check the layer above, the layer at, and the layer + -- below the target node), but is ignored if + -- near_nodes is not set. + near_nodes_count = num, -- How many of the above nodes must be within that + -- radius. Defaults to 1 but is ignored if near_nodes + -- isn't set. Bear in mind that the total area to be + -- checked is equal to: + -- (near_nodes_size^2)*near_nodes_vertical*2 + -- For example, if size is 10 and vertical is 4, then + -- the area is (10^2)*8 = 800 nodes in size, so you'll + -- want to make sure you specify a value appropriate + -- for the size of the area being tested. + air_size = num, -- How large of an area to check for air above and + -- around the target. If omitted, only the space + -- above the target is checked. This does not check + -- for air at the sides or below the target. + air_count = num, -- How many of the surrounding nodes need to be air + -- for the above check to return true. If omitted, + -- only the space above the target is checked. + plantlife_limit = num, -- The value compared against the generic "plants + -- can grow here" Perlin noise layer. Smaller numbers + -- result in more abundant plants. Range of -1 to +1, + -- with values in the range of about 0 to 0.5 being + -- most useful. Defaults to 0.1. + temp_min = num, -- Minimum temperature needed for the desired object + -- to spawn. This is a 2d Perlin value, which has an + -- inverted range of +1 to -1. Larger values + -- represent *colder* temperatures, so this value is + -- actually the upper end of the desired Perlin range. + -- See the temperature map section at the bottom of + -- this document for details on how these values work. + -- Defaults to +1 (unlimited coldness). + temp_max = num, -- Maximum temperature/lower end of the Perlin range. + -- Defaults to -1 (unlimited heat). + humidity_min = num, -- Minimum humidity for the plant to spawn in. Like + -- the temperature map, this is a Perlin value where + -- lower numbers mean more humidity in the area. + -- Defaults to +1 (0% humidity). + humidity_max = num, -- Maximum humidity for the plant to spawn at. + -- Defaults to -1 (100% humidity). + verticals_list = {table}, -- List of nodes that should be considered to be + -- natural walls. + alt_wallnode = "string", -- If specified, this node will be substituted in + -- place of the plant(s) defined by spawn_plants + -- above, if the spawn target has one or more adjacent + -- walls. In such a case, the two above facedir + -- parameters will be ignored. + spawn_on_side = bool, -- Set this to true to immediately spawn the node on + -- one side of the target node rather than the top. + -- The code will search for an airspace to the side of + -- the target, then spawn the plant at the first one + -- found. The above facedir and random_facedir + -- parameters are ignored in this case. If the above + -- parameters for selecting generic wall nodes are + -- provided, this option is ignored. Important note: + -- the facedir values assigned by this option only + -- make sense with wallmounted nodes (nodes which + -- don't use facedir won't be affected). + choose_random_wall = bool, -- if set to true, and searching for walls is + -- being done, just pick any random wall if there is + -- one, rather than returning the first one. + spawn_on_bottom = bool, -- If set to true, spawn the object below the + -- target node instead of above it. The above + -- spawn_on_side variable takes precedence over this + -- one if both happen to be true. When using this + -- option with the random facedir function above, the + -- values given to the facedir parameter are for + -- regular nodes, not wallmounted. + spawn_replace_node = bool, -- If set to true, the target node itself is + -- replaced by the spawned object. Overrides the + -- spawn_on_bottom and spawn_on_side settings. +} + +[*] spawn_plants must be either a table or a string. If it's a table, the +values therein are treated as a list of nodenames to pick from randomly on +each application of the ABM code. The more nodes you can pack into this +parameter to avoid making too many calls to this function, the lower the CPU +load will likely be. + +You can also specify a string containing the name of a function to execute. +In this case, the function will be passed a single position parameter +indicating where the function should place the desired object, and the checks +for spawning on top vs. sides vs. bottom vs. replacing the target node will be +skipped. + +By default, if a biome node, size, and count are not defined, the biome +checking is disabled. Same holds true for the nneighbors bit above that. + + +===== +biome_lib:register_generate_plant(biome, nodes_or_function_or_treedef) + +To register an object to be spawned at mapgen time rather than via an ABM, +call this function with two parameters: a table with your object's biome +information, and a string, function, or table describing what to do if the +engine finds a suitable surface node (see below). + +The biome table contains quite a number of options, though there are fewer +here than are available in the ABM-based spawner, as some stuff doesn't make +sense at map-generation time. + +biome = { + surface = something, -- What node(s). May be a string such as + -- "default:dirt_with_grass" or a table with + -- multiple such entries. + + ---- Everything else is optional, but you'll definitely want to use + ---- some of these other fields to limit where and under what + ---- conditions the objects are spawned. + + below_nodes = {table}, -- List of nodes that must be below the target + -- node. Useful in snow biomes to keep objects from + -- spawning in snow that's on the wrong surface for + -- that object. + avoid_nodes = {table}, -- List of nodes to avoid when spawning. Groups are + -- not supported here. + avoid_radius = num, -- How much distance to leave between the object to be + -- added and the objects to be avoided. If this or + -- the avoid_nodes value is nil/omitted, this check is + -- skipped. Avoid using excessively large radii. + rarity = num, -- How rare should this object be in its biome? Larger + -- values make objects more rare, via: + -- math.random(1,100) > this + max_count = num, -- The absolute maximum number of your object that + -- should be allowed to spawn in a 5x5x5 mapblock area + -- (80x80x80 nodes). Defaults to 5, but be sure you + -- set this to some reasonable value depending on your + -- object and its size if 5 is insufficient. + seed_diff = num, -- Perlin seed-diff value. Defaults to 0, which + -- causes the function to inherit the global value of + -- 329. + neighbors = {table}, -- What ground nodes must be right next to and at the + -- same elevation as the node to be spawned on. + ncount = num, -- At least this many of the above nodes must be next + -- to the node to spawn on. Any value greater than 8 + -- will probably cause the code to never spawn + -- anything. Defaults to 0. + depth = num, -- How deep/thick of a layer the spawned-on node must + -- be. Typically used for water. + min_elevation = num, -- Minimum elevation in meters/nodes. Defaults to + -- -31000 (unlimited). + max_elevation = num, -- Max elevation. Defaults to +31000 (unlimited). + near_nodes = {table}, -- what nodes must be in the general vicinity of the + -- object being spawned. + near_nodes_size = num, -- how wide of a search area to look for the nodes + -- in that list. + near_nodes_vertical = num, -- How high/low of an area to search from the + -- target node. + near_nodes_count = num, -- at least this many of those nodes must be in + -- the area. + plantlife_limit = num, -- The value compared against the generic "plants + -- can grow here" Perlin noise layer. Smaller numbers + -- result in more abundant plants. Range of -1 to +1, + -- with values in the range of about 0 to 0.5 being + -- most useful. Defaults to 0.1. + temp_min = num, -- Coldest allowable temperature for a plant to spawn + -- (that is, the largest Perlin value). + temp_max = num, -- warmest allowable temperature to spawn a plant + -- (lowest Perlin value). + verticals_list = {table}, -- Same as with the spawn_on_surfaces function. + check_air = bool, -- Flag to tell the mapgen code to check for air above + -- the spawn target. Defaults to true if not + -- explicitly set to false. Set this to false VERY + -- SPARINGLY, as it will slow the map generator down. + delete_above = bool, -- Flag to tell the mapgen code to delete the two + -- nodes directly above the spawn target just before + -- adding the plant or tree. Useful when generating + -- in snow biomes. Defaults to false. + delete_above_surround = bool, -- Flag to tell the mapgen code to also + -- delete the five nodes surrounding the above space, + -- and the five nodes above those, resulting in a two- + -- node-deep cross-shaped empty region above/around + -- the spawn target. Useful when adding trees to snow + -- biomes. Defaults to false. + spawn_replace_node = bool, -- same as with the ABM spawner. + random_facedir = {table}, -- same as with the ABM spawner. +} + +Regarding nodes_or_function_or_treedef, this must either be a string naming +a node to spawn, a table with a list of nodes to choose from, a table with an +L-Systems tree definition, or a function. + +If you specified a string, the code will attempt to determine whether that +string specifies a valid node name. If it does, that node will be placed on +top of the target position directly (unless one of the other mapgen options +directs the code to do otherwise). + +If you specified a table and there is no "axiom" field, the code assumes that +it is a list of nodes. Simply name one node per entry in the list, e.g. +{"default:junglegrass", "default:dry_shrub"} and so on, for as many nodes as +you want to list. A random node from the list will be chosen each time the +code goes to place a node. + +If you specified a table, and there *is* an "axiom" field, the code assumes +that this table contains an L-Systems tree definition, which will be passed +directly to the engine's spawn_tree() function along with the position on +which to spawn the tree. + +You can also supply a function to be directly executed, which is given the +current node position (the usual "pos" table format) as its sole argument. It +will be called in the form: + + somefunction(pos) + + +===== +biome_lib:grow_plants(options) + +The third function, grow_plants() is used to turn the spawned nodes above +into something else over time. This function has no return value, and accepts +a biome definition table as the only parameter. These are defined like so: + +options = { + grow_plant = "string", -- Name of the node to be grown into something + -- else. This value is passed to the ABM as the + -- "nodenames" parameter, so it is the plants + -- themselves that are the ABM trigger, rather than + -- the ground they spawned on. A plant will only grow + -- if the node above it is air. Can also be a table, + -- but note that all nodes referenced therein will be + -- grown into the same object. + grow_delay = num, -- Passed as the ABM "interval" parameter, as with + -- spawning. + grow_chance = num, -- Passed as the ABM "chance" parameter. + grow_result = "string", -- Name of the node into which the grow_plant + -- node(s) should transform when the ABM executes. + + ---- Everything from here down is optional. + + dry_early_node = "string", -- This value is ignored except for jungle + -- grass (a corner case needed by that mod), where it + -- indicates which node the grass must be on in order + -- for it to turn from the short size to + -- "default:dry_shrub" instead of the medium size. + grow_nodes = {table}, -- One of these nodes must be under the plant in + -- order for it to grow at all. Normally this should + -- be the same as the list of surfaces passed to the + -- spawning ABM as the "nodenames" parameter. This is + -- so that the plant can be manually placed on + -- something like a flower pot or something without it + -- necessarily growing and perhaps dieing. Defaults + -- to "default:dirt_with_grass". + facedir = num, -- Same as with spawning a plant. + need_wall = bool, -- Set this to true if you the plant needs to grow + -- against a wall. Defaults to false. + verticals_list = {table}, -- same as with spawning a plant. + choose_random_wall = bool, -- same as with spawning a plant. + grow_vertically = bool, -- Set this to true if the plant needs to grow + -- vertically, as in climbing poison ivy. Defaults to + -- false. + height_limit = num, -- Set this to limit how tall the desired node can + -- grow. The mod will search straight down from the + -- position being spawned at to find a ground node, + -- set via the field below. Defaults to 5 nodes. + ground_nodes = {table}, -- What nodes should be treated as "the ground" + -- below a vertically-growing plant. Usually this + -- should be the same as the grow_nodes table, but + -- might also include, for example, water or some + -- other surrounding material. Defaults to + -- "default:dirt_with_grass". + grow_function = something, -- [*] see below. + seed_diff = num, -- [*] see below. +} + +[*] grow_function can take one of three possible settings: it can be nil (or + not provided), a string, or a table. + +If it is not provided or it's set to nil, all of the regular growing code is +executed normally, the value of seed_diff, if any, is ignored, and the node to +be placed is assumed to be specified in the grow_result variable. + +If this value is set to a simple string, this is treated as the name of the +function to use to grow the plant. In this case, all of the usual growing +code is executeed, but then instead of a plant being simply added to the +world, grow_result is ignored and the named function is executed and passed a +few parmeters in the following general form: + + somefunction(pos, perlin1, perlin2) + +These values represent the current position (the usual table), the Perlin +noise value for that spot in the generic "plants can grow here" map for the +seed_diff value above, the Perlin value for that same spot from the +temperature map, and the detected neighboring wall face, if there was one (or +nil if not). If seed_diff is not provided, it defaults to 0. + +If this variable is instead set to a table, it is treated an an L-Systems tree +definition. All of the growing code is executed in the usual manner, then the +tree described by that definition is spawned at the current position instead, +and grow_result is ignored. + + +===== +find_adjacent_wall(pos, verticals, randomflag) + +Of the few helper functions, this one expects a position parameter and a table +with the list of nodes that should be considered as walls. The code will +search around the given position for a neighboring wall, returning the first +one it finds as a facedir value, or nil if there are no adjacent walls. + +If randomflag is set to true, the function will just return the facedir of any +random wall it finds adjacent to the target position. Defaults to false if +not specified. + +===== +is_node_loaded(pos) + +This acts as a wrapper for the minetest.get_node_or_nil(node_pos) +function and accepts a single position parameter. Returns true if the node in +question is already loaded, or false if not. + + +===== +dbg(string) + +This is a simple debug output function which takes one string parameter. It +just checks if DEBUG is true and outputs the phrase "[Plantlife] " followed by +the supplied string, via the print() function, if so. + +===== +biome_lib:generate_tree(pos, treemodel) +biome_lib:grow_tree(pos, treemodel) + +In the case of the growing code and the mapgen-based tree generator code, +generating a tree is done via the above two calls, which in turn immediately +call the usual spawn_tree() functions. This rerouting exists as a way for +other mods to hook into biome_lib's tree-growing functions in general, +perhaps to execute something extra whenever a tree is spawned. + +biome_lib:generate_tree(pos, treemodel) is called any time a tree is spawned +at map generation time. 'pos' is the position of the block on which the tree +is to be placed. 'treemodel' is the standard L-Systems tree definition table +expected by the spawn_tree() function. Refer to the 'trunk' field in that +table to derive the name of the tree being spawned. + +biome_lib:grow_tree(pos, treemodel) does the same sort of thing whenever a +tree is spawned within the abm-based growing code, for example when growing a +sapling into a tree. + + +===== +There are other, internal helper functions that are not meant for use by other +mods. Don't rely on them, as they are subject to change without notice. + + +=============== +Global Settings +=============== + +Set this to true if you want the mod to spam your console with debug info :-) + + plantlife_debug = false + + +====================== +Fertile Ground Mapping +====================== + +The mod uses Perlin noise to create "biomes" of the various plants, via the +minetest.get_perlin() function. At present, there are three layers of +Perlin noise used. + +The first one is for a "fertile ground" layer, which I tend to refer to as the +generic "stuff can potentially grow here" layer. Its values are hard-coded: + + biome_lib.plantlife_seed_diff = 329 + perlin_octaves = 3 + perlin_persistence = 0.6 + perlin_scale = 100 + +For more information on how Perlin noise is generated, you will need to search +the web, as these default values were from that which is used by minetest_game +to spawn jungle grass at mapgen time, and I'm still learning how Perlin noise +works. ;-) + + +=================== +Temperature Mapping +=================== + +The second Perlin layer is a temperature map, with values taken from +SPlizard's Snow Biomes mod so that the two will be compatible, since that mod +appears to be the standard now. Those values are: + + temperature_seeddiff = 112 + temperature_octaves = 3 + temperature_persistence = 0.5 + temperature_scale = 150 + +The way Perlin values are used by this mod, in keeping with the snow mod's +apparent methods, larger values returned by the Perlin function represent +*colder* temperatures. In this mod, the following table gives a rough +approximation of how temperature maps to these values, normalized to +0.53 = 0 °C and +1.0 = -25 °C. + +Perlin Approx. Temperature +-1.0 81 °C ( 178 °F) +-0.75 68 °C ( 155 °F) +-0.56 58 °C ( 136 °F) +-0.5 55 °C ( 131 °F) +-0.25 41 °C ( 107 °F) +-0.18 38 °C ( 100 °F) + 0 28 °C ( 83 °F) + 0.13 21 °C ( 70 °F) + 0.25 15 °C ( 59 °F) + 0.5 2 °C ( 35 °F) + 0.53 0 °C ( 32 °F) + 0.75 -12 °C ( 11 °F) + 0.86 -18 °C ( 0 °F) + 1.0 -25 °C (- 13 °F) + +Included in this table are even 0.25 steps in Perlin values along with some +common temperatures on both the Centigrade and Fahrenheit scales. Note that +unless you're trying to model the Moon or perhaps Mercury in your mods/maps, +you probably won't need to bother with Perlin values of less than -0.56 or so. + + +================ +Humidity Mapping +================ + +Last but not least is a moisture/humidity map. Like the temperature map +above, Perlin values can be tested to determine the approximate humidity of +the *air* in the area. This humidity map is basically the perlin layer used +for deserts. + +A value of +1.0 is very moist (basically a thick fog, if it could be seen), a +value of roughly +0.25 represents the edge of a desert as usually seen in the +game, and a value of -1.0 is as dry as a bone. + +This does not check for nearby water, just general air humidity, and that +being the case, nearby ground does not affect the reported humidity of a +region (because this isn't yet possible to calculate yet). Use the near_nodes +and avoid_nodes parameters and their related options to check for water and +such. + +The Perlin values use for this layer are: + + humidity_seeddiff = 9130 + humidity_octaves = 3 + humidity_persistence = 0.5 + humidity_scale = 250 + +And this particular one is mapped slightly differently from the others: + + noise3 = perlin3:get2d({x=p_top.x+150, y=p_top.z+50}) + +(Note the +150 and +50 offsets) + -- cgit v1.2.3