Issue with server counter

So theres a script in my game that displays how many people in the server, but about a week ago, I found an error.

Where there is 2 people in the server, it says there are 3 people in the server…
Script:

while true do
	wait(1)
	for i, v in pairs(game.Players:GetChildren()) do
		script.Parent.ServerPlayers.Text = "There is currently "..i.." player(s) in the server."
	end
end

A picture of where everything is:
Screen Shot 2020-10-08 at 1.58.37 pm

1 Like

I don’t see why a for loop is necessary here. You can use the length of the table returned from GetPlayers() as your number.

while wait(1) do
    local playerCount = #game.Players:GetChildren() -- # returns the length of a table
    thing.Text = "There is currently " .. playerCount .. " player(s) in the server."
end

Instead of a while loop, I’d suggest an event listener for Players being added/removed from your game.

local function updateText()
    -- Code to get the player count and update the text (hint hint ^^^) goes here.
end

game.Players.PlayerAdded:Connect(updateText)
game.Players.PlayerRemoving:Connect(updateText)

More explanation here if you’re new to events :slight_smile:

2 Likes

Use a PlayerAdded hook, and update the text whenever you need to.

In a PlayerAdded function increase the text’s value by 1,

In a PlayerRemoving hook decrease the text’s value by 1.

A while true do loop is pretty wasteful when you can use those two events.

1 Like

Testing this script now!
The weird thing is, it broke about a week ago, I have not edited that script for about 2 months.

He uses a loop to update the text.

1 Like

This is a much better solution, but a small adjustment I would make would be to have both the PlayerAdded and PlayerRemoving event connect to the same function that updates the text with the proper number of players. Something like this:

-- have a single function that updates player count to current number of players
local function updatePlayerCount()
    script.Parent.ServerPlayers.Text = "There is currently ".. #game.Players:GetPlayers() .. " player(s) in the server."
end
-- listen for when a player leaves/joins, and call that function
game.Players.PlayerAdded:Connect(updatePlayerCount)
game.Players.PlayerRemoving:Connect(updatePlayerCount)

I use the loop so every one second, it updates.

Im trying this script right now:

while wait(1) do
local playerCount = #game.Players:GetChildren() – # returns the length of a table
thing.Text = “There is currently " … playerCount … " player(s) in the server.”
end

It seems the most simple.

(Sorry for the three dots instead of 2, thats what devforum sets it to)

Yes, the loop is completely unnecessary. It’s similar to your task being

  • Make this value equal to 100

And your approach being

local value = 0
for i = 0, 100 do
   value = i
end

When it’s much more intuitive to simply set the value to 100 - the for loop is not needed at all.

value = 100

For clarification: I understand the purpose of the while loop and waiting one second each loop, that makes sense (even if it isn’t the most efficient method of handling this). My only concern was the inner for loop.

But would

while wait(1) do
    local playerCount = #game.Players:GetChildren() -- # returns the length of a table
    thing.Text = "There is currently " .. playerCount .. " player(s) in the server."
end

work?

Yes, if you’re not concerned with performance issues. The second method shown in my first reply is more similar to the standard way this problem should be approached. Both will work, but one is better than the other.

I might use the script I said, because I do not really understand events.

It might not create performance issues because its not really updating very often.

Did not work. Still says 2 people are in the server.
Its a roblox issue. I copied it into another place and it is working.
Only this place.

That’s the thing - it is updating every second. Regardless if the number changes or not from the last loop, the value is still being grabbed from GetPlayers() and the Text property is being updated.

A similar analogy would be only looking out the front door of your house when you’ve ordered pizza.

Ordering pizza expects an event to happen, and what will happen when the pizza man comes to your house? You will open the door! This is how events and event listeners work. They “listen” for a particular “event” to happen, and will perform an action when it does happen.
You’re “listening” for an “event” - the pizza delivery driver to come to your house. When that happens, you will perform an “action”, opening the door to receive your pizza!

When you use a while loop, you’re not considering whether or not the pizza delivery guy is at your door, or even whether or not you’ve ordered a pizza in the first place! You’re opening your door every single second, hoping pizza will come up - and maybe it will! But wouldn’t you agree that it’s a much more efficient use of your time to only open the door when you’re expecting pizza?

This same way of thinking can be applied to your problem here. Events are much more efficient and very much worth learning if you’d like to grow as a developer :smiley:

1 Like

My issue is not that its being updated, my issue is why is it always ONE above the real amount…?

Is it possible there’s another script conflicting with the one you says is producing the problem? Perhaps try changing things around in your original script. ex: Instead of #game.Players:GetPlayers(), try simply 4.

PlayerAdded and PlayerRemoving is used so that the script starts the function only when someone enters or exits the game.

Try this:

local function countUpdate()
	local playerCount = #game.Players:GetPlayers()
	script.Parent.ServerPlayers.Text = "There is currently " .. playerCount .. " player(s) in the server."
end

game.Players.PlayerAdded:Connect(countUpdate)
game.Players.PlayerRemoving:Connect(countUpdate)

I hope this helps, if you have any questions, just ask

1 Like