Script Rate/s Rising Infinitely (millions)

Hi!
I have a game called Brick Inc. where you collect bricks.

The scripts responsible for the collection of bricks causes a lot of lag. Its activity is at about 20%
and the rate/s rises by a few thousand per second.

Heres the script + the module in Server Script Service (Please help!)

local Folder = game:GetService("Workspace"):WaitForChild("Bricks")
local BrickCollection = require(game:GetService("ServerScriptService"):WaitForChild("BrickCollection"))
local NameTable = {"BrickA", "BrickB", "BrickC", "BrickD"}

Folder.ChildAdded:Connect(function(child: BasePart)
	
	do
		
		--print("ChildAddedToBrickFolder")

		--	if table.find(NameTable, child.Name) == nil then return end
		if not child:FindFirstChild("Player") then return end
		if not child:FindFirstChild("Collected") then return end
		if not child:FindFirstChild("Worth") then return end
		if child:FindFirstChild("Collected").Value == true then return end

		local player = child:FindFirstChild("Player").Value
		local debounce

		local connection = child.Touched:Connect(function(otherPart: BasePart)
			if debounce then return end
			--print("ChildFromBrickFolderTouched")
			debounce = true
			local TouchingModel = otherPart:FindFirstAncestorOfClass("Model")

			if TouchingModel then
				local PlayerValue = TouchingModel:FindFirstChild("Player")

				if PlayerValue then
					if PlayerValue.Value == player then
						BrickCollection.collect(otherPart, player, child)
					end
				end
			end
			debounce = false
		end)
	
		child.Destroying:Once(function()
			--print("ChildDestroyingFromBrickFolder(:Once)")
			if connection.Connected == true then
				connection:Disconnect()
			end
			connection = nil
		end)
		
	
	end
end)

Module:

local BrickCollection = {}

local multT = require(game:GetService("ServerScriptService").Upgrades).getUpgrade("BrickMultiplier")
local cdT = require(game:GetService("ServerScriptService").Upgrades).getUpgrade("SpawnBrickCooldown")
local ss = game:GetService("SoundService")
local PB = require(game:GetService("ServerScriptService"):WaitForChild("PlaceBricks"))
local PlaceBrick = PB.PlaceBrick
local random = math.random
local sfxEvent = game:GetService("ReplicatedStorage"):WaitForChild("ClientFXEvents"):WaitForChild("ClientSFX")
local MarketServ = game:GetService("MarketplaceService")
local BricksMultiplierPassID = 1019423456
local round = math.round

local function awardBricks(receiver: Player, brick: Part)
	
	do
		
		--print("AwardBricksStarted")
	
		if not receiver then return end
		if not brick.Parent then return end
		if not brick.Parent:FindFirstChild(brick.Name) then return end
		if not brick:FindFirstChild("Worth") then return end
		if not brick:FindFirstChild("Player") then return end
		if not brick:FindFirstChild("Collected") then return end
		if brick:FindFirstChild("Collected").Value == true then return end
		if not receiver:FindFirstChild("Quests") then return end
		if not receiver:FindFirstChild("Quests"):FindFirstChild("GoatedBrick") then return end
		if not receiver:FindFirstChild("Quests"):FindFirstChild("WeakBrick") then return end
		if not receiver:FindFirstChild("SpawnBrickCooldown") then return end
		if not receiver:FindFirstChild("OnCD") then return end
		if not receiver:FindFirstChild("LockPurple") then return end
		if not receiver:FindFirstChild("NextBrick") then return end
		if not receiver:FindFirstChild("Multipliers"):FindFirstChild("TotalMultiplier") then return end
		
		brick:FindFirstChild("Collected").Value = true

		-- Quests --

		local gbProgress

		local gb = receiver:FindFirstChild("Quests"):FindFirstChild("GoatedBrick")
		if brick.Name == "BrickD" and gb:FindFirstChild("GoatedBrickQuestCompletion").Value == false and gb:FindFirstChild("GoatedBrickStarted").Value == true then gbProgress = gb:FindFirstChild("GoatedBrickStarted"):FindFirstChild("Progress") end
		
		if gbProgress ~= nil then gbProgress.Value += 1 end
		
		local wbProgress
		
		local wb = receiver:FindFirstChild("Quests"):FindFirstChild("WeakBrick")
		if brick.Name == "BrickA" and wb:FindFirstChild("WeakBrickQuestCompletion").Value == false and wb:FindFirstChild("WeakBrickQuestStarted").Value == true then wbProgress = wb:FindFirstChild("WeakBrickQuestStarted"):FindFirstChild("Progress") end
		
		if wbProgress ~= nil then wbProgress.Value += 1 end
		
		-- --
		
		-- Multipliers + Award Bricks --
		
		local brickS: NumberValue = receiver:FindFirstChild("leaderstats"):FindFirstChild("Bricks")
		
		local TotalMultiplier = receiver:FindFirstChild("Multipliers"):FindFirstChild("TotalMultiplier").Value

		brickS.Value += round(brick:FindFirstChild("Worth").Value * TotalMultiplier)

		local cb = receiver:FindFirstChild("CurrentBricks")
		cb.Value -= 1


		-- --

		local soundEvent: RemoteEvent = sfxEvent:FireClient(receiver, ss[brick.Name], brick)

		brick:Destroy()

		local cd = cdT[receiver:FindFirstChild("SpawnBrickCooldown").Value][1]

		-- Fast Spawn at max BrickSpawnCooldown --
		if cd == 0 then 

			local pick = random(1, 2)

			if pick == 1 then

				local onCD = receiver:FindFirstChild("OnCD") -- BoolValue, parented to the player, that checks if the spawning is on cooldown

				local brick = receiver:FindFirstChild("NextBrick").Value -- picks a random bricktype using the modulescript

				if receiver:FindFirstChild("LockPurple").Value > 0 then brick = "BrickD" end

				PlaceBrick(receiver, brick) -- makes another script actually place the brick

				onCD.Value = false

			end

		end
		
	end

end

function BrickCollection.collect(otherPart: BasePart, player: Player, brick: Part)
	
--	print("CollectBrickFired")

	local pv 
	
	if otherPart:FindFirstAncestorOfClass("Model"):FindFirstChild("Player") ~= nil then 
		
		if otherPart:FindFirstAncestorOfClass("Model"):FindFirstChild("Player").Value == player then 
			
			pv = otherPart:FindFirstAncestorOfClass("Model"):FindFirstChild("Player").Value 
			
		end 
		
	end
	
	if pv ~= nil then awardBricks(pv, brick) return end
	if otherPart:FindFirstAncestorOfClass("Model") == player.Character then awardBricks(player, brick) return end

end


return BrickCollection

Thanks for any help! (also massive thanks to @BadDad2004 who already helped alot)

3 Likes

The touched event fires multiple times when a player moves. You have a debounce, but no task.wait in it which could be causing your lag.

Try printing each hit item name when the Touched event fires. Also maybe print how many items are being added to your table. If the script is adding a single Part numerous times that could cause issues.

3 Likes

The task.wait() slowed down the infinite rise of the rate/s in the dev console.
I do not know what you meant when you mentioned a table…? Could you please clarify?

A table is a object, well actually a variable that holds multiple objects or variables and such, as a example:

local myTable = {}

local playerData = {
    name = "John",   -- key is 'name', value is 'John'
    score = 100,     -- key is 'score', value is 100
    level = 5        -- key is 'level', value is 5
}
1 Like

I know what a table is. I dont know which table @Scottifly meant because I don’t believe there are any tables


local touches = {}
local connection = child.Touched:Connect(function(otherPart: BasePart)
if touches[otherPart] then return end
touches[otherPart] = true
debounce = true
---etc...
1 Like

I dont really understand that… could you please explain it?

Also another thing I have noticed: The lag only occurs in roblox servers. (Studio works just fine)

touches is a table. Whenever a Connect event occurs, it checks if the otherpart is already in the touches table and returns if it is. If not, it will add it to the table, so any subsequent checks on that part will not complete.

But the otherpart is the hitbox. Will it not “stun” the hitbox’s functionality?

Either way, the problem remains:

What works fine in studio, breaks on roblox servers / team test.

The rate is usually at 200 during a regular test and at +2000/s in team testing or the published game.

If the rate/s rises indefinitely every time you are not in studio I wouldn’t be surprised if that is an issue with the Roblox monitoring tab for the rate/s itself.

1 Like

I saw this and assumed you were using tables to place the Parts in.

local NameTable = {"BrickA", "BrickB", "BrickC", "BrickD"}

Did you try printing the .Name of the Part that was touched that I asked about?

If a script or place works in Studio but breaks on the server it’s likely because you have an issue with how the server and client are being used.
When you test in Studio the entire client/server setup is handled by your computer, which talks to itself easily. When you are dealing with any delay or incorrectly referenced item (I think a local script may work on your computer during testing as a server type script, but don’t quote me on that) it may be due to this kind of issue.

1 Like

No, I dont think it has anything to do with the client-server difference. That would most likely also spam errors in the output. And yes, I have already tried printing the name of the otherpart
This was always the hitbox of the collector

I changed the script once more: in a way, where it only destroys the bricks. It still caused masses of lag

Another Note: I managed to reduce the script activity to (amountOfPlayers)% by adding another script that checks for brick collections in the hitboxes.
The network RECV also went down from about 150kb/s → 60kb/s
The servers are STILL lagging a whole lot even though the rates are now consistently (not properly tested) at about 7k/s on a 3 player server

Additionaly: The place’s memory is rising a lot. “PhysicsParts”'s memory increase isn’t stopping
Is this because a type of my npcs model contains a union? The NPCs are bein deleted after moving about 120 studs

I found a solution: I removed the bricks on the server side and replaced them with CFrame values. The bricks will now only be displayed as bricks on the client.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.