Why doesn't this Thirst server script run for each player?

You can write your topic however you want, but you need to answer these questions:

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

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

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

put local in front of Thirst = Instance.new(“IntValue”)

@Sniperkaos has your solution, @Funkinoe.

Just to expand on the solution @Sniperkaos gave:

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)

wait im gonna try and define thirst in each of the remote events

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.

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