From 402e4e7b790835e847349212e5703d6a302ee991 Mon Sep 17 00:00:00 2001 From: bakawun Date: Thu, 23 Nov 2023 00:11:13 +0100 Subject: [PATCH 1/6] Spawning: fix random weighted choice --- mods/ENTITIES/mcl_mobs/spawning.lua | 40 +++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) mode change 100644 => 100755 mods/ENTITIES/mcl_mobs/spawning.lua diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua old mode 100644 new mode 100755 index 885391759..16ab73618 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -613,8 +613,8 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ spawn_dictionary[key]["check_position"] = check_position summary_chance = summary_chance + chance -end +end local two_pi = 2 * math.pi local function get_next_mob_spawn_pos(pos) @@ -973,9 +973,21 @@ if mobs_spawn then return spawning_position end + local cumulative_chance = nil + local mob_library_worker_table = nil + local function initialize_spawn_data() + if not mob_library_worker_table then + mob_library_worker_table = table_copy(spawn_dictionary) + end + if not cumulative_chance then + cumulative_chance = 0 + for k, v in pairs(mob_library_worker_table) do + cumulative_chance = cumulative_chance + v.chance + end + end + end + local function spawn_a_mob(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 @@ -992,18 +1004,25 @@ if mobs_spawn then perlin_noise = perlin_noise or minetest_get_perlin(noise_params) local noise = perlin_noise:get_3d(spawning_position) local current_summary_chance = summary_chance + local spawn_loop_counter = #mob_library_worker_table - 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 + while spawn_loop_counter > 0 do + table.shuffle(mob_library_worker_table) + local mob_chance_offset = math_random(1, cumulative_chance) 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 + if mob_index <= #mob_library_worker_table then + mob_chance = mob_library_worker_table[mob_index].chance + step_chance = step_chance + mob_chance + else + step_chance = 1000000 + end + end + if mob_index > #mob_library_worker_table then + mob_index = 1 end --minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance) @@ -1089,7 +1108,7 @@ if mobs_spawn then end current_summary_chance = current_summary_chance - mob_chance - table_remove(mob_library_worker_table, mob_index) + spawn_loop_counter = spawn_loop_counter - 1 end end @@ -1101,6 +1120,7 @@ if mobs_spawn then timer = timer + dtime if timer < WAIT_FOR_SPAWN_ATTEMPT then return end + initialize_spawn_data() timer = 0 local players = get_connected_players() From 55517154bd0e7547b9cb7ba98519c3951119c63c Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 27 Nov 2023 15:55:44 +0100 Subject: [PATCH 2/6] Mob spawning: Remove unused vars --- mods/ENTITIES/mcl_mobs/spawning.lua | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 16ab73618..2203e5ba0 100755 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -97,19 +97,6 @@ local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true) -local noise_params = { - offset = 0, - scale = 3, - spread = { - x = 301, - y = 50, - z = 304, - }, - seed = 100, - octaves = 3, - persistence = 0.5, -} - -- THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs -- Also used for missing parameter -- Please update the list when adding new biomes! @@ -875,8 +862,6 @@ minetest.register_chatcommand("spawn_mob",{ if mobs_spawn then - local perlin_noise - -- Get pos to spawn, x and z are randomised, y is range @@ -1001,8 +986,6 @@ if mobs_spawn then --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 local spawn_loop_counter = #mob_library_worker_table From e419e6d63b0d8d347fcc58528a5ff16f58f12052 Mon Sep 17 00:00:00 2001 From: bakawun Date: Mon, 27 Nov 2023 19:41:30 +0100 Subject: [PATCH 3/6] Spawning: remove another unused perlin var --- mods/ENTITIES/mcl_mobs/spawning.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 2203e5ba0..9130cab8f 100755 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -16,7 +16,6 @@ local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air local get_biome_name = minetest.get_biome_name local get_objects_inside_radius = minetest.get_objects_inside_radius local get_connected_players = minetest.get_connected_players -local minetest_get_perlin = minetest.get_perlin local math_random = math.random local math_floor = math.floor From d151e79fb994472f5e6f3ed928a9db0e13a2bf47 Mon Sep 17 00:00:00 2001 From: bakawun Date: Fri, 1 Dec 2023 15:39:08 +0100 Subject: [PATCH 4/6] Spawning: remove unused summary_chance --- mods/ENTITIES/mcl_mobs/spawning.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 9130cab8f..d6a9180df 100755 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -432,7 +432,6 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? local spawn_dictionary = {} --this is where all of the spawning information is kept for mobs that don't naturally spawn local non_spawn_dictionary = {} -local summary_chance = 0 function mcl_mobs:spawn_setup(def) if not mobs_spawn then return end @@ -494,7 +493,6 @@ function mcl_mobs:spawn_setup(def) check_position = check_position, on_spawn = on_spawn, } - summary_chance = summary_chance + chance end function mcl_mobs:mob_light_lvl(mob_name, dimension) @@ -598,8 +596,6 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ spawn_dictionary[key]["day_toggle"] = day_toggle spawn_dictionary[key]["check_position"] = check_position - summary_chance = summary_chance + chance - end local two_pi = 2 * math.pi @@ -985,7 +981,6 @@ if mobs_spawn then --grab mob that fits into the spawning location --randomly grab a mob, don't exclude any possibilities - local current_summary_chance = summary_chance local spawn_loop_counter = #mob_library_worker_table while spawn_loop_counter > 0 do @@ -1089,7 +1084,6 @@ if mobs_spawn then end end - current_summary_chance = current_summary_chance - mob_chance spawn_loop_counter = spawn_loop_counter - 1 end end From b2b63266b74dd3787687af3050ca6c210d19a180 Mon Sep 17 00:00:00 2001 From: bakawun Date: Fri, 1 Dec 2023 15:42:57 +0100 Subject: [PATCH 5/6] Spawning: break mob selection loop when out of bounds --- mods/ENTITIES/mcl_mobs/spawning.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index d6a9180df..5c58733e2 100755 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -995,12 +995,9 @@ if mobs_spawn then mob_chance = mob_library_worker_table[mob_index].chance step_chance = step_chance + mob_chance else - step_chance = 1000000 + break end end - if mob_index > #mob_library_worker_table then - mob_index = 1 - end --minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance) local mob_def = mob_library_worker_table[mob_index] From 4d90dfab0e162cad395cde564dc8a2c11e8fcc7b Mon Sep 17 00:00:00 2001 From: bakawun Date: Fri, 1 Dec 2023 15:50:07 +0100 Subject: [PATCH 6/6] Spawning: add a comment to clarify what the random select is doing --- mods/ENTITIES/mcl_mobs/spawning.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 5c58733e2..4108d038c 100755 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -980,7 +980,9 @@ if mobs_spawn then --output_mob_stats(mob_counts_wide) --grab mob that fits into the spawning location - --randomly grab a mob, don't exclude any possibilities + --use random weighted choice with replacement to grab a mob, don't exclude any possibilities + --shuffle table once every loop to provide equal inclusion probability to all mobs + --repeat grabbing a mob to maintain existing spawn rates local spawn_loop_counter = #mob_library_worker_table while spawn_loop_counter > 0 do