Spawn testing baseline

This commit is contained in:
Mateusz Uzdowski 2024-01-10 08:41:34 +13:00
parent d285a48fed
commit f4bcb6e4df
1 changed files with 134 additions and 0 deletions

View File

@ -1093,11 +1093,145 @@ if mobs_spawn then
end
end
local test_result = {}
local function test_spawn_a_mob_4(pos, cap_space_hostile, cap_space_non_hostile)
--create a disconnected clone of the spawn dictionary, prevents memory leak
local mob_library_worker_table = table_copy(spawn_dictionary)
local spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES)
if not spawning_position then
minetest.log("action", "[Mobs spawn] Cannot find a valid spawn position after retries: " .. FIND_SPAWN_POS_RETRIES)
return
end
local mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("spawn_class", spawning_position)
--output_mob_stats(mob_counts_close, total_mobs)
--output_mob_stats(mob_counts_wide)
--grab mob that fits into the spawning location
--randomly grab a mob, don't exclude any possibilities
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
local noise = perlin_noise:get_3d(spawning_position)
local current_summary_chance = summary_chance
table.shuffle(mob_library_worker_table)
while #mob_library_worker_table > 0 do
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
local mob_index = 1
local mob_chance = mob_library_worker_table[mob_index].chance
local step_chance = mob_chance
while step_chance < mob_chance_offset do
mob_index = mob_index + 1
mob_chance = mob_library_worker_table[mob_index].chance
step_chance = step_chance + mob_chance
end
--minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance)
local mob_def = mob_library_worker_table[mob_index]
if mob_def and mob_def.name and minetest.registered_entities[mob_def.name] then
local mob_def_ent = minetest.registered_entities[mob_def.name]
local mob_spawn_class = mob_def_ent.spawn_class
local cap_space_available = mob_cap_space (spawning_position, mob_spawn_class, mob_counts_close, mob_counts_wide, cap_space_hostile, cap_space_non_hostile)
if cap_space_available > 0 then
--mcl_log("Cap space available")
-- Spawn caps for animals and water creatures fill up rapidly. Need to throttle this somewhat
-- for performance and for early game challenge. We don't want to reduce hostiles though.
local spawn_hostile = (mob_spawn_class == "hostile")
local spawn_passive = (mob_spawn_class ~= "hostile") and math.random(100) < peaceful_percentage_spawned
--mcl_log("Spawn_passive: " .. tostring(spawn_passive))
--mcl_log("Spawn_hostile: " .. tostring(spawn_hostile))
if (spawn_hostile or spawn_passive) and spawn_check(spawning_position,mob_def) then
if mob_def.type_of_spawning == "water" then
spawning_position = get_water_spawn(spawning_position)
if not spawning_position then
minetest.log("warning","[mcl_mobs] no water spawn for mob "..mob_def.name.." found at "..minetest.pos_to_string(vector.round(pos)))
return
end
end
if mob_def_ent.can_spawn and not mob_def_ent.can_spawn(spawning_position) then
minetest.log("warning","[mcl_mobs] mob "..mob_def.name.." refused to spawn at "..minetest.pos_to_string(vector.round(spawning_position)))
return
end
--everything is correct, spawn mob
local spawn_in_group = mob_def_ent.spawn_in_group or 4
local spawn_group_hostile = (mob_spawn_class == "hostile") and (math.random(100) < hostile_group_percentage_spawned)
local spawn_group_passive = (mob_spawn_class ~= "hostile") and (math.random(100) < peaceful_group_percentage_spawned)
mcl_log("spawn_group_hostile: " .. tostring(spawn_group_hostile))
mcl_log("spawn_group_passive: " .. tostring(spawn_group_passive))
if spawn_in_group and (spawn_group_hostile or spawn_group_passive) then
local group_min = mob_def_ent.spawn_in_group_min or 1
if not group_min then group_min = 1 end
local amount_to_spawn = math.random(group_min, spawn_in_group)
if not test_result[mob_def.name] then
test_result[mob_def.name] = amount_to_spawn
else
test_result[mob_def.name] = test_result[mob_def.name] + amount_to_spawn
end
else
if not test_result[mob_def.name] then
test_result[mob_def.name] = 1
else
test_result[mob_def.name] = test_result[mob_def.name] + 1
end
end
else
--mcl_log("Spawn check failed")
end
else
--mcl_log("Cap space full")
end
end
current_summary_chance = current_summary_chance - mob_chance
table_remove(mob_library_worker_table, mob_index)
end
end
minetest.register_chatcommand("testmobspawn", {
description = S("Test mob spawn"),
privs = { debug = true },
func = function(name, param)
test_result = {}
local player = minetest.get_player_by_name(name)
if not player then return false, "Player not found" end
local total_mobs, total_non_hostile, total_hostile = count_mobs_total_cap()
local cap_space_hostile = math.max(mob_cap.global_hostile - total_hostile, 0)
local cap_space_non_hostile = math.max(mob_cap.global_non_hostile - total_non_hostile, 0)
for i=1,10000 do
test_spawn_a_mob_4(player:get_pos(), cap_space_hostile, cap_space_non_hostile)
end
minetest.log("action",string.format("mob_name,total_10k_spawns,avg_per_spawn"))
for m,c in pairs(test_result) do
minetest.log("action",string.format("%s,%d,%.2f", m, c, c/10000))
end
return true, "Done."
end,
})
--MAIN LOOP
local timer = 0
minetest.register_globalstep(function(dtime)
if true then return end
timer = timer + dtime
if timer < WAIT_FOR_SPAWN_ATTEMPT then return end