-- TODO: move these to the general api. local function listify_table (tab) local copy = {} for _, item in pairs(tab) do table.insert(copy, item) end return copy end local function shuffle (tab) tab = listify_table(tab) local shuffled = {} repeat local index = math.random(1, #tab) local value = tab[index] table.insert(shuffled, value) table.remove(tab, index) until #tab == 0 return shuffled end blockgame.register_abm({ nodenames = {"bg_terrain:grass"}, neighbors = {"bg_terrain:dirt"}, interval = 30, chance = 8, action = function (pos, node) local sides = listify_table(blockgame.vector.sides) local diagonally = {} for _, side in pairs(sides) do table.insert(diagonally, side + blockgame.vector.dirs.down) table.insert(diagonally, side + blockgame.vector.dirs.up) end sides = shuffle(sides) diagonally = shuffle(diagonally) for _, offset in pairs(sides) do if attempt_spread(pos + offset) then return true end end for _, offset in pairs(diagonally) do if attempt_spread(pos + offset) then return true end end return false end, }) function attempt_spread (pos) local name = minetest.get_node(pos).name if not blockgame.item_matches(name, {"group:grassable"}) then return false end if not blockgame.air_flows_through(pos + blockgame.vector.dirs.up) then return false end minetest.set_node(pos, {name = "bg_terrain:grass"}) return true end