Change main spawning look to use adaptive delay based on last run with maximum period of 2.5 seconds, put some logging behind a flag, remove unused constants

This commit is contained in:
teknomunk 2024-07-07 19:57:13 -05:00
parent b6c5893a30
commit cb76c3da36

View file

@ -51,9 +51,8 @@ local dbg_spawn_counts = {}
local remove_far = true local remove_far = true
local WAIT_FOR_SPAWN_ATTEMPT = 0.25 local MAX_SPAWN_CYCLE_TIME = 2.5
local FIND_SPAWN_POS_RETRIES = 1 local FIND_SPAWN_POS_RETRIES = 1
local FIND_SPAWN_POS_RETRIES_SUCCESS_RESPIN = 8
local MOB_SPAWN_ZONE_INNER = 24 local MOB_SPAWN_ZONE_INNER = 24
local MOB_SPAWN_ZONE_MIDDLE = 32 local MOB_SPAWN_ZONE_MIDDLE = 32
@ -1054,7 +1053,7 @@ if mobs_spawn then
local spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES) local spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES)
if not spawning_position then if not spawning_position then
fail_count = fail_count + 1 fail_count = fail_count + 1
if fail_count > 16 then if logging and fail_count > 16 then
minetest.log("action", "[Mobs spawn] Cannot find a valid spawn position in last 16 attemtps") minetest.log("action", "[Mobs spawn] Cannot find a valid spawn position in last 16 attemtps")
end end
return return
@ -1130,15 +1129,7 @@ if mobs_spawn then
return mcl_mobs.spawn(spawning_position, mob_def.name) return mcl_mobs.spawn(spawning_position, mob_def.name)
end end
--MAIN LOOP local function attempt_spawn()
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < WAIT_FOR_SPAWN_ATTEMPT then return end
timer = 0
local start_time_us = minetest.get_us_time()
local players = get_connected_players() local players = get_connected_players()
local total_mobs, total_non_hostile, total_hostile = count_mobs_total_cap() local total_mobs, total_non_hostile, total_hostile = count_mobs_total_cap()
@ -1149,10 +1140,6 @@ if mobs_spawn then
if total_mobs > mob_cap.total or total_mobs > #players * mob_cap.player then if total_mobs > mob_cap.total or total_mobs > #players * mob_cap.player then
minetest.log("action","[mcl_mobs] global mob cap reached. no cycle spawning.") minetest.log("action","[mcl_mobs] global mob cap reached. no cycle spawning.")
local took = (minetest.get_us_time() - start_time_us)
if took > debug_time_threshold then
minetest.log("action","[mcl_mobs] took "..took.." us")
end
return return
end --mob cap per player end --mob cap per player
@ -1164,10 +1151,34 @@ if mobs_spawn then
spawn_a_mob(pos, cap_space_hostile, cap_space_non_hostile) spawn_a_mob(pos, cap_space_hostile, cap_space_non_hostile)
end end
end end
end
local function fixed_timeslice(timer, dtime, timeslice_us, handler)
timer = timer - dtime
if timer > 0 then return timer, 0 end
-- Time the function
local start_time_us = minetest.get_us_time()
handler()
local stop_time_us = minetest.get_us_time()
-- Measure how long this took and calculate the time until the next call
local took = stop_time_us - start_time_us
timer = took / timeslice_us
return timer, took
end
--MAIN LOOP
local timer = 0
minetest.register_globalstep(function(dtime)
local next_spawn, took = fixed_timeslice(timer, dtime, 1000, attempt_spawn)
timer = next_spawn
if timer > MAX_SPAWN_CYCLE_TIME then timer = MAX_SPAWN_CYCLE_TIME end
local took = (minetest.get_us_time() - start_time_us)
if took > debug_time_threshold then if took > debug_time_threshold then
minetest.log("action","[mcl_mobs] took "..took.." us") minetest.log("action","[mcl_mobs] took "..took.." us")
minetest.log("Next spawn attempt in "..tostring(timer))
end end
end) end)
end end