In my opinion, the best way of detecting flying/teleporting on the server is to do magnitude checks. This is where you take the position of the HumanoidRootPart or the Torso, then again the next second or so. Then you can determine whether to kick the player by working out if they’ve travelled farther than they can normally walk.
The way you script this varies on what kind of game you’re making and might have to make necessary checks, here’s an edited version of the magnitude check I use in my games:
local players = game:GetService("Players")
local humanoidStates = {0, 3, 5, 7, 8, 10, 12, 15}
function loadChararacter(player)
while true do
local a, e = pcall(function()
if not player.Character then return end
local root = player.Character:FindFirstChild("HumanoidRootPart")
local humanoid = player.Character:FindFirstChild("Humanoid")
if not root or not humanoid then return end
local previousPosition = root.Position
local previousState = humanoid:GetState()
delay(1, function()
if not player.Character then return end
if not root or not humanoid then return end
if (root.Position - previousPosition).Magnitude >= 0 then -- 0 is how many studs the player gets to travel before getting kicked, increase this number if you get false positives.
wait(0.1)
if table.find(humanoidStates, humanoid:GetState().Value) or table.find(humanoidStates, previousState.Value) then return end -- Checks if player is falling.
if humanoid.FloorMaterial ~= Enum.Material.Air or humanoid.Health == 0 then return end -- Checks if player is falling or dead.
player:Kick(string.format("You just travelled %s studs in 1 second, kinda sus bro.", math.round((root.Position - previousPosition).Magnitude)))
end
end)
end)
if not a then
print(string.format("anti exploit error: %s", tostring(e)))
end
wait(1)
end
end
players.PlayerAdded:Connect(function(player)
if player.Character then loadChararacter(player) end
player.CharacterAdded:Connect(function(character)
loadChararacter(player)
end)
end)