What's the right way to set up intvalue changed events on the server?

players.PlayerAdded:Connect(function(player)
	local playerStats = game.ReplicatedStorage.PlayerStatStorage:WaitForChild(player.Name)
	player.CharacterAppearanceLoaded:Connect(function(character)
       playerStats.Stamina.Changed:Connect(function(value)
              print("stamina changing")
       end)
    end)
end)

This is a server script located in ServerScriptServices
The problem with this is that whenevever the player respawns “stamina changing” will print twice as much because the old changed event still exists.

A solution would be to not put it inside the charloaded Event and instead have local character = player.Character or player.CharacterAdded:Wait()
but when I reset and print(character.Parent) it prints nil

Ok so the char.Parent prints nil if i remove the charevent because it still refers to the old char so if I did soomething like

 playerStats.Stamina.Changed:Connect(function(value)
 local char = player.Character
               print("stamina changing")
        end)

would work, but what if I had to do

character.Humanoid.HealthChanged:Connect(function(currentHealth)
end)

Just disconnect the event after the character dies, like so:

players.PlayerAdded:Connect(function(player)
	local playerStats = game.ReplicatedStorage.PlayerStatStorage:WaitForChild(player.Name)
	player.CharacterAppearanceLoaded:Connect(function(character)
       local c = playerStats.Stamina.Changed:Connect(function(value)
              print("stamina changing")
       end)
       local c2;c2 = character:WaitForChild("Humanoid").Died:Connect(function()
           c:Disconnect();c2:Disconnect() 
       end)
    end)
end)
1 Like

So c represents the Stamina.Changed function
and c2 represents the humanoid.Died function

Why is this part formatted like this " local c2;c2 = "?
Why not just local c2 = character:…

I formatted it like so because the function passed into the :Connect() function is not yet aware that the c2 variable exists, because it is currently being assigned. Assigning it to nil first assures that the variable exists. It is the equivalent to

local c2
c2 = --[[blah blah blah]]

p.s.: these aren’t functions, these are Events

1 Like

oh i see. Thank you sir. Oh one last thing. So if I did local c2,c2 = is that the same as local c2;c2 = ?

No. The semi-colon is negligible (meaning that it’s not even required, I just put it there to look cleaner), however the comma means you’re assigning two variables.

1 Like

Disconnect the event once the player dies.

players.PlayerAdded:Connect(function(player)
    local playerStats = game.ReplicatedStorage.PlayerStatStorage:WaitForChild(player.Name)

	player.CharacterAppearanceLoaded:Connect(function(character)
        local connection = playerStats.Stamina.Changed:Connect(function(value)
            print("stamina changing")
        end)

        character.Humanoid.Died:Wait()
        connection:Disconnect()
    end)
end)
1 Like

so local c2 c2 = is the same as local c2;c2 =? or does the ; make it so that you can put it on one line?

Again, the semi-colon doesn’t do anything but make the code cleaner. You could substitute it for a space of course, but a semi-colon is usually my go-to. Any code can be put in one line, however you should be wary that not everything should go in one line. Always keep it consistent.

1 Like

what would be the differences from using

local c2;c2 = character:WaitForChild("Humanoid").Died:Connect(function()
           c:Disconnect();c2:Disconnect() 
end)

or

 character.Humanoid.Died:Wait()
        connection:Disconnect()

The second one technically is shorter but it yields and yielding typically is an undesirable effect as any code after it will not be run until the character dies (which is when the code will stop yielding).

1 Like

Both do the same thing.

1st connects Humanoid.Died, after the event is triggered it disconnects both of the connections.
And 2nd yields until the player dies then disconnects the changed connection.

1 Like
local c2;c2 = character:WaitForChild("Humanoid").Died:Connect(function()
           c:Disconnect();c2:Disconnect() 
       end)

This detects if the humanoid died. What if they didn’t die and player:LoadCharacter() was used on them? How would I detect that?

In this case, you could replace the “died” event (starting from character) with player.CharacterRemoving. This will fire whenever the character is being removed from the game,

1 Like