So, and function set up through register_on_generated runs after each and every node in the world is generated. I would then do my register_ore to set the maximum density I wished. I would need to write my on_generated function so that it checked to see if the current node was an ore that I wanted to vary according to distance from spawn, and if it was, possibly remove it (turn into normal stone) based on a random function, thereby creating increasing scarcity as nodes get closer to spawn. Am I following correctly?
Pretty close. Except you don't do any register_ore calls inside the LVM. Do that outside, and just handle the variation from spawn within the generated function. Otherwise, great!
I assume that letting minetest generate the ore and lua remove it would be more efficient then trying to write my own ore generation logic in lua? More efficent and MUCH easier.
What kind of impact would this have on map generation speed, probably not a whole lot?
Yeah, you will have a much easier time placing ore with the default ore mechanism and cleaning it up yourself compared to writing your own generation logic. More efficient? Still a moot point. The default ore generation takes next to no time, compared to
any action with LVM. But overall, it should take very little time. You're not calling any perlin noise, you're just visiting every node once. I'd say well under 100 ms per chunk, and that's being strict.
Oh, and one more question. could the deprecated default.generate_ore do what I want? I suppose it would be a very bad idea to use it in any case. :)
...Yeah, that could be bad. Plus, it doesn't override default ore gen. So you'd have to clean up the default ores as well.
and yes, an example (simple!) would be appreciated. I learn best by looking at examples.
Here you go!
Code: Select all
minetest.register_on_generated(function(minp, maxp, seed)
--if out of range of ore_gen limits
if minp.y > 0 then
return --quit; otherwise, you'd have wasted resources
end
--easy reference to commonly used values
local t1 = os.clock()
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 ("[ore_gen] chunk minp ("..x0.." "..y0.." "..z0..")") --tell people you are generating a chunk
--This actually initializes the LVM
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
--grab content IDs -- You need these to efficiently access and set node data. get_node() works, but is far slower
local c_air = minetest.get_content_id("air")
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 c_iron = minetest.get_content_id("default:stone_with_iron")
local c_diamond = minetest.get_content_id("default:stone_with_diamond")
for z = z0, z1 do -- for each xy plane progressing northwards
for y = y0, y1 do -- for each x row progressing upwards
local vi = area:index(x0, y, z) -- This accesses the node at a given position
for x = x0, x1 do -- for each node do
-- Now test the node if it's an ore that needs to be potentially thinned out
if data[vi] == c_iron or data[vi] == c_diamond then
-- it is, so now thin it based on distance from center
local dist = abs(x) + abs(y) + abs(z) + 1 -- This also accounts for vertical distance, so that you don't need new functions for deeper depths
-- Now threshold it and delete unwanted nodes
if math.random() > (1/dist) then -- 1/dist becomes exceeding small as dist increases. random is between 0 and 1.
data[vi] = c_stone -- remove the ore
end
end -- end ore existence check
end -- end 'x' loop
end -- end 'y' loop
end -- end 'z' loop
-- Wrap things up and write back to map
--send data back to voxelmanip
vm:set_data(data)
--calc lighting
vm:set_lighting({day=0, night=0})
vm:calc_lighting()
--write it to world
vm:write_to_map(data)
local chugent = math.ceil((os.clock() - t1) * 1000) --grab how long it took
print ("[ore_gen] "..chugent.." ms") --tell people how long
end)
Nam ex spatio, omnes res venire possunt.
Why let the ground limit you when you can reach for the sky?
Back to college now, yay for sophomore year schedules. :P