How can I yield my script?

I’m currently making a round based game, and I’ve come across an issue -

Everything works fine and dandy, however, after firing each remote event, I have to end up adding a wait() to stop the server from proceeding until the players have had their client sided interactions.

As of now, (and as said above) I have to put waits after firing each RE due to the fact that what I send over causes a type-writter UI effect that I want the player to be able to read before moving on, and I also have a little cutscene further down. I want to prevent timing issues from the waits I chose by adding some sort of yield in the script so that I can fire the remote, and wait for a response from the client.

And yes - I have thought of remote functions, however, the downfall to the remote functions is that you can only invoke one player at a time from the server. If there was an :invokeall event then this would patch things up.

Here is a sample of what my code looks like:

RE:FireAllClients("Notification","New round starting soon!")
		wait( (string.len("New round starting soon!")*.1) + 4 )
		
		RE:FireAllClients("Notification","Choosing this round's ghost...")

	RE:FireAllClients("Notification","Let the game commence!")
		
		wait( (string.len("Let the game commence!")*.1) + 4 )
		
		
		RE:FireAllClients("RoundStart",ChosenGhost)	

Any help would be much appreciated! thanks!

1 Like

Store the amount of players ingame in a variable, then make a variable that has a number value of 0

local counter = 0

Any time a player clicks continue it fires a remote that adds 1 to the counter’s value
and to yield, though there should be some type of safeguard just incase someone is afk

local players = game.Players:GetChildren()
local counter = 0
remote.OnServerEvent:Connect(function(player)
    counter = counter + 1
end)

local seconds = 0
repeat wait(1)
seconds = seconds + 1
if seconds >= 20 then print("Times up to read") break end
until counter >= #players
1 Like

Interesting, never thought of doing it this way, however, since I would have to do this each time I fire something important, wouldnt the excessive usage of remote events be bad for my game?

1 Like

I don’t believe so, remotes are always nice to avoid, but as long as you’re not giving the remote access to change anything in the game then really there shouldn’t be an issue. Just try to avoid putting too much stress on one remote, then latency can increase. I’ve never had an issue with that though, it’s just what I’m told from others.

To add onto what I said, for better security,

local PlayersWhoCompleted = {}
local players = game.Players:GetChildren()
local counter = 0

remote.OnServerEvent:Connect(function(player)
    if table.find(PlayersWhoCompleted,player) == nil then
        table.insert(PlayersWhoCompleted,player)
        counter = counter + 1
    end
end)

local seconds = 0
repeat wait(1)
seconds = seconds + 1
if seconds >= 20 then print("Times up to read") break end
until counter >= #players

Whenever you need to remove the player from the table

table.remove(PlayersWhoCompleted,table.find(PlayersWhoCompleted,player)
1 Like

Yielding is unnecessary,
why can’t you fire the remote for every client to let the server know interactions have been complete?

Try adding every player to a table once the event fires on the server, each time check whether #tab == #Players:GetPlayers(), if so, then all interactions have been completed.

1 Like

Same issue as @udi_g 's solution in the matter that I’ll have to be re-using the yield multiple times causing an overusage of remotes

OOF i’ve only been using 1 remote, good to know!

1 Like

You won’t have to yield at all, fire the same remote on the server.

Just fire the remote for every player once interaction is complete, on the server then add the player to a table and then check whether the number of players in the table equate to the number of players in the server, this method prevents yielding explicitly and will guarantee all users have completed interaction rather than assuming all users would have completed their interaction within a certain time window.

You could even try checking whether a certain amount of time has elapsed to disregard a client in idle state.

It’s also ideal to use canonical methodology, an array of only player objects is returned through Players:GetPlayers() unlike Players:GetChildren().

Don’t avoid Remote Events for the sake of supposed optimization, each remote has a limit of 50KB/s , not collectively.

Read this reply here (and my post there too, addressing limitations to remote events).

3 Likes