[0.4.8] LuaVoxelManipulator

User avatar
Inocudom
Member
Posts: 3121
Joined: Sat Sep 29, 2012 01:14
IRC: Inocudom
In-game: Inocudom

Re: [0.4.8] LuaVoxelManipulator

by Inocudom » Post

I need to destroy my pride completely and entirely:

Code: Select all

20<Inocudom>30    proller: http://forum.freeminer.org/threads/again-a-lua-mapgen-yappy.171/#post-1711 We have a big problem here.
T 1413130428 20<Inocudom>30    LuaVoxelManip is malfunctioning again for unknown reasons.
T 1413131387 24*    zat has quit (Quit: Leaving.)
T 1413133105 18<proller18>    because its shit ?
T 1413133284 24*    proller has quit (Quit: Leaving)
T 1413133295 20<Inocudom>30    proller: Would you be able to make a post in that topic then? And if not LuaVoxelManip, what then?
T 1413133376 23*    zat (~ale@179.57.205.11323) has joined
T 1413133385 23*    proller (~p@80.240.216.6923) has joined
T 1413135183 23*    iqualfragile (~iqualfrag@unaffiliated/iqualfragile23) has joined
T 1413135600 20<Inocudom>30    proller: But without LuaVoxelManip, how else would people be able to make Lua mapgens efficiently? Something would have to take its place, unless the goal is to make such omni-impossible.
T 1413140515 18<proller18>   Lua mapgens cant be  efficiently
T 1413140815 20<Inocudom>30   proller: Then it is as I said: omni-impossible?

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

Recently hmmmm realised his voxelmanip mapgen example, posted in the first post of this thread http://pastebin.com/x0DFYXQD has an error, the 'noise object' minetest.get_perlin_map() should not be created multiple times, only :get3dMap_flat() should be per mapchunk.
My code below, taken from 'levels' mod viewtopic.php?f=11&t=10888, shows the correct way to create the noise object once only during the generation of the first mapchunk. This method will make your mapgen a little faster.

Code: Select all

-- Initialize noise objects to nil

local nobj_terrain = nil

-- On generated function

minetest.register_on_generated(function(minp, maxp, seed)

	local x1 = maxp.x
	local y1 = maxp.y
	local z1 = maxp.z
	local x0 = minp.x
	local y0 = minp.y
	local z0 = minp.z
	
	print ("chunk minp ("..x0.." "..y0.." "..z0..")")
	
	local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
	local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
	local data = vm:get_data()
	
	local c_stone = minetest.get_content_id("default:stone")
	local c_water = minetest.get_content_id("default:water_source")
	local c_lava  = minetest.get_content_id("default:lava_source")
	
	local sidelen = x1 - x0 + 1
	local chulens3d = {x=sidelen, y=sidelen, z=sidelen}
	local minpos3d = {x=x0, y=y0, z=z0}
	
	nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulens3d)
	
	local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d)

	local ni3d = 1
	for z = z0, z1 do
		for y = y0, y1 do
			local vi = area:index(x0, y, z)
			for x = x0, x1 do
				local n_terrain = nvals_terrain[ni3d]
..
..
Last edited by paramat on Thu Jan 08, 2015 13:04, edited 1 time in total.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

Post deleted.
Last edited by paramat on Tue Jan 06, 2015 06:58, edited 4 times in total.

hmmmm
Member
Posts: 47
Joined: Tue Apr 02, 2013 04:04

Re: [0.4.8] LuaVoxelManipulator

by hmmmm » Post

I was wrong when I said that, you were always able to omit z from chulens. Nothing special needs to be coded for that.
Also as of the 0.4.11 release, the size parameters a noisemap object was created with has no bearing on the rest of the parameters.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

Thanks hmmmm, posts edited.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

I just discovered that the z component of 2D perlinmaps must be 'z=1' to avoid crashes. Chatting to hmmmm he realised his post above was actually not correct. This may be fixed soon but since players will be using your mods in 0.4.11 stable 'z=1' should be included.
See my latest lua mapgen 'levels' as an example of correct lua mapgen coding https://github.com/paramat/levels
Last edited by paramat on Thu Jan 08, 2015 13:33, edited 1 time in total.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

Levels mod had a bug, now fixed in version 0.2.6. I had restated the noise objects as locals within the on-generated function. This caused the noise objects to be re-created per mapchunk instead of only once.
Last edited by paramat on Sat Feb 14, 2015 09:27, edited 1 time in total.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

