Intro
So, lately many people have been asking how to detect and stop speed hacking. I would like to help everyone by teaching them how to make a basic speed hack prevention system!
Here is the script we will make. Feel free to use it in your projects and edit it as you please:
Let’s get started!
How do players speed hack?
Before we can stop speed hackers, we need to know how they speed hack in the first place! The truh is, there’s no single way people do this. The most basic hack could alter the player’s WalkSpeed, and more advanced hacks can change their FPS. This means we need a way to detect ALL speed hacks, not just a specific method of doing it.
How to detect speed hackers
The best way to detect a speed hacker is to check their location on the server. If a player seems to be moving too fast, we stop them. We cannot rely on properties like WalkSpeed or Velocity to catch a hacker, but we can compare their positions to see if they’re cheating! Don’t freak out if that sounds too complex for you, because it’s actually really easy.
The script
To begin, place a script into StarterCharacterScripts. Let’s add some variables first:
local maxspeed = 22 --The maximum distance the player can travel within a check time. Try to keep this higher than 16.
local checktime = 1 --How many seconds we wait before we record their speed.
--If we make checktime too fast, like ".1", the script will be recording positions too fast and thus will fail to work correctly!
local root = script.Parent:WaitForChild("HumanoidRootPart") --Get HumanoidRootPart so we can keep track of the player's position.
local lastcf = root.CFrame --We will store the player's CFrame so that we can move the player there if they seem to be hacking.
Note the values for maxspeed
and checktime
. They need to stay somewhat proportional to each other, or we might get false readings!
Also note how I didn’t make maxspeed
17, directly above the default 16 WalkSpeed. This is because we might get false positives from slower players who are still moving at 16 WalkSpeed but appear to be moving slightly faster to the server.
Now, for the actual checking, add this beneath your variables:
while wait(checktime) do
if math.floor((Vector3.new(lastcf.p.X, 0, lastcf.p.Z) - Vector3.new(root.Position.X, 0,
root.Position.Z)).magnitude) > maxspeed then --We compare the length of the last known position, lastcf.p, with the current position, root.Position. If it's greater than maxspeed, they're hacking.
--See how we ignored the Y axis in the calculation? Also notice how we rounded on the line above? This prevents an inaccurate reading.
print("Hack detected for "..script.Parent.Name.."!")
root.Parent:SetPrimaryPartCFrame(lastcf) --The player is hacking! Because this could be a false positive, we DO NOT KICK THE PLAYER. Instead, we peacefully move them back to their last known valid position!
end
lastcf = root.CFrame --We store the player's position so we can see if they're hacking later!
end
It looks messy here, but I will decipher it line-by-line so you can understand what is going on! First:
while wait(checktime) do
We use a loop that waits checktime
. This is how often we will compare the player’s position.
if math.floor((Vector3.new(lastcf.p.X, 0, lastcf.p.Z) - Vector3.new(root.Position.X, 0, root.Position.Z)).magnitude) > maxspeed then
The actual logic! We are comparing the distance of the last known CFrame of the player to their current position. We only read the data we have on the X
and Z
axes so we don’t get a false positive when the player falls. We then round our results with math.floor
so that we don’t get weird numbers like 16.4555~
or something. Lastly, we check if that value is greater than maxspeed
. If it is, we might have a hacker on our hands!
print("Hack detected for "..script.Parent.Name.."!")
This will print the name of our potential hacker…
root.Parent:SetPrimaryPartCFrame(lastcf)
Instead of kicking the player like most anti-hax folks would be tempted to do, we just move them to the last good position they were in. This will prevent any rage you might get from false positives.
lastcf = root.CFrame
Lastly, we actually record the player’s CFrame! Very simple.
Caveats
Unfortunately, using this method to detect speed hacking does come with a few drawbacks:
- It can generate false positives on slow connections. This is why we do not kick the player if the are detected hacking!
- It prevents teleportation. To get around this, disable the script for a few seconds while legitimately teleporting players.
Outro
If you want to make your own anti-hax, now you know where to begin! If you need help, just ask. Happy anti- hacking!