Page 1 of 1

How are temperatures assigned to coordinates?

PostPosted: Sun Sep 20, 2015 20:29
by Merlin
I am trying to write a mapgen mod for minetest, but I am running in some problems in understanding how map generation works.
What I understood so far is, that different biomes get assigned to different coordinates by comparing the temperature and humidity of the coordinates with the ones of the biome.
What I fail to understand is, how temperature and humidity are assigned to coordinates/are distributed across the map.
I searched for code showing that in several mods, but haven't been lucky.
Can anyone tell me how this is done?

Re: How are temperatures assigned to coordinates?

PostPosted: Sun Sep 20, 2015 20:35
by Sane
I am pretty sure Vanessa has solved that issue in her Biome Lib mod.
You might want ot have a peek at it's sources.

Re: How are temperatures assigned to coordinates?

PostPosted: Mon Sep 21, 2015 16:45
by paramat
Using 2D perlin noise, for an example of how to make a temperature/humidity biome system see https://github.com/paramat/paragenv7/blob/master/init.lua

Re: How are temperatures assigned to coordinates?

PostPosted: Tue Sep 22, 2015 10:30
by Sane
paramat wrote:Using 2D perlin noise, for an example of how to make a temperature/humidity biome system see https://github.com/paramat/paragenv7/blob/master/init.lua


Ah nice.

Uhm , well, please excuse me wearing my smarty-pants.
Maybe you could place all those minetest.get_content_id calls out of the callback function. So they don't have to be evaluated new for every map block.

Re: How are temperatures assigned to coordinates?

PostPosted: Tue Sep 22, 2015 17:43
by paramat
I thought that too, but was told by hmmmm that it's faster to state them as locals inside the function, apparently getting id is a very fast operation.

Re: How are temperatures assigned to coordinates?

PostPosted: Tue Sep 22, 2015 19:24
by Sane
paramat wrote:I thought that too, but was told by hmmmm that it's faster to state them as locals inside the function, apparently getting id is a very fast operation.

That is interesting. I'm always eager to learn.

But how can that be? The callback literally runs thousands of times.
So either calling minetest.get_content_id outside the callback takes very very long
or reading the mod local values takes considerably longer than what i've guessed.
I will investigate.

Re: How are temperatures assigned to coordinates?

PostPosted: Tue Sep 22, 2015 23:36
by Sane
Not sure if this is of interest for anyone but to be complete ...

I've run some simple speed tests and it seems that, to no big surprise
  • calling minetest.get_content_id outside the callback takes exact the same time than calling it inside.
  • getting the IDs from variables previously set on mod level takes about no time.
Also calling minetest.get_content_id is quite fast (more then 5,000 calls per second on my computer).
So getting the IDs in the callback will have no noticeable influence on performance. Which makes getting the IDs inside or outside a matter of taste.

Well that leaves me with the smarty pants again ... Sorry for that.

Re: How are temperatures assigned to coordinates?

PostPosted: Wed Sep 23, 2015 14:43
by Don
Keep being a smarty pants. Your info is helpful.

Re: How are temperatures assigned to coordinates?

PostPosted: Wed Sep 23, 2015 19:43
by hmmmm
I do remember saying that, but probably it only applies to interpreted Lua.

Re: How are temperatures assigned to coordinates?

PostPosted: Wed Sep 23, 2015 23:59
by paramat
Interesting, i will probably change my style then and move them outside.

Re: How are temperatures assigned to coordinates?

PostPosted: Thu Sep 24, 2015 00:24
by Don
Wondering if one of you could give a brief explanation of get_content_id and what you mean by inside and outside.
I am trying to learn but get stuck on things.

Re: How are temperatures assigned to coordinates?

PostPosted: Thu Sep 24, 2015 22:55
by Sane
Don wrote:Wondering if one of you could give a brief explanation of get_content_id and what you mean by inside and outside.
I am trying to learn but get stuck on things.


The function minetest.get_content_id returns a number that is internally used to identify nodes. Mapgen data contains those IDs.

