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