Looking for possible loopholes in anti-expIoit flight check

For reference:
NearbyParts is a table of parts near the player.
Registry.HumanoidRootPart is the players HumanoidRootPart.
- 2.852 is the distance between the HumanoidRootPart and Feet (standing point) of the players. Since my game has a set height limit for players, this number works perfectly.

What this script does is grab all nearby parts top surface position and then checks if the players feet are inside of a threshold of that position. If they’re not in any thresholds, they’re most likely flying.

I already have checks in place (not shown here) to account for falling, gravity and climbing.

--# This iteration loops through all nearby parts to see
	--| if they're standing on a part.
	for _, BasePart in pairs(NearbyParts) do
		--# This check makes sure to not calculate terrain
		--| for surface position calculations.
		if BasePart:IsA("Terrain") == false then
			--# This gets the parts top surface position 
			--| that'll later be used for threshold math.
			local TopSurfaceYAxis = (BasePart.CFrame * CFrame.new(0, BasePart.Size.Y / 2, 0)).Y
			
			--# This checks if the player is standing on
			--| a part within its threshold.
			if 
				Registry.HumanoidRootPart.Position.Y - 2.852 < TopSurfaceYAxis + 1.5
				and Registry.HumanoidRootPart.Position.Y - 2.852 > TopSurfaceYAxis - 1.5
			then
				return true
			end
		end
	end
	
	--# If no part is being stood on, this
	--| function will return false.
	return false

Exploiters are caught if the function returns false multiple times in a row. Also I have other bullet proof anti-exploit measures in place so exploiters aren’t allowed to fly, speed hack, teleport, etc.

I’m looking for possible errors (haven’t found any yet), optimizations (especially in the math area, it looks pretty hefty) and obviously any loopholes. This script is on the server and doesn’t interact with the client at all.

Please reply with any possible concerns or potential bugs/loopholes with my code if possible, thanks!

Also I should have added, feel free to use this code for your anti-cheats as well. I’d argue that flight related exploits are the hardest to patch in a performant way and this code is incredibly lightweight.


Current Problems:

  1. Doesn’t work with rotated parts or wedges/ramps.
    How can I get the position of the surface that's always facing up?

  2. Doesn’t work at all with multileveled MeshParts/UnionOperations. Only way to fix this is to utilize raycasting.

3 Likes

You should not be checking if the player is standing on something, what I would do is firing a ray from the characters root part in specified situations, e.g. the player starts to jump (so you fire a ray to check if they are standing on something). I wouldn’t use that method because, what happens when the player gets lauched through something? You should also be checking if the player is “PlatformStanding” (that’s a humanoid state and a property in the humanoid), because many flight scripts make you do that, to disable all forces the characters humanoid sends out.

I don’t plan on publicly releasing this anticheat source or adding launchers to my game, so I don’t need to worry about rare cases like so.

Don’t know how this property would help me. Unless you’re saying I should enable this when the player is caught cheating, then I get why I’d use it. However what I do currently is take NetworkOwnership of the HumanoidRootPart and it makes it so that the player movement is done on the server instead of the client, which effectively cancels out all movement exploits momentarily.

Also you mentioned raycasting, but I’m trying my best to avoid it because my anticheat runs for every player (up to 20) every frame. It does this so no movement is left unmonitored. up to 20 raycasts (maybe exponentially more because raycasting straight down doesn’t always get the part being stood on) per frame cannot be healthy for server performance. For 8 players I’ve seen script activity go up to 2%. Albeit I just created this code so I no longer have to use raycasts for BaseParts, effectively saving some performance.

For anyone lurking trying to create their own flight anticheat system, do what I’m doing for normal Parts and then if none of those parts are being stood on, start raycasting. You’ll save on performance by not raycasting unless necessary.

Why are you doing it then? Don’t you want to script a good one?

Many flight exploit scripts use that property/state to disable other physics and animations for the camera. The roblox client does not enabled that state by itself, so only exploiters or your scripts enable that.

Bro?! You are looping through every descendant of the workspace or your reading parts from a region3, thats way more performance eating than racasting.

2% is totally fine for an anti cheat in my opinion, but as you said you dont want to script a good one, so just forget it.

My game won’t ever need it, why script something I’ll never use?

Exploiters tweaking that property won’t let them bypass my script. My script checks serverside values only.

I’m not looping through workspace. I won’t get heavily into it but I have a performant way of getting a table of parts near the player. Trust me on this one.

2% isn’t good at all for 8 players when my max player count is 20. Anything around 5% will start to slow down chat and other services.

Ended up fixing all my problems through help with scripting support, I’ll mark my reply as the solution because I’m no longer interested in people reviewing it as this code is pretty outdated. Feel free to use this snippet of code as inspiration however!

Determining if the player is on ground through raycasting is not reliable and bad practice. Instead, use the FloorMaterial property of the humanoid. Due to the recent changes of the replication of the property, exploiters can’t spoof it to the server.

I looked into this, and I suggest everyone should as well, and it seems that for my situation that listening to FloorMaterial is a more performant solution than raycasting. However:

My anticheat only raycasts up to 5 times and I’m not sure if I’ll ever need higher precision than that.

My anticheat only raycasts up to 5 times and I’m not sure if I’ll ever need higher precision than that.

It may cast up to 9 times to reliably determine the floor material. Read my reply here for more info: