Status bar not working

I’m trying to make a status bar for my game, but the text will not show!
Here’s the explorer:


Here’s the main script

local RepStore = game:GetService("ReplicatedStorage")
local SerStore = game:GetService("ServerStorage")
local StarterGui = game:GetService("StarterGui")
local Players = game:GetService("Players")

--Other Vars
local Status = RepStore:FindFirstChild("status")
local Lives = RepStore:FindFirstChild("Lives")
local Icons = StarterGui.HUD.Icons

while wait(1) do
	
	--Wait For Enough Players
	repeat
		
		Status.Value = "Not Enough Players"
		wait(1)
	until #Players:GetPlayers() >2
	
	--Intermission
	
	for i = 60,0,-1 do
		Status.Value = "Intermission: "..i
		wait(1)
	end

Here’s the Client Side Script

local RepStore = game:GetService("ReplicatedStorage")
local SerStore = game:GetService("ServerStorage")

local StatusText = game:GetService("StarterGui").HUD:FindFirstChild("Status").StatusTitle.Text
local Status = RepStore:FindFirstChild("status")

Status:GetPropertyChangedSignal("Value"):Connect(function()
	StatusText = Status.Value
end)

(I am a new Dev, so if this some simple error, please forgive me. There were no error’s in the output.)

the status text wont change because you are changing the startergui and not the playergui.

Hmm… 2 things.

  1. I don’t know why you have a variable in your LocalScript for ServerStorage, because the client can’t even access that.

  2. You’re using game.StarterGui. You should be getting your status bar from the player’s PlayerGui. Example code:

local player = game.Players.LocalPlayer

local text = player:WaitForChild("PlayerGui").HUD:FindFirstChild("Status").StatusTitle.Text
-- etc etc
1 Like

Here’s the code now, still not working for some reason.

local RepStore = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer
local StatusText = player:WaitForChild("PlayerGui").HUD:FindFirstChild("Status").StatusTitle.Text
local Status = RepStore:FindFirstChild("status")


Status:GetPropertyChangedSignal("Value"):Connect(function()
	StatusText = Status.Value
end)

Make sure the value in ReplicatedStorage is named exactly “status”, as referenced in your script. If that’s correct, and it still doesn’t work, try the following code:

local RepStore = game:GetService("ReplicatedStorage") -- gets the 'ReplicatedStorage' service
local player = game.Players.LocalPlayer -- gets the local player
local StatusText = player:WaitForChild("PlayerGui").HUD:FindFirstChild("Status").StatusTitle.Text -- the status bar's text

StatusText = Status.Value -- setting the status bar's text to the value from ReplicatedStorage by default
Status:GetPropertyChangedSignal("Value"):Connect(function() -- if the value changes, etc etc
	StatusText = Status.Value
end)

Here’s how I would write your ServerScript

local Services = require(game:GetService("ReplicatedStorage").Services) -- obvsly you don't have this so you will have to fix the Services yourself

local debounce = false
local RS = Services.ReplicatedStorage
local Status = RS.status


local cons 
local function intermission() 
	cons = Services.RunService.Heartbeat:Connect(function() 
        if debounce then return end
	    if #Services.Players:GetPlayers() >= 2 then
		  debounce = true
	    end
		for i = 1, 60, 1 do
			Status.Value = "Intermission: "..i
			wait(1)
		end
	end)
end

local function CharacterAdded(character) 
	intermission()
end

local function PlayerRemoving() 
	if #Services.Players:GetPlayers() <= 2 then
		debounce = false
		cons:Disconnect()
		cons = nil    
	end
end

local function PlayerAdded(player) 
	CharacterAdded(player.Character or player.CharacterAdded:Wait())
	player.CharacterAdded:Connect(CharacterAdded)
	player.PlayerRemoving:Connect(PlayerRemoving)
end

for _, plr in pairs(Services.Players:GetPlayers()) do
	spawn(function() 
		PlayerAdded(plr)
	end)
end

Services.Players.PlayerAdded:Connect(PlayerAdded)

Thank you for your suggestion! I’m a beginner scripter, and this is a little complicated for me. Would you mind explaining the code? (I’d love to learn!)

Alright, I’ll do my best, meanwhile, please do mind the error I’ve now fixed, so you should review the changes that has been made.

Generally, infinite loops (while true) are used incorrectly. Most of the time you want an exit condition, but that is a bit complicated to comprehend at the moment, so just do not use them yet. You simply didn’t think it through enough! And we don’t really need the repeat loop either since… well we only need to change the value of the text label whenever a change prompts it.

This is where logical creativity comes in. Fundamentally, you’re saying "whenever there are not enough players, we want the text label to say “not enough players!!”. In this scenario, we need two things. A trigger and a check. A trigger for when we should change the text and a check to see how many players we currently have.

I’ll now write pseudo code (…code that abstractly shows the concept but it is not real coding) to explicitly explain how it should look.

    trigger.Connect(function() 
        checkhowManyPlayers()
    end)

