Anti-cheat questions

I’ve tried many times in the past to make an effective anti-cheat only to find myself disabling it for one reason or another. I’ve looked over almost every big anti-cheat related thread on the DevForum over the past year or so. I generally understand the big problems with making an anti-cheat. I have yet to find something conclusive and something that wraps all of it together so I can know what to do.

The major issue I’m mainly trying to tackle with this post is movement related cheats (the most common and hard to patch).

One of the most annoying parts is I’ve seen some effective anti-cheats, but not how they work. The two underlying principles I see in an effective anti-cheat is the ability to successfully stop cheaters and to not mess with the normal player’s experience. Just to name a game, Outlaster has, from what I’ve seen, a great anti-cheat. For those who don’t know, the minigames/challenges in that game are mostly movement based, so this is a big thing to have. I got flung one time and got teleported back from moving too quickly. Before this, I hadn’t noticed there was an anti-cheat at all. Pretty smooth. Along with that, I hadn’t seen any cheaters either.

From that experience and everything else I’ve learned, I have quite a few questions:

What value do they source the player’s speed/velocity from? How optimized are these checks so you aren’t using a significant amount of server resources on something the normal player wouldn’t run into? What’s the maximum movement threshold where it starts to teleport you back? How does the system account for ping to not make laggy players unhappy?

3 Likes

You can check the magnitude of the last position and the position that I have now.

Thanks for the reply. I’m aware this is how you check movement related cheats. The more advanced questions I’m trying to get at are listed in the last paragraph of my post:

Most people make their anti cheats via local scripts(which is bad and will NOT work since exploiters can delete anything related to the client) I have made an anti exploit that is decent and in a server sided script, but it has A LOT of false positives, the way you want to do it is not check their walkspeed, that replicates to the client as well. You need to check the players distance in a short period of time. Edit: I get the players descendants with for i,v in pairs and do v.Changed:Connect(function() and make a number value go up and constantly down as well, and if the value is above a certain value(100) it kicks the player.

Again, please read the last paragraph in my post. I’m aware of how to create an anti-cheat that works on the server and is effective to a certain extent. I’m trying to answer more complex questions which could improve the overall performance of the system:

Hello, sorry this did not help, try checking my edit to see if it helps more.

1 Like

Try this:
It can contain an error because I wrote it in mobile.

        game.Players.LocalPlayer.CharacterAdded:Wait()
        local char = game.Players.LocalPlayer.Character
        local hum = char.Humanoid

        function checkTp()
        local pos1 = hum.Position

        delay(1, function()
        local pos2 = hum.Position
        if (pos1 - pos2).magnitude >= 150 then

        --what you want to do. (Kick etc)

        end

        end)
        end

        -- at end of script
        while wait() do
        checkTp()
        end

Hi, this will not help that much because exploiters can delete anything related to the client like I said. LocalPlayer goes for local scripts. Edit: You can also check the walkspeed the player has in their client with a local script as well.

2 Likes

Yes, but we can add server scripts preventing this.

But this can also be checked on server.

1 Like

Hi, thank you for explaining more clear. The method I use is checking the players descendants, it has false positives but you can try making it go down slower and changing the value.

local players = game:GetService("Players")

players.PlayerAdded:Connect(function(plr)
    local value = Instance.new("NumberValue",plr)
    value.Name = "AntiHack"
    plr.CharacterAdded:Connect(function(char)
        wait(10)
        for i,v in pairs(char:GetDescendants()) do
            v.Changed:Connect(function()
                value.Value = value.Value +1
                wait(1)
                value.Value = value.Value -1
                if value.Value >100 then
                    if char.Humanoid.Health ~= 0 then
                    plr:Kick('Exploiting!')
                    end
                end
            end)
        end
    end)
end)

And that line? So if the value is more than 100 and i oofed, then I am kicked?

No, if your health does not equal 0 it does not kick the player. I did this to prevent people from being kicked for falling off the map.

Oh ok, sorry I didn’t saw the ~

1 Like

Movement anticheat can be hard, especially when ping and lag can cause players to rubber band and teleport. I think I’ve come up with a somewhat smart system. I haven’t had any issues with it. Anticheats can be tough becuse you dont want ledgit players to fire it or laggy players, which makes it really hard. I think ive thouht of a solution to help prevent laggy players from triggering the anticheat. This is all serversided.

I get the players velocity by taking Position initial - Position final. That will give a vector3 of their velocity, and you can .Magnitude it. You can then check that against their (walkspeed + a stretch room amount) / amount of times a second you are checking, and if its over that i then add 2 to a counter for that player. If they are under that amount, i would remove 1 from that counter.

If the player’s counter is over a certain # (i user 12) then you would teleport them to their last position, and don’t update there current position at the end of the checks, so it teleports them back to the same place. Its important you want to multiply the velocity by Vector3.new(1,0,1) so it cant get triggered if someone jumps.

The whole point of the counter is to prevent a lag spike from teleporting someone back.

You also want to take their floorparts velocity into play. I have a solution which works just fine for my specific game, but im gonna try to explain one i think will work for any game: You would get the parts velocity they are standing on and then subtract the velocity from that from the players velocity. I haven’t tested this, but in thought this should work.

I also don’t teleport them if they have a forcefield, to prevent anything from happening when the user respawns. This next thing is a bandaid solution(i think), but i also have a wait counter i give to each player which for as long as that number isn’t 0, it basically disables the anticheat for that user for that many cycles.

I also teleport the players back if they are over some absurd distance even if their counter isn’t above the number, to prevent teleportation aswell.

Finally at the end if they haven’t set it off, you would save there position to a variable multiplied by vector3.new(1, 0, 1) so you can use that for the next check as there past position.

Hopefully this helped. Ive had no issues with my testing of this, so i think it should work for you

6 Likes

Anti-Cheats simply look at the player’s position, whether using the player’s head or humanoid root part, over time and if a player’s speed which is over a certain amount the player’s position is set to the last position. Just be lenient with the speed.

I have an Anti-Exploit resource that you can take a look at if you want.

1 Like

The more recent prototype of my anti-cheat used a magnitude checking system like what you describe. The only issue in hindsight is there was no counter to see how many recent violations a user might’ve gotten. It would just teleport them back if the magnitude from their last position was greater than a specifically test amount. When you mention the longer distance instant teleports, that’s also a good idea. I’ll for sure add these to the list of things to do.

The surface the player is standing on is also a interesting solution. Mostly for anything like moving platforms. I’ll have to put some thought into this.

Quick note: the ForceField check wouldn’t work if the spawn location has the ForceField timer set to 0.

I havent thought of if the spawn has forcefield set to 0. Maybe you can hook up a characteradded to the wait thing and bassically disable it for them for a bit so it can update there position, or maybe force update the position when the player respawns.

Moving platforms were probably what took me the most time to get. My games specific solution i just disabled it if the user was on a moving part which had the collectionservice tag, but this wont really work massive scale for other games.

1 Like

client-sided anti-cheats are not all bad and will work if you know what you are doing, but yes, most client-sided anti-cheats are bad

The reason I say they are bad is because exploiters can delete local scripts or anything related to the client. (Even most skids)