Tree Growing script

I made a tree gen script that obviously has some likely bad practices and is rather messy I am currently trying to redo the script using an oop approach using the rxi Classic module for Lua GitHub - rxi/classic: Tiny class module for Lua but I am kinda stuck on figuring out where my worst parts of the script are so I can avoid making the same mistakes in my new build
Tree Gen - Roblox here is the tree gen in an uncopylocked place if you want to look at it that way
the code:

 `----------EARLY TESTING TREE GROWING SCRIPT BY MANACHRON------------------
---Gonna guess this is filled with memory leaks or some trash
local TreeType = require(script.Parent.TreeTypes.Test)
local Properties = TreeType.TreeProperties()

local TreeSections = {}
local Tree 

local RunService = game:GetService("RunService")

local StartTime = os.clock() -- gamestart time for loop


local function newBranch() ---- creates new part for trees
	local part = Properties.BarkModel:Clone()
	part.BrickColor = Properties.BarkColor
	part.Material = Properties.BarkMaterial
	part.Transparency = Properties.BarkTransparency
	part.Reflectance = Properties.BarkReflectance
	part.Size = Vector3.new(Properties.BranchWidth, 0.5, Properties.BranchWidth)
	part.Anchored = true
	return part
end

local function newLeafs()
	local part = Properties.LeafModel:Clone()
	part.BrickColor = Properties.LeafColor
	part.Material = Properties.LeafMaterial
	part.Transparency = Properties.LeafTransparency
	part.Reflectance = Properties.LeafReflefctance
	part.Size = Vector3.new(0.75, 0.3, 0.75)
	part.Anchored = true
	return part
end

local function getRandomAngles(min,max) --- creates random cframe angles based on min and max split angles
	--local Angle = math.random(min, max)
	local MaxSplitAngle = Properties.MaxSplitAngle
	return CFrame.Angles(math.rad(math.random(MaxSplitAngle.min, MaxSplitAngle.max)), 0, math.rad(math.random(MaxSplitAngle.min, MaxSplitAngle.max)))
end

local function newSection(Pos,NumBranches, oldSize, leafSize) --- creates a new section tree
	local Section = Instance.new("Model") ---- creates a section model to keep all the branches together
	Section.Name = "Section" 
	Section:SetAttribute("IsGrowing", true) --- for checking if the section needs to recive growth calls
	if NumBranches then --- bad code honestly but kinda a check for if its a starting trunk but i guess that doesnt make too much sense how i did it
		for i = 1, NumBranches do --- creates a bunch of branches based on the number we give the new section
			local newBranch = newBranch()
			newBranch:SetAttribute("CanSplit", true) --- for checking if branch has reached adult
			newBranch.Name = "Trunk"
			newBranch.Size = Vector3.new(oldSize.X*0.9, 0, oldSize.X*0.9)
			local moveUp = Vector3.new(0,newBranch.Size.Y/2,0) --- offset for the lenth of the branch
			local newCframe = CFrame.new(Pos.Position + moveUp)	* getRandomAngles() ---- adding angles
			newBranch:PivotTo(newCframe) --- moving to new position based on the pos and angles of part
			newBranch.Parent = Section ---- put into Section model the branches stay with eachother
			
			local NewLeafs = newLeafs()
			NewLeafs.Name = "Leaf"
			NewLeafs.Size = leafSize
			NewLeafs.Anchored = true
			local moveUpLeaf = Vector3.new(0,newBranch.Size.Y/2,0)
			local newCframeLeaf = CFrame.new(newBranch.CFrame.Position + moveUpLeaf)* getRandomAngles()
			NewLeafs:PivotTo(newCframeLeaf * CFrame.new(moveUp))
			NewLeafs.Parent = newBranch
			
		end
	else -- Initial seedling suppposdly tho i need a better start/Check
		local newBranch = newBranch()
		newBranch:SetAttribute("CanSplit", true) --- Check for adultHood
		newBranch.Name = "Trunk"
		local moveUp = Vector3.new(0,newBranch.Size.Y/2,0) --- Length offset
		newBranch:PivotTo(Pos*CFrame.new(moveUp))
		newBranch.Parent = Section
		
		local NewLeafs = newLeafs()
		NewLeafs.Name = "Leaf"
		local moveUp = Vector3.new(0,newBranch.Size.Y/2,0)
		NewLeafs:PivotTo(newBranch.CFrame * CFrame.new(moveUp))
		NewLeafs.Parent = newBranch
		
	end
	if not table.find(TreeSections,Section) then
		TreeSections[#TreeSections+1] = Section ---- adds to table for grow calls
	end
	return Section -- returns section to place into proper tree model
end



local function doGrowth()
	for i, section in TreeSections do
		local branches = section:GetChildren()
		local BranchsFullyGrown = true
		if section:GetAttribute("IsGrowing") then
			for int, branch in branches do
				if branch.Size.Y < Properties.BranchLength then
					BranchsFullyGrown = false
					local OldPos = branch.CFrame * CFrame.new(0, branch.Size.Y/-2, 0)
					branch.Leaf.Size = Vector3.new(branch.Leaf.Size.X+0.1, branch.Leaf.Size.Y+0.03, branch.Leaf.Size.X+0.1)
					branch.Size = Vector3.new(branch.Size.X, branch.Size.Y + 0.5, branch.Size.X) -- grows the branch longer
					local moveUp = Vector3.new(0,branch.Size.Y/2,0) --- Size offset
					branch:PivotTo(OldPos * CFrame.new(moveUp))
					branch.Leaf:PivotTo(branch.CFrame  * CFrame.new(moveUp))
				end
			end
		end
		if BranchsFullyGrown then
			if #Tree:GetChildren() < Properties.MaxSections then 
				for _,branchsplit in branches do
					if branchsplit:GetAttribute("CanSplit") == true then
						branchsplit:SetAttribute("CanSplit", false)
						local leafSize = branchsplit.Leaf.Size
						branchsplit.Leaf:Destroy()
						local moveUp = Vector3.new(0,branchsplit.Size.Y/2,0) --- sizeOffset
						local SplitSection = newSection(branchsplit.CFrame * CFrame.new(moveUp),math.random(Properties.MinSplits,Properties.MaxSplits), branchsplit.Size, leafSize)
							-- creates new section with random amount of branches
						SplitSection.Parent = Tree --- puts the newly created section into the treemodel
					end
				end
				
			else
				print("endSegment")
			end
			table.remove(TreeSections, i)
		end
	end
end

local function newTree(Pos) -- creates a new tree model then calls the newSection to start a trunk
	local TreeModel = Instance.new("Model")
	TreeModel.Name = "Tree"
	local TrunkSection = newSection(Pos)
	TrunkSection.Parent = TreeModel
	TreeModel.Parent = workspace.Trees
	Tree = TreeModel
end

RunService.Heartbeat:Connect(function()--- calls growth call after time in seconds that have passed for GrowthSpeed
	local TimePassed = os.clock() - StartTime
	if TimePassed > Properties.GrowthSpeed then
		doGrowth()
		StartTime = os.clock()
	end
end)

newTree(workspace.SpawnPart.CFrame)`

gif of it in work https://media.discordapp.net/attachments/865347524860051456/1031077944648552488/RobloxStudioBeta_fYVJQDdJPY-2.gif

4 Likes

thanks veryyyyyyyyyyyyyyyyyyyy much