## Post your modding questions here

bobomb
Member

Posts: 115
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

### Re: Post your modding questions here

what is the best method to determine surface height given an x,z coordinate? is there something in the lua api? is there a preferred algorithm?

i found this but it was never merged? https://github.com/minetest/minetest/pull/640

thanks

Hybrid Dog
Member

Posts: 2728
Joined: Thu Nov 01, 2012 12:46

### Re: Post your modding questions here

bobomb wrote:what is the best method to determine surface height given an x,z coordinate? is there something in the lua api? is there a preferred algorithm?

i found this but it was never merged? https://github.com/minetest/minetest/pull/640

thanks

ln which situation do you need to find out the surface height?
mapgen for example offers a heightmap mapgen_object

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

bobomb
Member

Posts: 115
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

### Re: Post your modding questions here

i have solved this but the situation is not a mapgen situation. it is after the world is generated.

I ended up converting a function made for core that was never merged from: https://github.com/sapier/minetest/blob/c6f814b52a5e2b2f12c76215db3524571c56fe20/src/environment.cpp#L868

here it is:
Code: Select all
`function get_surface(basepos, searchup, searchdown, walkable_only)   local max = searchup + basepos.y   if searchdown then basepos.y = basepos.y - searchdown end   local last_node = minetest.get_node(basepos)   local node = last_node   local runpos = basepos   local last_was_walkable = node.walkable   while ( runpos.y < max and minetest.get_content_id(node.name) ~= c_air ) do      runpos.y = runpos.y + 1      last_node = node      node = minetest.get_node(runpos)      if not (walkable_only) then         if minetest.get_content_id(last_node.name) ~= c_air         and minetest.get_content_id(last_node.name) ~= c_ignore         and minetest.get_content_id(node.name) == c_air then            return runpos.y         end      else         local is_walkable = node.walkable         if last_was_walkable and not is_walkable then            return runpos.y         end         last_was_walkable = is_walkable      end   end   return basepos.y - 1end`

there are still some issues with this, like it returns max when nothing no air was detected, and it returns 0 when no ground was detected. also i don't know how to test for "is_walkable" in lua. how does one test a node for various group memberships, and is walkability a group or something else in the lua api?

Hybrid Dog
Member

Posts: 2728
Joined: Thu Nov 01, 2012 12:46

### Re: Post your modding questions here

bobomb wrote:i have solved this but the situation is not a mapgen situation. it is after the world is generated.

I ended up converting a function made for core that was never merged from: https://github.com/sapier/minetest/blob/c6f814b52a5e2b2f12c76215db3524571c56fe20/src/environment.cpp#L868

here it is:
Code: Select all
`function get_surface(basepos, searchup, searchdown, walkable_only)   local max = searchup + basepos.y   if searchdown then basepos.y = basepos.y - searchdown end   local last_node = minetest.get_node(basepos)   local node = last_node   local runpos = basepos   local last_was_walkable = node.walkable   while ( runpos.y < max and minetest.get_content_id(node.name) ~= c_air ) do      runpos.y = runpos.y + 1      last_node = node      node = minetest.get_node(runpos)      if not (walkable_only) then         if minetest.get_content_id(last_node.name) ~= c_air         and minetest.get_content_id(last_node.name) ~= c_ignore         and minetest.get_content_id(node.name) == c_air then            return runpos.y         end      else         local is_walkable = node.walkable         if last_was_walkable and not is_walkable then            return runpos.y         end         last_was_walkable = is_walkable      end   end   return basepos.y - 1end`

there are still some issues with this, like it returns max when nothing no air was detected, and it returns 0 when no ground was detected. also i don't know how to test for "is_walkable" in lua. how does one test a node for various group memberships, and is walkability a group or something else in the lua api?

node.walkable is nil because node is from minetest.get_node(pos), which returns a table containing the name, param1 and param2 of the node at pos
this function should test if a node is walkable:
Code: Select all
`-- is_walkable(minetest.get_node(pos).name)local function is_walkable(name)local data = minetest.registered_nodes[name]if not data thenreturn falseendreturn not (data.walkable == false)end`

walkable is not a group, it's something of the node definition, groups is something of the node definition, too
if you want to find out if a node is in a specific group, there's a function for it http://dev.minetest.net/minetest.get_item_group

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

bobomb
Member

Posts: 115
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

### Re: Post your modding questions here

i knew that walkable code would not work, anyway here is a complete translation of sapier's function without any changes like "downsearch" which is redundant. (still need to deal with cases of no top found / no bottom found)
Code: Select all
`-- a lua rewrite of sapier's get_surface() proposal, see:-- https://github.com/sapier/minetest/blob/c6f814b52a5e2b2f12c76215db3524571c56fe20/src/environment.cpp#L868function get_surface(basepos, searchup, walkable_only)   local max = searchup + basepos.y   local last_node = minetest.get_node(basepos)   local node = last_node   local runpos = basepos   local last_was_walkable = minetest.registered_nodes[node.name].walkable   while ( runpos.y < max and minetest.get_content_id(node.name) ~= c_air ) do      runpos.y = runpos.y + 1      last_node = node      node = minetest.get_node(runpos)      if not (walkable_only) then         if minetest.get_content_id(last_node.name) ~= c_air         and minetest.get_content_id(last_node.name) ~= c_ignore         and minetest.get_content_id(node.name) == c_air then            return runpos.y         end      else         local is_walkable = minetest.registered_nodes[node.name].walkable         if last_was_walkable and not is_walkable then            return runpos.y         end         last_was_walkable = is_walkable      end   end   return basepos.y - 1end`

