Anti-cheat questions

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)

I’ll consider the thread answered but there’s really one thing left I’d want to question: the performance impact on the server. Preferable the anti-cheat would have as minimal impact on the server as possible. That might mean doing plenty of micro-optimizations to make sure it runs smoothly. That might be storing smaller values, storing the least values possible, and charging the frequency of the checks. What would be ideal here?

1 Like

I would say this would be impossible, the only thing you can do is make it harder and less likely to have false positives. Even jailbreak with one of the best anti cheats false kicked a player before. The only thing you can do is make it rare to false kick. As long as it doesnt completely ban the player it should be fine, I don’t think you should completely auto-ban a player just for exploiting anyway unless they are going to copy your game or use remotes to do some bad scripts. That is up to Roblox.

I’m not worried about false positives. You mention kicking as well, but that’s also a bad approach. The best way of working around movement cheats is to take the most passive approach possible and just teleport them back. It is most definitely possible to work on the optimization of an anti-cheat. Working with inefficient code can be a really bad thing.

1 Like

I completely agree with you and I rarely see someone think like this. Though I don’t see what you mean on the impact on the server?

Preferably an anti-cheat would have minimal performance impact on the server. Anti-cheats are the kind of thing that wouldn’t (or shouldn’t) affect normal players, making it the majority of the people who play the game. If the server spent most of the processing time on the anti-cheat, it becomes counterproductive.

This is what I mean by false positives, this is also impossible. As long as it rarely teleports a normal player you are fine.

Exploiters can use a for i loop to bypass that Anti-Teleport. I would prefer more like this but i wrote it in 5 minutes so there may be a mistake.

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

Players.PlayerAdded:Connect(function(Player)
	local lastWarning
	local teleportWarnings = 0
	local lastPosition = Vector3.new(0, 0, 0)

	Player.CharacterAdded:Connect(function(Character)
		RunService.Heartbeat:Wait()

		local Torso = Character:FindFirstChild("Torso") or Character:FindFirstChild("LowerTorso")
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		lastPosition = Torso.Position

		RunService.Heartbeat:Connect(function()
			if not Character or not Torso or not HumanoidRootPart then
				if Character then
					Character:BreakJoints()
				end
				return
			end

			if Character:FindFirstChild("TPBypass") then
				lastTeleport = tick()
				lastPosition = Torso.Position
				return
			end

			if (Torso.Position - lastPosition).Magnitude > 180 then
				Character:MoveTo(lastPosition)
				lastTeleport = tick()
				TeleportWarnings = TeleportWarnings +1
				return
			end

			lastPosition = Torso.Position
			if TeleportWarnings > 3 and tick() - lastTeleport <= 3 then
				TeleportWarnings = 0
				Player:Kick("Teleport.")
			end
		end)
	end)
end)
2 Likes

Actually we cannot add server scripts preventing this, the server can’t detect what happens client side such as the client deleting their scripts.