Page 1 of 1
How can I find the height of the ground in Lua?

Posted:
Fri Jan 03, 2014 02:20
by Kodiologist
The application here is that I'm writing a game that randomly chooses node positions the player is supposed to visit. The x- and z-coordinates are chosen without regard for terrain, but I'd like to choose the y-coordinate to be 1 unit above ground level at that point. So if the mapgen happens to make a mountain there, you'd have to climb it, or if the mapgen makes a lake there, you'd have to swim to the lakebed.
The Mapgen class seems to have a getGroundLevelAtPoint method at the C++ level, but it seems inaccessible to mods.
minetest.register_on_generated seems difficult to use for this purpose because the first generated slice of map including the (x, z) coordinates in question may not include the ground-level y-coordinate.

Posted:
Fri Jan 03, 2014 09:00
by Nore
There was a pull request about that, but it was not merged:
https://github.com/minetest/minetest/pull/640The other possibility is to start somewhere in the ground (like y = -100), and while the light is less than 15 (sunlight), increase y. You then have ground level... (however, you need to wait that the area is generated before doing that...)

Posted:
Fri Jan 03, 2014 09:32
by aldobr
start at 0 heigth.
if node is air, walk node by node, decreasing heigth by one until node no longer is air.
z positon is current position + 1
if node is not air, walk node by node, increasng heigth by one until node is air.
z position is current position

Posted:
Fri Jan 03, 2014 13:22
by Kodiologist
Nore wrote:There was a pull request about that, but it was not merged
Rats.
Lazy map generation seems to be the chief obstacle here. (x, -100, z) may well never be generated if the player doesn't dig down there. Similar concerns apply to your solution, aldobr. Is there any way to force generation of a map chunk containing a given node position?

Posted:
Fri Jan 03, 2014 13:41
by Nore
You can always know if the player is above or below the level of ground (except lakebeds) by looking at the sunlight. So: if the player is somewhere where there is no sunlight, you know he is below ground level, etc.

Posted:
Fri Jan 03, 2014 17:18
by paramat
Until the terrain generates at a particular distant x z location, the y value of ground level is undefined, the only way to know that in advance is to rewrite mapgen v6 in lua and do the perlin noise calculations to see where ground level will be, this is possible (i could do it but not interested) but not easy.

Posted:
Fri Jan 03, 2014 19:29
by Sokomine
Hybrid Dog wrote:It wouldn't work if you redefine water to let sunlight through it.
In such a case, checking one node above might be enough. Perhaps the original poster doesn't care about positions on water anyway.

Posted:
Sat Jan 04, 2014 01:53
by Kodiologist
Great, I seem to have been able to get this to work by checking the light level (as you suggested, Nore) along with a manual check for water. Here's my implementation in MoonScript:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
MAX_LIGHT = 15
NOON = .5
waypoints = for _ = 1, 1
{created: false,
ymin: -1/0, -- negative infinity
ymax: 1/0, -- positive infinity
pos: {x: 5, z: 5}}
--waypoints = for _ = 1, 2
-- {created: false,
-- ymin: -1/0, -- negative infinity
-- ymax: 1/0, -- positive infinity
-- pos: {
-- x: (if coinflip! then 1 else -1) * math.random(100, 200),
-- z: (if coinflip! then 1 else -1) * math.random(100, 200)}}
minetest.register_on_generated (minp, maxp, blockseed) ->
for wp in *waypoints
if not wp.created and do
wp.pos.x >= minp.x and wp.pos.x <= maxp.x and do
wp.pos.z >= minp.z and wp.pos.z <= maxp.z
for y = minp.y, maxp.y
here = {x: wp.pos.x, y: y, z: wp.pos.z}
if minetest.get_node_light(here, NOON) == MAX_LIGHT or do
minetest.get_node(here).name == 'default:water_source'
wp.ymax = math.min wp.ymax, y
else
wp.ymin = math.max wp.ymin, y + 1
if wp.ymin == wp.ymax
wp.pos.y = wp.ymin
wp.created = true