I am reworking a racing system I made a while ago, and it used while loops to detect players in a start point and end point. Now I know that using while loops to do that would cause a lot of lag, so I need a good replacement for it. It needs to be a server script so I cannot use RenderStepped. Any suggestions are appreciated.
You could use RunService.Stepped or RunService.Heartbeat to get a similar implementation to when using RenderStepped.
But it doesn’t actually matter if you use a while loop or listen to an event that fires e.g. 30 times per second. You’ll still be doing calculations 30 times per second.
Have you actually tested it to see if it’s laggy? If it’s not a problem, don’t worry about it.
If you want us to help optimize your code, post it and tell us about your use case so we can take a look.
A module has been released called Zone+ which allows you to detect players inside a region3 area. Yeah, it uses a while loop, but that’s the only way to actually detect players. No, doing a while loop doesn’t lag the game unless you use a heavy task Doing a while loop lags depending on several factors, one of them being the time of the loop and how heavy the loop script is.
I haven’t implemented that part yet as I wanted to see if there is another way of doing it than while loops, but I wanted to fire a bindable to a main script, which looks like this:
local rs = game.ReplicatedStorage
local remotes = rs:WaitForChild("remotes")
local bindables = rs:WaitForChild("bindables")
local races = workspace:WaitForChild("races")
local racesList = {
race1 = {
participants = {},
finishedPlayers = {},
available = true,
started = false,
preparing = false,
},
}
local function getIndex(tab,val)
for i,v in pairs(tab) do
if v == val then
return true,i
end
end
return false
end
remotes.addRemove.OnServerInvoke = function(player,raceName,condition)
if #racesList[raceName]["participants"] >= 1 and not racesList[raceName]["preparing"] then
racesList[raceName]["preparing"] = true
bindables.start:Fire(raceName)
end
if condition and not racesList[raceName]["started"] then
table.insert(racesList[raceName]["participants"],racesList[raceName]["participants"]+1,player.Name)
elseif not condition and racesList[raceName]["started"] then
local found,index = getIndex(racesList[raceName]["participants"],player.Name)
if not found then return racesList end
table.remove(racesList[raceName]["participants"],index)
end
return racesList
end
bindables.start.Event:Connect(function(raceName)
local count = 10
while wait(1) do
for i,v in pairs(racesList[raceName]["participants"]) do
local player = game.Players[v]
remotes.countDown:FireClient(player,count)
end
count -= 1
if count == 0 then break end
end
races[raceName].checkPoints["1"].Transparency = 0.5
races[raceName].startLocation.Transparency = 1
racesList[raceName]["started"] = true
racesList[raceName]["preparing"] = false
end)
bindables.checkPointFinished.Event:Connect(function(player,raceName)
remotes.showFinishLocation:FireClient(player,raceName,racesList)
end)
bindables.finished.Event:Connect(function(player,raceName)
if races[raceName].endLocation.Transparency ~= 0.5 then return end
table.insert(racesList[raceName]["finishedPlayers"],racesList[raceName]["finishedPlayers"] + 1,player.Name)
if #racesList[raceName]["finishedPlayers"] == #racesList[raceName]["participants"] then
for i,finished in pairs(racesList[raceName]["finishedPlayers"]) do
if i == 1 then
game.Players[finished].cash.Value += 200
elseif i == 2 then
game.Players[finished].cash.Value += 150
elseif i == 3 then
game.Players[finished].cash.Value += 100
else
game.Players[finished].cash.Value += 50
end
end
racesList[raceName]["available"] = true
end
end)
I’m not seeing anything related to Region3 or seeing which players are in a region in the code you posted?
A couple other things:
-
getIndex
could be replaced by the built-in table.find. - Adding newlines to your code after almost every line is not great. Having newlines to group things that “belong together” is good style, but you’re overdoing it IMO.
- How would I use table.find to get the index of the value in the table?
- I include those newlines in my indentation etiquette, so in all my scripts are like that and they never bothered me
That’s what table.find(t, v)
does. It returns the index at which v
appears in t
, or nil
if it does not appear.
Interesting, I thought it was used solely for if statements, thanks for the info