What is the best way to detect a speed hacker?

If it is just speed hacking, you could have this in a LocalScript (since it is usually not detected server-side) in the starter player scripts:

local Remote = game.ReplicatedStorage:WaitForChild("SpeedCheck")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
while Character do
    if Character.Humanoid.WalkSpeed > 16 then
        Remote:FireServer()
    end
end

This would check locally if they player’s speed is above 16. Then on the server-side, kick them:

local Remote = game.ReplicatedStorage:WaitForChild("SpeedCheck")
Remote.OnServerEvent:Connect(function(cheater) --First parameter is always the player firing the event.
    cheater:Kick("You have been kicked for possibly using speed hacks.")
end)

Of course if you would like to implement bans, just make use of DataStores. But they will not be necessary if you are only checking for speed. :slightly_smiling_face:

3 Likes

Let’s think of it in two ways:

  1. The player may be hacking to become faster than others
  2. The player may not be hacking, but another user may be changing the speed of others.

I don’t know a way to find out if a player has been hacked by someone else, so you’ll have to tinker.

But, @deprecatedHeart has suggested a very good alternative and method of detecting players with unusual speeds.

2 Likes

Thank you. However I don’t think it would be that easy for a basic exploiter to change the speed of others, since he would have to be able to either:

  1. Fire a RemoteEvent that changes the player’s speed (which won’t be possible since humanoid properties are usually only changed in LocalScripts - there would be none in his game to fire).
  2. Access the server side of the game (which would already be a different story, if the exploiter can do this then he would be able to hack almost any game in Roblox).

So I think that being hacked by others is not a worry.

1 Like

If we assume that exploiters have full access to anything client-sided then an experienced one could figure out there is an anti-cheat and disable it.

From the server you can’t detect a local change in the players’ walkspeed, but you can monitor their character position over time to estimate their speed and kick suspected speed hackers. Be aware this method may cause some false positives, however as there are a ton of other factors that can mess with a system like this.

A client sided anti-exploit can always be thwarted, but once the server decides to kick a player there’s no escaping it.

4 Likes

I am pretty sure any advanced exploiter can just remove the script. Correct me if I am wrong.

3 Likes

Well, you don’t know when someone may access certain commands. Say you used a free model, that has an access script inside of it, or if a script was unsecure and didn’t have proper walls put in place to prevent others from accessing them etc…

I agree with your remark, but it is always safe to be careful, since this is a perfect example of what could happen.

What I’ve done, and it does interact with laggy people, so you should play around with it, is I take the magnitude of the HumanoidRootPart, wait about .5 seconds, and then see if they have moved more than they can with the default 16 walk speed. And if they have, I set them back to their original position, because if you kick them, you could have a lot of false positives, and you’d be kicking innocent players

1 Like

What kind of game is it? Occasionally players who collide with objects or fall from a height may gain velocity and get kicked for no reason when the use of [speed] > 16 is implemented. Also, if there are speed boosters or anything of such then the player may also be kicked so using > 16 won’t really be that great of a solution.

1 Like

Height gained by velocity does not affect WalkSpeed of a humanoid. Also, the value can always be changed. For example,

local MaxSpeed = Player.MaxSpeed.Value --IntValue for the player's speed limit.
while Character do
    if Character.Humanoid.WalkSpeed > MaxSpeed then
        Remote:FireServer()
    end
end

And the value can be changed at any time, when the speed boost is applied.

1 Like

Fall from a great height onto a wedge is counted as (temporary) change in walkspeed

A better method of countering exploiters who change their own character speed is to design the game in a way that speed does not make you win. Game design is very essential to hold these exploiters out.

For some instances, a game with speed powerups can have issues finding out if the user is an exploiter by measuring their speed. It is very difficult to perfectly design the filter if chosen to.

Instead of wildly kicking them, most games employs a method to reposition the exploiter’s character to its previous positions possible rather than illegal ones.

5 Likes

This may actually be a good solution if done right.

For example,

-- Defining the player's features
local plr = game.Players.LocalPlayer
local char = plr.Character

-- The remote(s)
local Remote = game.ReplicatedStorage:WaitForChild("SpeedCheck")

char.Humanoid.Running:Connect(function(speed) -- Making the event
print(speed) -- When running, this will change to 16, so 16 is the max walk speed
if speed > 17 and not plr:FindFirstChild("SpeedPower") then 
remote:FireServer()
else
print("Not a speed hacker")
end
end)

Then, in a server script, write:

local Remote = game.ReplicatedStorage:WaitForChild("SpeedCheck")
Remote.OnServerEvent:Connect(function(speedExploiter) 
    speedExploiter("Are you speed hacking?")
end)

Although, as @Operatik has stated, power ups may affect this, so you want to check to see if they are in a power up mode, hence the ‘SpeedPower’ check

If speed increase is used to exploit gameplay, you’ll need to insert this chunk of code into a LocalScript which is very important to the gameplay (nothing will work without that script):

local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAppearanceLoaded:Wait()
char.Humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function() --WalkSpeed never changes while walking/falling
    if char.Humanoid.WalkSpeed > 16 then game.Players.LocalPlayer:Kick("script by UnpalatabIe owo") end
    --You can actually kick LocalPlayer from the client, suprise.
    --Also, if you have any legal speed boosters, instead of 16 use maximum speed that can be given by boosters
end)

Otherwise, if exploiters increase speed to annoy players, you’ll need to use Velocity detection methods described above.

The exploiter can view client-sided, so wouldn’t they just need to copy the script remove that part and paste it?

also you can do a velocity check on the server using v = d/t to calculate speed, I would remove Y when calculating distance because if a player falls it will factor that in. With this method lag may be an issue but you can be little lenient with it and let them go alittle faster to prevent false positives.

1 Like

They can’t replace the script. They can only decompile and save it, which is already a very laggy process. Plus, even if they could modify and compile code, would they bother making insane scripts to erase the speed check part just to exploit 1 game with few hunderds of players?

Exploits can replace scripts, If they are local. Most exploiting software has ways to view local scripts and they can modify and compile the code if they want. client side checks are not going to stop them it may prevent a few people who don’t really understand what they are doing, but people who know what they are doing will bypass it. You said, “would they bother making insane scripts to erase the speed check part just to exploit 1 game with few hunderds of players”, you underestimate the lengths people will go through to exploit.

Really? I have not seen that happen at all.

1 Like

Not exactly the situation I mentioned but you get the point.

Scripts:
– if speed is over 16 but simplified (There are no speed boosters in the place) –
script.Parent.Humanoid.Running:Connect(function(speed)
if speed > 16 then
print(“Player’s speed is above 16”)
game.Players.LocalPlayer:Kick(“Speed above 16”)
else
print(“Player is at normal speeds”)
end
end)


– Trip over script (I couldn’t replicate the falling velocity increase for now)
enabled = true
function onTouched(hit)
if not enabled then return end
enabled = false
local h = hit.Parent:findFirstChild(“Humanoid”)
if (h ~= nil) then
h.Sit = true
end
enabled = true
end
script.Parent.Touched:connect(onTouched)


I uploaded the game at https://www.roblox.com/games/5369665745/Roblox-Speed-Bug so you can try it yourself.

1 Like

Don’t even bother trying to block exploiters using a Client Script, they can just delete the script.

If you have to, atleast set the script’s parent to ‘nil’. It will annoy the crap out of exploiters.

game:GetService("RunService").Stepped:Connect(function()
	Player.Character.Humanoid.WalkSpeed = 16
end)

If you are using a sprinting system or a powerup. Just make a bool value inside the player and server check it.