How to Detect Flying Exploits from the ServerSide

Hello, i’ve been wondering on how to detect Flying Exploits in the ServerSide and the ways you guys use to prevent Flying Exploits. If you have a way of doing so , please share it in the comments. Thank you :slightly_smiling_face:

4 Likes

I am afraid it is quite hard to look in player’s character component from the server. Advanced exploits even have the ability to spoof humanoid states among every other client behavior.
I would just put measures like, for example, for an obby if someone flies through, the server has to check for the previous checkpoint, and if it does defy logic, then execute the measures taken. Do something similar to this in your game.
Hope this helps!

The Concept

You can attempt to raycast downwards to see if the player is in the air. You can then do this check over a certain amount of time for a certain amount of iterations.

More Over

I am mentioning ray casting because some methods of flying may instead set the player’s CFrame and mess with their humanoid states (meaning Humanoid.FallingDown will never be invoked)

Lets say you check every 0.5 seconds if the player is in the air via a ray cast and with that ray cast you get their distance from the part below them. If you then do 10 iterations of that and they all return true that means they have been in the air for 5 seconds. If a player has been in the air for an extended amount of time then there is likely something suspicious going on.

The Catch

This will certainly have flaws. Player’s who are flung or have insane network issues could be detected as cheating. If there is a risk of the player being falsely detected then it is much better to use a less-harsh method of dealing with the problem (teleport them to a part below them, re-spawn their character, kick them)

Also someone will always bypass your anti exploit. It is 100% guaranteed to happen if your game is going to be out for a long period of time and lots of people are going to be playing the game.

Example Code:

There are ways you could improve this code but I wanted to just type up something quickly to illustrate the concept. (I also did not test this!)

What you can do is setup a function that has a character, distance, and threshold parameter. The character argument is well, the character you’re ray casting down from. The distance argument is how far you should look down to look for a surface. And finally the theshold argument is the max difference in the currentPosition and position before a player is considering flying (When the threshold is passed the function will return true, meaning the player is likely “flying”)

local function raycastDown(character, distance, threshold)
    local root = character:FindFirstChild("HumanoidRootPart")

    if not root then return end

    local currentPosition = root.Position

    local ray = Ray.new( --// new ray
        currentPosition,
        currentPosition + Vector3.new(0, -distance, 0) --// a position that is distance units below the player in world space
    )

    local part, position = workspace:FindPartOnRay(ray, character) --// get what the ray might have hit

    if part then
        local difference = (currentPosition - position).Magnitude --// difference in position as a scalar

        if difference > threshold then
            return true
        else
            return false
        end
    end
end

Extra

If you have never used rays or need to refine your skill at using them I suggest checking out this article:

This question has been asked before and so it is recommended you read the solutions on those posts (here are some example threads asking the same question):

11 Likes

I know this is just a suggestion, but please do not suggest this again. Kicking players is bad UX, especially when you can’t 100% verify an exploit.

1 Like

Won’t his suggestion have to call a remote every single half a second? or is there another method of affecting a player’s character from the server?
And what even happens if rays collide?

That is
performance
Intensive
If i’m not wrong, that is a straight up, no

I’m not sure what you’re referring to, but I was talking about kicking players.

I was talking about EpicMetatableMoment’s suggestion

You don’t need remote events to use @EpicMetatableMoment’s implementation. Exploiters can easily send mock up data to the server to make it seem as if they never got off the ground. The good thing about his implementation is it’s completely server-sided. Unless the exploiter has powerful tools that prevents the client from replicating position data, there will be almost no way to prevent flying exploits.

Besides, it’s just a single ray every 5 seconds or so. Nothing performance intensive.

2 Likes

If a client is not replicating their position every second they are no longer flying, they are just teleporting. You could try to counter this by checking their current position within the check for the raycast. If their previous position and current position have an insane distance (like 100) studs then something is suspicious. A player with 0 ping will move 16 studs per second (16 walkspeed) but due to most players having around 50 to 100 ping you should expect them to move around 20 studs per second (estimate).

And I did consider not putting the :Kick method in my post; I thought I should include it just because it is a method that can be used instead of a ban of some sort. Thanks for the feedback though! :sunglasses: :+1:

Also I suggested a ray every 0.5 seconds not every 5, but every 0.5 seconds is still not intensive. The only things that might make a ray intensive to cast is over large distances and maybe at complex geometry.

In fact, I wrote some code maybe a few months ago which you can check out to show how long it takes to cast x rays over d distance. The main thing that causes a significant increase in time is calling :FindPartsOnRay with a ray who shot over a long distance.

image

The 1.16 seconds was for casting 10000 rays to 0, 5, 10000 from 0, 5, 0 and then calling :FindPartOnRay on that ray.
The 0.068 seconds was for casting 10000 rays to 0, 5, 100 from 0, 5, 0 and then calling :FindPartOnRay on that ray.

Here is a place you can check the code out (I believe I did this before the new lua vm so the results may be inconsistent with the comments) : https://www.roblox.com/games/3239804501/raycast-speed-check

1 Like

I would use Humanoid.FloorMaterial since the raycasting is already done for you (and you won’t be adding any extra performance cost).

If the FloorMaterial is air you know they’re off the ground. Then you can do some velocity checks on RunService.Stepped (which fires immediately after physics calculations take place, whereas heartbeat fires before)

Their WalkSpeed is their max X/Z velocity.
Their JumpPower is their max positive Y velocity.

5 Likes

But what if the player is falling down from a high location?

3 Likes

I can do something like detection humanoid stats from local script but put that detection into core game local script? If the script got disabled or destroyed local game getting broke