The inside / outside talk refers to the code that paramat mentioned.(https://github.com/paramat/paragenv7/bl ... r/init.lua)

It's about wether to write:
Code: Select all
...
minetest.register_on_generated(function(minp, maxp, seed)
...
   local c_air = minetest.get_content_id("air")
...
   -- Using c_air somewhere ...


or rather:
Code: Select all
...
local c_air = minetest.get_content_id("air")
minetest.register_on_generated(function(minp, maxp, seed)
...
   -- Using c_air somewhere ...


The point is that calling minetest.get_content_id("air") takes time, although not much. That time is spent every time the callback is called. If the ID is acquired outside the callback, minetest.get_content_id("air") is run only once.

Re: How are temperatures assigned to coordinates?

PostPosted: Thu Sep 24, 2015 23:36
by Don
Thanks. I understand now.

Re: How are temperatures assigned to coordinates?

PostPosted: Fri Sep 25, 2015 10:13
by Ferk
Sane wrote:But how can that be? The callback literally runs thousands of times.
So either calling minetest.get_content_id outside the callback takes very very long
or reading the mod local values takes considerably longer than what i've guessed.

Doesn't each chunk get generated only once in the entire life of the world?

I guess after a big area of the map has already been generated it might be less likely for new chunks to require generation (normally players would just settle down nearby the spawn), so if get_content_id is very cheap you'd rather want to avoid having variables in the "global" scope of the module wasting memory. No player is gonna explore the 775x775x775 chunks of the entire world.

But I'm just guessing. I doubt the difference is very significant anyway.

Re: How are temperatures assigned to coordinates?

PostPosted: Sat Sep 26, 2015 10:27
by Sane
Ferk wrote:
Sane wrote:But how can that be? The callback literally runs thousands of times.
So either calling minetest.get_content_id outside the callback takes very very long
or reading the mod local values takes considerably longer than what i've guessed.

Doesn't each chunk get generated only once in the entire life of the world?

I guess after a big area of the map has already been generated it might be less likely for new chunks to require generation (normally players would just settle down nearby the spawn), so if get_content_id is very cheap you'd rather want to avoid having variables in the "global" scope of the module wasting memory. No player is gonna explore the 775x775x775 chunks of the entire world.

But I'm just guessing. I doubt the difference is very significant anyway.


Yes, I came to the same conclusion. (see post)

For example getting 10 ids would take about 1/500 seconds on my computer. That is per newly emerged map block. And that will have no noticable impact on the user experience. Especially for singleplayer worlds.

When calcualting the impact on the whole wrold:
32,000 * 32,000 * 32,000 nodes =
400 * 400* 400 map blocks =
64000000 calls =
128000 seconds for 10 IDs each call
--------------
> That's about 35,5 hours of server computing time that could have been spent with calculating interesting stuff.
... Maybe worth a thought.

Re: How are temperatures assigned to coordinates?

PostPosted: Sat Oct 10, 2015 17:55
by Merlin
@paramat

I have some questions about that code, I understand some chunks, but not nearly everything.
First question:
What does each of the variables in this table do?

Code: Select all
-- 2D noise for temperature

local np_temp = {
   offset = 0,
   scale = 1,
   spread = {x = 2048, y = 2048, z = 2048},
   seed = 9130,
   octaves = 3,
   persist = 0.33
}

Re: How are temperatures assigned to coordinates?

PostPosted: Sun Oct 11, 2015 12:31
by paramat
2D noise outputs a noise value for every (X, Z) column of nodes in a mapchunk.
The 'perlinmap' is a table of 80x80 values.
3D noise outputs a noise value for every (X, Y, Z) node in a mapchunk, and the code is therefore 80 times heavier.
The 'perlinmap' is a table of 80x80x80 values.

'offset' is the centre value of the noise value, often 0.

'scale' is the approximate variation of the noise value either side of the centre value, often 1.
Depending on the number of octaves and the persistence the variation is usually 1 to 2 times the scale value. The exact variation can be calculated from octaves and persistence.
(To be exact, scale is the variation of octave 1, additional octaves add extra variation, see below).

'spread' is the size in nodes of the largest scale variation. If the noise is terrain height this would be the approximate size of the largest islands or seas, there will be no structure on a larger scale than this.
There are 3 values for x, y, z so you can stretch or squash the shape of your structures, normally you would set all 3 values to be the same, even for 2D noise where the y value is not used).

'octaves' is the number of levels of detail in the noise variation.
The largest scale variation is 'spread', that is octave 1. Each additional octave adds variation on a scale one half the size, so here you will have variation on scales of 2048, 1024, 512 nodes.

'persist' is persistence. This is how large the variation of each additional octave is relative to the previous octave.
Octave 1 always outputs a variation from -1 to 1, the 'amplitude' is 1.
With 3 octaves persist 0.5, a much used standard noise:
Octave 2 outputs a variation from -0.5 to 0.5 (amplitude 0.5).
Octave 3 will output -0.25 to 0.25 (amplitude 0.5 x 0.5).
The 3 octaves are added to result in a noise variation of -1.75 to 1.75.
'persist' is therefore the roughness of the noise pattern, 0.33 is fairly smooth, 0.67 is rough and spiky, 0.5 is a medium value.

'seed' is the magic seed number that determines the entire noise pattern.
Just type in any random number, different for each use of noise.
This is actually a 'seed difference', the noise actually uses 'seed' + 'world seed', to make any noise pattern world-dependant and repeatable.
'seed' then makes sure each use of noise in a world is using a different pattern.

Re: How are temperatures assigned to coordinates?

PostPosted: Sun Oct 11, 2015 13:04
by Don
Wow paramat! Is this in the dev wiki? If not could you add it? This is very helpful information.

Re: How are temperatures assigned to coordinates?

PostPosted: Mon Oct 12, 2015 00:52
by paramat
I can't access the wiki, someone else can do it =}

Re: How are temperatures assigned to coordinates?

PostPosted: Tue Nov 17, 2015 23:13
by afflatus
Ah I see why so much of the documentation is incomplete.
I'd be happy to do it, but first I will have to find out who holds the keys and get an account.

Re: How are temperatures assigned to coordinates?

PostPosted: Fri Nov 20, 2015 21:36
by Ferk
I tried to request access some time ago in this thread, but all I got was a http://wiki.minetest.net account, not a http://dev.minetest.net account.

It would be cool if there were more links from dev.minetest to the actual code in github. This way one would be able to see by himself in case the documentation is lacking or out of date.

Re: How are temperatures assigned to coordinates?

PostPosted: Sat Nov 21, 2015 11:41
by afflatus
Ah, thanks Ferk.
Not much point in having a wiki if no-one is allowed to edit.

Re: How are temperatures assigned to coordinates?

PostPosted: Sat Nov 21, 2015 12:04
by Ferk
Maybe it would be best to contribute to rubenwardy's modding book.

It also includes a lua api reference that is automatically generated out of the lua_api.txt from github, which is a nice source of quick info and more frequently kept up to date.

Perhaps the official wiki should be replaced with something more like this.

It would be nice if we could reference to sections of the autogenerated html by using hashtag references (something like doing.. luaref.html#minetest.formspec_escape ). In the lua_api.txt you can only reference by line number, so as soon as the txt gets changed the link no longer points to the right place.

Re: How are temperatures assigned to coordinates?

PostPosted: Sat Nov 21, 2015 15:18
by afflatus
Ferk wrote:Maybe it would be best to contribute to rubenwardy's modding book.
Perhaps the official wiki should be replaced with something more like this.


Now there's a really good idea!
The official wiki just needs keeping up to date with more / better examples.
Tutorial / Guides are best kept separate, as they may contain opinion and original ideas.

Ferk wrote:It would be nice if we could reference to sections of the autogenerated html by using hashtag references ...


Wouldn't it just?

Re: How are temperatures assigned to coordinates?

PostPosted: Sun Nov 29, 2015 15:53
by rubenwardy
afflatus wrote:
Ferk wrote:It would be nice if we could reference to sections of the autogenerated html by using hashtag references ...

Wouldn't it just?


You can, click the grey # symbols. Making it easy to see is on my todo list.