Extended the API yet again, this time adding a Perlin-based temperature map

(two new variables defining min and max temperature, normalized to 0.53 = 0
degrees centigrade).

The values used for this new Perlin layer come from Splizard's Snow Biomes mod,
so other mods that use plantlife to create biomes should be able to blend
nicely with that mod.
This commit is contained in:
Vanessa Ezekowitz 2013-01-12 00:47:50 -05:00
parent 94770d713b
commit 4eff513bbd
2 changed files with 109 additions and 17 deletions

55
API.txt
View File

@ -18,8 +18,8 @@ of variables. All of the variables below, if specified at all, must be
specified exactly in the order given here. This function has no return value. specified exactly in the order given here. This function has no return value.
spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface,
savoid, seed_diff, lightmin, lightmax, nneighbors, savoid, seed_diff, lightmin, lightmax, nneighbors, ocount,
ocount, facedir, depthmax, altitudemin, altitudemax) facedir, depthmax, altitudemin, altitudemax, tempmin, tempmax)
The first several of these are all required, and are from the last version of The first several of these are all required, and are from the last version of
the flowers mod, so this part of the API should be the same as before. the flowers mod, so this part of the API should be the same as before.
@ -52,9 +52,9 @@ From here down are several optional parameters. You can use as many as you
need, but you must specify them in order (so if you want lightmax, you need need, but you must specify them in order (so if you want lightmax, you need
lightmin and seed_diff also, but not the rest). lightmin and seed_diff also, but not the rest).
seed_diff: The perlin seed difference value passed to the seed_diff: The Perlin seed difference value passed to the
minetest.env:get_perlin() function. Used along with the minetest.env:get_perlin() function. Used along with the
global perlin controls below to create the "biome" in global Perlin controls below to create the "biome" in
which the plants will spawn. Usually a value of somewhere which the plants will spawn. Usually a value of somewhere
in the 10 to 100 range is good. Defaults to 0 if not in the 10 to 100 range is good. Defaults to 0 if not
provided. provided.
@ -92,6 +92,10 @@ airradius: How large of an area to check for air around the target.
Defaults to 0 (only check the target). Defaults to 0 (only check the target).
aircount: How many of the surrounding nodes need to be air for the aircount: How many of the surrounding nodes need to be air for the
above check to return true. Defaults to 1. above check to return true. Defaults to 1.
tempmin: Minimum 2d Perlin value (which has a floating point range of
-1 to +1) needed in the temperature map for the desired
plant to spawn. Defaults to -1 if not supplied.
tempmax: Maximum temperature. Defaults to +1.
By default, if a biome node, size, and count are not defined, the biome 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. checking is disabled. Same holds true for the nneighbors bit above that.
@ -151,7 +155,7 @@ grow_function: Execute the named function (which must be supplied as just
position of the node to be "grown" (in the usual table position of the node to be "grown" (in the usual table
format), and the Perlin noise value at the location in format), and the Perlin noise value at the location in
question. question.
seed_diff: The perlin seed diff to be use to calculate the noise seed_diff: The Perlin seed diff to be use to calculate the noise
value given to the above grow_function. Should be the value given to the above grow_function. Should be the
same as the seed diff used when first spawning the plant same as the seed diff used when first spawning the plant
that's being grown. that's being grown.
@ -182,10 +186,10 @@ Enable this if you want the mod to spam your console with debug info :-)
plantlife_debug = false plantlife_debug = false
The mod uses perlin noise to create "biomes" of the various plants. Aside The mod uses Perlin noise to create "biomes" of the various plants. Aside
from plantlife_seed_diff (see below), these values are the ones plugged from plantlife_seed_diff (see below), these values are the ones plugged
directly into the minetest.env:get_perlin() function. For more information on directly into the minetest.env:get_perlin() function. For more information on
how perlin noise is generated, you will need to search the web, as these how Perlin noise is generated, you will need to search the web, as these
default values were arrived at through trial and error. default values were arrived at through trial and error.
plantlife_seed_diff = 123 plantlife_seed_diff = 123
@ -193,7 +197,7 @@ default values were arrived at through trial and error.
perlin_persistence = 0.2 perlin_persistence = 0.2
perlin_scale = 25 perlin_scale = 25
This value is compared against the output of the above perlin noise function This value is compared against the output of the above Perlin noise function
to decide when to actually place a plant. Smaller numbers mean larger biomes to decide when to actually place a plant. Smaller numbers mean larger biomes
and more abundant plants. and more abundant plants.
@ -227,3 +231,38 @@ growing ABM.
grow_delay = 1000 grow_delay = 1000
grow_chance = 10 grow_chance = 10
===================
Temperature Mapping
===================
This mod uses Perlin noise to establish a rough 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.
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.

View File