Alright! So, let’s dive into some real coding. Ultimately, it’s about players, so whenever a new player joins we check again, how many players do we NOW have. A useful event is called PlayerAdded, whenever a player joins, this event fires.

    game.Players.PlayerAdded:Connect(function() 
        checkhowManyPlayers() -- this is still pseudo
    end)

Alright, what can we do to get how many players we have! If you’re familiar with tables, maybe you didn’t know that you could get the size of this table by putting a # in front of it. For example #table → for ex: 4.

    ex: 
    local table = {
        1,
        2,
        3,
        "apple",
    }

We can see that the table has 4 values, thus when we do #table, it will give us 4 because there is 4 values in it. And as many knows, game.Players:GetPlayers() returns a table of all the players. Thus…

    local players = game:GetService("Players")
    players.PlayerAdded:Connect(function() 
        print(#players:GetPlayers()) --> how many players there are in the server
    end)

Okay, so now we have a trigger for whenever we should check the playerlist. And since we want minimum two players, whenever a player is added, we will check if the serverpool is greater than 2.

    local players = game:GetService("Players")
    players.PlayerAdded:Connect(function() 
        if #players:GetPlayers() > 2 then
            -- do something!
        end
    end)

Onto the big finale, we want to make our intermission counter and, we do indeed use a for loop to increase the counter. But we also want to have the authority to cancel this loop if it occurs that some player chooses to leave and we no longer have 2 players. A common stratergy is probably to implement a boolean check inside the for loop, I am unsure which is more performant but I have chosen to use a runService connection as they are fairly optimised.

--notice how I explicitly put the connection as a value, this is so that we can use the Disconnect method later on!
local debounce = false 
local players = game:GetService("Players")

local connection = game:GetService("RunService").Heartbeat:Connect(function() 
    if debounce then return end

    if #players:GetPlayers() >= 2 then
        debounce = true
    end
    for i = 1, 60, 1 do
        Status.Value = "Intermission: "..i
        wait(1)
    end
end)

Now make this new connection into a function and mesh it into with the code we learned since before.

local debounce = false 
local players = game:GetService("Players")

local function intermission() -- made this into a function so that we can choose when to invoke it
    local connection = game:GetService("RunService").Heartbeat:Connect(function() 
        if debounce then return end

        if #players:GetPlayers() >= 2 then
            debounce = true
        end
        for i = 1, 60, 1 do
            Status.Value = "Intermission: "..i
            wait(1)
        end
    end)
end

players.PlayerAdded:Connect(function() 
    intermission()
end)

And the more advanced API, playerRemoving, whenever the player leaves the game, we want to check whether we still have more than 2 players.

local function PlayerRemoving() 
    if players:GetPlayers() <= 2 then
        debounce = false
        cons:Disconnect()
        cons = nil    
    end
end

The end reuslt will be this.

local debounce = false 
local players = game:GetService("Players")

local function intermission() -- made this into a function so that we can choose when to invoke it
    local connection = game:GetService("RunService").Heartbeat:Connect(function() 
        if debounce then return end

        if #players:GetPlayers() >= 2 then
            debounce = true
        end
        for i = 1, 60, 1 do
            Status.Value = "Intermission: "..i
            wait(1)
        end
    end)
end

local function PlayerRemoving() 
    if players:GetPlayers() <= 2 then
        debounce = false
        cons:Disconnect()
        cons = nil    
    end
end

players.PlayerAdded:Connect(function(player) 
    intermission()
    player.PlayerRemoving:Connect(playerRemoving)
end)


1 Like

Okay, i think i understand most of it. Tell me if i’m wrong here, but basically the code checks how many players there are every frame and, if there are 2, continues with the script. I still don’t understand the PlayerRemoving function, but it seems really advanced, so feel free not to explain it to me. Overall, I think I might want to start my coding a little simpler than this, but I learned a lot, so thank you! (sorry if that came out as rude)

I ran some tests and here are a couple of interesting things I found:
Client Script:

local player = game.Players.LocalPlayer
local StatusText = player:WaitForChild("PlayerGui").HUD:FindFirstChild("Status").StatusTitle.Text
local status = RepStore:WaitForChild("Status")
StatusText = status.Value

status:GetPropertyChangedSignal("Value"):Connect(function()
	print("Bruh")
	StatusText =  status
end)

I found that the “Bruh” doesn’t print, so the client isn’t detecting the change.
However, the value itself (in repstore) is indeed updating

put this script under statustitle

local plr = game.Players.LocalPlayer
local gui = script.Parent

game.ReplicatedStorage.Status.Changed:Connect(function()
 gui.Text = game.ReplicatedStorage.Status.Value
end

-- Edit: Posted before I finished

Is this to Replace the client script? or just in addition to it

It worked! TYSM. Thank you to everyone for their contributions.