My current problem is mostly with the first requirement. Following is my way of implement “180 seconds per game”
-- in ServerScript
local gameLength
while true do -- game loop
-- some game logic
gameLength = 180
while gameLength > 0 do
wait(1)
gameLength = gameLength - 1
end
end
I actually learn this code from Alvin_Blox’s Youtube video. It works.
But I don’t know whether I am doing it the good way.
That link is probably what you read, but to summarize: wait() will wait a minimum of the time specified in the parentheses, it can wait a lot longer though in bigger games. The link puts an emphasis on avoiding the need for wait() all together instead of yielding the thread with wait().
A possible solution is using Heartbeat connected to a function. Capture tick() as soon as the match starts and add 180 seconds to it. Check and debounce as-needed.
PROS:
If Heartbeat is connected to a function, then you can always disconnect the RBXSignal when it isn’t in use.
This Heartbeat event function can be set up to only start when there is a timer needed so it isn’t constantly running forever.
You can, in theory, set this up as a single module that connects to any function that needs the same functionality of wait. For example: a script passes how long it wishes to wait and your Heartbeat module starts the event connection, then adds the time you want to wait to tick() and stores that value in a table. A different script also needs to wait a certain amount of time, so it calls the module sending its wait time as well; the script then adds the wait time to the table as well. Each frame the module checks both values and sends a response back to the calling script if its time is up and deletes its entry inside the table.
Having only one Heartbeat event connection like this can also be used to guarantee the specific order code is run.
It will also guarantee when the code will run (as opposed to wait() potentially yielding for longer than expected)
CONS:
Having too much code underneath the Heartbeat can cause some serious delays and make the subsequent functions out of sync. A coroutine may solve this problem, but be extra careful threads aren’t created every frame. Instead only use Heartbeat to check if tick is >= the value stored in the table and only then create a thread for each value as-needed to tell the calling script that the time is up.
The threads aren’t trapped inside the module, but instead return to the script that called them as soon as they add their entry to the table. While this isn’t necessarily bad, it does mean there needs to be a method to have the module connect back to the correct calling script (Bindable or if the calling script is a Module, an Initialize is needed to get around a cyclic dependency if the latter is used).
Since Heartbeat is bound to frame frequency, this means that Heartbeat is a variable frequency. What this means is that it will run more times on a more powerful machine and less times on a less powerful machine. Again, this isn’t bad, but it is definitely something to keep in mind. It can cause issues if the server expects every client to send a small packet at the same time. (Not saying you’ll run into this issue, but keep it in mind when working with anything that runs off of frame frequency)
It’s more complicated to set up rather than just having a loop that uses wait(180).
Once set up, then it should be a completely non-yielding alternative to wait(). It’s actually on my to-do list to make it, so I can’t really say for sure if there are any other kinks to work out or if something unforeseen could wreck this entire idea. The good news is it shouldn’t be that hard to set up.
There shouldn’t be any issues with using wait()
Using wait is actually very handy as it allows you to have more control over how fast your scripts run so you can prevent all kinds of disasters from happening.
For example a simple while loop like this could crash games:
while true do
Instance.new("Part",game.Workspace)
end
This is because it will try to run it as many times as quickly as possible as there are no waits and no limitations set. Using a simple wait can prevent game crashes from simple things.
I recommend using a numeric for instead - it’s a lot more readable and cleaner to use.
for Count = 180, 1, -1 do
print("Seconds left:", Count);
wait(1);
end
If you’re concerned about wait (which you really shouldn’t, unless if its duration time’s so low it doesn’t make a difference), you could try using @Maximum_ADHD’s custom task scheduler and see how it fares.