@ -2,6 +2,10 @@
-- 2013-01-00 -- 2013-01-00
-- --
-- License: WTFPL -- License: WTFPL
--
-- I got the temperature map idea from "hmmmm", values used for it came from
--
-- Various settings - most of these probably won't need to be changed -- Various settings - most of these probably won't need to be changed
@ -13,6 +17,11 @@ local perlin_octaves = 3
local perlin_persistence = 0.6 local perlin_persistence = 0.6
local perlin_scale = 100 local perlin_scale = 100
local temperature_seeddiff = 112
local temperature_octaves = 3
local temperature_persistence = 0.5
local temperature_scale = 150
local plantlife_limit = 0.1 -- compared against perlin noise. lower = more abundant local plantlife_limit = 0.1 -- compared against perlin noise. lower = more abundant
-- Local functions -- Local functions
@ -35,7 +44,29 @@ end
-- The spawning ABM -- The spawning ABM
spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, savoid, seed_diff, lightmin, lightmax, nneighbors, ocount, facedir, depthmax, altmin, altmax, sbiome, sbiomesize, sbiomecount, airsize, aircount) spawn_on_surfaces = function(
sdelay,
splant,
sradius,
schance,
ssurface,
savoid,
seed_diff,
lightmin,
lightmax,
nneighbors,
ocount,
facedir,
depthmax,
altmin,
altmax,
sbiome,
sbiomesize,
sbiomecount,
airsize,
aircount,
tempmin,
tempmax)
if seed_diff == nil then seed_diff = 0 end if seed_diff == nil then seed_diff = 0 end
if lightmin == nil then lightmin = 0 end if lightmin == nil then lightmin = 0 end
if lightmax == nil then lightmax = LIGHT_MAX end if lightmax == nil then lightmax = LIGHT_MAX end
@ -49,6 +80,8 @@ spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, savoid,
if sbiomecount == nil then sbiomecount = 1 end if sbiomecount == nil then sbiomecount = 1 end
if airsize == nil then airsize = 0 end if airsize == nil then airsize = 0 end
if aircount == nil then aircount = 1 end if aircount == nil then aircount = 1 end
if tempmin == nil then tempmin = -2 end
if tempmax == nil then tempmax = 2 end
minetest.register_abm({ minetest.register_abm({
nodenames = { ssurface }, nodenames = { ssurface },
interval = sdelay, interval = sdelay,
@ -57,9 +90,14 @@ spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, savoid,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z } local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
local n_top = minetest.env:get_node(p_top) local n_top = minetest.env:get_node(p_top)
local perlin = minetest.env:get_perlin(seed_diff, perlin_octaves, perlin_persistence, perlin_scale ) local perlin1 = minetest.env:get_perlin(seed_diff, perlin_octaves, perlin_persistence, perlin_scale)
local noise = perlin:get2d({x=p_top.x, y=p_top.z}) local perlin2 = minetest.env:get_perlin(temperature_seeddiff, temperature_octaves, temperature_persistence, temperature_scale)
if noise > plantlife_limit and is_node_loaded(p_top) then local noise1 = perlin1:get2d({x=p_top.x, y=p_top.z})
local noise2 = perlin2:get2d({x=p_top.x, y=p_top.z})
if noise1 > plantlife_limit
and noise2 >= tempmin
and noise2 <= tempmax
and is_node_loaded(p_top) then
local n_light = minetest.env:get_node_light(p_top, nil) local n_light = minetest.env:get_node_light(p_top, nil)
if minetest.env:find_node_near(p_top, sradius + math.random(-1.5,2), savoid) == nil if minetest.env:find_node_near(p_top, sradius + math.random(-1.5,2), savoid) == nil
and n_light >= lightmin and n_light >= lightmin
@ -93,7 +131,20 @@ end
-- The growing ABM -- The growing ABM
grow_plants = function(gdelay, gchance, gplant, gresult, dry_early_node, grow_nodes, facedir, need_wall, grow_vertically, height_limit, ground_nodes, grow_function, seed_diff) grow_plants = function(
gdelay,
gchance,
gplant,
gresult,
dry_early_node,
grow_nodes,
facedir,
need_wall,
grow_vertically,
height_limit,
ground_nodes,
grow_function,
seed_diff)
if need_wall ~= true then need_wall = false end if need_wall ~= true then need_wall = false end
if grow_vertically ~= true then grow_vertically = false end if grow_vertically ~= true then grow_vertically = false end
if height_limit == nil then height_limit = 62000 end if height_limit == nil then height_limit = 62000 end
@ -144,10 +195,12 @@ grow_plants = function(gdelay, gchance, gplant, gresult, dry_early_node, grow_no
end end
else else
if seed_diff == nil then seed_diff = 0 end if seed_diff == nil then seed_diff = 0 end
local perlin = minetest.env:get_perlin(seed_diff, perlin_octaves, perlin_persistence, perlin_scale ) local perlin1 = minetest.env:get_perlin(seed_diff, perlin_octaves, perlin_persistence, perlin_scale)
local noise = perlin:get2d({x=pos.x, y=pos.z}) local perlin2 = minetest.env:get_perlin(temperature_seeddiff, temperature_octaves, temperature_persistence, temperature_scale)
dbg("Want to execute "..grow_function.."("..dump(pos)..","..noise..")") local noise1 = perlin1:get2d({x=p_top.x, y=p_top.z})
assert(loadstring(grow_function.."("..dump(pos)..","..noise..")"))() local noise2 = perlin2:get2d({x=p_top.x, y=p_top.z})
dbg("Call function: "..grow_function.."("..dump(pos)..","..noise1..","..noise2..")")
assert(loadstring(grow_function.."("..dump(pos)..","..noise1..","..noise2..")"))()
end end
end end
}) })