Ways to make anticheat better

There are big problems with your code!

#1. You don’t manage already loaded players and characters

There is a chance where players and characters have already loaded before your code runs, so PlayerAdded or CharacterAdded won’t fire.

Something like this:

local Players = game:GetService("Players")

local function onPlayerAdded(player)
  local function onCharacterAdded(character)
    if not character:IsDescendantOf(workspace) then
       character.AncestryChanged:Wait()
    end

    -- your raycast stuff...
  end

  if not player.Character then
    coroutine.wrap(onCharacterAdded)(player.Character)
  end

  player.CharacterAdded:Connect(onCharacterAdded)
end

for _, player in ipairs(Players:GetPlayers()) do
  coroutine.wrap(onPlayerAdded)(player)
end

Players.PlayerAdded:Connect(onPlayerAdded)

#2. Every time your character respawns, the while loops will stack, and the previous one won’t stop.

CharacterAdded is fired whenever your character respawns, so if your character dies, the while loop doesn’t stop and another while loop is added. This can significantly lag your game.

So instead of while true do, just check if the character is alive in the condition statement:

Get the character’s Humanoid so you can check its health
while humanoid.Health > 0 do

#3. Use the new raycasting API

Roblox just released a new Raycasting API, that you should use. FindPartOnRay methods are deprecated and should not be used in new work.

1 Like