Here's another improvement to my lua mapgen coding, realised when bugfixing with hmmmm.
Until now my mapgens have ended with these lines:

Code: Select all

	vm:set_data(data)
	vm:set_lighting({day=0, night=0})
	vm:calc_lighting()
	vm:write_to_map(data)
	vm:update_liquids()
Any light values pre-existing in the mapchunk were cleared with 'set_lighting' before re-calculating light.
It is actually more efficient to set the mapgen parameters to have no light right from the start and calculate it once only after the voxelmanip has added content.
So now near the beginning of your code add this for a singlenode mapgen:

Code: Select all

minetest.register_on_mapgen_init(function(mgparams)
	minetest.set_mapgen_params({mgname="singlenode", flags="nolight"})
end)
Or this for core mapgens:

Code: Select all

minetest.register_on_mapgen_init(function(mgparams)
	minetest.set_mapgen_params({flags="nolight"})
end)
Then after the mapgen loop there is no need for 'set_lighting', the end code look should be:

Code: Select all

	vm:set_data(data)
	vm:calc_lighting()
	vm:write_to_map(data)
	vm:update_liquids()

Sokomine
Member
Posts: 4276
Joined: Sun Sep 09, 2012 17:31
GitHub: Sokomine
IRC: Sokomine
In-game: Sokomine

Re: [0.4.8] LuaVoxelManipulator

by Sokomine » Post

I'd be glad if you could take a look at the recent version of mg_villages. Most of the code is pretty fast, but some of those recent optimizations might help as well, especially regarding the calculation of noise?
A list of my mods can be found here.

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

1. Can I rotate node with VoxelManip? I tried to use it to speedup moving many nodes at once, but it just forgets the facedir.

2. Why is it implemented as a completely different interface? Was it harder to implement just a way to get the node area and work inside it with the old set_node and get_node? What I mean is some kind of a transaction that would speed-up working with a set of nodes instead of getting and setting them one by one. But VoxelManip is something with a completely different interface, not sure what it was designed for.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

1. Yes you can get and set a big chunk of param2 (rotation) data, i'm now doing this in flexrealm to rotate nodes properly https://github.com/paramat/flexrealm/bl ... r/init.lua
Note you can also do this with param1 (light) data also.

2. Voxelmanip is exactly that, a way to get, process and write a big chunk of nodes in lua at once, instead of accessing the map via C++ (which is slow) one node at a time with get_node/add_node. The speedup is huge, my first lua mapgens took 1 minute per chunk to generate.

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

paramat wrote:1. Yes you can get and set a big chunk of param2 (rotation) data, i'm now doing this in flexrealm to rotate nodes properly https://github.com/paramat/flexrealm/bl ... r/init.lua
Note you can also do this with param1 (light) data also.

2. Voxelmanip is exactly that, a way to get, process and write a big chunk of nodes in lua at once, instead of accessing the map via C++ one node at a time with get_node/add_node. The speedup is huge, my first lua mapgens took 1 minute per chunk to generate.
Thanks. Wiki did't say anything about param1 and param2 data :(
2. Yes, I see that. But why a different interface? Why not make something like data[pos].set_node with the exact same parameters as a set_node(pos)?
And, emm, why light is named "param1" and facedir a "param2"?

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

paramat wrote:Note you can also do this with param1 (light) data also.
How do I set a "default" one as remove_node does?

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

There also is set_node_at and get_node_at. Can I use these to move nodes, or it won't be faster than set_node? And does it "move" the metadata?

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

The wiki is out of date, best to refer to lua_api.txt.
Param2 is usually the rotation but not always, it can be used for other things, see lua_api.txt.

> How do I set a "default" one as remove_node does?

There isn't a default value for light level, it's best to leave that alone because light level for each node is calculated at the end in 'vm:calc_lighting()' or 'vm:update_map()'.

> set_node_at and get_node_at. Can I use these to move nodes, or it won't be faster than set_node? And does it "move" the metadata?

Those allow you to get or set individual nodes in the voxelmanip while you are processing it. They allow you to get/set the node name, node light level (param1) and node rotation (param2). Those are for when you want to get/set just a few nodes plus their param1/param2 data in the vm without having to read/write a whole mapchunk's worth (500000 nodes) of param data. So for a just few nodes those methods are faster.
For your use with setting rotation of large objects it's best to not use those.

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

paramat wrote:There isn't a default value for light level, it's best to leave that alone because light level for each node is calculated at the end in 'vm:calc_lighting()' or 'vm:update_map()'.
Wiki says these 2 methods are to be used only when implementing a map generator. But I need to move a structure of nodes along with their facedir and light data. When it moves, the space behind it becomes air and I need to "reset" its lighting.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

