Adding timer to waiting for 6 players

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Starting the game when there is 6 players (can do) OR when 30 seconds passed
  2. What is the issue? Include screenshots / videos if possible!
    I cant figure out the second part
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    i tried adding a repeat adding 1 to a string when there’s one player until 30 but everything else seems to stop.
    After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
local players = game.Players:GetChildren() 
local timer = script.Parent.Frame.timer --UI for timer
local value = timer.Value -- value for timer
local UI = script.Parent.Frame["Player count"] --UI for player
local ready = false -- if the fame is ready this is true


while true do
	timer.Text = value.Value -- so when i change value itll replicate to UI
end



if #players <= 1 then -- theres a better way to do this id image but idk
	UI.Text = ("1/6")
elseif #players == 2 then
	UI.Text = ("2/6")
elseif #players == 3 then 
	UI.Text = ("3/6")
elseif #players == 4 then
	UI.Text = ("4/6")
elseif #players == 5 then
	UI.Text = ("5/6")
elseif #players == 6 then
	UI.Text = ("6/6")
	if ready == true then return end
	ready = true
end



if ready then
	print("Selection time")
end

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

1 Like

Note beforehand: The topic was a little vague (partially because I only skimmed it) and this code is all untested. I have no idea if it works, but the logic is there. I don’t know if you wanted the timer to count down and THEN check if there was enough players to play, or if you wanted the timer to count down and the player label update at the same time.

Did my best to make it understandable. Also, as far as the UIs and the LocalScript go, I pretty much took a guess on where the UIs may have been parented to and what they might’ve been named.


There’s some things you need to realize before help can be provided.

  • UIs properties should be changed on the client while your round logic should be done on the server
  • Event-driven programming > yielding (.Changed event for ValueBases)
  • You should look into for loops for counting down the timer
  • You’ll need a task.wait() inside of your while true do loop anyways to prevent Studio from crashing

The setup for ReplicatedStorage:

image


How it might look on your server code (a Script under ServerScriptService)

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local timerTag = ReplicatedStorage:WaitForChild("Timer") -- Int
local playersReadyTag = ReplicatedStorage:WaitForChild("PlayersReady") -- Int

while true do
    -- Timer
    for i = 10, 0, -1 do
        timerTag.Value = i
        task.wait(1)
    end
    
    -- Wait for the players
    repeat
        playersReadyTag.Value = #Players:GetPlayers()
        task.wait(1)
    until
        #Players:GetPlayers() >= 6
    
    print("Selection time")
end

How it might look like on your client code (a LocalScript under StarterPlayer.StarterPlayerScripts)

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = playerGui:FindFirstChildOfClass("ScreenGui")
local _frame = screenGui:WaitForChild("Frame")
local timerLabel = _frame:WaitForChild("timer")
local playerCountLabel = _frame:WaitForChild("Player count")

local timerTag = ReplicatedStorage:WaitForChild("Timer")
local playersReadyTag = ReplicatedStorage:WaitForChild("PlayersReady")

timerTag.Changed:Connect(function(newTime)
    timerLabel.Text = newTime
end)

playersReadyTag.Changed:Connect(function(newAmount)
    playerCountLabel.Text = "#"..newAmount.."/6"
end)

You should always use GetPropertyChangedSignal as an alternative to Changed, as Changed is more obsolete compared to GetPropertyChangedSignal.

What’s the difference? In this case it’s simpler to use IntValue.Changed because it passes in the value and doesn’t require and if statement to check the property changed.

GetPropertyChangedSingal is also an event if you didn’t already know. The difference is the event ONLY fires when the specified Property given has changed.

Ex:

UI:GetPropertyChangedSignal("Enabled"):Connect(function()

Would only fire when the Enabled property on the UI changed.

UI.Changed:Connect(function()

Would fire if the Name, or Parent, or any of that changed.

Forgot about this part:

Nonetheless, ValueBases have only 1 useful property (.Value) so I don’t think it’s entirely necessary to change over to :GetPropertyChangedSignal although for non-ValueBase instances you should.

1 Like

“:GetPropertyChangedSignal()” is an instance method not an event, it returns an event object (RBXScriptSignal instance) through/on which you can call the instance methods “:Connect()” or “:Wait()”, the former would be to connect a callback function to the event and the latter would be to yield the thread until the signal has been fired a single time.

The “.Changed” event behaves differently for “BaseValue” instances (the base class for “Value” suffixed instances) than it does for standard instances (they have their own implementation of the event). In this circumstance the “.Changed” event would be far more favorable than ":GetPropertyChangedSignal(“Value”) because the “.Changed” event of a “ValueBase” instance specifically only fires when its “Value” property changes, if for example its “Name” or “Parent” or “Archivable” property changes the event won’t fire. The other benefit of “.Changed” is that when it fires on a “ValueBase” instance the parameter received by the event represents the “Value” property’s new value whereas when an event object returned by “:GetPropertyChangedSignal()” fires no parameters are received by the event.