--[[ outline: do the following regularly: 1. create an empty list for mapblocks to process. 2. for every online player: 2.1. go through every mapblock near them, and add the mapblock to the list if it's not already added. 3. for every mapblock in the list: 3.1. load the mapblock. - the "keep track of loaded mapblocks" part could be useful for other things too. ]]-- -- max distance from players, in mapblocks, within which mapblocks will be random-ticked. local max_load_range = 4 -- max amount of mapblocks to get random-ticked each server step. local max_ticked_block_count = 200 -- amount of random ticks to apply to each mapblock. local random_tick_count = 4 local settings = minetest.settings local view_range = settings:get("viewing_range") local load_range = math.min(math.floor(view_range / 16), max_load_range) local function random_tick (mapblock_pos) for i=1, random_tick_count do local x = mapblock_pos.x * 16 + math.random(0, 15) local y = mapblock_pos.y * 16 + math.random(0, 15) local z = mapblock_pos.z * 16 + math.random(0, 15) local pos = vector.new(x, y, z) local node_def = minetest.registered_nodes[minetest.get_node(pos).name] if not node_def then return end if type(node_def.on_random_tick) == "function" then node_def.on_random_tick(pos, node, i) end end end blockgame.register_globalstep(function () -- find loaded mapblocks local mapblocks = {} local visited_blocks = {} for _, player in pairs(minetest.get_connected_players()) do local node_pos = player:get_pos() local mapblock_pos = {} for key, value in pairs(node_pos) do mapblock_pos[key] = math.floor(value / 16) end for x = mapblock_pos.x - load_range, mapblock_pos.x + load_range do for y = mapblock_pos.y - load_range, mapblock_pos.y + load_range do for z = mapblock_pos.z - load_range, mapblock_pos.z + load_range do local hash = x .. "," .. y .. "," .. z if not visited_blocks[hash] then visited_blocks[hash] = true table.insert(mapblocks, vector.new(x, y, z)) end end end end end mapblocks = blockgame.shuffle(mapblocks) -- tick mapblocks local ticked_mapblock_count = 0 repeat ticked_mapblock_count = ticked_mapblock_count + 1 local index = math.random(1, #mapblocks) local mapblock = mapblocks[index] table.remove(mapblocks, index) if mapblock then random_tick(mapblock) end until ticked_mapblock_count >= max_ticked_block_count or #mapblocks == 0 end)