> set_node_at and get_node_at [...] And does it "move" the metadata?

No, as far as i know.

> Wiki says these 2 methods are to be used only when implementing a map generator.

Ignore that, you can use anything for anything as long as it works.

> I need to move a structure of nodes along with their facedir and light data. When it moves, the space behind it becomes air and I need to "reset" its lighting.

Don't bother moving light data. Light levels, including any lights inside your airship will be re-calculated by 'update_map()' at the end. For example if you fly under a floatland you need the airship exterior to go dark.
The space of air behind the airship can only be reset by re-calculating light levels using 'update_map()'.

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

paramat wrote:> set_node_at and get_node_at [...] And does it "move" the metadata?

No, as far as i know.

> Wiki says these 2 methods are to be used only when implementing a map generator.

Ignore that, you can use anything for anything as long as it works.

> I need to move a structure of nodes along with their facedir and light data. When it moves, the space behind it becomes air and I need to "reset" its lighting.

Don't bother moving light data. Light levels, including any lights inside your airship will be re-calculated by 'update_map()' at the end. For example if you fly under a floatland you need the airship exterior to go dark.
The space of air behind the airship can only be reset by re-calculating light levels using 'update_map()'.
Do I need only calc_lighting or update_map is needed anyway?

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

There are 2 types of voxelmanip, one is for mapgen and worlks on a whole 80^3 mapchunk. The one you should use is the 'non-mapgen voxelmanip' that i use here to move rain clouds https://github.com/paramat/rain/blob/master/init.lua You define the voxelmanip volume yourself to any size or shape.

Code: Select all

local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
local data = vm:get_data()
...
...
...
vm:set_data(data)
vm:write_to_map()
vm:update_map()
Last edited by paramat on Tue Mar 24, 2015 22:18, edited 1 time in total.

User avatar
neko259
Member
Posts: 805
Joined: Sun Jun 19, 2011 06:51

Re: [0.4.8] LuaVoxelManipulator

by neko259 » Post

There are 2 types of voxelmanip, one is for mapgen and worlks on a whole 80^3 mapchunk.
I use this one. I'm only interested if I need to run update_map or just calc_lighting. What's the difference?

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

calc_lighting is for the 'mapgen object voxelmanip'.
update_map is for the other voxelmanip and does the same thing, it resets lighting.
However your mod will not work properly using the mapgen object voxelmanip.

User avatar
bobomb
Member
Posts: 162
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

Re: [0.4.8] LuaVoxelManipulator

by bobomb » Post

Can someone explain how one would use voxel manipulator to make ABMs more efficient? you still need to register an abm to trigger a manipulation, then what? i have a situation where I want to run an abm action on all nodes of a similar type at once. wouldn't i have to still allow all nodes of the type to be identified by the abm search? is there a way to use vm to make this search process more efficient? or would vm only be useful to apply the transformation? what i need is a way to get the extent of a volume that would enclose all of a given node type (actually based on an identifier in the metadata), and apply a transformation to all these at once. but then the abm must stop scanning all those nodes individually to gain a benefit. can someone enlighten me?

User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: [0.4.8] LuaVoxelManipulator

by Hybrid Dog » Post

bobomb wrote:Can someone explain how one would use voxel manipulator to make ABMs more efficient? you still need to register an abm to trigger a manipulation, then what? i have a situation where I want to run an abm action on all nodes of a similar type at once. wouldn't i have to still allow all nodes of the type to be identified by the abm search? is there a way to use vm to make this search process more efficient? or would vm only be useful to apply the transformation? what i need is a way to get the extent of a volume that would enclose all of a given node type (actually based on an identifier in the metadata), and apply a transformation to all these at once. but then the abm must stop scanning all those nodes individually to gain a benefit. can someone enlighten me?
l did it for lavacooling
https://github.com/HybridDog/minetest_g ... s.lua#L134

if you want to get nodes touching each other, just use tables https://github.com/HybridDog/minetest-m ... it.lua#L28 https://github.com/HybridDog/replacer/b ... t.lua#L302 https://github.com/HybridDog/cave_light ... it.lua#L49

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

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

The LVM example posted by hmmmm in the first post is out of date, the usage of 'vm:write_to_map(data)' is wrong, see viewtopic.php?f=18&t=18533

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: [0.4.8] LuaVoxelManipulator

by paramat » Post

New LVM example code is here viewtopic.php?f=18&t=19836

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests