Does my flag animation script have issues and how could I improve it?

Hello I’ve recently made a flag animation script that is very optimised and works with lots of Animated Flags.
It animates the flags locally when there are available players. It’s also scales with more flags performantly, it also works better than other flag animation scripts because its local, making the animation super smooth and it doesn’t produce unnecessary replication data.

I’d like to know that if there are any potential issues with this script and how I could make it better.
I would also like to know how to make this properly support StreamingEnabled and other replication related destroying stuff

Here is the server script

-- Flag model by Sinahi
-- Flag animation script by AsetCreator_ii(ALE111_boiPNG) - 2021 - Made a new script which is much better and much more performant.

--[[ReadMe*
	This model uses MeshParts to animate the flag. The previous frame turns transparent
	while the next frame becomes visible.
	
	If you would like to use your own custom flag, for your ROBLOX group or country, 
	select all the children in the "Flag" model and paste in a ROBLOX decal asset in 
	the "TextureID" slot. If you receive an error, try subtracting 1 from the decal id.
		
		rbxassetid://DECALID
		
		http://www.roblox.com/asset/?id=DECALID
	
	Any ROBLOX decal in the Developers Library will work, or you may upload your own 
	flag decal to insert in. Rectangular decals are recommended for this flag. 
		*If you use a decal with a transparent background in the MeshPart's TextureID, 
		the transparent background will default to black. Instead, insert the actual
		decal into every MeshPart in "Flag." This will allow you to change the BrickColor
		of the flag with the decal on top.
	
	The flags have been UV mapped to flip the flag design on the other side. 
		e.g. You won't see the blue box of the United States flag on the other side
			 of the flag on its end, but close to the pole for both sides.
				
	Thank you and have a wonderful day.
	(MeshParts rendered using Blender)
--]]

-- // Configuration

local WAIT_TIME = 0.025 -- Time between each "Frame"
local FLAG_AMOUNT = 16 -- How many flags are there. Only change the value if you have changed the amount of flags inside the "Flag" model.



-- // Do not touch code below!!! Unless you known what you are doing. \/


local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterPlayerScripts = game:GetService("StarterPlayer"):WaitForChild("StarterPlayerScripts")
local flagModel = script.Parent:WaitForChild("Flag")


do
	local foundAnimator = StarterPlayerScripts:FindFirstChild("FlagClientAnimator")
	if not foundAnimator then
		script:WaitForChild("FlagClientAnimator"):Clone().Parent = StarterPlayerScripts
	end

	local flagsContainer = ReplicatedStorage:FindFirstChild("FlagsContainer")
	if not flagsContainer then
		flagsContainer = Instance.new("Folder")
		flagsContainer.Name, flagsContainer.Archivable, flagsContainer.Parent = "FlagsContainer", false, ReplicatedStorage
	end

	local flagInfo = Instance.new("Folder")
	flagInfo.Name, flagInfo.Archivable = "FlagInfo", false

	local waitTimeValue, flagAmountValue, flagObjectValue = Instance.new("NumberValue"), Instance.new("IntValue"), Instance.new("ObjectValue")

	waitTimeValue.Name, flagAmountValue.Name, flagObjectValue.Name = "WaitTime", "FlagAmount", "FlagModel"
	waitTimeValue.Value, flagAmountValue.Value, flagObjectValue.Value = WAIT_TIME, FLAG_AMOUNT, flagModel
	waitTimeValue.Archivable, flagAmountValue.Archivable, flagObjectValue.Archivable = false, false, false
	waitTimeValue.Parent, flagAmountValue.Parent, flagObjectValue.Parent = flagInfo, flagInfo, flagInfo

	flagInfo.Parent = flagsContainer
end

task.wait(2)

if RunService:IsStudio() and #Players:GetPlayers() <= 0 then -- // We ideally want to do the animations on the client but if there are no clients we do it on the server.
	local flags, last = {}, 1

	for i = 1, FLAG_AMOUNT do
		table.insert(flags, flagModel:WaitForChild(tostring(i)))
	end

	RunService.Heartbeat:Connect(function()
		local current = math.clamp(math.floor((os.clock()) / WAIT_TIME) % FLAG_AMOUNT + 1, 1, FLAG_AMOUNT)

		if current ~= last then
			flags[current].Transparency = 0
			flags[last].Transparency = 1
		end

		last = current
	end)
end

Here is the client script

-- // Do not touch this script at all! Unless you known what you are doing. Also do not remove this as the flag will not work!
-- // Made by AsetCreator_ii(ALE111_boiPNG)

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local flagsContainer = ReplicatedStorage:WaitForChild("FlagsContainer")
local flagModelsHolder = {}

local function connectValue(object, callback, ...)
	if object.Value then
		callback(object.Value, ...)
	end
	
	while true do
		object:GetPropertyChangedSignal("Value"):Wait()
		if object.Value then
			callback(object.Value, ...)
		end
	end
end

local function StartFlag(flag, waitTime, flagAmount)
	local flags, flagTemp, last = {}, {}, 1
	for i = 1, flagAmount do
		table.insert(flagTemp, flag:WaitForChild(tostring(i)))
	end

	if not flagModelsHolder[flagAmount] then
		flagModelsHolder[flagAmount] = {}
	end

	if not flagModelsHolder[flagAmount][waitTime] then
		table.insert(flags, flagTemp)
		flagModelsHolder[flagAmount][waitTime] = flags
	else
		table.insert(flagModelsHolder[flagAmount][waitTime], flagTemp)
		return
	end
	
	task.wait(1)

	RunService:BindToRenderStep("ClientFlagAnimation", 2048, function()
		local current = math.clamp(math.floor(os.clock() / waitTime) % flagAmount + 1, 1, flagAmount)

		if current ~= last then
			for _, v in ipairs(flags) do
				v[current].Transparency = 0
				v[last].Transparency = 1
			end
		end

		last = current
	end)
end

Players.LocalPlayer.CharacterAdded:Wait()
task.wait(1)
print("Using AsetCreator_ii(ALE111_boiPNG)'s animated flag script.")

for _, v in ipairs(flagsContainer:GetChildren()) do
	coroutine.wrap(connectValue)(v:WaitForChild("FlagModel"), StartFlag, v:WaitForChild("WaitTime").Value, v:WaitForChild("FlagAmount").Value)
end

flagsContainer.ChildAdded:Connect(function(child)
	connectValue(child:WaitForChild("FlagModel"), StartFlag, child:WaitForChild("WaitTime").Value, child:WaitForChild("FlagAmount").Value)
end)

Here is a full game file.
Flag_Place1.rbxl (36.8 KB)

It doesn’t play nicely with StreamingEnabled and has other replication related issues (relating to flags being :Destroy()ed or otherwise cleaned up).

I am checking it right now what is the issue.

Ok I fixed the issue with .Parenting, it was because it didn’t check if the flag is already in the animation table.

But it still doesn’t play nicely with SreamingEnabled, and it has a memory leak when flags are parented to nil