Please help, MULTIPLE bugs with sanity script!

LONG EXPLANATION (if you don’t want to read this, go to the TLDR at the bottom)
Hi there. I have very limited scripting knowledge and only went with tutorials on YouTube to accomplish this, and the script is working! There’s just a couple of factors that happened.

With this sanity script, you can go inside a zone that is ‘not safe’ and it’ll decrease your sanity slowly the more you stay inside. If your sanity is below 50, it’ll start to become black and white, until eventually it’s fully monochrome and you cannot see ANYTHING until you go to a place that is safe.

There’s a folder with ‘zones’ that I’ve setup, and every time you go in it, your sanity decreases and when you walk out- it goes back to normal. Simple! But I’ve encountered something that’s really… unusual.

It goes above 100% sanity, going up into 101% or even more. And if it reaches 0% sanity, it’ll go into the negatives. I want to correct this ASAP, but I have no idea how. Additionally, if the player character dies, the sanity script doesn’t work anymore! I’m making a horror game and this just really makes everything worse with my development, so I came here for assistance.

TLDR:
Having issues with a sanity script, interfering with a death system and it goes into the negatives or above 100. Need help. Attached is the testing place provided.

File attached
Testing Purposes - Vermiculus.rbxl (70.3 KB)

4 Likes

You could use math.clamp(Sanity.Value,0,100) to fix the first issue
For the 2nd issue, I advise you to move the values out of the character and just update them whenether a player dies. Checking the output helps.

1 Like

That’s great to hear! But how would I use that, and where would I place it at? I did say that I have a bit of limited scripting knowledge, and most of this stuff stems from tutorials from videos.

Also, how would I accomplish the 2nd issue, if you could explain it to someone that isn’t that well versed into scripting?

really good system, i dind’t check any script but i already know the issue,
consider sanity as Health Bar

it will regen,
you may be damaged, but will not get past 0 or 100 ( in most games)

i have some code here, wait a moment and i’ll post

1 Like

Please take your time, and thank you!

For the first issue you could just put Sanity.Value = math.clamp(Sanity.Value,0,100) at the end of the loop
For the second one however, if you want to keep the values in your character, you can do a check if it’s there first and return its value once it is there, otherwise you can return any other number.
I’ve run into another problem though. PlayerAdded checks for the value in someone’s character. However, when you change the character, the value doesn’t change with it. It still tries to set the value of the old value. You can put this at the beginning of the loop:

if Character~=p.Character then --it was also checking the old character of the player, which didn't exist after a respawn
	Character = p.Character
end
if Character:FindFirstChild("Sanity")then
	Sanity = Character:FindFirstChild("Sanity")
end

Also I advise to check if some values you’re checking for in the script aren’t nothing. I’ve found 3 which have been trying to get a value from an instance that didn’t exist. Place something like Character:FindFirstChild("put instance name") ~= nil at the beginning of your checks your checks to check if an instance in the character even exists. Hope this helped.

1 Like

Hi

