Repost because I accidentally posted it early
Almost every day the #resources:community-resources section is blessed with an anti-exploit which can’t even do its job because it indulges in some bad practices. Now while these posts are met with valid criticism, and usually get locked within a few hours, I’d like to attempt to educate any aspiring anti-exploit developers with a few of the most common bad practices I see in such posts.
My personal big three of the bad practice list are
- Client-sided security
- Common false positives
- Lack of versatility / bad UX
Client Sided Security
While it’s not a terrible idea to secure the client a little, I just hope you understand that it takes one competent exploiter to release a script to the masses and forever nullify your client’s security measures.
That’s not the only reason why, however. The second and most important reason is that the exploiter has full control of what the client does. Anything the client can do, an exploiter can do. I’ll go over a brief list of common client-sided anti-cheat measures which can be bypassed within minutes.
- Memory checking
- Indexing literally anything
- CoreGui descendant checking
- Kicking on the client
Everything listed above can be spoofed by an exploiter. They’re able to completely override any method called on the client. If you want to learn more about spoofing, do check out this thread. In summary, don’t rely too heavily on client security. It’s not worth your time.
I advise against memory checking not only because it can be bypassed within 10 lines of code, but also because it can return false positives on players with lower-end hardware. Speaking of false positives…
False Positives
For those who don’t know, a false positive is when someone is incorrectly labeled as an exploiter. This can be for any number of reasons but usually boils down to a small oversight on what the developer believed was possible at the time of writing their code.
I’ll use a recent example of a false positive gold mine.
This is a bad way of detecting (and dealing with) speed hacks for a few reasons, but the main one I’ll point out is that this can be set off by physics acting up. The speed
argument passed when the .Running event fires does not pass the value of the Humanoid’s WalkSpeed, but rather the velocity at which the HumanoidRootPart was going when it does. This also includes vertical momentum, so even if you’re falling too fast, this will go off.
As for alternatives, I would suggest measuring strictly horizontal velocity, and detecting for consistent time intervals that the speed goes above the norm.
Bad UX
UX, or user experience goes both ways here.
I’ll start with bad player experience, which I’ll define as not punishing potential cheaters effectively. No matter how great your anti-cheat may be, you will always catch a false positive one way or another. It’s just a matter of how frequent it is.
So when your anti-exploit “catches” someone, you’ll want to punish them accordingly. So what’s the best course of action to take if your script catches someone going over the speed limit?
- Ban the player
- Kick the player
- Teleport the player back to where they should be
This is a pretty subjective question, but I strongly believe it’s best to be tame and reasonable when dishing out punishments, at least when a machine is the one doing it. As suggested by @Pokemoncraft5290, it would be much friendlier to simply teleport the player back to before their speed changed suddenly.
If your anti-exploit goes haywire and starts banning or kicking people, your players won’t like that. You’re far less likely to lose players by giving them a small setback as opposed to removing them from the game entirely. Not everyone has that much patience.
Of course, even lax punishments that start going crazy can eventually lead people to leave out of frustration, but as someone who has played games with anti-exploits, the less invasive the better. A game with an invasive anti-exploit that constantly pesters legit players is not fun. Even if it mitigates the threat of exploiters, I personally wouldn’t have much fun with the base game.
Now for bad developer experience. This only applies to the people making anti-exploits for public use, as games with a special anti-exploit tailored specifically for that game probably don’t have bad dev UX.
When you do make a public resource, I think it makes perfect sense to try to appeal to as many developers as possible, which means you should not bar potential consumers by marking certain API usage as an ‘exploit.’
Once again borrowing from a recent example.
This code just outright boots players who enter the PlatformStanding humanoid state. Now while this code does its job in punishing some fly scripts, it’s a bandaid solution that can be bypassed by just, not using the PlatformStanding state type. I personally use this state type for ragdolls in my game, but I know I’m not the only one who uses the PlatformStanding state type.
The obvious fix to anyone who wants to use this particular anti-exploit is just to remove that block of code, but this also is just not a good countermeasure for fly exploits.
Closing Remarks
There’s nothing wrong with making anti-exploits. They’re a necessary addition to any game, and small fixes can go a long way.
But when developing one, you should have user experience and practicality in mind. A bad anti-exploit is just as good as no anti-exploit. People who flood this part of the forum have good intentions, but bad implementations. I’d like to emphasize that it’s okay if your ideas and implementations aren’t great. Learning is an important step in making a good, versatile anti-exploit. Criticism may sting, but it’s a necessary component if you want to make any resource.
Don’t harass or bully anyone who may be guilty of any of the bad practices listed. Politely let them know that their methods aren’t the best, and move on. Don’t be rude.