Move most of mapgen into mapgen thread

This commit is contained in:
Desour 2024-03-17 15:38:49 +01:00 committed by HybridDog
parent 9c3fc65544
commit 8be1f839c5
5 changed files with 166 additions and 48 deletions

View File

@ -1,6 +1,8 @@
dofile(nether.path .. "/settings.lua")
local in_mapgen_env = nether.env_type == "ssm_mapgen"
-- vars
nether.v = {}
local v = nether.v
@ -132,14 +134,16 @@ function nether.query_contents()
end
if nether.log_level >= 1 then
local mod_prefix = in_mapgen_env and "[nether(mg)] " or "[nether] "
function nether:inform(msg, spam, t)
if spam <= self.log_level then
local info
if t then
info = "[nether] " .. msg .. (" after ca. %.3g s"):format(
info = mod_prefix .. msg .. (" after ca. %.3g s"):format(
(minetest.get_us_time() - t) / 1000000)
else
info = "[nether] " .. msg
info = mod_prefix .. msg
end
print(info)
if self.log_to_chat then

View File

@ -1,17 +1,24 @@
local function r_area(manip, width, height, pos)
local netherstructure_height = 6
local function vmanip_with_r_area(width, height, pos)
local manip = minetest.get_voxel_manip()
local emerged_pos1, emerged_pos2 = manip:read_from_map(
{x=pos.x-width, y=pos.y, z=pos.z-width},
{x=pos.x+width, y=pos.y+height, z=pos.z+width}
)
return VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
return manip, VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
end
local function inform_grow(pos, t1, name, generated)
nether:inform(name.." grew at " .. minetest.pos_to_string(pos),
generated and 3 or 2, t1)
end
local function set_vm_data(manip, nodes, pos, t1, name, generated)
manip:set_data(nodes)
manip:write_to_map(not generated)
nether:inform(name.." grew at " .. minetest.pos_to_string(pos),
generated and 3 or 2, t1)
inform_grow(pos, t1, name, generated)
end
local c, contents_defined
@ -22,20 +29,10 @@ local function define_contents()
end
end
function nether.grow_netherstructure(pos, generated)
local t1 = minetest.get_us_time()
local function grow_netherstructure_into_raw(area, nodes, pos, generated)
define_contents()
if not pos.x then print(dump(pos))
nether:inform("Error: "..dump(pos), 1)
return
end
local height = 6
local manip = minetest.get_voxel_manip()
local area = r_area(manip, 2, height, pos)
local nodes = manip:get_data()
local height = netherstructure_height
local vi = area:indexp(pos)
for _ = 0, height-1 do
@ -75,9 +72,37 @@ function nether.grow_netherstructure(pos, generated)
end
end
end
set_vm_data(manip, nodes, pos, t1, "blood", generated)
end
function nether.grow_netherstructure_into(area, nodes, pos, generated)
local t1 = minetest.get_us_time()
if not pos.x then print(dump(pos))
nether:inform("Error: "..dump(pos), 1)
return
end
grow_netherstructure_into_raw(area, nodes, pos, generated)
inform_grow(pos, t1, "blood", generated)
end
function nether.grow_netherstructure(pos, generated)
local t1 = minetest.get_us_time()
if not pos.x then print(dump(pos))
nether:inform("Error: "..dump(pos), 1)
return
end
local height = netherstructure_height
local manip, area = vmanip_with_r_area(2, height, pos)
local nodes = manip:get_data()
grow_netherstructure_into_raw(area, nodes, pos, generated)
set_vm_data(manip, nodes, pos, t1, "blood", generated)
end
local poshash = minetest.hash_node_position
local pos_from_hash = minetest.get_position_from_hash

View File

@ -17,7 +17,10 @@ if not rawget(_G, "nether") then
nether = {}
end
nether.path = minetest.get_modpath"nether"
-- similar to INIT
nether.env_type = "ssm" -- server-side-modding
nether.path = minetest.get_modpath("nether")
local path = nether.path
dofile(path .. "/common.lua")
@ -28,9 +31,43 @@ dofile(path .. "/pearl.lua")
dofile(path .. "/grow_structures.lua")
dofile(path .. "/mapgen.lua")
if minetest.register_mapgen_script then
minetest.log("info", "nether mapgen running in mapgen env")
minetest.register_mapgen_script(path .. "/init_emerge.lua")
minetest.set_gen_notify("custom", nil,
{"nether:please_grow_trees", "nether:please_fix_light"})
minetest.register_on_generated(function(minp, maxp, blockseed)
local t0 = minetest.get_us_time()
local gennotify = minetest.get_mapgen_object("gennotify")
-- forest trees
local trees_hashed = gennotify.custom["nether:please_grow_trees"] or {}
for i = 1, #trees_hashed do
local pos = minetest.get_position_from_hash(trees_hashed[i])
nether.grow_tree(pos, true)
end
if #trees_hashed > 0 then
nether:inform(#trees_hashed .. " trees set", 2, t0)
end
-- fix light
local fixlight_area = gennotify.custom["nether:please_fix_light"]
if fixlight_area then
t0 = minetest.get_us_time()
minetest.fix_light(fixlight_area[1], fixlight_area[2])
nether:inform("light fixed", 2, t0)
end
end)
else
minetest.log("info", "nether mapgen running in main env")
dofile(path .. "/mapgen.lua")
end
--abms

13
nether/init_emerge.lua Normal file
View File

@ -0,0 +1,13 @@
-- This is run in mapgen env (see register_mapgen_script)
nether = {}
nether.env_type = "ssm_mapgen"
nether.path = minetest.get_modpath("nether")
local path = nether.path
dofile(path .. "/common.lua")
dofile(path .. "/grow_structures.lua")
dofile(path .. "/mapgen.lua")

View File

@ -1,5 +1,6 @@
local path = nether.path
local in_mapgen_env = nether.env_type == "ssm_mapgen"
-- vars
local v = nether.v
@ -189,7 +190,7 @@ local data = {}
local structures_enabled = true
local vine_maxlength = math.floor(NETHER_HEIGHT/4+0.5)
-- Create the Nether
minetest.register_on_generated(function(minp, maxp, seed)
local function on_generated(minp, maxp, seed)
--avoid big map generation
if not (maxp.y >= NETHER_BOTTOM-100 and minp.y <= nether_start) then
return
@ -442,39 +443,77 @@ minetest.register_on_generated(function(minp, maxp, seed)
end
end
end
nether:inform("most stuff set", 2, t1)
local t2 = minetest.get_us_time()
local bl_cnt = 0
local tr_cnt = 0
local tr_snd_cnt = 0
if structures_enabled then -- Blood netherstructures
bl_cnt = #tab
for i = 1, #tab do
nether.grow_netherstructure_into(area, data, tab[i], true)
end
end
if bl_cnt > 0 then
nether:inform(bl_cnt .. " blood structures set", 2, t2)
end
t2 = minetest.get_us_time()
vm:set_data(data)
-- vm:set_lighting(12)
-- vm:calc_lighting()
-- vm:update_liquids()
vm:write_to_map(false)
nether:inform("nodes set", 2, t1)
local t2 = minetest.get_us_time()
local tr_bl_cnt = 0
if structures_enabled then -- Blood netherstructures
tr_bl_cnt = #tab
for i = 1,tr_bl_cnt do
nether.grow_netherstructure(tab[i], true)
end
end
if forest_possible then -- Forest trees
tr_bl_cnt = tr_bl_cnt + #trees
for i = 1,#trees do
nether.grow_tree(trees[i], true)
end
end
if tr_bl_cnt > 0 then
nether:inform(tr_bl_cnt .. " trees and blood structures set", 2, t2)
if not in_mapgen_env then
vm:write_to_map(false)
end
nether:inform("data written", 2, t2)
t2 = minetest.get_us_time()
minetest.fix_light(minp, maxp)
if forest_possible then -- Forest trees
if in_mapgen_env then
-- Trees can get too big (>16 nodes in one direction) for usual
-- overgeneration onion layer. nether.grow_tree will make new vmanips
-- to emerge blank (= ignore-filled) blocks to overcome this. But the
-- main server thread needs to do this.
tr_snd_cnt = #trees
local trees_hashed = {}
for i = 1, #trees do
trees_hashed[i] = minetest.hash_node_position(trees[i])
end
assert(minetest.save_gen_notify("nether:please_grow_trees", trees_hashed))
else
tr_cnt = #trees
for i = 1, #trees do
nether.grow_tree(trees[i], true)
end
end
end
nether:inform("light fixed", 2, t2)
if tr_cnt + tr_snd_cnt > 0 then
nether:inform(string.format("%s trees set, %s trees sent",
tr_cnt, tr_snd_cnt), 2, t2)
end
if in_mapgen_env then
assert(minetest.save_gen_notify("nether:please_fix_light", {minp, maxp}))
else
t2 = minetest.get_us_time()
minetest.fix_light(minp, maxp)
nether:inform("light fixed", 2, t2)
end
nether:inform("done", 1, t1)
end)
end
if in_mapgen_env then
minetest.register_on_generated(function(_, minp, maxp, blockseed)
return on_generated(minp, maxp, blockseed)
end)
else
minetest.register_on_generated(on_generated)
end