There probably isn’t much you can do, as far as im concerned every popular FPS on roblox (and AAA titles) have had to deal with this problem. FPS games rely on quick responses between the client and the server. Client-side anti-cheats give you the low latency you might want but the drawback is what you are now experiencing. I suggest monitoring character movement on the server. Things like how fast they are going, how high they are jumping could be indicators on whether they are exploiting or not. Overwatch uses things like “Critical hit percentage” to flag potential exploiters. If you have fired 100’s of shots and have a 95% “Critical hit percentage” chances are you are doing something fishy. Or even accuracy in general, if you fired 1000 shots in a given game and your hit percentage is oddly high then again they should be flagged and look at by a moderator. A strike system could also handle any flags.
Here’s an idea: compute different kinds of behaviors into different stats, and use those stats to compute a “exploitation confidence score”. Here are some stats you can use:
- Amount of recent damage.
- A score based on how much damage was located on the same body part.
- A score based on how many of the player’s recent shots didn’t miss i.e. recent accuracy score.
- If your game allows players to shoot through walls due to trusting the client or leeway for network latency, then a score based on how many walls the bullet probably passed through for the recent damage.
- When a player “misses”, it’s possible to compute if any player was directly in the bullet’s path i.e. if the aimbot was trying to shoot through walls. This can be a stat.
- For every second that Player A can see Player B, raise a “visibility time” for player B. For every second that Player A cannot see Player B, lower the “visibility time” three times as much as you raise it. This “visibility time” can be one of your stats that you factor in for each kill. Aimbots have a low visibility time.
- Compute these stats into a “base confidence score”. The longer that the base confidence score is over a certain number, increase a “final confidence score” in a similar manner to how visibility time is calculated, but in reverse (go up fast, go down slow).
Using just these stats, we can say that an exploiter likely gets a lot of kills in a short amount of time on the same body part, barely missing, possible shooting through walls and likely shooting as soon as possible (low visibility time). An exploiter is likely consistently exploiting i.e. consistently has a high base confidence score.
When you see a player with a high final confidence score, do something about it. I’m hesitant to say you should kick them since an algorithmic approach like this can have false positives. Disabling damage (while still counting towards exploit score) is a nice solution. Throwing them into an exploiters-only server for a while is another alright solution.
An important thing about these stats is that you can calculate them all on the server. Additionally, the confidence score gives you a sort of “fuzzy match” for exploiters so that you aren’t relying on one behavior that pros sometimes have. A good idea is to look at common confidence scores for average, pro, and exploiter players before implementing any consequences. You can also look at individual stats of average, pro, and exploiter players to tune your confidence score.
Some of these stats are light to compute on their own, but when multiplied by a full server’s players they become a performance issue. Some even grow significantly fast: visibility time takes n^2 - n
checks in order to check all players where n
is the number of players.
Good news! You have n + 1
computers to do computations on! For stats that are performance-intensive when running them on every player from the server, you can have two clients compute those stats on the client instead. If those two players disagree heavily, have two other random players handle it as one is at worst exploiting and lying, and at best is unreliable. Never let a player calculate their own stats or stats that they’re involved in.
Thanks for all the replies and suggestions.
The only issue I see with this is the spread of the gun, but I guess using the mouse target instead of the raycast would still give the same effect.
The hard thing is to separate these cheaters from good players. Good aim will be able to trace characters accurately, and high damage in a recent amount of time could come from different weapon types.
Currently, I’m only listening for suspicious inputs from the client. Holding an abnormal key is sent to a webhook, with a plethora of data. This is because (most) aimbots require an aim key to be held.
A common excuse from cheaters is “It’s my push to talk key”. The green notices are sent to help separate only holding the key when shooting, or holding it without shooting as well.
Accuracy, as Corecii suggested, is already tracked for the time that they were holding the suspected key. It displays the unique hits as well, which if the player only hit the Torso only that’d be shown.
The hard thing is to not trust the client when all of this data is collected from the client (Inputs, shooting).
If anyone has suggestions for other methods to try, I’m open.
Perhaps a method you could try is detection of camera movement without pressing right click, as usually in order to move the camera angle you would need to be holding right click.
You could track if their camera angle is facing towards a specific body part consistently. Although this would only really be beneficial for aimbot types that use the camera, instead of moving the mouse for you.
obfuscate your new one so decompilers don’t recognize it
What’s the point if it’ll be decompiled again?
There are a number of things to consider, and a lot of great points made by others in this thread.
- Clients can be compromised.
- You can make your non-compromised game clients work for you (but if they can decompile your anti-cheat, they can decompile that, too and get ideas for how to tweak them).
What I want you to consider is that this is your game, and you are responsible for the game mechanics and the game being fun. If players are abusing the game to get some benefit figure out how to work that into a game mechanic to keep the game balanced and fun. For example, the more successful your cheating player is, the more the game can make it harder in other ways to balance the game and keep it fun for the less successful players. Here are a few ideas:
- You can’t run as fast or turn around as fast.
- If you turn too fast, your gun stops working for some time (enforce this on the server).
- Perhaps every other player sees a big icon where the current kill leader is - there is nowhere to hide.
- Maybe you get your health reduced or damage dealt gets reduced. No one shot kills.
- Your head grows every time the server thinks you’re cheating. Soon everyone can make headshots on you…
- Respawn time increases.
Obviously your game mechanics might make this make no sense. These are just a few ideas to get you started. Some might be more fun than others.
That’s one strategy for mitigating cheats. There are obvious and some non-obvious ways to detect cheats and fix them server side, potentially not impacting game play for normal players. You’re in a 3D floating point world. If the player shoots precisely at the center of another player’s head, like spot on exact to several orders of magnitude – that it had to be a calculation less than some small epsilon away, and not possible to get that accurate from a mouse, consider it a cheat and take action. If the hacker can figure this out that you are doing this, they might add some noise. Maybe you add some random noise to every shot at the server and increase that noise as the likelihood of cheating goes up - the closer you aim to their center of their head, the more noise it generates on the server. Sometimes when you think you hit something in multiplayer games, they moved due to lag, so maybe this works out in their favor sometimes. Make this feel like that - a natural element of networked game play. For players that get too good, give them more latency - they can auto-aim, but their aim goes to where the player was 0.1-0.9 seconds ago (this requires server work, and maybe that incurs latency), so it only hits players that don’t move. FPS games are highly intolerant of latency, so a couple hundred milliseconds can be enough to destroy the race to the trigger button. It can also ruin the game experience just as much as people cheating can. Pay attention to what your players are telling you and play test your changes often.
You can incorporate client reporting approaches where players can tag others for bad game play, but I’d be remiss if I didn’t caution you that doing this also opens an avenue for abuse where a gang of players can make the game bad for others by reporting them. You can also incorporate some form of deputizing system where the players who have played the game longest (or have some other metric) are granted some admin controls that the game respects to make your game somewhat self policing. Again, avenues exist for abuse.
I’m not going to claim I have a magic bullet for solving this problem, and it’s a subtle art to re-balancing the game without making the cheaters more engaged than the other players. I feel like you must have good user engagement to have this problem. Maybe what you really need is a good strategy to group players together onto servers by skill level. If cheaters advance quicker, soon they will be playing with other cheaters at their own level. A quick Google search revealed that others on the dev forum have made some variety of this. Here’s one result I found.
The most important thing to remember is not to be defeated by the bad actors. There will always be bad actors, and they will eventually find and exploit and all holes in your game and our products. Where they meet with success, they will continue to explore. This problem is actually a pretty strong measure of success - you have made something of value. Whatever it is that you have done, keep doing it!
Exploiting Explained is a pretty good article on the topic. I’ll end with a variant of the same advice @Autterfly did: Listen to your players.
PS. It occurs to me that maybe if cheaters are hacking the client to enjoy your game, that in addition to server side protection, you could make a game pass for auto-aim that disables the server side protection and adds similar client-side functionality in a “legit” fashion. Then you can control the experience and game balance a little better. This can be a dangerous slippery slope / double edged sword, so tread carefully with this idea. You want to avoid angering your core player community, and this just might break your fan base. It’s worth repeating a 3rd time: Listen to your players!
decompilers can’t see obfuscated code
Although obfuscating the code can make it harder for the exploiter to read, they can still steal the obfuscated code and just remove the obfuscation. Additionally, it’d make it a lot harder for the developer to update the code.
As others have said, your best bet is to apply server-sided patches and detection to prevent the exploiter from affecting the game as much. This won’t really stop all of the exploits; however, it’ll definitely make it a lot harder.
“Ironbrew” is used to obfuscate some exploiter’s scripts, it does, however, also work on game scripts. It has never been successfully decompiled, and if you do manage to decompile it, they will reward you.
Strucid’s anticheat uses it to obfuscate the client-sided anticheat and other parts of the client code we don’t want exploiters to see. The best they can do is dump the constants of the script; they can’t even see it until an exploit releases a LuaU compatible decompiler.
That’s not really accurate. Exploits run their decompilers as a separate process usually, and even if it was part of the process, it’s unlikely Roblox would enumerate it as it’s not part of it.
Likely, some kind of in-Roblox UI that is used by the exploit or as an interface for calling the decompiler is what’s being loaded. This is part of the reason that tracking memory is such a bad idea: it’s unpredictable. One day Roblox could make a change and suddenly everyone is kicked.
Lastly, exploits can run way before client scripts even do. So no amount of memory tracking would fix that.
De-obfuscate the code is so difficult, it is easier for them to get the original by begging the owner
I don’t know much about making an anticheat, but Synapse can only decompile local scripts