Code: Select all
Stage
1 Every 'abm_interval' (minetest.conf) seconds:
2 For each registered ABM:
( Oh, what a nice mod, I want it.And this too, and this ... -> more, moore, mooore ABMs )
3 For each active mapblock: ( 27 , or 125 ? per player)
4 If 'catch_up' = true , evaluate 'chance' reduction
5 For z = min -> max (northwards)
6 For y = min -> max (upwards)
7 For x = min -> max (eastwards)
... following is done 16*16*16 = 4096 times per active mapblock ...
... if 27 active mapblocks per player, [color=#FF0000]110592 times per player[/color]
... if 125 active mapblocks per player,[color=#FF0000] 512000 times per player
.... ( half a million ! )[/color]
8 If node(x,y,z) belongs to 'nodenames'
9 If any of its 26 neighbors belong to 'neighbors'
10 If ...'chance' & RNG then call our callback
11 func(pos, node, active_object_count, active_object_count_wider)
12 [If <condition X> then] [b] <condition X>[/b] could be none
13 [b]<do whatever>[/b]
Most of it is silent, hidden, highly efficient C++, but an enormous work.
And for some uses, the goal, <do whatever>, depends on some <condition X>
All is OK if <condition X> needs to be evaluated per-node.
But if <condition X> is met more widely, there is a HUGE waste of CPU.
Examples:
- Some mod has a good reason to temporarily suspend one of its ABMs
- Turn leaves brown if season == 'autumn'
- Spawn mob if z > 0 (a world with safe south and risky north)
- Spawn photophobic monster if time of day == night
- Do something if y < -20 (if underground)
- Do something not extremely accurate depending on biome/humidity/temperature
(things that vary smoothly, roughly equal through a mapblock)
Performance would greatly improve allowing extra conditions to prune the ABM tasks in earlier stages, for example:
- In stage 2 - each ABM could have a boolean 'active' flag, mods could suspend and resume.
- Between stages 2 and 3 - <ABM global condition> (things like season, time of day...)
- Between stages 3 and 4 - <ABM mapblock condition> (things like pos, biome, heat, humidity...)
<ABM global condition> and <ABM mapblock condition> could be easily added as optional arguments:
Code: Select all
minetest.register_abm({
label = "...",
nodenames = {...},
neighbors = {...},
interval = ...,
chance = ...,
action = function(pos, node)...end,
global_condition = function()...end, --OPTIONAL
mapblock_condition = function(pos)...end --OPTIONAL
})
And perhaps (requires ABM labels to be unique).Or using ABM index returned at registration
Code: Select all
minetest.pause_abm( ABM_label )
minetest.resume_abm( ABM_label )