place this in `ServerScriptService´


game.Players.PlayerAdded:Connect(function(player)

	local RegenAtivado = false	
	local ReducionAtivado = false 
	
	
	local Sanity = Instance.new("NumberValue", player) -- Your default sanity	
	Sanity.Name = "Sanity"	
	Sanity.Value = 0
	
	local Max_Sanity = Instance.new("NumberValue", player) -- your max sanity, until where it can reach, the max, i would say
	Max_Sanity.Name = "Max Sanity"
	Max_Sanity.Value = 100	
	
	
	
	
	
	
	
	
	-- Below you will see Sanity function, regen like an health bar, difference is none)
	
	
	
	
	
	local plrSanity = player:WaitForChild("Sanity")
	local plrMaxSanity = player:WaitForChild("MaxSanity")

	player:WaitForChild("Sanity").Changed:Connect(function(NewValue)

		print(player.Name .. " Actual Sanity: " .. " == " .. NewValue) 

		if Sanity.Value <= 0 then
			print(player.Name .. "Recently Lost all Sanity... ")
		end


		if Sanity.Value > Max_Sanity.Value then
			print(player.Name .. "Testing purposes --- why sanity just bypass Maxsanity? lol")

		end


		if RegenAtivado == true then -- checks if sanity function is already running, if yes, then it will not repeat again, preventing spam
			print"Already Activated" 
			return nil
		end



		if Sanity.Value < Max_Sanity.Value and RegenAtivado == false then --  if Player Sanity is lesser than Max Sanity -- then

			RegenAtivado = true -- activate regen
			repeat	

				task.wait(1) -- you can adjust here, see how much time the playe will wait until he gets more sanity

			

				if Sanity.Value >= Max_Sanity.Value then -- checking if, somehow, sanity reached Max Sanity, it will stop regenering
					print"Breaked Sanity Regen"
					break
				end

				if Sanity.Value <= 0 then
					print"You lost all Sanity!"
				
					task.wait(2)			
					print"the player died"
							
					break						
							
				end

				Sanity.Value = Sanity.Value + 1 -- can adjust here too ( amount of sanity )
			

				print"Regenering Sanity..."
			until

			Sanity.Value >= Max_Sanity.Value -- repeat until Sanity is equal or Highter than Max Sanity

			RegenAtivado = false
			print"Regen Stopped"

		end


		if Sanity.Value > Max_Sanity.Value and ReducionAtivado == false then -- if somehow Sanity bypass Max Sanity then
			ReducionAtivado = true
			repeat
				task.wait(0.1)


				if Sanity.Value <= Max_Sanity.Value then -- if PHASE 1 was not activated, since it must be equal to 100, this will trigger, disabling reduction since this may remove player's sanity too much
					print"Fixed, Sanity is back to 100 or lesser"
					break
				end

				Sanity.Value = Sanity.Value -1 	
				
				print"Fixing Sanity..."


			until
			Sanity.Value <= Max_Sanity.Value


			ReducionAtivado = false
			
		else if Sanity.Value == Max_Sanity.Value then -- if Sanity is normal, then prints ok
				print"The Sanity is ok..."

				ReducionAtivado = false -- disables Reduction mode, since it was fixed

				--PHASE 1--
			end		
		end
	end)
	
end)

dasadasdfas

create frames, and put the names exactly as i did

Only sanity , ignore the other Frames like Experience, and etc

and don’t Forget to create ''SanityGUI" <<
ddddddddddddddddddddddddddddddddd

then place everything inside, in order, otherwise nothing will work and will drop errors

alright now for the second part, client visuals:

search for ''StarterPlayer" >> StarterCharacterScripts

and place this here:

--First, create some LocalScript, then paste this:

task.wait(5)
print"Starting System"

local plr = game.Players.LocalPlayer
local playerGui = plr:WaitForChild("PlayerGui")
local TweenServc = game:GetService("TweenService")--Get Tween Service

local Character = plr.Character or plr.CharacterAdded:Wait() --Wait For The Player Humanoid to load
local Humanoid = Character:WaitForChild("Humanoid") --Get The Player Humanoid


local Sanity = plr:WaitForChild("Sanity")

local Max_Sanity = plr:WaitForChild("Max Sanity")

local Sanity_Frame = playerGui:WaitForChild("SanityGUI").SanityLimit.Sanity
local Sanity_Text = playerGui:WaitForChild("SanityGUI").SanityLimit.DisplaySanity

Sanity_Text.Text = Sanity.Value -- automatically updates to the current sanity the user has, 



-- Will be 0, AS Default! can change in Sanity Main server script...




local function UpdateSanityBar() 

	local sanityClamper = math.clamp(Sanity.Value / Max_Sanity.Value, 0, 1) --Maths

	local tween_information = TweenInfo.new(Sanity.Value / Max_Sanity.Value,Enum.EasingStyle.Linear,Enum.EasingDirection.InOut,0,false,0) --Tween Info

	TweenServc:Create(Sanity_Frame,tween_information,{Size = UDim2.fromScale(sanityClamper, 1)}):Play() -- Create The Tween Then Play It
	
	Sanity_Text.Text = Sanity.Value -- this is the Display Sanity Text, each time sanity is update, this will update too
	
end

UpdateSanityBar()

Sanity:GetPropertyChangedSignal("Value"):Connect(UpdateSanityBar) -- when Sanity changes, it will update texts and tween animation
Max_Sanity:GetPropertyChangedSignal("Value"):Connect(UpdateSanityBar) -- if you wish to increase more sanity, then this is useful, since this will notify and change the bar according to how much Max sanity the player has
    

the result:

results

Changing (Client-Side), if you change (Server-Side)

the Auto-Regen will start
results

Proof that this method works:

1 Like

Thank you very VERY much for this extensive response. I will try to do what you said really quick.

Hi! So I’ve done some testing on the script you’ve told me to do, as well as the instructions…
There seems to be errors within the LocalScript you’ve given.

image

Additionally, I’ve also followed what you told me to do about the SanityLimit.
image

I was a bit confused, so I also tried this as well.
image

None of these worked, and it just remained as ‘Label’ and nothing else.

There’s also an error in the script you’ve given me for the ServerScriptService as well, which is the code at the very bottom.
image

If you would like, you could give it a test to see why it’s not working. I didn’t change the text or the label, and I’ve also followed your instructions on everything. Could you please pinpoint me in the right direction?
This is the place with your script installed.
Sanity Testing 1.1.rbxl (70.2 KB)

I’ll give this one a shot, I’ll ask anymore questions if I need to! Thank you.

Hi there again! I want to quickly say that the first issue was a success! The other values are for the zones and to see whether or not it’s detected.But it’s still going into the negatives. Here’s a video showcasing this, because it does work, I just don’t know what’s causing it to go into the negatives. It’s worrying since I want to turn it into a bar-like indicator, and if it goes into the negatives, it’ll just go into reverse and cause problems.

Here’s the script on what you told me to do, please tell me if I put anything in the wrong spot.

local Settings = {
	ZoneRequired = true; 
	MinDecreaseTime = 1;
	MaxDecreseTime = 1;
	
}
local function SanityChecker(p, Action) 
	local Character = p.Character or p.CharacterAdded:Wait() 
	local Sanity = Character:WaitForChild("Sanity") 
	
	if Action == "CheckSanity" then 
		return Sanity.Value 
	end
end

for _, v1 in pairs(workspace.Zones:GetChildren()) do 
	if v1:IsA("BasePart") then 
		v1.Touched:Connect(function(h)
			local Humanoid = h.Parent:FindFirstChild("Humanoid") 
			if Humanoid then 
				local Player = game.Players:GetPlayerFromCharacter(h.Parent)
				h.Parent:WaitForChild("Unsafe").Value = true
				h.Parent.Zone.Value = v1.Name
			end
		end)
		
		v1.TouchEnded:Connect(function(h) 
			local Humanoid = h.Parent:FindFirstChild("Humanoid") 
			if Humanoid then
				local Player = game.Players:GetPlayerFromCharacter(h.Parent)
				h.Parent:WaitForChild("Unsafe").Value = false 
				h.Parent.Zone.Value = "" 
			end
		end)
	end
end

game.ReplicatedStorage.SanityHandler.OnServerInvoke = SanityChecker 

game.Players.PlayerAdded:Connect(function(p) 
	local Character = p.Character or p.CharacterAdded:Wait() 
	local Sanity = Character:WaitForChild("Sanity")
	local debounce1 = false
	
	spawn(function() 
		while not debounce1 and wait(math.random(Settings.MinDecreaseTime,Settings.MaxDecreseTime)) do 
			if Character.Unsafe.Value then 
				if Settings.ZoneRequired then 
					if Character.Zone.Value ~= nil and Character.Zone.Value ~= "" then 
						local module = require(game.ReplicatedStorage.Modules.Zones) 
						if module[Character.Zone.Value] then 
							Sanity.Value -= module[Character.Zone.Value].decrease 
							if Character~=p.Character then --it was also checking the old character of the player, which didn't exist after a respawn
								Character = p.Character
							end
							if Character:FindFirstChild("Sanity")then
								Sanity = Character:FindFirstChild("Sanity")
							end
						else
							Sanity.Value -= 1 
							warn("Zone not found:",Character.Zone.Value)
						end
					end
				else
					Sanity.Value -= 1 
				end
			else
				if Character.Regen.Value then 
					Sanity.Value += 1 
					Sanity.Value = math.clamp(Sanity.Value,0,100)
				end
			end
		end
	end)
	
end)

Please tell me what else I need to do here. Thank you.

this should be a easy fix
just setup proper checks
use > and <
if value =< 0 then
it is negative or 0
end

Again, I’m very limited in my scripting knowledge… I said that in the post.
I don’t know where you would even put that. I just only followed tutorials.

1 Like

send your updated rbxl file and ill try fixing it up

2 Likes

Absolutely.
Here is the updated rbxl file using LR2IR’s setup for the scripts.
Testing Purposes - Vermiculus 1.1.rbxl (70.5 KB)

1 Like

Fixed
Testing Purposes - Vermiculus 1.1.rbxl (70.5 KB)

1 Like

Thanks! I just playtested it and it does work! BUT… there’s a slight problem.

The numbers don’t change, even if you die. It just stays there, stuck. Any ideas?

you want it to reset to 100 when you die?

1 Like

ah i see the problem now!!!

1 Like

Yes. That is correct. I want it to reset back to 100, because the person that I was doing the tutorial with made it clear that it would reset back to 100, but it doesn’t work.