Elegant way to set match length to 180 seconds

My specs:

  • each match last 180 seconds
  • when match ends, new game start automatically
  • player can use tool to change match length

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.

I remember vaguely that Wait() is not good.

Any thoughts?

2 Likes

If you do not want to set the remaining time of the round in the GUI, etc, you can set it to wait(180).

The method is the same. This post category is the code review

?

Who is hwa??? Your language is strange

Your code isn’t new and he looking for a way to avoid using wait().

Good, do you have a better code to use

This is what I know and it works well

If you have another method, tell us about it so everyone can benefit from it

I entered here to learn and correct my mistakes

He don’t need working code. he looking for a way to avoid using wait()

I’m sorry

Most of the time the translation is not comprehensible

I also look for another way, but I didn’t find it

1 Like

The reason Wait() not good because it is deprecated but that doesn’t mean it won’t work.

Instead of using a while loop, it’s much better to use a for loop which eliminates the use of a while loop inside a while loop.

    if gameLength > 0 do
        for i = gameLength, 0, -1 do
            gameLength -= i
            wait(1)
        end
    end

Here is the reason why wait() is avoided.

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:

  1. If Heartbeat is connected to a function, then you can always disconnect the RBXSignal when it isn’t in use.

  2. This Heartbeat event function can be set up to only start when there is a timer needed so it isn’t constantly running forever.

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

  4. Having only one Heartbeat event connection like this can also be used to guarantee the specific order code is run.

  5. It will also guarantee when the code will run (as opposed to wait() potentially yielding for longer than expected)

CONS:

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

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

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

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

1 Like

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.

1 Like

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.

Thx for everyone, especially to @SteelMettle1 :smiley:

I still need time to digest everything. I don’t know much about heartbeat. But it seems promising.