rubenwardy
Moderator

Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

### Re: Post your modding questions here

Hybrid Dog wrote:
Code: Select all
`local data = minetest.registered_nodes[name]if not data then    return falseendreturn not (data.walkable == false)`

Would be simpler as:

Code: Select all
`return data and data.walkable`

Table look ups can be costly. minetest.get_node can also be costly. get_node will return { name = "ignore" } is the MapBlock hasn't been loaded yet. Node that there may be stacked worlds - floating lands etc at 30000 (in the future) and you may be in a cave.

bobomb
Member

Posts: 115
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

### Re: Post your modding questions here

Thanks Ruben. I am going to revise the function to handle caves and skylands, one way or another. My first approach was to make it relative to the player, but anyway that is on the to do list...

is Hybrid Dog's function necessary or can I just do
Code: Select all
`return minetest.registered_nodes[node.name].walkable`

i know node name exists because that's what's being tested.

rubenwardy
Moderator

Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

### Re: Post your modding questions here

There may be unknown nodes in the world, this will cause the game to crash.

Hybrid Dog
Member

Posts: 2728
Joined: Thu Nov 01, 2012 12:46

### Re: Post your modding questions here

rubenwardy wrote:
Hybrid Dog wrote:
Code: Select all
`local data = minetest.registered_nodes[name]if not data then    return falseendreturn not (data.walkable == false)`

