Without a lot of context it is hard to really guess at what is going on, but it is unlikely that RejectcharacterDeletions
is being bypassed. You’re probably just running into edge cases with how the engine creates characters, and how the engine can remove parts.
This can happen if a player glitches out of a map, falls, etc to the FallenPartsDestroyHeight. It can also happen sometimes under certain physics situations iirc, I think if stuff gets NaN velocities or something along those lines it can get auto deleted by the engine. (I don’t know what conditions that happens in or why but I’ve encountered it rarely a couple times in the past. It probably has to do with how FallenPartsDestroyHeight is implemented, if I had to make a guess)
It is possible (and potentially relatively likely depending on the specific code that is breaking) that your code simply ran before the player’s Humanoid was created. CharacterAdded will guarantee it, but player.Character
is set before all the children are necessarily added to the player’s character, including the Humanoid
.
I am not saying this is the correct way to do this in all cases or anything, but, there are a couple things that I personally do to make checks easier and more adaptable.
In general I personally use FindFirstChild/FindFirstChildWhichIsA where I can, since there are often a lot of cases where you can’t reliably know if descendants will exist, so it makes it less to think about and potentially change in the future, it just always works in all cases no matter what.
-- By chaining conditions like this you can grab a bunch of stuff at once without much effort and then check them later
local character = player.Character
local humanoid = character and character:FindFirstChildWhichIsA("Humanoid")
local rootPart = humanoid and humanoid.RootPart
if not humanoid then return end
-- By the way, this pattern of "if thing then return" or "if thing then continue" is called a guard clause, you're just cancelling the code when a certain condition is/isn't met.
-- It prevents you from having really tall nested if statements, which usually makes it easier to work with the code
You can also put your code into small helper functions e.g. like this to reduce how much you have to repeat this code. And then it becomes easier to copy and paste it across files you need it in as well.
local function getRootPart(player: Player)
local character = player.Character
local humanoid = character and character:FindFirstChildWhichIsA("Humanoid")
local rootPart = humanoid and humanoid.RootPart
return rootPart
end
-- Somewhere else
local rootPart = getRootPart(player)
if not rootPart then return end
Doing some of that in both server-side and client-side code for parts is also probably a good idea, so that code you write is always streaming compatible, in case you want to share it between both the client and server.