How do I create an proper anti exploit?
Do you want to know how to secure your game? Do you want to know how to make a Roblox anti-exploit? Well, this is the guide for you.
Lets start with Sanity Checks.
Sanity checks are the act of validating data or variables to ensure that they are what they are expected to be and to prevent errors that could occur if incorrect data is processed. For example, in remote events exploiters are able to send incorrect data and do stuff they aren’t supposed to do, lets create an example Item purchase Remote Event.
ServerScript
RemoteEvent.OnServerEvent:Connect(function(Player, ItemName, Price)
Player.leaderstats.Cash.Value -= price
ServerStorage:FindFirstChild(ItemName):Clone().Parent = Player.Backpack
end)
ClientScript
BuyButton.MouseButton1Click:Connect(function()
if LocalPlayer.leaderstats.Cash.Value >= price then
RemoteEvent:FireServer("Sword", price)
end
end)
This is a bad way to create a Shop Remote, an exploiter could just Fire the RemoteEvent with false arguments, and get the weapon for free, an example of this:
RemoteEvent:FireServer("Sword", 0)
Done, the exploiter just got the sword for free! This is not good, lets sanitize the remote and make sure they can’t do this, lets add a check and make sure the user has enough money on the server.
ServerScript
RemoteEvent.OnServerEvent:Connect(function(Player, ItemName, Price)
if Player.leaderstats.Cash.Value >= Price then
Player.leaderstats.Cash.Value -= Price
ServerStorage:FindFirstChild(ItemName):Clone().Parent = Player.Backpack
end
end)
Awesome, now the exploiter cannot spoof there leaderstats value and fire the remote, getting the sword for free, but they can still fake the price value, lets fix that, lets validate the price on the server.
ServerScript
RemoteEvent.OnServerEvent:Connect(function(Player, ItemName)
local Price = Items[ItemName].Price
if Player.leaderstats.Cash.Value >= Price then
Player.leaderstats.Cash.Value -= Price
ServerStorage:FindFirstChild(ItemName):Clone().Parent = Player.Backpack
end
end)
In this scenario, we have a table named Items
that’s storing all the prices of tools inside of it. Now, the exploiter cannot get the item for free by firing the remote with the price set to 0. Let’s now make sure the ItemName
is a string so that the exploiter doesn’t try to cause an error in the script. Additionally, let’s make sure the item actually exists.
ServerScript
RemoteEvent.OnServerEvent:Connect(function(Player, ItemName)
if type(ItemName) ~= "string" then
return
end
if not Items[ItemName] then
return
end
local Price = Items[ItemName].Price
if Player.leaderstats.Cash.Value >= Price then
Player.leaderstats.Cash.Value -= Price
ServerStorage:FindFirstChild(ItemName):Clone().Parent = Player.Backpack
end
end)
Good Job! We have successfuly secured our remote the exploiter cannot error the script nor get the weapon anymore, wasn’t that easy?
Now, lets move on to Relying on the client
You have likely heard the phrase “Never trust the client” numerous times. However, it actually depends on what you’re trusting the client with. Players have full control over their client, they can manipulate and alter information. But, this doesn’t mean you should solely rely on the client for everything. When creating anti-exploits, don’t base them solely on the client, as it can provide false information. You can utilize the client, but don’t rely on it entirely.
Lets also talk about False Positives
While developing your anti-exploit, you are prone to having false positives. Now, what exactly are false positives? This means that an innocent player who has not exploited in the game has been falsely detected by your anti-exploit. You should keep this in mind at all times and always attempt to prevent these false positives from happening. For example, a teleport check could false positive on a laggy player. Since on the server, they were randomly teleported to a position due to their connection, they will get flagged by your teleportation check unless you have the proper measures in place against it.
Lets now move on to basic detections such as teleporation
We are going to create a server script that detects whenever a user teleports. How, you may ask? Simple, by using magnitude . We are going to compare the user’s first position with their second position, calculate the magnitude value, and check if it’s too high.
Let’s start by getting position A, which can be obtained by gettingthe X and Z axis of the character. It’s important to ignore the Y axis to avoid false positives.
local HumanoidRootPart = Character.HumanoidRootPart
local Position = Vector3.new(HumanoidRootPart.CFrame.Position.X, 0, HumanoidRootPart.CFrame.Position.Z)
Now, let’s wait a second and get position B.
task.wait(1)
local NewPosition = Vector3.new(HumanoidRootPart.CFrame.Position.X, 0, HumanoidRootPart.CFrame.Position.Z)
Alright, now that we have position B, let’s get the magnitude value.
local Magnitude = (Position - NewPosition).Magnitude
Now, the magnitude represents the number of studs the user traveled between position one and position two in one second.
So, lets check if the user walked too many studs, we are going to check if the magnitude is higher then the users walkspeed by 3
if Magnitude >= Humanoid.WalkSpeed + 3 then
print('Teleporation Detected')
end
And now, we have scucessfully detected teleporation! Good Job.
Teleporation Code
local HumanoidRootPart = Character.HumanoidRootPart
local Position = Vector3.new(HumanoidRootPart.CFrame.Position.X, 0, HumanoidRootPart.CFrame.Position.Z)
task.wait(1)
local NewPosition = Vector3.new(HumanoidRootPart.CFrame.Position.X, 0, HumanoidRootPart.CFrame.Position.Z)
if Magnitude >= Humanoid.WalkSpeed + 3 then
print(‘Teleporation Detected’)
end
And with that, this guide has now concluded, do you have any suggestions? Feel free to post or PM me. I will continue to edit this guide with more information.
Other Awesome Guides You Could Use
Guide by Reapimus: A Guide to Making Proper Anti-Exploits - #5 by iGottic
Guide by Dancdx: How exploits work and how to combat them
Latest Updates: