Page 1 of 1

How to randomly generate trees?

PostPosted: Thu May 09, 2013 22:11
by scifiboi
One of the main troubles I am having while programming my mod is making trees generate. I have an idea on how on how to make the trees generate without randomizing the leaves, but that takes a MASSIVE amount of repetitious code. How does minetest generate trees like it does? I have searched through the worldgen.lua in the default mod in the default game, but I couldn't find anything about trees. Could someone help with this?

PostPosted: Thu May 09, 2013 22:23
by PilzAdam
Look at src/treegen.cpp

I also have the treegen ported to Lua in my farming mod.

PostPosted: Thu May 09, 2013 22:46
by scifiboi
I don't know cpp that well. :P But I'll have a look at your mod and see what I can figure out. Thanks! :)
EDIT: I'm having trouble finding code for any trees at all. In your post, you said something about rubber trees, but in the zip, I can't find anything to do with trees.

PostPosted: Thu May 09, 2013 23:34
by PilzAdam

PostPosted: Tue May 21, 2013 13:56
by Mihobre
Hey, if you ever know ho to generate a tree, make a mod that makes coal, iron, and mese trees, with stones as trunks

PostPosted: Tue May 21, 2013 13:59
by Evergreen
This code makes the actual model for the tree, but Idk how to make them spawn randomly.
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
function farming:generate_tree(pos, trunk, leaves, underground, replacements)
    pos.y = pos.y-1
    local nodename = minetest.env:get_node(pos).name
    local ret = true
    for _,name in ipairs(underground) do
        if nodename == name then
            ret = false
            break
        end
    end
    pos.y = pos.y+1
    if not minetest.env:get_node_light(pos) then
        return
    end
    if ret or minetest.env:get_node_light(pos) < 8 then
        return
    end

    node = {name = ""}
    for dy=1,4 do
        pos.y = pos.y+dy
        if minetest.env:get_node(pos).name ~= "air" then
            return
        end
        pos.y = pos.y-dy
    end
    node.name = trunk
    for dy=0,4 do
        pos.y = pos.y+dy
        minetest.env:set_node(pos, node)
        pos.y = pos.y-dy
    end

    if not replacements then
        replacements = {}
    end

    node.name = leaves
    pos.y = pos.y+3
    for dx=-2,2 do
        for dz=-2,2 do
            for dy=0,3 do
                pos.x = pos.x+dx
                pos.y = pos.y+dy
                pos.z = pos.z+dz

                if dx == 0 and dz == 0 and dy==3 then
                    if minetest.env:get_node(pos).name == "air" and math.random(1, 5) <= 4 then
                        minetest.env:set_node(pos, node)
                        for name,rarity in pairs(replacements) do
                            if math.random(1, rarity) == 1 then
                                minetest.env:set_node(pos, {name=name})
                            end
                        end
                    end
                elseif dx == 0 and dz == 0 and dy==4 then
                    if minetest.env:get_node(pos).name == "air" and math.random(1, 5) <= 4 then
                        minetest.env:set_node(pos, node)
                        for name,rarity in pairs(replacements) do
                            if math.random(1, rarity) == 1 then
                                minetest.env:set_node(pos, {name=name})
                            end
                        end
                    end
                elseif math.abs(dx) ~= 2 and math.abs(dz) ~= 2 then
                    if minetest.env:get_node(pos).name == "air" then
                        minetest.env:set_node(pos, node)
                        for name,rarity in pairs(replacements) do
                            if math.random(1, rarity) == 1 then
                                minetest.env:set_node(pos, {name=name})
                            end
                        end
                    end
                else
                    if math.abs(dx) ~= 2 or math.abs(dz) ~= 2 then
                        if minetest.env:get_node(pos).name == "air" and math.random(1, 5) <= 4 then
                            minetest.env:set_node(pos, node)
                            for name,rarity in pairs(replacements) do
                                if math.random(1, rarity) == 1 then
                                minetest.env:set_node(pos, {name=name})
                                end
                            end
                        end
                    end
                end

                pos.x = pos.x-dx
                pos.y = pos.y-dy
                pos.z = pos.z-dz
            end
        end
    end
end

PostPosted: Tue May 21, 2013 14:16
by VanessaE
Don't build trees with Lua, use the in-engine L-systems code instead. See my moretrees and plantlife mods for examples of how to use it.

PostPosted: Tue May 21, 2013 15:01
by VanessaE
Four nodes, actually. One field for the trunk, two kinds of leaves, and a field intended for specifying fruit, which could also be used to make a third type of leaves if so desired.

PostPosted: Sat Oct 19, 2013 20:26
by fessmK
nice code for the tree.
Can I use it?

You can use perlin noise (see the docfarming mod) or you can use an ABM that continues to generate them through the game.