Iteration over players not working even though I'm in the game

  1. What do you want to achieve? The loop to run.

  2. What is the issue? I’ve never had this problem before. I’m trying to loop through the players in the game and it just won’t. I’m literally playing the game and it is not iterating through as if there is no player in the game.

  3. What solutions have you tried so far? All I did was debug the code with print statement and then change :GetPlayers() to :GetChildren(). I as well tried using an ipairs loop instead of a pairs loop.


image

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

print("Script runs.")

local Milestones = {
	["1"] = 2130337229,
	["100"] = 2130337289,
	["500"] = 2130337298,
	["1000"] = 2130337305,
	["2000"] = 2130337311
}

print("Script still runs.")

for _, player in pairs(Players:GetPlayers()) do
	print("Looping through players.")
	local UserId = player.UserId
	
	local Leaderstats = player:WaitForChild("leaderstats")
	local Bricks = Leaderstats:WaitForChild("Bricks")
	
	Bricks:GetPropertyChangedSignal("Value"):Connect(function()
		print("Amount was changed.")
		for key, value in pairs(Milestones) do
			print("Looping through the table.")
			if tonumber(key) <= value then
				print("Everything is going well..")
				BadgeService:AwardBadge(UserId, value)
				break
			end
		end
	end)
end

I even tried playing like actually inside the game instead of testing in studio and it still didn’t work and printed the same things out. I swear I’m about to be the first man in the entire humankind to find a programming language bug.

Actually the reason why when your loop isnt running is because when the server starts up, the server scripts is ran first before you were able to join in. Meaning when it ran, there were no players in Players! You can fix this by adding a player.PlayerAdded event to check when a player is added

game.Players.PlayerAdded:Connect(function(player)
    -- on player joined
end)
1 Like

Would a Players.PlayerAdded:Wait() before the loop would work as well?

Yes, but only the first player who joined would get the badges since the logic is applied to them. While the others wont

Why is that? 30 c hara cterss aughhhhhhhhh

Maybe try this?

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

print("Script runs.")

local Milestones = {
	["1"] = 2130337229,
	["100"] = 2130337289,
	["500"] = 2130337298,
	["1000"] = 2130337305,
	["2000"] = 2130337311
}

print("Script still runs.")

Players.PlayerAdded:Connect(function(player: Player)
        print(player, "has joined")

	local UserId = player.UserId
	
	local Leaderstats = player:WaitForChild("leaderstats")
	local Bricks = Leaderstats:WaitForChild("Bricks")
	
	Bricks:GetPropertyChangedSignal("Value"):Connect(function()
     print("Amount was changed.")
		for key, value in pairs(Milestones) do
			print("Looping through the table.")
			if tonumber(key) <= value then
				print("Everything is going well..")
				BadgeService:AwardBadge(UserId, value)
				break
			end
		end
	end)
end)

Oh, you mean it’s cause of the for loop? Well, I don’t think that’s true so I might just correct you right there:

You can loop check if a player touches multiple instances by looping through the instances or their tags and then connecting the event to them. You can try it yourself, it has worked for me before and I’m pretty sure it works for players as well.

Would you like to provide some code about that?

Edit: Ignore what I said, Let me explain what I did to your code rq

I can indeed. Here are two versions of it, one with CollectionService and one without CollectionService.

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

for i = 1, 3, 1 do
	local Part = Instance.new("Part", workspace)
	CollectionService:AddTag(Part, "TestParts")
end

for _, tagged in pairs(CollectionService:GetTagged("Testparts")) do
	tagged.Touched:Connect(function()
		print("Test part named "..tagged.Name.." was touched by an instance.")
	end)
end
for _, part in pairs(SomeRandomFolder:GetChildren()) do
    part.Touched:Connect(function()
        print("Part named "..part.Name.." was touched by an instance.")
    end)
end)

btw too late lmao already started coding you the examples

Actually I replace the loop with a joined event, if you didn’t see yet. The reason why is that you wanted to give all the players the event so when they earn enough bricks, they get a badge. You can do a while loop and a for loop under there, but it would be unnecessary, and very lengthy, so just using a joined event you can just connect the badge giving logic to the player who joined, and will work for newer players who had joined the game

Try one of the codes for me in Studio (They might not work if the parts are inside the void, I didn’t set their positions.)

Ok you are right about the parts using collection service or folders, but we are talking about players. They can vary in numbers and change in matter of seconds, since people leave or join into the game. A simple for loop on player will simply wont work since the script is first ran with no players existing in Players. This will only run once after finishing the loop. If you added a wait lets say 10 seconds, the players who are in the game before and after the code is ran, with those players, and the others who join in late will not get the badges since the code wasn’t able to connect the events to them

Oh, I get you know. Alright, thank you for all the help!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.