I have been trying to figure out some mob spawning logic that takes into account the rate of fire of ABMs as determined by the Active Block Range... this post is a bit of a request for comment really, on whether these calculations seem right, and whether a better calculation, built-in to mobs libraries, would seem desirable/necessary...
Reasoning
A "map block" consists of 16 x 16 x 16 nodes.
If the active block range is set to `1` then only the immediate block in which the player is will run ABMs.
If the *abr* is set to `2`, everything within a radius of 2 blocks from the player will run their ABMs -- that is, a `(2 * 16) ^3 = 3276` number of blocks.
If the *abr* is set to `3` (the default), then that is raised to `(3 * 16) ^ 3 = 110592`
These numbers rack up pretty fast - a geometric progression copmounded by an exponential.
For mobs, if you consider spawning a bird, in the air, and the player is standing on the ground, then it is likely only half the space is filled with air. In the case of an *abr* set to 3, we have 110592 / 2 = 55296. This means that the chance of spawning a bird {when the ABM's main node is "air" and the neighbours is "air"} should be set to 55296 (or, (abr * 16)^3 / 2), if you want a bird to spawn anywhere a player is (1 in 1 chance); but if the ABR is changed to 1, the chance needs to be reduced to 4096.
Proposed heuristic calculation
In the code below, I define a function that can scale the chance, depending on the actual active_block_range, and an example of how it could be used ...
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
local mt_abr = tonumber(minetest.setting_get("active_block_range") ) or 3 -- 3 is the default as described in minetest.conf.example
-- abr_chance() : calculate a chance based on the actual ABR
-- a raw chance of 4096 supplied to the ABM means an air mobs is likely to spawn once in range of player at ABR=1, but 2 times if ABR=2
-- So, we derive from that chance a new chance based on the currently set active_block_range
-- abr1chance is a chance based on ABR = 1 - if all mobs using this library specify on a basis of ABR=1
local function abr_chance(abr1chance)
local normalizer = 4096 -- kludge heuristic value for a 1/1 chance at ABR=1
local effective_abr_chance = math.pow( (mt_abr*16) , 3 )
return math.floor( (abr1chance / normalizer) * effective_abr_chance )
end
-- start defining ABMs for mob spawns ... :
local chanceperblock = 1
local rangestyle = {
air = 4096,
land = 4096/2,
constrainedarea = 4096/4
}
minetest.register_abm({
....
chance = abr_chance(chanceperblock * rangestyle.land)
....
})
Any thoughts ?