Does anybody have any tips on how I could optimize my music zones script?

My game has a music zones script that seems to randomly cause massive lag spikes on the server side, making my game basically unplayable.

This is the code, does anybody have any tips on how I could optimize it?
(I originally took part of the code from another DevForum post about music zones)

local musicZones = {
	{workspace.MusicZones.TokensMusicZone, "rbxassetid://1840313516"},
	{workspace.MusicZones.ClothesMusicZone, "rbxassetid://1844487326"},
	{workspace.MusicZones.PoliceMusicZone, "rbxassetid://1839318061"},
	{workspace.MusicZones.TrainStationZone, "rbxassetid://0"},
	{workspace.MusicZones.CafeMusicZone, "rbxassetid://16755115716", 5},
}

local inPart = {}
local possiblePlayers = {}


local players = game:GetService('Players')

function check(v)
	possiblePlayers[v[1].Name] = {}

	local parts = workspace:GetPartsInPart(v[1])


	for _, part in parts do
		local player = players:GetPlayerFromCharacter(part.Parent)
		if player and not table.find(	possiblePlayers[v[1].Name], player) then
			table.insert(	possiblePlayers[v[1].Name], player)
		end
	end

	for _, player in 	possiblePlayers[v[1].Name] do
		if not table.find(inPart[v[1].Name], player) then

			if v[1].Name == "TrainStationZone" then
				game.ReplicatedStorage.Events.TrainAmbience:FireClient(player, true)
			else

				local volume = v[3]

				if not v[3] then

					volume = 0.5

				end

				game.ReplicatedStorage.Events.UpdateMusic:FireClient(player, v[2], volume)
			end



		end
	end

	for _, player in inPart[v[1].Name] do
		if not table.find(	possiblePlayers[v[1].Name], player) then

			if v[1].Name == "TrainStationZone" then
				game.ReplicatedStorage.Events.TrainAmbience:FireClient(player, false)
			else
				game.ReplicatedStorage.Events.UpdateMusic:FireClient(player, 0, 0.5)
			end
		end
	end

	inPart[v[1].Name] = 	possiblePlayers[v[1].Name]
end

for i,v:BasePart in pairs(musicZones) do
	
	inPart[v[1].Name] = {}
	possiblePlayers[v[1].Name] = {}

	v[1].Touched:Connect(function()
		

		check(v)


	end)
	
	v[1].TouchEnded:Connect(function()
		check(v)
	end)
	


end

I would have a table of Parts and another table of Sounds, with indexes respective to the first table, and a variable for the current music. When a part is touched, stop any music that’s playing, play the sound corresponding to the part, and update the current music. Have another event that detects when the current music ends where it restarts.

What about using zoneplus to trigger the sounds locally when the player enters or stop it when they exit

The problem probably arises from the fact that your GetPartsInPart function is returning a whole map load of parts and you’re looping through a lot of parts every time it’s touched (which means multiply by 7 for R6 rigs (without accessories) or 16 for R15 Rigs (without accessories).


It’s been ages, but I’m pretty sure my solution from here still works.

Though rather than using Region3 I’d use this function I have saved around since it’s way cleaner and easier to use.

local function isInsideBrick(position: Vector3, brick: BasePart)
	local v3 = brick.CFrame:PointToObjectSpace(position);
	return (math.abs(v3.X) <= brick.Size.X / 2)
		and (math.abs(v3.Y) <= brick.Size.Y / 2)
		and (math.abs(v3.Z) <= brick.Size.Z / 2);
end

Thanks for the input everybody!
This is the solution I settled on for now, might update it later to have better checks for if a player is in the brick.

local Players = game:GetService('Players')

local musicZones = {
	{workspace.Map.MusicZones.TokensMusicZone, "rbxassetid://1840313516"},
	{workspace.Map.MusicZones.ClothesMusicZone, "rbxassetid://1844487326"},
	{workspace.Map.MusicZones.PoliceMusicZone, "rbxassetid://1839318061"},
	{workspace.Map.MusicZones.TrainStationZone, "rbxassetid://0"},
	{workspace.Map.MusicZones.CafeMusicZone, "rbxassetid://16755115716", 5},
}

local inPart = {}


for i,v:BasePart in pairs(musicZones) do

	inPart[v[1].Name] = {}

	v[1].Touched:Connect(function(hit:BasePart)

		local char = hit:FindFirstAncestorOfClass("Model")

		if not char or table.find(inPart[v[1].Name], char.Name) or hit.Name ~= "HumanoidRootPart" then
			return
		end

		if char then

			local plr = Players:GetPlayerFromCharacter(char)

			if plr then
				table.insert(inPart[v[1].Name], plr.Name)
				if v[1].Name == "TrainStationZone" then
					game.ReplicatedStorage.Events.TrainAmbience:FireClient(plr, true)
				else
					game.ReplicatedStorage.Events.UpdateMusic:FireClient(plr, v[2], 0.5)
				end
				
			else
				return
			end
		end
	end)

	v[1].TouchEnded:Connect(function(hit)

		local char = hit:FindFirstAncestorOfClass("Model")

		if not char or not table.find(inPart[v[1].Name], char.Name) or hit.Name ~= "HumanoidRootPart" then
			return
		end

		if char then

			local plr = Players:GetPlayerFromCharacter(char)

			if plr then

				table.remove(inPart[v[1].Name], table.find(inPart[v[1].Name], plr.Name))
				if v[1].Name == "TrainStationZone" then
					game.ReplicatedStorage.Events.TrainAmbience:FireClient(plr, true)
				else
					game.ReplicatedStorage.Events.UpdateMusic:FireClient(plr, 0, 0.5)
				end

			else

				return

			end
		end
	end)

end

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