Pulse to music script lagging game

I’m currently working on a vibe game and I have made a script that tweens Camera FOV, Neon Parts Transparency & Point Lights Brightness. But the issue is, this script makes my game go 10 FPS. This is a localscript, located in StarterPlayerScripts.

I know, I am using RunService which is a really bad practice. Please let me know if there is anything I could optimize it and make it less laggy.

function soundPlayback(sound)
	local Camera = game.Workspace.CurrentCamera	
	if (sound.PlaybackLoudness/1000) >= 0.30 and Camera.FieldOfView < 74 then
		local Properties = {FieldOfView = 68 + (sound.PlaybackLoudness/100)}
		local Info = TweenInfo.new(0.09, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
		local T = game:GetService("TweenService"):Create(game.Workspace.CurrentCamera, Info, Properties)
		T:Play()
		
		for i, v in pairs(game.Workspace:GetDescendants()) do
			if v:IsA("Light") then
				local Properties2 = {Brightness = (sound.PlaybackLoudness/250)}
				local Info2 = TweenInfo.new(0.09, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
				local T2 = game:GetService("TweenService"):Create(v, Info2, Properties2)
				T2:Play()			
			end
		end
		
		for i, v in pairs(game.Workspace:GetDescendants()) do
			if v:IsA("BasePart") and v.Material == Enum.Material.Neon then
				local Properties2 = {Transparency = 0.25 +  sound.PlaybackLoudness/1000}
				local Info2 = TweenInfo.new(0.09, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
				local T2 = game:GetService("TweenService"):Create(v, Info2, Properties2)
				T2:Play()
			end
		end
	else
		local Properties = {FieldOfView = 68 - (sound.PlaybackLoudness/1000)}
		local Info = TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.In)
		local T = game:GetService("TweenService"):Create(game.Workspace.CurrentCamera, Info, Properties)
		T:Play()
		
		for i, v in pairs(game.Workspace:GetDescendants()) do
			if v:IsA("Light") then
				local Properties2 = {Brightness = (sound.PlaybackLoudness/1000)}
				local Info2 = TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
				local T2 = game:GetService("TweenService"):Create(v, Info2, Properties2)
				T2:Play()
			end
		end
		
		for i, v in pairs(game.Workspace:GetDescendants()) do
			if v:IsA("BasePart") and v.Material == Enum.Material.Neon then
				local Properties2 = {Transparency = 0 + sound.PlaybackLoudness/1000}
				local Info2 = TweenInfo.new(0.09, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
				local T2 = game:GetService("TweenService"):Create(v, Info2, Properties2)
				T2:Play()
			end
		end
	end
end


game:GetService("RunService").RenderStepped:Connect(function()
	soundPlayback(game.Workspace.CurrentMusic)
end)
1 Like

You’re doing tweens every frame, which is pretty bad for performance.

Instead of tweening the properties of everything, just set it to the property. You don’t need to use tweens when its updating hopefully 60 times a second.

2 Likes

But I need it to be really smooth. I can stop using tween, but don’t you think changing your FOV and all lights brightness constantly is pretty weird.

It will be smooth, thats what RunService.RenderStepped is for.

1 Like

Oh thanks, I’ll try removing tween and see how it looks.

Performance A big reason why this is lagging your game is because you are iterating many instances every frame.
		for i, v in pairs(game.Workspace:GetDescendants()) do
			if v:IsA("Light") then
				local Properties2 = {Brightness = (sound.PlaybackLoudness/1000)}
				local Info2 = TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
				local T2 = game:GetService("TweenService"):Create(v, Info2, Properties2)
				T2:Play()
			end
		end
		
		for i, v in pairs(game.Workspace:GetDescendants()) do
			if v:IsA("BasePart") and v.Material == Enum.Material.Neon then
				local Properties2 = {Transparency = 0 + sound.PlaybackLoudness/1000}
				local Info2 = TweenInfo.new(0.09, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
				local T2 = game:GetService("TweenService"):Create(v, Info2, Properties2)
				T2:Play()
			end

All you have to do here is combine them into one for loop (Example of optimized code)

for _, v in ipairs(workspace:GetDescendants()) do -- ipairs > pairs for iterating arrays
   if v:IsA("Light") then 
       -- code
   elseif ( v:IsA("BasePart") and v.Material == Enum.Material.Neon ) then
      -- code
   end
end

Another thing you can do to greatly improve performance is to store constants. In the loops you wrote you retrieved a service and created a new TweenInfo every iteration, instead just cache the service and TweenInfo at the top of the script.

	local Camera = game.Workspace.CurrentCamera	
	if (sound.PlaybackLoudness/1000) >= 0.30 and Camera.FieldOfView < 74 then
		local Properties = {FieldOfView = 68 + (sound.PlaybackLoudness/100)}
		local Info = TweenInfo.new(0.09, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
		local T = game:GetService("TweenService"):Create(game.Workspace.CurrentCamera, Info, Properties)

???
You create the variable Camera then proceed to not use it?


Readability The way you are currently structuring your code makes it nearly unreadable. You have many unneeded loops and if statements. For example the whole purpose that you have for the if statement is to create 2 different tweens, but the rest of the code is mostly the same. There is no point to repeating yourself.

Pieces of code that are in RunService events should be optimized to their full capacity for the reason of they are running 60 times a second (max).

2 Likes

Ah I’ve seen the OP read the thread I made, which wasn’t the best solution as it was a demo I recently updated the code shown below! And in the way, I did the neon size was simply by just setting the part size using the playbackloudness. Thus you only need to use one created tween.

function soundPlayback()
	local Camera = workspace.CurrentCamera -- reference this somewhere at the top to cache
	local Tween = game:GetService("TweenService") -- same with this
	local Info = TweenInfo.new(0.10, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut) -- also this.

	local Properties

	if (sound.PlaybackLoudness/1000) >= 0.30 and Camera.FieldOfView < 74 then
		Properties = {FieldOfView = 68 + (sound.PlaybackLoudness/100)}
	else
		Properties = {FieldOfView = 68 - (sound.PlaybackLoudness/1000)}
	end

	local T = Tween:Create(Camera, Info, Properties)
	T:Play()
end

Not to mention using delta if you’re using RunService.

1 Like

Yup, I took most ideas for the script from your script and I really appreciate you. However, you script were not laggy at all - it became laggy after I added light & neon pulse.

But the main issue i found in my script was, I was using game.Workspace:GetDescendants() constantly which was causing extreme lag. And to fix the issue, I made a table and put all the desired items in the table first manually - then looped through it which made the perfomance much smoother.

1 Like

Yeah I’d of imagined! But just for the sake of optimising it. That’s good you’ve managed to fix it! I just iterate through a folder named, ‘SoundParts’ then do stuff from there on.

1 Like

Another thing you can do to greatly improve performance is to store constants. In the loops you wrote you retrieved a service and created a new TweenInfo every iteration, instead just cache the service and TweenInfo at the top of the script.

GetService is a very optimal function, it should be cached in a variable since it’s good practice but do note that retrieving it won’t create the service again if it already exists, so that won’t cause a noticeable pefromance difference.

Pieces of code that are in RunService events should be optimized to their full capacity for the reason of they are running 60 times a second (max).

This isn’t accurate, RunService events can fire more than 60 times assuming the client is getting higher FPS via an fps unlocker (assuming you’re using them on the client).