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)
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.
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).
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.
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.
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.
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).