Script not changing every player's leaderstats

I am making a round based game, and whenever you kill the boss, everyone on the playing team is supposed to get money and xp. It works but it is only to one player. Here is the script:

while wait(0.5) do
	local Players = game:GetService("Players")
	local xptogain = 50
	if script.Parent.Hp.Value <= 0 then
		print("Died")
		for i, player in pairs(Players:GetChildren()) do
			if player.Team == game.Teams.Playing then
				print(player)-- this prints all of the players playing when I test with bots
				player.leaderstats.Cash.Value = player.leaderstats.Cash.Value + 200
				player.LevelsInfo.Experience.Value += xptogain
				wait(5)
				game.ReplicatedStorage.GameActive.Value = false
				player:LoadCharacter()
				game.Workspace.Music:FindFirstChild("Intensity"):Stop()
	
				end
			
		end
	end
end
1 Like

I think putting wait(5) in loop is very bad habbit. You can use

task.delay(5,function()
	    game.ReplicatedStorage.GameActive.Value = false
		player:LoadCharacter()
		game.Workspace.Music:FindFirstChild("Intensity"):Stop()
end)

it would look like this

while wait(0.5) do
	local Players = game:GetService("Players")
	local xptogain = 50
	if script.Parent.Hp.Value <= 0 then
		print("Died")
		for i, player in pairs(Players:GetChildren()) do
			if player.Team == game.Teams.Playing then
				print(player)-- this prints all of the players playing when I test with bots
				player.leaderstats.Cash.Value = player.leaderstats.Cash.Value + 200
				player.LevelsInfo.Experience.Value += xptogain
				task.delay(5,function()
                      game.ReplicatedStorage.GameActive.Value = false
                      player:LoadCharacter()
                      game.Workspace.Music:FindFirstChild("Intensity"):Stop()
                end)
	
				end
			
		end
	end
end

i would also dont change game variables in loop, do it once outside of loop

1 Like

This line should be:

for i, player in pairs(Players:GetPlayers()) do

The reason why it’s not updating everyone’s leaderstats ie because of the “wait” call.

Instead, use:

task.delay(5, function()
game.ReplicatedStorage.GameActive.Value = false
player:LoadCharacter()|
game.Workspace.Music:FindFirstChild(Intensity):Stop()
end)
1 Like

Thanks! This works but now it runs multiple times. When I add a debounce it still runs multiple times for one player, and once for the other. How would I add a debounce that works?

1 Like

you can use Change event instead of looping this condition

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

local XpToGain = 50
local MoneyToReceive = 200

local IntensityMusic = game.Workspace.Music:WaitForChild("Intensity")

script.Parent.Changed:Connect(function(Value)
	print("Died")
	if Value <= 0 then
		for _, Player in pairs(Players:GetPlayers()) do
			if Player.Team == game.Teams.Playing then
				print(Player.Name)
				Player.leaderstats.Cash.Value += MoneyToReceive
				Player.LevelsInfo.Experience.Value += XpToGain
				task.wait(5)
				ReplicatedStorage.GameActive.Value = false
				Player:LoadCharacter()
				IntensityMusic:Stop()
			end
		end		
	end
end)

organized it

Thanks! But now it only gives gold and xp for one player. Why is this? There are no errors in the output. I got rid of the wait, as suggested earlier.

the only possible problem is the condition of this statement
cuz its where the player will recieve gold and gain xp

there are probably only 1 player on the Playing team when this statement proceeds

try checking your other scripts as you may not have set another player’s team on the Playing team

My round system script changes all the players teams to the playing. I can check it when I test with two bots. There are multiple people on that team. When the game active is false, it makes all of the players go to the lobby team. Im not by my computer right now, but would I need to change the game active to false in a different script?

This is what my script looks like now:

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

local XpToGain = 50
local MoneyToReceive = 200

local IntensityMusic = game.Workspace.Music:WaitForChild("Intensity")

script.Parent.Hp.Changed:Connect(function(Value)
	if Value <= 0 then
		for _, Player in pairs(Players:GetPlayers()) do
			if Player.Team == game.Teams.Playing then
				Player.leaderstats.Cash.Value += MoneyToReceive
				Player.LevelsInfo.Experience.Value += XpToGain
				IntensityMusic:Stop()
				game.ReplicatedStorage.GameActive.Value = false
				Player:LoadCharacter()
			end
		end		
	end
end)

It still only does it to one player. I know all of the players are on the playing team before it gives money

Not sure of why it’s not working, But i tried making your Script better and fixing it. One thing i recommend you to do is to not use the Instance.Changed Event but use the Instance:GetPropertyChangedSignal("Value") one. It’ll only listen to whenever the Instances’ value property changes. Another thing you should do is only stop the music and set the value once and not everytime it loops through each Player. Try using the Script below and let me know if it works! :slight_smile:

-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")

-- Instances
local IntensityMusic = workspace.Music:WaitForChild("Intensity")
local GameActive = ReplicatedStorage:WaitForChild("GameActive")
local HP = script.Parent:WaitForChild("Hp")

-- Variables
local HPChangedConnection = nil
local XpToGain = 50
local MoneyToReceive = 200

-- Connection
HPChangedConnection = HP:GetPropertyChangedSignal("Value"):Connect(function()
	if HP.Value <= 0 then
		-- Disconnect the HPChangedConnection.
		-- We disconnect so it doesn't runs another time.
		if HPChangedConnection then
			HPChangedConnection:Disconnect()
			HPChangedConnection = nil
		end

		-- Set `GameActive` to false and stop the `IntensityMusic`
		GameActive.Value = false
		IntensityMusic:Stop()

		-- Loop through Players, Award Players and Respawn them.
		-- Always use task.spawn to Load the Characters, So it doesn't
		-- Yields until the Character is Loaded.
		for _, Player in pairs(Players:GetPlayers()) do
			if Player.Team == Teams.Playing then
				Player.leaderstats.Cash.Value += MoneyToReceive
				Player.LevelsInfo.Experience.Value += XpToGain
				task.spawn(Player.LoadCharacter, Player)
			end
		end
	end
end)
2 Likes

I think you have to reeplace “GetChildren()” to “GetPlayers()”

Wow, thanks so much! I wasn’t expecting you to remake the whole script. It worked!

No problem! Glad i could help you.

Also, Ensure to mark my reply as the solution so people know that it has been fixed and doesn’t needs help anymore.