[/quote

Would be simpler as:

Code: Select all
`return data and data.walkable`

l'm not sure if this works.
But you could short it this way:
Code: Select all
`local data = minetest.registered_nodes[name]return data and data.walkable ~= false`

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

bobomb
Member

Posts: 115
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

### Re: Post your modding questions here

I rewrote the function to scan from the top down which is much simpler and deals with caves and overhangs at least in a basic way:
https://gist.github.com/bobombolo/6127b153228344eb037a

SAMIAMNOT
Member

Posts: 416
Joined: Wed Sep 03, 2014 00:51
Location: Desert
In-game: notanewbie

### Re: Post your modding questions here

How do you spawn nodes and/or mobs? I tried modding the More Mesecons mod and changed the add_item function to add_node but that did not work for the Mobs Redo mob NPCs.
I test mines.

Nathan.S
Member

Posts: 969
Joined: Wed Sep 24, 2014 17:47
Location: Bigsby Texas
GitHub: NathanSalapat
IRC: NathanS21
In-game: NathanS21

### Re: Post your modding questions here

Doubtless I'm just an idiot but can somebody tell me what is wrong with this?
Code: Select all
`if inv:contains_item('fuel', 'group:tree') then`

It works just fine for non-groups, but I want to support multiple fuels as inputs in a smoker I'm making. I suppose I could just do a chain of if statements but a group would be quicker and easier.
I record Minetest videos, Mod reviews, Modding tutorials, and Lets plays.
Check out my website, and brand new Minetest Modding Course

kaeza
Moderator

Posts: 2162
Joined: Thu Oct 18, 2012 05:00
Location: Montevideo, Uruguay
GitHub: kaeza
IRC: kaeza diemartin blaaaaargh
In-game: kaeza

### Re: Post your modding questions here

Note: UNTESTED:

Code: Select all
`local function is_item_in_group(itemname, group)  local def = minetest.registered_items[name]  if not def then return end  return (def.groups and (def.groups[group] or 0)>0)end-- In your code (this assumes "fuel" inv only has a single slot):-- ...local item = inv:get_stack("fuel", 1)local fuel_groups = { "tree", "wood", "oil", "radiactive" } -- Groups considered "fuel"if item and (not item:is_empty()) then  for _, g in ipairs(fuel_groups) do    if is_item_in_group(item:get_name(), g) then      -- We found some fuel. Do something with it.      return    end  endend-- ...`

Of course, the proper solution would be to implement group resolution or whatever in `contains_item`.
Your signature is not the place for a blog post. Please keep it as concise as possible. Thank you!

Check out my stuff! | Donations greatly appreciated! PayPal

Nathan.S
Member

Posts: 969
Joined: Wed Sep 24, 2014 17:47
Location: Bigsby Texas
GitHub: NathanSalapat
IRC: NathanS21
In-game: NathanS21

### Re: Post your modding questions here

Thank you so much kaeza, this looks like it should work. I just want people to be able to use logs, so I'll just be using the tree group. I tried just making a table and doing a if in table, which I know would work in python, but unfortunately LUA doesn't have that same feature.
I record Minetest videos, Mod reviews, Modding tutorials, and Lets plays.
Check out my website, and brand new Minetest Modding Course

minetestcr
Member

Posts: 58
Joined: Fri Feb 13, 2015 21:31

### Re: Post your modding questions here

Hello!

Is there a way to have one user in creative mode while the others are not? It would be the server admin in creative mode, and the players in survival.

thanks.

benrob0329
Member

Posts: 1319
Joined: Thu Aug 06, 2015 22:39
Location: Michigan
GitHub: Benrob0329
IRC: benrob0329
In-game: benrob03

### Re: Post your modding questions here

Unified Inventory has a creative priv, that could work.
Social: YouTube Peertube Matrix Room: #minetest:matrix.org | Games: The Infinite IKEA

minetestcr
Member

Posts: 58
Joined: Fri Feb 13, 2015 21:31

### Re: Post your modding questions here

benrob0329 wrote:Unified Inventory has a creative priv, that could work.

Thanks benrob0329.

BrunoMine
Member

Posts: 1070
Joined: Thu Apr 25, 2013 17:29
Location: SP-Brasil
GitHub: BrunoMine

### Re: Post your modding questions here

how to identify the lag of a client. I do not care only server lag, but each client individually.

Semmett9
Member

Posts: 155
Joined: Sun Oct 07, 2012 13:48
Location: Gallifrey

### Re: Post your modding questions here

How to activate a file if a mod is installed?

Is they a way to activate a file or bit of code if a mod is installed.

I have just mad a mod called "Beer_Test" and I’m currently working on a new mod "Farm_Test". Is they a way for me to add a line of code which looks for a mod called "Beer_Test"; and if it finds it will then activate some code which connects the two mods together.

Many Thanks

kaeza
Moderator

Posts: 2162
Joined: Thu Oct 18, 2012 05:00
Location: Montevideo, Uruguay
GitHub: kaeza
IRC: kaeza diemartin blaaaaargh
In-game: kaeza

### Re: Post your modding questions here

You need to add a file named `depends.txt` to the `farm_test` mod (if it doesn't already have one), and add this line to the file:

Code: Select all
`beer_test?`

This ensures the `beer_test` mod gets loaded first if found, but the mod is not required (i.e. it is optional).

Then, in `farm_test/init.lua` (or wherever appropriate), you use code like this:

Code: Select all
`if minetest.get_modpath("beer_test") then  -- beer_test is installed. Add some glue code, extra items, etc. here.end`
Your signature is not the place for a blog post. Please keep it as concise as possible. Thank you!

Check out my stuff! | Donations greatly appreciated! PayPal

Joz
Member

Posts: 41
Joined: Fri Oct 25, 2013 21:37

### Re: Post your modding questions here

What is the best method to determine if the actual node has been initialised?

Themes: world generating, singlenode

When my lua map generators write nodes into an uninitialised chunk (for example trees, special caves, big pyramids…) the changes will be overridden when the on_register function of that chunk is called. There will be cut trees and leaf hanging in the air decaying.

So I have to know which nodes have been placed by a map generator. Is this possible? I tried it with testing if a node's id is not == minetest.get_content_id("ignore") but no node had this id. I also tried the same with …content_id("air") but there were still many empty chunks.

ArguablySane
Member

Posts: 116
Joined: Sun Oct 12, 2014 21:29

### Re: Post your modding questions here

Does anyone know of a fast way to hash 2 or more numbers together in Lua such that the result is deterministic, depends on the order of the parameters, and has a reasonably low probability of collisions?
Almost any standard hash function would be fine, but Lua 5.1 doesn't even support bitwise operators which rather limits my options.

The reason I need this is that I want to generate deterministic seeds from xyz coordinates and edges in a graph. It was incredibly easy to throw together a proof-of-concept cave generator in Python, but now that I'm trying to port it to Lua I'm fighting against awkward syntax and missing features.

The best idea I have had so far is to use minetest's PRNG with a function like:
Code: Select all
`local function hash(n1,n2)  local prng = PseudoRandom(n1)  local n3 = prng.next() + n2  prng = PseudoRandom(n3)  return prng.next()end`

but creating a new PRNG object for every number I want to hash just seems horribly inefficient.
The above post and any ideas expressed therein are released to the public domain under a Creative Commons CC0 license.

rubenwardy
Moderator

Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

### Re: Post your modding questions here

Isn't Minetest. Serialise position for this purpose?

ArguablySane
Member

Posts: 116
Joined: Sun Oct 12, 2014 21:29

### Re: Post your modding questions here

rubenwardy wrote:Isn't Minetest. Serialise position for this purpose?

Is it? Can PseudoRandom(seed) accept a string as its seed, and will it use the entire string rather than just truncating it? If so, that would simplify things massively.
The above post and any ideas expressed therein are released to the public domain under a Creative Commons CC0 license.

rubenwardy
Moderator

Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

### Re: Post your modding questions here

wrong name, it's minetest.hash_node_position({x=,y=,z=})

http://rubenwardy.com/minetest_modding_ ... .html#misc

PreviousNext