mirror of
https://github.com/mt-mods/biome_lib.git
synced 2024-12-25 10:20:18 +01:00
rewrote block queue handlers to reduce code duplication
and improve lag management minetest.conf settings added: biome_lib_dtime_limit: Maximum lag allowed, in seconds. Default 0.5s. Larger values allow for more lag, but make map updates run a bit faster. biome_lib_queue_run_ratio: If positive, this is the approximate number of globalstep ticks to skip between map updates. If negative, it becomes the positive number of map updates to run per globalstep tick before lag is checked. No minimum value, maximum +100. Default: -100 (that is, 100 updates per globalstep tick, with none intentionally skipped). Use positive numbers for slow machines or biome_lib-using mods that tend to cause lag, and negative values for fast machines and mods.
This commit is contained in:
parent
8ecb401309
commit
a325c2ccd8
198
init.lua
198
init.lua
@ -9,27 +9,16 @@
|
|||||||
biome_lib = {}
|
biome_lib = {}
|
||||||
biome_lib.air = {name = "air"}
|
biome_lib.air = {name = "air"}
|
||||||
|
|
||||||
biome_lib.blocklist_aircheck = {}
|
biome_lib.block_log = {}
|
||||||
biome_lib.blocklist_no_aircheck = {}
|
|
||||||
|
|
||||||
biome_lib.surface_nodes_aircheck = {}
|
|
||||||
biome_lib.surface_nodes_no_aircheck = {}
|
|
||||||
|
|
||||||
biome_lib.surfaceslist_aircheck = {}
|
|
||||||
biome_lib.surfaceslist_no_aircheck = {}
|
|
||||||
|
|
||||||
biome_lib.actioncount_aircheck = {}
|
|
||||||
biome_lib.actioncount_no_aircheck = {}
|
|
||||||
|
|
||||||
biome_lib.actionslist_aircheck = {}
|
biome_lib.actionslist_aircheck = {}
|
||||||
biome_lib.actionslist_no_aircheck = {}
|
biome_lib.actionslist_no_aircheck = {}
|
||||||
|
|
||||||
|
biome_lib.surfaceslist_aircheck = {}
|
||||||
|
biome_lib.surfaceslist_no_aircheck = {}
|
||||||
|
|
||||||
biome_lib.modpath = minetest.get_modpath("biome_lib")
|
biome_lib.modpath = minetest.get_modpath("biome_lib")
|
||||||
|
|
||||||
biome_lib.total_no_aircheck_calls = 0
|
|
||||||
|
|
||||||
biome_lib.queue_run_ratio = tonumber(minetest.settings:get("biome_lib_queue_run_ratio")) or 100
|
|
||||||
|
|
||||||
local function tableize(s)
|
local function tableize(s)
|
||||||
return string.split(string.trim(string.gsub(s, " ", "")))
|
return string.split(string.trim(string.gsub(s, " ", "")))
|
||||||
end
|
end
|
||||||
@ -328,7 +317,7 @@ local function populate_single_surface(biome, pos, perlin_fertile_area, checkair
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function biome_lib:populate_surfaces(biome, nodes_or_function_or_model, snodes, checkair)
|
function biome_lib.populate_surfaces(biome, nodes_or_function_or_model, snodes, checkair)
|
||||||
local items_added = 0
|
local items_added = 0
|
||||||
|
|
||||||
biome_lib:set_defaults(biome)
|
biome_lib:set_defaults(biome)
|
||||||
@ -427,104 +416,78 @@ function biome_lib:populate_surfaces(biome, nodes_or_function_or_model, snodes,
|
|||||||
return items_added
|
return items_added
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Primary mapgen spawner, for mods that can work with air checking enabled on
|
-- Primary log read-out/mapgen spawner
|
||||||
-- a surface during the initial map read stage.
|
|
||||||
|
|
||||||
function biome_lib:generate_block_with_air_checking()
|
function biome_lib.generate_block()
|
||||||
if not biome_lib.blocklist_aircheck[1] then
|
if not biome_lib.block_log[1] then return end -- the block log is empty
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local minp = biome_lib.blocklist_aircheck[1][1]
|
local minp = biome_lib.block_log[1][1]
|
||||||
local maxp = biome_lib.blocklist_aircheck[1][2]
|
local maxp = biome_lib.block_log[1][2]
|
||||||
|
local airflag = biome_lib.block_log[1][3]
|
||||||
|
local pos_hash = minetest.hash_node_position(minp)
|
||||||
|
|
||||||
-- use the block hash as a unique key into the surface nodes
|
if not biome_lib.pos_hash then -- we need to read the maplock and get the surfaces list
|
||||||
-- tables, so that we can write the tables thread-safely.
|
biome_lib.pos_hash = {}
|
||||||
|
biome_lib.pos_hash.surface_node_list = airflag
|
||||||
local blockhash = minetest.hash_node_position(minp)
|
and minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck)
|
||||||
|
or minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_no_aircheck)
|
||||||
if not biome_lib.surface_nodes_aircheck.blockhash then -- read it into the block cache
|
biome_lib.pos_hash.action_index = 1
|
||||||
biome_lib.surface_nodes_aircheck.blockhash =
|
if #biome_lib.pos_hash.surface_node_list > 0 then
|
||||||
minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck)
|
biome_lib:dbg("Mapblock at "..minetest.pos_to_string(minp)..
|
||||||
biome_lib.actioncount_aircheck.blockhash = 1
|
" has "..#biome_lib.pos_hash.surface_node_list..
|
||||||
if #biome_lib.surface_nodes_aircheck.blockhash > 0 then
|
" surface nodes to work on (airflag="..dump(airflag)..")")
|
||||||
biome_lib:dbg("Mapblock at "..minetest.pos_to_string(minp).." added, with "..#biome_lib.surface_nodes_aircheck.blockhash.." surface nodes detected.")
|
|
||||||
end
|
end
|
||||||
|
elseif not (airflag and biome_lib.actionslist_aircheck[biome_lib.pos_hash.action_index])
|
||||||
|
and not (not airflag and biome_lib.actionslist_no_aircheck[biome_lib.pos_hash.action_index]) then
|
||||||
|
-- the block is finished, remove it
|
||||||
|
if #biome_lib.pos_hash.surface_node_list > 0 then
|
||||||
|
biome_lib:dbg("Deleted mapblock "..minetest.pos_to_string(minp).." from the block log")
|
||||||
|
end
|
||||||
|
table.remove(biome_lib.block_log, 1)
|
||||||
|
biome_lib.pos_hash = nil
|
||||||
else
|
else
|
||||||
if biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash] then
|
-- below, [1] is biome, [2] is the thing to be added
|
||||||
-- [1] is biome, [2] is node/function/model
|
local added = 0
|
||||||
local added = biome_lib:populate_surfaces(
|
if airflag then
|
||||||
biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][1],
|
if biome_lib.actionslist_aircheck[biome_lib.pos_hash.action_index] then
|
||||||
biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][2],
|
added = biome_lib.populate_surfaces(
|
||||||
biome_lib.surface_nodes_aircheck.blockhash, true)
|
biome_lib.actionslist_aircheck[biome_lib.pos_hash.action_index][1],
|
||||||
if added > 0 then
|
biome_lib.actionslist_aircheck[biome_lib.pos_hash.action_index][2],
|
||||||
biome_lib:dbg("Ran biome_lib:populate_surfaces for block at "..minetest.pos_to_string(minp)..
|
biome_lib.pos_hash.surface_node_list, true)
|
||||||
". Entry #"..biome_lib.actioncount_aircheck.blockhash.." added "..added.." items.")
|
biome_lib.pos_hash.action_index = biome_lib.pos_hash.action_index + 1
|
||||||
end
|
end
|
||||||
biome_lib.actioncount_aircheck.blockhash = biome_lib.actioncount_aircheck.blockhash + 1
|
|
||||||
else
|
else
|
||||||
table.remove(biome_lib.blocklist_aircheck, 1)
|
if biome_lib.actionslist_no_aircheck[biome_lib.pos_hash.action_index] then
|
||||||
biome_lib.surface_nodes_aircheck.blockhash = nil
|
added = biome_lib.populate_surfaces(
|
||||||
biome_lib.actioncount_aircheck.blockhash = nil
|
biome_lib.actionslist_no_aircheck[biome_lib.pos_hash.action_index][1],
|
||||||
|
biome_lib.actionslist_no_aircheck[biome_lib.pos_hash.action_index][2],
|
||||||
|
biome_lib.pos_hash.surface_node_list, false)
|
||||||
|
biome_lib.pos_hash.action_index = biome_lib.pos_hash.action_index + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
if added > 0 then
|
||||||
end
|
biome_lib:dbg("biome_lib.populate_surfaces ran on mapblock at "..
|
||||||
|
minetest.pos_to_string(minp)..". Entry #"..
|
||||||
-- Secondary mapgen spawner, for mods that require disabling of
|
(biome_lib.pos_hash.action_index-1).." added "..added.." items.")
|
||||||
-- checking for air during the initial map read stage.
|
|
||||||
|
|
||||||
function biome_lib:generate_block_no_aircheck()
|
|
||||||
if not biome_lib.blocklist_no_aircheck[1] then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local minp = biome_lib.blocklist_no_aircheck[1][1]
|
|
||||||
local maxp = biome_lib.blocklist_no_aircheck[1][2]
|
|
||||||
|
|
||||||
local blockhash = minetest.hash_node_position(minp)
|
|
||||||
|
|
||||||
if not biome_lib.surface_nodes_no_aircheck.blockhash then
|
|
||||||
biome_lib.surface_nodes_no_aircheck.blockhash =
|
|
||||||
minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_no_aircheck)
|
|
||||||
biome_lib.actioncount_no_aircheck.blockhash = 1
|
|
||||||
|
|
||||||
else
|
|
||||||
if biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash] then
|
|
||||||
biome_lib:populate_surfaces(
|
|
||||||
biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][1],
|
|
||||||
biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][2],
|
|
||||||
biome_lib.surface_nodes_no_aircheck.blockhash, false)
|
|
||||||
biome_lib.actioncount_no_aircheck.blockhash = biome_lib.actioncount_no_aircheck.blockhash + 1
|
|
||||||
else
|
|
||||||
table.remove(biome_lib.blocklist_no_aircheck, 1)
|
|
||||||
biome_lib.surface_nodes_no_aircheck.blockhash = nil
|
|
||||||
biome_lib.actioncount_no_aircheck.blockhash = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- "Play" them back, populating them with new stuff in the process
|
-- "Play" them back, populating them with new stuff in the process
|
||||||
|
|
||||||
local step_duration = tonumber(minetest.settings:get("dedicated_server_step"))
|
biome_lib.dtime_limit = tonumber(minetest.settings:get("biome_lib_dtime_limit")) or 0.5
|
||||||
|
local rr = tonumber(minetest.settings:get("biome_lib_queue_run_ratio")) or -100
|
||||||
|
|
||||||
|
biome_lib.queue_run_ratio = 100 - rr
|
||||||
|
biome_lib.entries_per_step = math.max(-rr, 1)
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
if dtime >= step_duration + 0.1 -- don't attempt to populate if lag is already too high
|
if math.random(100) > biome_lib.queue_run_ratio
|
||||||
or math.random(100) > biome_lib.queue_run_ratio
|
or dtime > biome_lib.dtime_limit then
|
||||||
or (#biome_lib.blocklist_aircheck == 0 and #biome_lib.blocklist_no_aircheck == 0) then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
for s = 1, biome_lib.entries_per_step do
|
||||||
biome_lib.globalstep_start_time = minetest.get_us_time()
|
biome_lib.generate_block()
|
||||||
biome_lib.globalstep_runtime = 0
|
|
||||||
while (#biome_lib.blocklist_aircheck > 0 or #biome_lib.blocklist_no_aircheck > 0)
|
|
||||||
and biome_lib.globalstep_runtime < 200000 do -- 0.2 seconds, in uS.
|
|
||||||
if #biome_lib.blocklist_aircheck > 0 then
|
|
||||||
biome_lib:generate_block_with_air_checking()
|
|
||||||
end
|
|
||||||
if #biome_lib.blocklist_no_aircheck > 0 then
|
|
||||||
biome_lib:generate_block_no_aircheck()
|
|
||||||
end
|
|
||||||
biome_lib.globalstep_runtime = minetest.get_us_time() - biome_lib.globalstep_start_time
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -532,26 +495,14 @@ end)
|
|||||||
-- to prevent unpopulated map areas
|
-- to prevent unpopulated map areas
|
||||||
|
|
||||||
minetest.register_on_shutdown(function()
|
minetest.register_on_shutdown(function()
|
||||||
if #biome_lib.blocklist_aircheck == 0 then
|
if #biome_lib.block_log == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
print("[biome_lib] Stand by, playing out the rest of the aircheck mapblock log")
|
print("[biome_lib] Stand by, playing out the rest of the mapblock log")
|
||||||
print("(there are "..#biome_lib.blocklist_aircheck.." entries)...")
|
print("(there are "..#biome_lib.block_log.." entries)...")
|
||||||
while #biome_lib.blocklist_aircheck > 0 do
|
while #biome_lib.block_log > 0 do
|
||||||
biome_lib:generate_block_with_air_checking(0.1)
|
biome_lib.generate_block()
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_shutdown(function()
|
|
||||||
if #biome_lib.blocklist_aircheck == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
print("[biome_lib] Stand by, playing out the rest of the no-aircheck mapblock log")
|
|
||||||
print("(there are "..#biome_lib.blocklist_no_aircheck.." entries)...")
|
|
||||||
while #biome_lib.blocklist_no_aircheck > 0 do
|
|
||||||
biome_lib:generate_block_no_aircheck(0.1)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -746,22 +697,17 @@ function biome_lib:get_nodedef_field(nodename, fieldname)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if DEBUG then
|
if DEBUG then
|
||||||
biome_lib.last_count_air = 0
|
biome_lib.last_count = 0
|
||||||
biome_lib.last_count_no_air = 0
|
|
||||||
|
|
||||||
function biome_lib.show_pending_block_counts()
|
function biome_lib.show_pending_block_count()
|
||||||
if biome_lib.last_count_air ~= #biome_lib.blocklist_aircheck
|
if biome_lib.last_count ~= #biome_lib.block_log then
|
||||||
or biome_lib.last_count_no_air ~= #biome_lib.blocklist_no_aircheck then
|
biome_lib:dbg("Pending block count: "..#biome_lib.block_log)
|
||||||
biome_lib:dbg(string.format("Pending block counts, air: %-7i no-air: %i",
|
biome_lib.last_count = #biome_lib.block_log
|
||||||
#biome_lib.blocklist_aircheck, #biome_lib.blocklist_no_aircheck))
|
|
||||||
|
|
||||||
biome_lib.last_count_air = #biome_lib.blocklist_aircheck
|
|
||||||
biome_lib.last_count_no_air = #biome_lib.blocklist_no_aircheck
|
|
||||||
end
|
end
|
||||||
minetest.after(1, biome_lib.show_pending_block_counts)
|
minetest.after(1, biome_lib.show_pending_block_count)
|
||||||
end
|
end
|
||||||
|
|
||||||
biome_lib.show_pending_block_counts()
|
biome_lib.show_pending_block_count()
|
||||||
|
|
||||||
minetest.after(0, function()
|
minetest.after(0, function()
|
||||||
print("Registered a total of "..(#biome_lib.surfaceslist_aircheck)+(#biome_lib.surfaceslist_no_aircheck).." surface types to be evaluated, spread")
|
print("Registered a total of "..(#biome_lib.surfaceslist_aircheck)+(#biome_lib.surfaceslist_no_aircheck).." surface types to be evaluated, spread")
|
||||||
|
@ -65,9 +65,7 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
|
|||||||
|
|
||||||
local bmin = {x=minx, y=miny, z=minz}
|
local bmin = {x=minx, y=miny, z=minz}
|
||||||
local bmax = {x=minx + 15, y=miny + 15, z=minz + 15}
|
local bmax = {x=minx + 15, y=miny + 15, z=minz + 15}
|
||||||
|
biome_lib.block_log[#biome_lib.block_log + 1] = { bmin, bmax, true }
|
||||||
biome_lib.blocklist_aircheck[#biome_lib.blocklist_aircheck + 1] = { bmin, bmax }
|
|
||||||
biome_lib.blocklist_no_aircheck[#biome_lib.blocklist_no_aircheck + 1] = { bmin, bmax }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user