Does having many while loops across multiple different server scripts take a toll on performance? If so, what’s the most efficient way to listen for things from the server side constantly?
depends on the while loop
if its a while loop that will stop quickly, for example
local i = 60
while i > 0 do
i -=1
task.wait()
end
these dont do much performance wise (unless you have a ton of them all using up the cpu)
if the loop never ends (a while true) then that will freeze your game because its trying to loop forever all at once (not possible)
so some people do a waited while true
while true do
task.wait()
end
OR
while task.wait() do end
some people think these dont cause problems but they do if you leave them for a while. this loop is never ending and after some time your game will start to slow down a lot leading eventually to a crash (from my experience)
so whenever you want repeat something that will last for a long time. use RunService
for stuff involving the screen → RunService.RenderStepped
for stuff involving physics → RunService.Heartbeat (theres also RunService.Stepped that runs before the main physics update, but in my opinion its not very good to use it for complex computations)
its still fine to use while loops but you have to remember to stop them at some point
while loops are great for things that must wait (for example, pathfinding), you can also do this in RunService with debounces (waits dont work in RunService) but its more work
RunService doesn’t work on the server side though.
RunSevice.RenderStepped is client only
RunService.Heartbeat and RunService.Stepped is server and client
While loop is cost-performant by nature. You can seek .Changed
or .GetPropertyChangedSignal
event to listen for things as an alternative. I believe it takes up memory, but it stresses less.
The performance difference between using a RunService.Heartbeat connection or a while loop with RunService.Heartbeat:Wait() is negligible or non existant.
from my experience when i used while loops that last a long time the game would crash
So how would I check a value constantly from the server side that is performant friendly?
You can just do what @.nvthane said
This is an example of GetPropertyChangedSignal
local workspace = game:GetService("Workspace")
local part = workspace.Part
part:GetPropertyChangedSignal("Name"):Connect(function()
print("Name of the part is now "..part.Name)
end)
I’m trying to detect when the player has run out of food, currently I’m doing this:
RunService.Heartbeat:Connect(function()
if Food.Value <= 0 then
Humanoid.Health -= 0.100
end
end)
Which is not good for performance.
Food:GetPropertyChangedSignal("Value"):Connect(function()
if Food.Value <= 0 then
repeat task.wait(s); Humanoid.Health -= 0.1 until Food.Value > 0
end
end)
For performance, it doesn’t matter if you use RunService or a loop, you will still iterate through functions / statements. What matters is how you use the iterations in your script. In this example, I’m using an NPC to find the nearest target and moving it to them. Very basic pathfinding script.
local myNpc = workspace.NPC
local target = nil
-- The main function, as an example.
local function findNearestTarget()
for i,player in game.Players:GetPlayers() do
if player:DistanceFromCharacter(myNpc.PrimaryPart.Position) < 100 then
return player.Character
end
end
end
-- The iterator / loop.
while true do
task.wait(1)
target = findNearestTarget()
if target then
myNPC.Humanoid:MoveTo(target.PrimaryPart.Position)
end
end
-- A RunService example.
local elapsed = 0
game["Run Service"].Heartbeat:Connect(function(dt)
elapsed += dt
if elapsed < 1 then return end
elapsed = 0
target = findNearestTarget()
if target then
myNPC.Humanoid:MoveTo(target.PrimaryPart.Position)
end
end)
This is okay, not the best script you will see in pathfinding, but it will do the job in a simple game of cat and mouse. Performance in this case, is dependent on what you perform between those iterations. However, if you were to make more complicated games, such as a zombie shooter game where you need a lot of NPCs, then the performance will become detrimental.
That’s one of the main reasons why it’s vital to stay away from loops and iterating large quantities, as it can build up cost of performance. There’s many ways to optimize large quantity loops, but a very good method is to run functions based on events and not loops.
Ultimately, you’re still running the same functions but with a different iterating method. RunService is technically safer in this case because a while loop can yield and completely break the game.
So how would you go about listening for this every second on the server?
RunService.Heartbeat:Connect(function()
if Food.Value <= 0 then
Humanoid.Health -= 0.100
end
end)
The RunService example that I’ve given above, has the solution. Please read the post.
Edit: Your original post is about X, and then your actual issue is Y. Respectfully, if you needed help, you should bring the actual issue into the original post, since you’re simply wasting time by not presenting the main problem.
Read about the X and Y here: https://xyproblem.info/
I did read your post, you stated that there’s no difference between while loops and run service ↓
You said its all about iterations, if that’s the case, then run service wouldn’t be a viable option either in a case where I do have a large game.
This should be fine if it’s only one per player, but you should multiply 0.100
with the amount of time since the last frame or it will be inconsistent.
I’m not going to sit and argue about what iterations are, nor try to make you understand the deeper level of iterations, but the solution is inside my first post. You can read more about RunService events like Heartbeat that passes a delta time parameter.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.