Local Script Breaking After Death

Essentially making a small place holder anti cheat for my game and making an error checking system so that players cant break variables with auto execute, problem is this works fine upon joining whenever I change my walkspeed and it prints out “WalkSpeed Detection”, just if I die and change walkspeed, there is no print.

I already know it is something wrong with variables, the script still exists. This script is located in Replicated first and is parented to nil upon loading.

script.Parent = nil

local Timer = 0
local HookTimer

local Player
local Character
local Humanoid

local Success, ReturnedData = pcall(function()
Player = game:GetService("Players").LocalPlayer
Character = Player.Character or game:GetService("Workspace"):WaitForChild(Player.Name)
	Humanoid = Character:WaitForChild("Humanoid")
end)

local function SetupVariables()
	local GlobalSuccess = false
	local Success, ReturnedData = pcall(function()
		Player = game:GetService("Players").LocalPlayer
		Character = Player.Character or game:GetService("Workspace"):WaitForChild(Player.Name)
		Humanoid = Character:WaitForChild("Humanoid")
	end)
	if Success then
		GlobalSuccess = Success
	end
	repeat
		if Timer == 15 then
			local KickSuccess, ReturnedKickData = pcall(function()
				game:GetService("Players").LocalPlayer:Kick("Error Verifiying You | Please Rejoin")
			end)
			if not game:GetService("RunService"):IsStudio() then
				-- crash script here --
		end
		task.wait(.75)
		Timer += 1
	until GlobalSuccess == true
end

SetupVariables()

pcall(function()
	Humanoid.Changed:Connect(function(PropertyChanged)
		if PropertyChanged == "WalkSpeed" then
			print("Walkspeed changed")
		end
	end)
end)
1 Like

its because you’re not doing CharacterAdded

3 Likes

I already tried this, that doesnt work, I tried in the local function and in the first pcall() with the variable setting.

1 Like

I assume you’re doing it wrong, this should work
The ugly connections thing in this is just a bad way to clear up unused connections because roblox doesn’t properly destroy characters, event handlers would definitely be better to use.

script.Parent = nil
script = nil

local localPlayer = game:GetService("Players").LocalPlayer
local connections = {}
localPlayer.CharacterAdded:Connect(function(character)
    local humanoid = character:WaitForChild("Humanoid",10)
    if not humanoid then
        return
    end
    table.insert(connections,humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
        localPlayer:Kick()
    end))
end)
localPlayer.CharacterRemoving:Connect(function()
    for i,v in ipairs(connections) do
        v:Disconnect()
        table.remove(connections,i)
    end
end)

you really should be using a serverscript with magnitude checks to detect walkspeed though, people can disable your connections to keep your script from noticing changes and movement cheats are one of the things that you should rely on the server for.

1 Like

I wont be doing it on server sided, and that script above wont work out for me for how i am setting this up. Do you know what is causing my variables to do this? I am assuming its relating to character and printing out variables doesnt debug well as non return nil or changed

you’re pcalling everything which makes debugging a huge mess, get rid of any pcalls you have and you can find the root issue

also, when you die, your humanoid is deleted. Upon respawning, you get a new humanoid so you have to set up connections again and the old ones will not work.

1 Like

Alright, I will do this and try it out. Thank you

1 Like

re-enable script after the player dies

It is breaking simply because it gets the humanoid only once, when a character respawns, your humanoid variable will return nil. But there is nothing changing it to the new humanoid. Causing your script to stop working after you die.

What do you mean by this? 30 cccc

If this script is local, try putting it in StarterCharacterScripts. It should reset on death.

1 Like

It does work properly if I do set it there, problem is I want to make it as secure as possible from exploiters so I set it to Replicated first and Parent it to nil.

script.Parent = nil

local Timer = 0

local Player
local Character
local Humanoid

local function SetupVariables()
	local GlobalSuccess = false
	local Success, ReturnedData = pcall(function()
		Player = game:GetService("Players").LocalPlayer
		Character = Player.Character or game:GetService("Workspace"):WaitForChild(Player.Name)
		Humanoid = Character:WaitForChild("Humanoid")
	end)
	if Success then
		GlobalSuccess = Success
	end
	repeat
		if Timer == 15 then
			local KickSuccess, ReturnedKickData = pcall(function()
				game:GetService("Players").LocalPlayer:Kick("Error Verifiying You | Please Rejoin")
			end)
			if not game:GetService("RunService"):IsStudio() then
				-- crash script here --
		end
		task.wait(.75)
		Timer += 1
	until GlobalSuccess == true
end

SetupVariables()

pcall(function()
	Humanoid.Changed:Connect(function(PropertyChanged)
		if PropertyChanged == "WalkSpeed" then
			print("Walkspeed changed")
		end
	end)
end)

What is changed in this script?

I had to wrap most of the code into a characteradded()