You can write your topic however you want, but you need to answer these questions:
I have this section of script which works in single player, which what it’s suppose to do is when a player joins, it adds a intValue to them, and then counts up to 100, when it reaches 100 the player dies. So a hunger/thirst system.
However the issue comes when a second player and so on player joins. Only the latest player that has joined has their value count up. while all previous players do not count up and have their thirst set back to 0 at the exact instant the latest player has spawned.
When i tried to find the problem, I found that every player is still getting their intValue added to their game.Players.Player, for each player that joins as normal. however its here where it diverges, as only one (latest joined) player gets their intValue counted up. This has left me stumped and Im unsure what to do to make thirst work for every single player.
game.Players.PlayerAdded:Connect(function(player)
print(player.Name)
Thirst = Instance.new("IntValue", player)
Thirst.Name = "Thirst"
Thirst.Value = 0 --max Thirst
player.CharacterAdded:Connect(function(char)
humanoid = char:FindFirstChild("Humanoid") -- changed period to a colon
--Thirst Code
-- This section is completely unnecessary because it is set to zero on spawn right above
--player.CharacterAdded:Connect(function()
-- Thirst.Value = 0 --resets on death
--end)
while task.wait(decrease_frequency) do -- would recommend task.wait(decrease_frequency) but its your choice.
--run the code here.
Thirst.Value += decrease_amount -- Moved this inside the while loop so it actually decreases
if Thirst.Value == 50 then
local line = math.random(1, #lines)
game.Chat:Chat(player.Character.Head, (lines[line]), Enum.ChatColor.White)
end
if Thirst.Value >= 100 or humanoid.Health <= 0 then
humanoid.Health = -100
Thirst.Value = 0
break -- End the while loop after the player dies
end
end
end)
end)
I think i have found the problem, the PlayerAdded thing creates a coroutine of everything inside it right?, but for some reason the there is only one instance of the Thirst Variable which is shared across all the coroutines. But now im not sure how i would make each coroutine have their own Thirst Variable.
In Lua, the local keyword is used to declare a local variable. It’s best practice to always use it. If you don’t, it’s called a global variable (global variables cause all sorts of messes).
Not using the local keyword when making a new variable is the same as doing:
local Thirst -- This how a variable is treated if you don't declare it as local
game.Players.PlayerAdded:Connect(function(player)
print(player.Name)
Thirst = Instance.new("IntValue", player)
Thirst.Name = "Thirst"
Thirst.Value = 0 --max Thirst
player.CharacterAdded:Connect(function(char)
humanoid = char:FindFirstChild("Humanoid") -- changed period to a colon
--Thirst Code
-- This section is completely unnecessary because it is set to zero on spawn right above
--player.CharacterAdded:Connect(function()
-- Thirst.Value = 0 --resets on death
--end)
while task.wait(decrease_frequency) do -- would recommend task.wait(decrease_frequency) but its your choice.
--run the code here.
Thirst.Value += decrease_amount -- Moved this inside the while loop so it actually decreases
if Thirst.Value == 50 then
local line = math.random(1, #lines)
game.Chat:Chat(player.Character.Head, (lines[line]), Enum.ChatColor.White)
end
if Thirst.Value >= 100 or humanoid.Health <= 0 then
humanoid.Health = -100
Thirst.Value = 0
break -- End the while loop after the player dies
end
end
end)
end)
It’s clear in the modified code above how that’s causing a problem: all the player connections are using the same Thirst variable!
One tip is that the script editor should give you a warning (I think) if you try to make a global variable. Avoid them if you can, but typos happen too, so the script editor will help you there.
That solution does partially work, however I have more code beneath the PlayerAdded thing, which relies on the scope of the thirst variable.
I’ve tried nesting this code inside of the PlayerAdded beneath where the local Thirst variable is defined, however now i have multiple functions with “player” and “Player” parametres. Which Im pretty sure makes the entire script do something unintended
game.ReplicatedStorage.Eat.OnServerEvent:Connect(function(Player)
--run code here
print("Drank")
Thirst.Value -= increase_amount
humanoid.Health += increase_amount
if Thirst.Value < 0 then
humanoid.Health += (Thirst.Value)
humanoid.Health += (-1)
Thirst.Value = 0
end
local char = Player.Character or Player.CharacterAdded:Wait()
tool = char:FindFirstChildOfClass("Tool")
tool:Destroy()
end)
game.ReplicatedStorage.Drain.OnServerEvent:Connect(function(Player)
--run code here
print("Ran")
Thirst.Value += 7
end)
YuumilHot’s Solution looks like it works as both intValues now count up when running a local server.
I’ve tested the thirst handler is indeed updating each player’s intValue separately as when one player dies prematurely, the other’s thirst is unaffected so problem solved.
Did notice a fluke where after dying of thirst, you sometimes (frequently) revert back to 0 thirst until you reset again.
could just because Im running two players in studios but I guess this topic is done. Thank yous!
I’d reference the Thirst IntValue with player.Thirst in the other code (and make sure to name it Thrist) in that case.
This is probably from this line of code:
When the character dies, it’s possible that this loop would go one iteration after. I would add a check in the while loop to make sure the character isn’t one that’s already dead.
-- Wait until the loop is ready to run (not ideal code because the two events below might never happen, though I'm lazy and it's not important)
while not humanoid:IsDescendantOf(workspace) and (humanoid.Health > 0) do
task.wait()
end
-- Does a while [the humanoid is alive and not destroyed] loop with a delay of `decrease_frequency`
-- (Basically only runs the loop's logic when the character is alive)
while humanoid:IsDescendantOf(workspace) and (humanoid.Health > 0) do
--run the code here.
Thirst.Value += decrease_amount -- Moved this inside the while loop so it actually decreases
if Thirst.Value == 50 then
local line = math.random(1, #lines)
game.Chat:Chat(player.Character.Head, (lines[line]), Enum.ChatColor.White)
end
if Thirst.Value >= 100 then
humanoid.Health = -100
end
task.wait(decrease_frequency)
end
The old code stops the loop once the character is dead, but not before changing the thirst to zero.
That means if the character died and then a new character was spawned while the loop was waiting, the loop would see the old character died and set the thirst to zero.