Scripting optimazation

im using a script made by alvinblox where it checks for a player if they are in a specific area to play music Roblox - Play music in different areas - Scripting tutorial (2020 updated version) - YouTube However whenever it checks for a player the game slightly lags. Any idea how can i stop this?

sorry for the weird black bars i dont have a good screen recorder on hand

3 Likes

I use :GetPartsInPart then get the players in it, and it works fine for me. I don’t know what method you are using, if it is Region3, I suggest you move on to better alternatives like :GetPartsInPart.

2 Likes

Can I see the code? For help, I need what you have the script as, as you could have modified it and those videos aren’t always straight forward.

1 Like

table.clear(AlreadyCounted)
	task.wait(1)
	local OLP = OverlapParams.new()
	OLP.FilterDescendantsInstances = {game.Workspace.Coins,game.Workspace.MapParts,game.Workspace.Extra}
	OLP.FilterType = Enum.RaycastFilterType.Blacklist
	local PartsInArea = game.Workspace:GetPartsInPart(box,OLP)
	local Players = Players:GetPlayers()
	for i,v in pairs(PartsInArea) do
		local PossibleChar = v.Parent
		if PossibleChar then if PossibleChar:FindFirstChild("Humanoid") then
			local Player = game.Players:WaitForChild(PossibleChar.Name,2)
			if Player then
				if not table.find(AlreadyCounted,Player.UserId) then
					local PlrID = Player.UserId
					local ToSend = {}
					ToSend.PlrId = PlrID
					ToSend.Type = "Xp"
					ToSend.Value = 10
					table.insert(TotalToSend,ToSend)
					table.insert(AlreadyCounted,Player.UserId)
				end
			end end
		end
	end

This is one of my old scripts, but just change what is under the if not table.find(AlreadyCounted,Player.UserId) then line to what you want your function to do.

keep the table.insert()s at the bottom because that is what makes sure that the Player isn’t detected twice

3 Likes

Keep note that to detect, you need a part with CanCollide disabled so that it detects the players in the part.

1 Like

I would probably add a task.wait(0.1) in the for i,v loop. It’s a pretty interesting coding style too.

1 Like

It is not a heavy task so it is not needed, but can be added.

(Unless there are 40-400 people in the part, then that would need it.)

2 Likes

Yeah, add a task.wait(0.1) there, or increase the time on line 2, make it 2 or something to decrease lag.

1 Like

It was one of my older scripts (I say old, it is about a Month old). And I sure am far better at scripting then I was a month ago.

task.wait() would make each loop be seperated by a heartbeat.

If something like 0.1 is in task.wait(), that means 10 players detected per second, which is pretty slow.

task.wait() or task.wait(0.02) would be fine.

2 Likes

It depends on the size of the game. If it’s a small game, then 10 per second is fine, to reduce on lag as much as possible. If you’re in the beta program and you have a 700 player game, then I would remove the wait altogether, the servers will already be super laggy.

1 Like

But even a change from 0.1 to 0.05 would not make much lag.

The system itself, even when run every heartbeat, is not performance-hogging and would be fine eithier way.

1 Like

Yeah, I’m waiting for @pvnchys and his lag at this point, yoursdoesn’t have that much of a performance tank from looking at it.

local SoundRegionsWorkspace = game.Workspace:WaitForChild("SoundRegions")

local Found = false

while wait(1) do

	for i, v in pairs (SoundRegionsWorkspace:GetChildren()) do

		Found = false
		local region = Region3.new(v.Position - (v.Size/2),v.Position + (v.Size/2))

		local parts = game.Workspace:FindPartsInRegion3WithWhiteList(region, game.Players.LocalPlayer.Character:GetDescendants())


		for _, part in pairs(parts) do
			-- Loop one by one through the parts table
			if part:FindFirstAncestor(game.Players.LocalPlayer.Name) then
				print("Player was found")
				Found = true
				break
			else
				Found = false
				print("Player was not found in region")
			end
		end

		if Found == true then
			-- Start playing some music
			if script.Parent.SoundRegions[v.Name].IsPlaying == false then
				script.Parent.SoundRegions[v.Name]:Play()
				break
			end
		else
			script.Parent.SoundRegions[v.Name]:Stop()
		end

	end
end

I’m not sure why Region3 is being used when the Touched event should be used instead, as this is a non-precise operation.

Here’s an example of something I made back in 2019:
Area Sound Kit v4
(I would also disable CanQuery if using raycasting of any kind.)

1 Like
local SoundRegionsWorkspace = game.Workspace:WaitForChild("SoundRegions")
local Found = false
while task.wait(1) do
	for i, v in pairs (SoundRegionsWorkspace:GetChildren()) do
                task.wait(0.1)
		Found = false
		local region = Region3.new(v.Position - (v.Size/2),v.Position + (v.Size/2))
		local parts = game.Workspace:FindPartsInRegion3WithWhiteList(region, game.Players.LocalPlayer.Character:GetDescendants())
		for _, part in pairs(parts) do
                        task.wait(0.1)
			if part:FindFirstAncestor(game.Players.LocalPlayer.Name) then
				Found = true
				break
			else
				Found = false
			end
		end
		if Found == true then
			if script.Parent.SoundRegions[v.Name].IsPlaying == false then
				script.Parent.SoundRegions[v.Name]:Play()
				break
			end
		else
			script.Parent.SoundRegions[v.Name]:Stop()
		end

	end
end

I have optimized it for you, later on I might minify it if I feel like I want to. Right now, it shouldn’t have that much lag anymore. Lmk about any further issues :+1:

Also, always use task.wait() instead of wait().

1 Like

.1 wait is what is going to cause the lag, as there would be a significant delay between detecting the parts.
Makes no sence to add little lag optimization to delay a script, which is a type of lag.

It’s not lagging the client anymore, I dont think that it needs to be instant.

task.wait() with no parameters is not instant but frequent, and that would prevent both delay and lag. Win-win situation.

1 Like

I made a function that would take a part with some overlap params (if any) and detect and return the players in the part as an array:

local function GetPlayersInPart(part:Part,OLP:OverlapParams?)
	local TotPlr = {}
	local InstancesInPart = workspace:GetPartsInPart(part,OLP or OverlapParams.new())
	
	if InstancesInPart then
		for _, P in pairs(InstancesInPart) do
			local PosChar = Players:GetPlayerFromCharacter(P.Parent)
			if PosChar then
				if not table.find(TotPlr,PosChar)then
					table.insert(TotPlr,PosChar)
				end
			end
		end
	end
	return TotPlr
	
end

this does the job even better, thank you!!!

1 Like