Change 800 scripts for only 1

I have a tree cutting system in which each tree has a script that is exactly the same as the other trees, I want to make a single script that works exactly the same but without having to use more than 800 scripts. I don’t know how to do it and where the new script should be placed.

local Tree = script.Parent
local Health = Tree:FindFirstChild("Health") or Instance.new("IntValue", Tree)
Health.Name = "Health"
Health.Value = 100

local OnHitEvent = Tree:FindFirstChild("OnHitEvent") or Instance.new("BindableEvent", Tree)
OnHitEvent.Name = "OnHitEvent"

if not Tree.PrimaryPart then
	Tree.PrimaryPart = Tree:FindFirstChild("Tronco")
end

local function ShakeTree()
	local originalPosition = Tree.PrimaryPart.Position
	local shakeIntensity = 0.5
	local shakeDuration = 0.2
	local startTime = tick()

	while tick() - startTime < shakeDuration do
		local offset = Vector3.new(math.random() * shakeIntensity - (shakeIntensity / 2), 0, math.random() * shakeIntensity - (shakeIntensity / 2))
		Tree.PrimaryPart.Position = originalPosition + offset
		wait(0.05)
	end

	Tree.PrimaryPart.Position = originalPosition
end

local function OnHit(damage)
	if Health then
		local dividedDamage = damage / 2 -- Divide el daño en dos
		Health.Value = Health.Value - dividedDamage
		if Health.Value <= 0 then
			FellTree()
		else
			ShakeTree()
		end
	end
end


if OnHitEvent then
	OnHitEvent.Event:Connect(OnHit)
end

function FellTree()
	local fallingSound = Tree:FindFirstChild("TreeFallingSound")
	if fallingSound then
		fallingSound:Play()
	end

	for _, part in ipairs(Tree:GetChildren()) do
		if part:IsA("BasePart") then
			part.CanCollide = false
			part.Anchored = false
		end
	end

	Tree:SetAttribute("HasFallen", true)

	local logModels = {"TrunkModel1", "TrunkModel2", "TrunkModel3"}
	local numLogs = math.random(1, 3)
	local replicatedStorage = game:GetService("ReplicatedStorage")
	local logsFolder =  replicatedStorage:FindFirstChild("Logs")
	local itemsFolder = workspace:FindFirstChild("Items")

	for i = 1, numLogs do
		local logModel = logModels[math.random(#logModels)]
		local log = logsFolder:FindFirstChild(logModel):Clone()
		log.Parent = itemsFolder or workspace
		log.CFrame = Tree.PrimaryPart.CFrame * CFrame.new(math.random(-5, 5), 0, math.random(-5, 5))
	end
	wait(3)

	local treePosition = Tree.PrimaryPart.Position
	local treeOrientation = Tree.PrimaryPart.CFrame

	Tree:Destroy()

	local waitTime = 10
	wait(waitTime)

	local newTree = replicatedStorage:FindFirstChild(Tree.Name):Clone()
	if newTree then
		newTree.Parent = workspace.Trees
		newTree:SetPrimaryPartCFrame(CFrame.new(treePosition))
		local newHealth = newTree:FindFirstChild("Health")
		if newHealth then
			newHealth.Value = 100
		end
		newTree:SetAttribute("HasFallen", false)
	end
end```

You can use something called collection service, or what you can do, which I find easier, is parent all your trees to a folder, then use a for loop to loop through them!

E.g.

local trees = workspace.Trees

for index, Tree in pairs(trees:GetChildren()) do
    print(Tree) -> prints the tree

    -- // Do the rest of your code after this point, except now you just dont need to define the Tree variable as its set in the for loop
end

While you’re at it I recommend making the ShakeTree function have an argument which would be the Tree you want to shake, in the case you dont know how to do that, ignore this lol, or look up advanced functions or something like that

1 Like

all my trees are in a folder, this code should be placed in that folder?

1 Like

The script can be placed anywhere (probably recommend placing it under ServerScriptService), and then as long as you do everything right it should work!

1 Like

Using CollectionService is the reccomended approach as it’s more future proof (accounts for trees that might not be in that folder)

local trees = game:GetService("CollectionService"):GetTagged("Tree")

for _, tree in trees do -- _ is the discard operator, it's more efficient to use it in this case because you don't need a reference to the index of the current object
    -- Apply logic here
end

You can add tags to objects through the properties tab.