Tree generation system

For a long time now, the Lumber Tycoon 2 tree generation system has been fascinating me, and I’ve been trying to recreate my own system but I kept failing until now!
The script probably has a ton of bugs and is obviously not the best. I struggle to use CFrame, so it’s pretty hard for me to fix them, but I thought that it would be cool to share this resource since there isn’t much about open source tree generation system out there.

--// Module script, scripted by hypixel26

local TreeGenerationPackage = {}

function GenPart(Name, Size, Type)
	local Part = Instance.new("Part")
	local Attachment
	Part.Size = Size
	Part.Anchored = true
	Part.Name = Name

	if Type == "Wood" then
		Part.Color = Color3.fromRGB(119, 81, 55)
		Part.Material = Enum.Material.Concrete

		Attachment = Instance.new("Attachment")
		Attachment.Parent = Part
		Attachment.Position = Vector3.new(0, Part.Size.Y / 2, 0)

	elseif Type == "Leaf" then
		Part.Color = Color3.fromRGB(115, 209, 120)
		Part.Material = Enum.Material.Grass
		Part.Transparency = .05
		Part.CanCollide = true
	end

	return Part, Attachment
end

function PlaceOnAttachment(Attachment, CenterAttachment, Part, AngleXZ)
	Attachment.WorldPosition = CenterAttachment.WorldPosition
	Attachment.WorldOrientation = Vector3.new(math.random(AngleXZ - 20, AngleXZ + 20) + (math.random() * -1), math.random(0, 180), -math.random(AngleXZ - 20, AngleXZ + 20) + (math.random() * -1))

	Part.CFrame = Attachment.WorldCFrame * CFrame.new(0, Part.Size.Y / 2 - .25, 0)

	Attachment.Position = Vector3.new(0, Part.Size.Y / 2, 0)
end

function TreeGenerationPackage.GenerateTree(Origin, Name)
	if Origin == nil and Name == nil then return end

	local OriginHit = workspace:Raycast(Origin + Vector3.new(0, 10, 0), Vector3.new(0, -1000, 0))
	Origin = (OriginHit ~= nil) and OriginHit.Position or Origin

	local TreeElements = {}
	local SubBranchesList = {}

	local X, Y, Z = math.rad(math.random(0, 15)), math.rad(math.random(0, 180)), math.rad(math.random(0, 15))
	local Branches = 3

	local IndexAngle = math.floor(45 / Branches)

	local Trunk, Center = GenPart("Trunk", Vector3.new(1, 8, 1), "Wood")
	table.insert(TreeElements, Trunk)
	Trunk.CFrame = CFrame.new(Origin + Vector3.new(0, Trunk.Size.Y/2 - .6, 0)) * CFrame.Angles(X, Y, Z)

	for Integer = 1, Branches do
		local Branch, Attachment = GenPart("Branch", Vector3.new(.55, 7.5, .55), "Wood")
		table.insert(TreeElements, Branch)

		PlaceOnAttachment(Attachment, Center, Branch, IndexAngle * Integer)

		local SubBranches = math.random(2, 3)
		local IndexAngle2 = math.floor(45 / SubBranches)

		for _Integer = 1, SubBranches do
			local SubBranch, SubAttachment = GenPart("SubBranch", Vector3.new(.35, 4.5, .35), "Wood")
			table.insert(TreeElements, SubBranch)
			table.insert(SubBranchesList, SubBranch)

			PlaceOnAttachment(SubAttachment, Attachment, SubBranch, IndexAngle2 * _Integer)
		end

		Attachment:Destroy()
	end

	for _Index, Value in ipairs(SubBranchesList) do
		if Value:IsA("BasePart") then
			local Leaves = math.random(1, 2)
			local IndexLeafAngle = math.floor(15 / Leaves)

			for Integer = 1, Leaves do
				local Leaf = GenPart("Leaf", Vector3.new(4.5, .85, 4.5), "Leaf")
				table.insert(TreeElements, Leaf)

				Leaf.CFrame = CFrame.new(Value.Attachment.WorldPosition.X, Value.Attachment.WorldPosition.Y + Leaf.Size.Y / 2 - .5, Value.Attachment.WorldPosition.Z) * CFrame.Angles(math.rad(IndexLeafAngle * Integer), math.random(0, math.pi), math.rad(IndexLeafAngle * Integer))
			end

			Value.Attachment:Destroy()
		end
	end

	Center:Destroy()
	local TreeModel = Instance.new("Model")
	TreeModel.Name = Name

	for _Index, Value in ipairs(TreeElements) do
		if Value:IsA("BasePart") then
			Value.Parent = TreeModel
		end
	end

	TreeModel.Parent = workspace
	return TreeElements, TreeModel
end

return TreeGenerationPackage

Usage :

--// Server script
local TreeGen = require(game:GetService("ReplicatedStorage"):WaitForChild("Shared").GenerationScript)

TreeGen.GenerateTree(Vector3.new(0, 0, 0), "My first tree")
14 Likes

Neat, will use. :shallow_pan_of_food: :shallow_pan_of_food:

1 Like

Wow this works wonders!!! Nice work

1 Like

Amazing, saved me hours of work! Will be in my credits! :grin: