1
0
mirror of https://github.com/mt-mods/biome_lib.git synced 2025-06-29 06:40:44 +02:00

6 Commits

Author SHA1 Message Date
ed0b23677d fix typo 2021-04-08 08:09:59 -04:00
3b35fc67c6 Periodically re-trigger the mapblock queue code if it's idle,
to give old, deferrred blocks a chance to time-out.  Needed
because if players aren't currently creating new terrain,
old blocks would never get processed, causing the block log
to only grow rather than eventually run dry (which could result
in very long shutdown times).
2021-04-08 06:33:43 -04:00
eabc053c05 If a block has to be re-checked, renew its timestamp 2021-04-07 09:12:57 -04:00
dd650da443 Allow old blocks to time-out after a while
(default 5 minutes).

Rationale: if a block is old enough, there's a very high probability
that the engine's done screwing around with its neighbors, so it's safe
to process.
2021-04-07 07:41:48 -04:00
0a34e3c7af rename debug variable and option for consistency
make global so it can be changed while running
2021-04-07 07:41:32 -04:00
07c2b1d9d4 move all settings at the top of the code
(some were scattered here and there)
2021-04-07 07:13:53 -04:00
2 changed files with 76 additions and 39 deletions

106
init.lua
View File

@ -4,12 +4,28 @@
-- Splizard's snow mod.
--
biome_lib = {}
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if minetest.global_exists("intllib") then
if intllib.make_gettext_pair then
S = intllib.make_gettext_pair()
else
S = intllib.Getter()
end
else
S = function(s) return s end
end
biome_lib.intllib = S
-- Various settings - most of these probably won't need to be changed
biome_lib = {}
biome_lib.air = {name = "air"}
biome_lib.block_log = {}
biome_lib.block_recheck_list = {}
biome_lib.run_block_recheck_list = false
biome_lib.actionslist_aircheck = {}
biome_lib.actionslist_no_aircheck = {}
@ -54,28 +70,22 @@ biome_lib.default_wet_surfaces = c3 and tableize(c3) or {"default:dirt", "defaul
biome_lib.default_ground_nodes = c4 and tableize(c4) or {"default:dirt_with_grass"}
biome_lib.default_grow_nodes = c5 and tableize(c5) or {"default:dirt_with_grass"}
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if minetest.global_exists("intllib") then
if intllib.make_gettext_pair then
S = intllib.make_gettext_pair()
else
S = intllib.Getter()
end
else
S = function(s) return s end
end
biome_lib.intllib = S
biome_lib.debug_log_level = tonumber(minetest.settings:get("biome_lib_debug_log_level")) or 0
local DEBUG_LEVEL = tonumber(minetest.settings:get("biome_lib_debug")) or 0
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)
function biome_lib.dbg(msg, level)
local l = tonumber(level) or 0
if DEBUG_LEVEL >= l then
print("[Biome Lib] "..msg)
minetest.log("verbose", "[Biome Lib] "..msg)
end
end
-- the timer that manages the block timeout is in microseconds, but the timer
-- that manages the queue wakeup call has to be in seconds, and works best if
-- it takes a little longer than the block timeout interval.
local t = tonumber(minetest.settings:get("biome_lib_block_timeout")) or 300
biome_lib.block_timeout = t * 1000000
biome_lib.block_queue_wakeup_time = t * 1.1
local time_speed = tonumber(minetest.settings:get("time_speed"))
biome_lib.plantlife_seed_diff = 329 -- needs to be global so other mods can see it
@ -94,7 +104,6 @@ local humidity_persistence = 0.5
local humidity_scale = 250
local time_scale = 1
local time_speed = tonumber(minetest.settings:get("time_speed"))
if time_speed and time_speed > 0 then
time_scale = 72 / time_speed
@ -107,6 +116,14 @@ biome_lib.perlin_humidity = PerlinNoise(humidity_seeddiff, humidity_octaves, hum
-- Local functions
function biome_lib.dbg(msg, level)
local l = tonumber(level) or 0
if biome_lib.debug_log_level >= l then
print("[Biome Lib] "..msg)
minetest.log("verbose", "[Biome Lib] "..msg)
end
end
local function get_biome_data(pos, perlin_fertile)
local fertility = perlin_fertile:get_2d({x=pos.x, y=pos.z})
@ -440,9 +457,6 @@ local function confirm_block_surroundings(p)
return true
end
biome_lib.block_recheck_list = {}
biome_lib.run_block_recheck_list = false
function biome_lib.generate_block(shutting_down)
if shutting_down then
@ -472,11 +486,13 @@ function biome_lib.generate_block(shutting_down)
local pos_hash = minetest.hash_node_position(minp)
if not biome_lib.pos_hash then -- we need to read the maplock and get the surfaces list
local now = minetest.get_us_time()
biome_lib.pos_hash = {}
minetest.load_area(minp)
if not confirm_block_surroundings(minp)
and not shutting_down then -- if any neighbors appear not to be loaded, skip this block for now
and not shutting_down
and (blocklog[1][4] + biome_lib.block_timeout) > now then -- if any neighbors appear not to be loaded and the block hasn't expired yet, defer it
blocklog[1][4] = now -- reset the timer, give this block more time to "cook"
if biome_lib.run_block_recheck_list then
biome_lib.block_log[#biome_lib.block_log + 1] = table.copy(biome_lib.block_recheck_list[1])
table.remove(biome_lib.block_recheck_list, 1)
@ -537,11 +553,6 @@ end
-- "Play" them back, populating them with new stuff in the process
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)
if not biome_lib.block_log[1] then return end -- the block log is empty
@ -551,6 +562,25 @@ minetest.register_globalstep(function(dtime)
end
end)
-- Periodically wake-up the queue to give old blocks a chance to time-out
-- if the player isn't currently exploring (i.e. they're just playing in one area)
function biome_lib.wake_up_queue()
if #biome_lib.block_recheck_list > 0
and #biome_lib.block_log == 0 then
-- we move the second element and not the first because we can't be
-- sure if the recheck list's first item is the one currently acted upon
-- (else it'd be the first item in the main block log)
biome_lib.block_log = table.copy(biome_lib.block_recheck_list)
biome_lib.block_recheck_list = {}
biome_lib.queue_idle_flag = false
biome_lib.dbg("Woke-up the map queue to give old blocks a chance to time-out.", 3)
end
minetest.after(biome_lib.block_queue_wakeup_time, biome_lib.wake_up_queue)
end
biome_lib.wake_up_queue()
-- Play out the entire log all at once on shutdown
-- to prevent unpopulated map areas
@ -763,17 +793,23 @@ function biome_lib:get_nodedef_field(nodename, fieldname)
return minetest.registered_nodes[nodename][fieldname]
end
if DEBUG_LEVEL >= 3 then
if biome_lib.debug_log_level >= 3 then
biome_lib.last_count = 0
function biome_lib.show_pending_block_count()
if biome_lib.last_count ~= #biome_lib.block_log then
biome_lib.dbg("Pending block count: "..(#biome_lib.block_log + #biome_lib.block_recheck_list), 3)
biome_lib.dbg(string.format("Pending block counts - ready to process: %-8icurrently deferred: %i",
#biome_lib.block_log, #biome_lib.block_recheck_list), 3)
biome_lib.last_count = #biome_lib.block_log
biome_lib.queue_idle_flag = false
elseif not biome_lib.queue_idle_flag then
if #biome_lib.block_recheck_list > 0 then
biome_lib.dbg("Mapblock queue only contains blocks that can't yet be processed.", 3)
biome_lib.dbg("Idling the queue until new mapblocks show up.", 3)
biome_lib.dbg("Idling the queue until new blocks arrive or the next wake-up call occurs.", 3)
else
biome_lib.dbg("Mapblock queue has run dry.", 3)
biome_lib.dbg("Idling the queue until new blocks arrive.", 3)
end
biome_lib.queue_idle_flag = true
end
minetest.after(1, biome_lib.show_pending_block_count)

View File

@ -56,6 +56,7 @@ end
-- split into individual mapblocks to reduce lag
minetest.register_on_generated(function(minp, maxp, blockseed)
local timestamp = minetest.get_us_time()
for x = 0, 4 do
local minx = minp.x + x*16
for y = 0, 4 do
@ -65,8 +66,8 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
local bmin = {x=minx, y=miny, z=minz}
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.block_log[#biome_lib.block_log + 1] = { bmin, bmax, false }
biome_lib.block_log[#biome_lib.block_log + 1] = { bmin, bmax, true, timestamp }
biome_lib.block_log[#biome_lib.block_log + 1] = { bmin, bmax, false, timestamp }
end
end
end