Server-side Movement Antiexploit

Hi,

I’ve been developing an antiexploit working by calculating the difference in a player’s character’s position in the workspace over the period of one second, whilst taking into account factors like whether the player’s character is falling.

Everything seems to be working fine, but I’m interested in whether anybody can see any major flaws that could be exploited within my code, and whether there are any use cases that I haven’t accounted for (an example I’ve thought of while writing is that this prevents players from using in-game teleporters between locations).

Any feedback is appreciated!

Save for downloading any files, I’ve posted my code to Pastebin.

If the exploiter changes his humanoid state to Free falling or any whitelisted state he can fly easily without any limitations.

1 Like

Thanks for the feedback.

I’ve tried testing that just now and I’ve noticed that the server picks up on a change of humanoid state, so even if the client can change their state, it should be picked up by the server either way!

A player can destroy the ExploitIntValue on their character on the client, and it will replicate to the server since the player almost has all control over their character. You should make a new instance if it doesn’t find one to prevent this.

1 Like

That’s a really good point, thank you.

Perhaps it would be easier to have a folder under Players with a list of IntValues with player names?

Thanks for the feedback!


Edit: Decided to forgo the IntValue in favour of adding an attribute to the player. Much less hassle that way!

Yea, or just add the IntValue under their player instance.

2 Likes

char:FindFirstChild("ExploitScore")

Exploiters can delete anything under their character, I suggest making this serversided, stored in an array or dictionary. Also you wouldn’t want exploiters seeing other palyers exploit scores, would you?

Thanks for the input!

I’ve completely forgotten to update the code on Pastebin, so it’s a few versions out-of-date. I’ve since refactored to add an attribute to the player instead.

Either way, shouldn’t be too much of a hassle if an exploiter were to see another player’s karma - even if they were able to change it.

The true value of ExploitScore isn’t stored within the player’s attribute, but internally within the script - preventing an exploiter from being able to alter values and have the player kicked.

Appreciate the feedback, though!

1 Like

Maybe change the wait to task.wait?

Wouldn’t make too much of a different either way, you’re still yielding the current thread for a specified amount of time.

I’m currently refactoring my antiexploit (again!) to be event-based, instead of using the current while true do method, so the script isn’t handling frames with unnecessary data.

Thanks for the feedback, though!

1 Like

Would you want to expand more on this? I created a serverside movement anticheat myself and I found a lot of little ways to stop calculations for unnecessary frames.

A few of em:

  • Only look for shady movement if the player has actually moved. You can achieve this by using RunService.Heartbeat and checking the HumanoidRootPart.Position between the previous and current frame.
  • Don’t look for shady movement if the player is currently being punished. In my anticheat I punish the player temporarily by taking away NetworkOwnership, so they can still move but it’s pretty annoying. This punishment should only last for 5 seconds or so, before returning NetworkOwnership to the player.
  • Probably a few more but I abandoned the anticheat a bit ago as so many new Roblox methods and functions have came out that it just needs a rewrite.
1 Like

Flex your time on others is a sword fighting game that utilizes this and it’s quite flawed. It checks the distance someone moved (50 studs) in 1 second intervals. Exploiters are able to disable all client-side anti-exploits and move as far as they want within that 1 second interval period as long as they teleport back before the server-side anti-exploit checker calculates how far you’ve moved.

How’s this?

__PLAYERS.PlayerAdded:Connect(function(__PLAYER)
      __PLAYER.CharacterAdded:Connect(function(__CHAR)
		__CHAR.DescendantRemoving:Connect(function(__INST)
			if __INST.Name == "ExploitScore" then
				__PLAYER:Kick("DO NOT DELETE: " ..__INST.Name)
			end
		end)
   end)
end)

This will probably false flag if they drop into the void, you shouldn’t be putting these values where they can be deleted if you don’t want them to be deleted

if THEY DROP into the void, other than that, it’s completely 100% reliant. I use the same method and nobody has yet to be falsely kicked.

Ok, but what if someone runs a fling script to throw players into the void and falsely kick them?

An anticheat should never rely on methods that are able to false flag players.
If you have an anticheat that is prone to false kicks, you should just silently log the players for moderators to manually review the case.

then make an anti-fling script?? idk why youre so competent about the void, you can just block it off.
Plus i don’t think dying in void removes ANYTHING under your character model.
Not to mention you can disable dying to the void.

1 Like

Stuff being deleted depends on the type of instance
The main thing I’m trying to get to is you shouldn’t be putting things somewhere that they can be deleted.

If exploitscore is just a boolvalue or something similar, it would be less effort to just store the values somewhere outside of their character (tables, variables, other instances they don’t have ownership of)
but you have to clean it up after they leave or die

If only we had UDP/Unreliable remotes we could be able to make “seamless” server sided movement and replicating the player’s camera data to the server with no problem, this is how Valve approached a safe and efficient movement system on TF2.

It also sucks that instance deletion by the client if it’s in the client’s character can be replicated to the server.

1 Like