Fix large steps caused by uninterruptable spawn seed initialization within activation
Update version number to 0.0.8master
parent
1a56f668d4
commit
5965e4a9de
2
api.lua
2
api.lua
|
@ -25,7 +25,7 @@ function adv_spawning.register(spawner_name,spawning_def)
|
||||||
end
|
end
|
||||||
|
|
||||||
adv_spawning.spawner_definitions[spawner_name] = spawning_def
|
adv_spawning.spawner_definitions[spawner_name] = spawning_def
|
||||||
print("ADV_SPAWNING: registering spawner \"" .. spawner_name .. "\"")
|
adv_spawning.dbg_log(0, "registering spawner \"" .. spawner_name .. "\"")
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
|
6
init.lua
6
init.lua
|
@ -8,10 +8,10 @@
|
||||||
--
|
--
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
local version = "0.0.7"
|
local version = "0.0.8"
|
||||||
|
|
||||||
if adv_spawning ~= nil then
|
if adv_spawning ~= nil then
|
||||||
core.log("error","MOD: adv_spawning requires adv_spawning variable to be available")
|
core.log("error", "MOD: adv_spawning requires adv_spawning variable to be available")
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -31,4 +31,4 @@ dofile (adv_modpath .. "/spawn_seed.lua")
|
||||||
|
|
||||||
adv_spawning.initialize()
|
adv_spawning.initialize()
|
||||||
|
|
||||||
core.log("action","Advanced spawning mod version " .. version .. " loaded")
|
core.log("action", "Advanced spawning mod version " .. version .. " loaded")
|
||||||
|
|
90
internal.lua
90
internal.lua
|
@ -63,6 +63,8 @@ function adv_spawning.initialize()
|
||||||
adv_spawning.spawner_y_offset = 20
|
adv_spawning.spawner_y_offset = 20
|
||||||
adv_spawning.max_spawning_frequency_hz = 5
|
adv_spawning.max_spawning_frequency_hz = 5
|
||||||
adv_spawning.max_mapgen_tries_per_step = 3
|
adv_spawning.max_mapgen_tries_per_step = 3
|
||||||
|
adv_spawning.spawner_warned = {}
|
||||||
|
adv_spawning.loglevel = 0
|
||||||
|
|
||||||
adv_spawning.active_range = minetest.setting_get("active_block_range")
|
adv_spawning.active_range = minetest.setting_get("active_block_range")
|
||||||
|
|
||||||
|
@ -154,7 +156,9 @@ function adv_spawning.mapgen_hook(minp,maxp,blockseed)
|
||||||
if x > minp.x and
|
if x > minp.x and
|
||||||
y > minp.y and
|
y > minp.y and
|
||||||
z > minp.z then
|
z > minp.z then
|
||||||
adv_spawning.quota_leave()
|
if not adv_spawning.quota_leave() then
|
||||||
|
adv_spawning.dbg_log(2, "mapgen_hook did use way too much time 1")
|
||||||
|
end
|
||||||
minetest.add_entity({x=x,y=y,z=z},"adv_spawning:spawn_seed")
|
minetest.add_entity({x=x,y=y,z=z},"adv_spawning:spawn_seed")
|
||||||
adv_spawning.quota_enter(true)
|
adv_spawning.quota_enter(true)
|
||||||
adv_spawning.log("info", "adv_spawning: adding spawner entity at "
|
adv_spawning.log("info", "adv_spawning: adding spawner entity at "
|
||||||
|
@ -167,7 +171,9 @@ function adv_spawning.mapgen_hook(minp,maxp,blockseed)
|
||||||
end
|
end
|
||||||
|
|
||||||
adv_spawning.queue_mapgen_jobs(minp,maxp)
|
adv_spawning.queue_mapgen_jobs(minp,maxp)
|
||||||
adv_spawning.quota_leave()
|
if not adv_spawning.quota_leave() then
|
||||||
|
adv_spawning.dbg_log(2, "mapgen_hook did use way too much time 2")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
assert("Mapgen hook could not be executed" == nil)
|
assert("Mapgen hook could not be executed" == nil)
|
||||||
end
|
end
|
||||||
|
@ -221,7 +227,9 @@ function adv_spawning.global_onstep(dtime)
|
||||||
|
|
||||||
if adv_spawning.quota_enter() then
|
if adv_spawning.quota_enter() then
|
||||||
adv_spawning.handle_mapgen_spawning()
|
adv_spawning.handle_mapgen_spawning()
|
||||||
adv_spawning.quota_leave()
|
if not adv_spawning.quota_leave() then
|
||||||
|
adv_spawning.dbg_log(2, "globalstep took to long")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -233,25 +241,34 @@ end
|
||||||
function adv_spawning.quota_enter(force)
|
function adv_spawning.quota_enter(force)
|
||||||
--ONLY enable this one if you're quite sure there aren't bugs in
|
--ONLY enable this one if you're quite sure there aren't bugs in
|
||||||
--assert(adv_spawning.quota_starttime == nil)
|
--assert(adv_spawning.quota_starttime == nil)
|
||||||
|
local retval = false
|
||||||
|
|
||||||
if adv_spawning.quota_left <= 0 then
|
if adv_spawning.quota_left <= 0 then
|
||||||
|
|
||||||
if force == true then
|
if force == true then
|
||||||
print("Quota: task is too important to skip do it anyway," ..
|
if adv_spawning.quota_left < -10 then
|
||||||
" quota already passed by: " ..
|
adv_spawning.dbg_log(1, "Quota: task is too important to skip do it anyway," ..
|
||||||
string.format("%.2f ms",adv_spawning.quota_left))
|
" quota already passed by: " ..
|
||||||
else
|
string.format("%.2f ms",adv_spawning.quota_left))
|
||||||
if adv_spawning.quota_left * -2 > adv_spawning.quota_reload then
|
end
|
||||||
print("Quota: no time left: " ..
|
retval = true
|
||||||
|
else
|
||||||
|
if adv_spawning.quota_left * -2 > adv_spawning.quota_reload then
|
||||||
|
adv_spawning.dbg_log(1, "Quota: no time left: " ..
|
||||||
string.format("%.2f ms",adv_spawning.quota_left))
|
string.format("%.2f ms",adv_spawning.quota_left))
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
retval = true
|
||||||
end
|
end
|
||||||
-- print("+++++++++++++++++Quota enter+++++++++++++++++++++")
|
-- print("+++++++++++++++++Quota enter+++++++++++++++++++++")
|
||||||
-- print(debug.traceback())
|
-- print(debug.traceback())
|
||||||
-- print("+++++++++++++++++++++++++++++++++++++++++++++++++")
|
-- print("+++++++++++++++++++++++++++++++++++++++++++++++++")
|
||||||
adv_spawning.quota_starttime = adv_spawning.gettime()
|
if retval then
|
||||||
return true
|
adv_spawning.quota_starttime = adv_spawning.gettime()
|
||||||
|
end
|
||||||
|
|
||||||
|
return retval
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -301,8 +318,15 @@ function adv_spawning.quota_leave()
|
||||||
else
|
else
|
||||||
adv_spawning.quota_left = adv_spawning.quota_left - time_passed
|
adv_spawning.quota_left = adv_spawning.quota_left - time_passed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (adv_spawning.quota_left < -adv_spawning.quota_reload) then
|
||||||
|
adv_spawning.dbg_log(1, "excessive overtime, quota remaining: " .. adv_spawning.quota_left)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
adv_spawning.quota_starttime = nil
|
adv_spawning.quota_starttime = nil
|
||||||
--print("-----------------Quota leave----------------------")
|
--print("-----------------Quota leave----------------------")
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -1296,7 +1320,6 @@ function adv_spawning.check_active_block(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1338,11 +1361,16 @@ function adv_spawning.handle_mapgen_spawning()
|
||||||
tries < adv_spawning.max_mapgen_tries_per_step and
|
tries < adv_spawning.max_mapgen_tries_per_step and
|
||||||
(not adv_spawning.time_over(10)) )do
|
(not adv_spawning.time_over(10)) )do
|
||||||
|
|
||||||
|
local single_spawn_check = adv_spawning.gettime()
|
||||||
|
|
||||||
local retval,permanent_error = adv_spawning.handlespawner(toprocess.spawner,
|
local retval,permanent_error = adv_spawning.handlespawner(toprocess.spawner,
|
||||||
{x=0,y=0,z=0},
|
{x=0,y=0,z=0},
|
||||||
toprocess.minp,
|
toprocess.minp,
|
||||||
toprocess.maxp,
|
toprocess.maxp,
|
||||||
true)
|
true)
|
||||||
|
|
||||||
|
local delta = adv_spawning.gettime() - adv_spawning.quota_starttime
|
||||||
|
|
||||||
if retval then
|
if retval then
|
||||||
toprocess.spawntotal = toprocess.spawntotal -1
|
toprocess.spawntotal = toprocess.spawntotal -1
|
||||||
end
|
end
|
||||||
|
@ -1421,3 +1449,37 @@ function adv_spawning.dump_area(minp,maxp)
|
||||||
print("")
|
print("")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- @function [parent=#adv_spawning] check_time
|
||||||
|
-- @param starttime time since when to check
|
||||||
|
-- @param checkid name of this check
|
||||||
|
--
|
||||||
|
-- @return current time for next check
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function adv_spawning.check_time(starttime, checkid)
|
||||||
|
local currenttime = adv_spawning.gettime()
|
||||||
|
local delta = currenttime - starttime
|
||||||
|
|
||||||
|
if (delta > adv_spawning.quota_reload) then
|
||||||
|
if adv_spawning.spawner_warned[checkid] ~= true then
|
||||||
|
adv_spawning.dbg_log(1, "spawner " .. checkid ..
|
||||||
|
"\n\texceeded more then full reload time on init (" .. delta .. " ms)." ..
|
||||||
|
"\n\tFix it as it will cause major lag on mapgen!")
|
||||||
|
adv_spawning.spawner_warned[checkid] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return currenttime
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- @function [parent=#adv_spawning] dbg_log
|
||||||
|
-- @param loglevel level print it
|
||||||
|
-- @param message message to print
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function adv_spawning.dbg_log(loglevel, message)
|
||||||
|
if (adv_spawning.loglevel >= loglevel ) then
|
||||||
|
core.log("action", "ADV_SPAWNING: " .. message)
|
||||||
|
end
|
||||||
|
end
|
|
@ -25,6 +25,11 @@ function adv_spawning.seed_step(self,dtime)
|
||||||
if (self.mydtime < 1/adv_spawning.max_spawning_frequency_hz) then
|
if (self.mydtime < 1/adv_spawning.max_spawning_frequency_hz) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--check if we did finish initialization of our spawner list by now
|
||||||
|
if not adv_spawning.seed_scan_for_applyable_spawners(self) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if adv_spawning.quota_enter() then
|
if adv_spawning.quota_enter() then
|
||||||
self.pending_spawners = {}
|
self.pending_spawners = {}
|
||||||
|
@ -39,12 +44,14 @@ function adv_spawning.seed_step(self,dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
local per_step_count = 0
|
local per_step_count = 0
|
||||||
|
local key = nil
|
||||||
|
|
||||||
while #self.pending_spawners > 0 and
|
while #self.pending_spawners > 0 and
|
||||||
per_step_count < adv_spawning.max_spawns_per_spawner do
|
per_step_count < adv_spawning.max_spawns_per_spawner and
|
||||||
|
adv_spawning.time_over(10) do
|
||||||
|
|
||||||
local rand_spawner = math.random(1,#self.pending_spawners)
|
local rand_spawner = math.random(1,#self.pending_spawners)
|
||||||
local key = self.pending_spawners[rand_spawner]
|
key = self.pending_spawners[rand_spawner]
|
||||||
|
|
||||||
local tries = 1
|
local tries = 1
|
||||||
|
|
||||||
|
@ -63,7 +70,9 @@ function adv_spawning.seed_step(self,dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
--check quota again
|
--check quota again
|
||||||
adv_spawning.quota_leave()
|
if not adv_spawning.quota_leave() then
|
||||||
|
adv_spawning.dbg_log(2, "spawner " .. key .. " did use way too much time")
|
||||||
|
end
|
||||||
if not adv_spawning.quota_enter() then
|
if not adv_spawning.quota_enter() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -76,9 +85,11 @@ function adv_spawning.seed_step(self,dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if (#self.pending_spawners > 0) then
|
-- if (#self.pending_spawners > 0) then
|
||||||
-- print("Handled " .. per_step_count .. " spawners, spawners left: " .. #self.pending_spawners)
|
-- adv_spawning.dbg_log(3, "Handled " .. per_step_count .. " spawners, spawners left: " .. #self.pending_spawners)
|
||||||
-- end
|
-- end
|
||||||
adv_spawning.quota_leave()
|
if not adv_spawning.quota_leave() then
|
||||||
|
adv_spawning.dbg_log(2, "spawner " .. key .. " did use way too much time")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -103,13 +114,14 @@ function adv_spawning.seed_activate(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
adv_spawning.seed_validate_spawndata(self)
|
adv_spawning.seed_validate_spawndata(self)
|
||||||
|
|
||||||
adv_spawning.seed_scan_for_applyable_spawners(self)
|
|
||||||
|
|
||||||
self.pending_spawners = {}
|
self.pending_spawners = {}
|
||||||
|
self.initialized_spawners = 0
|
||||||
self.activated = true
|
self.activated = true
|
||||||
|
|
||||||
adv_spawning.quota_leave()
|
if not adv_spawning.quota_leave() then
|
||||||
|
adv_spawning.dbg_log(2, "on activate " .. self.name .. " did use way too much time")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -208,9 +220,27 @@ end
|
||||||
-- @return true/false
|
-- @return true/false
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function adv_spawning.seed_scan_for_applyable_spawners(self)
|
function adv_spawning.seed_scan_for_applyable_spawners(self)
|
||||||
|
|
||||||
|
if self.initialized_spawners >= #adv_spawning.spawner_definitions then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local runindex = 0
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
for key,value in pairs(adv_spawning.spawner_definitions) do
|
for key,value in pairs(adv_spawning.spawner_definitions) do
|
||||||
|
if not adv_spawning.quota_enter() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local starttime = adv_spawning.gettime()
|
||||||
local continue = false
|
local continue = false
|
||||||
|
|
||||||
|
if runindex >= self.initialized_spawners then
|
||||||
|
self.initialized_spawners = self.initialized_spawners + 1
|
||||||
|
else
|
||||||
|
continue = true
|
||||||
|
end
|
||||||
|
|
||||||
|
runindex = runindex + 1
|
||||||
|
|
||||||
--check if cyclic spawning is enabled
|
--check if cyclic spawning is enabled
|
||||||
if not continue and
|
if not continue and
|
||||||
|
@ -234,6 +264,7 @@ function adv_spawning.seed_scan_for_applyable_spawners(self)
|
||||||
continue = true
|
continue = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
starttime = adv_spawning.check_time(starttime, key .. " at spawn range check")
|
||||||
|
|
||||||
--check for presence of environment
|
--check for presence of environment
|
||||||
if not continue then
|
if not continue then
|
||||||
|
@ -246,6 +277,7 @@ function adv_spawning.seed_scan_for_applyable_spawners(self)
|
||||||
continue = false
|
continue = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
starttime = adv_spawning.check_time(starttime, key .. " at environment check")
|
||||||
|
|
||||||
if not continue then
|
if not continue then
|
||||||
self.spawning_data[key] = value.spawn_interval * math.random()
|
self.spawning_data[key] = value.spawn_interval * math.random()
|
||||||
|
@ -253,4 +285,6 @@ function adv_spawning.seed_scan_for_applyable_spawners(self)
|
||||||
self.spawning_data[key] = nil
|
self.spawning_data[key] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return self.initialized_spawners == #adv_spawning.spawner_definitions
|
||||||
end
|
end
|
|
@ -19,13 +19,13 @@ function adv_spawning.verify_check_entities_around(entities_around)
|
||||||
for i=1,#entities_around,1 do
|
for i=1,#entities_around,1 do
|
||||||
|
|
||||||
if type(entities_around[i].distance) ~= "number" then
|
if type(entities_around[i].distance) ~= "number" then
|
||||||
print("ADV_SPAWNING: missing distance in entities_around definition")
|
adv_spawning.dbg_log(0, "missing distance in entities_around definition")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if entities_around[i].type ~= "MIN" and
|
if entities_around[i].type ~= "MIN" and
|
||||||
entities_around[i].type ~= "MAX" then
|
entities_around[i].type ~= "MAX" then
|
||||||
print("ADV_SPAWNING: invalid type \"" ..
|
adv_spawning.dbg_log(0, "invalid type \"" ..
|
||||||
dump(entities_around[i].type) ..
|
dump(entities_around[i].type) ..
|
||||||
"\" in entities_around definition")
|
"\" in entities_around definition")
|
||||||
return false
|
return false
|
||||||
|
@ -46,13 +46,13 @@ function adv_spawning.verify_check_nodes_around(nodes_around)
|
||||||
for i=1,#nodes_around,1 do
|
for i=1,#nodes_around,1 do
|
||||||
|
|
||||||
if type(nodes_around[i].distance) ~= "number" then
|
if type(nodes_around[i].distance) ~= "number" then
|
||||||
print("ADV_SPAWNING: missing distance in entities_around definition")
|
adv_spawning.dbg_log(0, "missing distance in entities_around definition")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if nodes_around[i].type ~= "MIN" and
|
if nodes_around[i].type ~= "MIN" and
|
||||||
nodes_around[i].type ~= "MAX" then
|
nodes_around[i].type ~= "MAX" then
|
||||||
print("ADV_SPAWNING: invalid type \"" ..
|
adv_spawning.dbg_log(0, "invalid type \"" ..
|
||||||
dump(nodes_around[i].type) ..
|
dump(nodes_around[i].type) ..
|
||||||
"\" in entities_around definition")
|
"\" in entities_around definition")
|
||||||
return false
|
return false
|
||||||
|
@ -60,7 +60,7 @@ function adv_spawning.verify_check_nodes_around(nodes_around)
|
||||||
|
|
||||||
if nodes_around[i].name == nil or
|
if nodes_around[i].name == nil or
|
||||||
type(nodes_around[i].name) ~= "table" then
|
type(nodes_around[i].name) ~= "table" then
|
||||||
print("ADV_SPAWNING: invalid type of name \"" ..
|
adv_spawning.dbg_log(0, "invalid type of name \"" ..
|
||||||
type(nodes_around[i].name) .. "\"" .. " Data: " ..
|
type(nodes_around[i].name) .. "\"" .. " Data: " ..
|
||||||
dump(nodes_around[i].name) ..
|
dump(nodes_around[i].name) ..
|
||||||
" in nodes_around definition")
|
" in nodes_around definition")
|
||||||
|
|
|
@ -133,22 +133,22 @@ adv_spawning.register("some_bogus_entity_4",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
minetest.register_chatcommand("stats",
|
minetest.register_chatcommand("adv_stats",
|
||||||
{
|
{
|
||||||
params = "",
|
params = "",
|
||||||
description = "show advanced spawning satistics" ,
|
description = "print advanced spawning satistics to logfile" ,
|
||||||
func = function()
|
func = function()
|
||||||
local stats = adv_spawning.get_statistics()
|
local stats = adv_spawning.get_statistics()
|
||||||
|
|
||||||
print("Adv. Spawning stats:")
|
adv_spawning.dbg_log(0, "Adv. Spawning stats:")
|
||||||
print("----------------------------------------")
|
adv_spawning.dbg_log(0, "----------------------------------------")
|
||||||
print("Spawners added: " .. stats.session.spawners_created)
|
adv_spawning.dbg_log(0, "Spawners added: " .. stats.session.spawners_created)
|
||||||
print("Spawnees added: " .. stats.session.entities_created)
|
adv_spawning.dbg_log(0, "Spawnees added: " .. stats.session.entities_created)
|
||||||
print("")
|
adv_spawning.dbg_log(0, "")
|
||||||
print("Longest step: " .. stats.step.max)
|
adv_spawning.dbg_log(0, "Longest step: " .. stats.step.max)
|
||||||
print("")
|
adv_spawning.dbg_log(0, "")
|
||||||
print("Current load: " .. stats.load.cur)
|
adv_spawning.dbg_log(0, "Current load: " .. stats.load.cur)
|
||||||
print("Average load: " .. stats.load.avg)
|
adv_spawning.dbg_log(0, "Average load: " .. stats.load.avg)
|
||||||
print("Maximum load: " .. stats.load.max)
|
adv_spawning.dbg_log(0, "Maximum load: " .. stats.load.max)
|
||||||
end
|
end
|
||||||
})
|
})
|
Loading…
Reference in New Issue