How can I optimize this code?

I made a “geometry triangle lines background” rendering system, the issue is that the code has (a heavy) perfomance issue

Place file:
https://www.roblox.com/games/8824346832/Random-geometry-lines-rendering-showcase-place

1 Like

I’ve tried optimizing it by reusing dots instead of destroying them and recreating them, and decreased the maximum dots to 35, can someone help me optimize it to work on higher counts?

local serv = {
	RunService = game:GetService("RunService");
	Debris = game:GetService("Debris");
	TweenService = game:GetService("TweenService");
}
local RootRender = script.Parent
local Dots: {Frame} = {}
local Lines: {{FirstDot: Frame, SecondDot: Frame, Line: Frame}} = {}
local Rand = Random.new()
local RbxWindowSize = workspace.CurrentCamera.ViewportSize
workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
	RbxWindowSize = workspace.CurrentCamera.ViewportSize
	return
end)

local function GetRandomUDim2OffsetBasedOnRbxWindowSize()
	return UDim2.new(0, Rand:NextInteger(0, RbxWindowSize.X), 0, Rand:NextInteger(0, RbxWindowSize.Y))
end

local function GetLineFromArray(fd, sd)
	for index, line in ipairs(Lines) do
		if line.FirstDot == fd and line.SecondDot == sd then
			return line, index
		end
	end
	return
end

local function RandomlyTweenDotInCameraSpace(dot)
	local tw = serv.TweenService:Create(dot, TweenInfo.new(6, Enum.EasingStyle.Linear), {Position = GetRandomUDim2OffsetBasedOnRbxWindowSize()})
	tw.Completed:Connect(function()
		RandomlyTweenDotInCameraSpace(dot)
	end)
	tw:Play()
	return
end

local function CreateDot()
	local dot = Instance.new("Frame")
	dot.Name = "Dot"
	dot.Size = UDim2.new(0, 10, 0, 10)
	dot.AnchorPoint = Vector2.new(0.5, 0.5)
	dot.Position = GetRandomUDim2OffsetBasedOnRbxWindowSize()
	dot.BorderSizePixel = 0
	dot.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	dot.Parent = RootRender
	table.insert(Dots, dot)
	RandomlyTweenDotInCameraSpace(dot)
	return dot
end

--[[
local function CleanLinesWithoutDot()
	for index, line in ipairs(Lines) do
		if (not line.FirstDot) or (not line.SecondDot) or (not line.FirstDot.Parent) or (not line.SecondDot.Parent) then
			serv.Debris:AddItem(line.Line, 0)
			table.remove(Lines, index)
		end
	end
end
--]]

--// https://devforum.roblox.com/t/drawing-a-path-with-uis/252604/2
function drawPath(clineframe, startBtn, endBtn)
	local startX, startY = startBtn.Position.X.Offset, startBtn.Position.Y.Offset
	local endX, endY = endBtn.Position.X.Offset, endBtn.Position.Y.Offset
	local Line = if not clineframe then Instance.new("Frame") else clineframe
	Line.AnchorPoint = Vector2.new(0.5, 0.5)
	Line.Size = UDim2.new(0, ((endX - startX) ^ 2 + (endY - startY) ^ 2) ^ 0.5, 0, 5) -- Get the size using the distance formula
	Line.Position = UDim2.new(0, (startX + endX) / 2, 0, (startY + endY) / 2) -- Get the position using the midpoint formula
	Line.Rotation = math.atan2(endY - startY, endX - startX) * (180 / math.pi) -- Get the rotation using atan2, convert radians to degrees
	return Line
end
--\\

local function RenderAndHandleLines()
	--// task.spawn(CleanLinesWithoutDot)
	for _, dot: Frame in next, Dots do
		for _, seconddot: Frame in next, Dots do
			if seconddot ~= dot and (dot.AbsolutePosition - seconddot.AbsolutePosition).Magnitude <= 150 then
				local linedata = GetLineFromArray(dot, seconddot)
				if not linedata then
					local line = Instance.new("Frame")
					line.Name = "Line"
					line.BorderSizePixel = 0
					line.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
					line.Size = UDim2.new(0, 0, 0, 0)
					line.Parent = RootRender
					linedata = {FirstDot = dot, SecondDot = seconddot, Line = line}
					table.insert(Lines, linedata)
				end
				--// print("in range")
				local transparency = math.clamp((dot.AbsolutePosition - seconddot.AbsolutePosition).Magnitude, 1, 150) / 150
				linedata.Line.BackgroundTransparency = transparency
				--// print(transparency)
				drawPath(linedata.Line, dot, seconddot)
			else
				local line, index = GetLineFromArray(dot, seconddot)
				if line then
					table.remove(Lines, index)
					serv.Debris:AddItem(line.Line, 0)
				end
			end
		end
	end
end

for i = 1, 35 do
	CreateDot()
end

--// serv.RunService:BindToRenderStep("RenderGeometryLines", 1, RenderAndHandleLines)
serv.RunService.Heartbeat:Connect(RenderAndHandleLines)

GeometryBackgroundRenderSystem.rbxl (38.8 KB)