This code makes a countdown timer in the game and checks whether there are enough players in the game; if they are, the game automatically starts. I just wanted to know if there is a way to make the code more efficient/faster.
local timeLeft = 60
for players = 1,2,1 do
local player = Instance.new("Part", game.Players)
end
while true do
local playersInGame = #game.Players:GetChildren()
if playersInGame >= 3 then
break
end
print(playersInGame)
timeLeft = timeLeft-1
if timeLeft < 0 then
break
end
game.StarterGui.ScreenGui.Frame.TextLabel.Text = timeLeft
wait(1)
end
print("Game starting!")
timeLeft = 60
game.StarterGui.ScreenGui.Frame.TextLabel.Text = timeLeft
Yes. You can improve on efficiency and practice here.
I’m not sure what the point of the for loop is, but don’t put non-Player objects in the Players service. If you need to test code that requires two or more players, look into Multi-Client Simulation instead. This feature was specifically created for use cases much like your own.
Be consistent. Use GetService whenever you need to access a service, avoid using dot syntax. Later down the line when you need to start interacting with other services that require the use of GetService (either because they’re inaccessible in the DataModel through direct indexing or because they aren’t named properly), you’ll have a jarring mix of GetService for some services and others without it.
Use GetPlayers when you’re trying to get the players in a game, not GetChildren.
Updates to StarterGui will not be seen by other players, nor should you ever use the server to modify player Guis. Look into Remote Functions and Events to have the server communicate updates to the client about the game’s status, or take advantage of the replication behaviour of ValueObjects such as StringValue to help you here. If you don’t understand the applicability of replication, start familiarising yourself with the Roblox Client-Server Model.
Wait never waits exactly one second unless you’re a lucky magician who can get that to happen. The wait function will yield a thread for the amount of seconds you specify but then it must also slip the thread into an open slot to be resumed, so it spends extra time waiting. A busy scheduler can have your thread waiting for a while: some cases have had a wait(1) end up waiting 3 seconds instead (1 for yielding, 2 for looking for an open resume slot). If you want to obtain a degree of precision, look into a custom wait system with Heartbeat. There are some already made implementations on the web though, like Quenty’s heartbeatWait. Make sure to credit licensed external resources.
The reason I didn’t use getplayers was because I was using parts to act as players, since my laptop crashes when using multi-client simulation. However, I will take the rest of the things you said in mind. Thank you for the detailed response!
Well ultimately the client’s FPS doesn’t matter here because hopefully you will be running this script from the server-side and not the client-side.
Heartbeat fires with a deltaTime argument which tells you how many miliseconds elapsed between the last frame and the current frame in which Heartbeat fired for. The key isn’t to make it fire every second but rather to check that the approximate amount of time elapsed exceeds at least one second: and if it hasn’t, then to keep tracking that.
Lazy impelmentation of a Heartbeat wait I just wrote that can help you visualise this:
local Heartbeat = game:GetService("RunService").Heartbeat
local function newWait(seconds)
local msElapsed = 0
while msElapsed < seconds do
msElapsed = msElapsed + Heartbeat:Wait()
end
end