Token based hitbox extender anticheat?

For context, I was thinking about ways to prevent hitbox extending for melee games. I’d already made a basic version that detects the hit on the client and sends an event to the server to verify the positions of the players and null the hits if they were too far apart. This worked really well until I realized that different attacks exist with different hitboxes and I wouldn’t want the anticheat nulling the wrong attacks, so I came up with the solution to pass the attack type as a parameter. This has one massive problem: It can be spoofed so the anticheat allows hitboxes that are as large as the biggest hitbox ingame. I had no idea to solve this until I remembered something.

I don’t even know if this relates to the issue but while ago, I came across an anti-cheat for a melee game. This melee game had different sized weapons with different sized hitboxes so they should’ve had the same problem I did, so I used some ethically questionable tactics to see what made their anti hitbox extenders work and I realized that every time I landed a hit on the client, an event would be sent to the server with the usual parameters (Attacker and target) but I also noticed something else: A token parameter. Every time I landed a hit, a seemingly random token would be sent to the server and if I tried using that token again, nothing would happen. My best guess is that they used some form of encryption to encrypt the type of move and send it as a parameter but then comes the problem of having to decrypt it and whatnot.

So my main question is, how would I go about doing this myself? Would it even work and is there a better solution?

1 Like

You could have limits per weapon. Like, for a short sword the Magnitude should be under “10” studs, and tag long weapons, mid, short range. (Which is something so annoying for me… specially having hundreds of weapons…)

For games that are based on combat/melee. I think the systems that should handle the “touchs” should not be based on Touched event, which is not reliable, clients can manipulate enable/disable it even if server side manipulates it too. And yeah the HitBox issue which a client can change its size/pos etc… Not trustable at all.

I think would be better using RayCasting instead of using Touched events.
For example, server does a Raycast from the attack position to the attack direction, if the ray hits a player deal the damage. Not needing using hitboxes anymore.

2 Likes

I think would be better using RayCasting instead of using Touched events.
For example, server does a Raycast from the attack position to the attack direction, if the ray hits a player deal the damage. Not needing using hitboxes anymore.

This is a good idea. Personally, I would never use a touched event for hitboxing but I can see many people doing that.

You could have limits per weapon. Like, for a short sword the Magnitude should be under “10” studs, and tag long weapons, mid, short range. (Which is something so annoying for me… specially having hundreds of weapons…)

Thats the problem I’m facing. You would have to pass the move itself to the server but since you’re passing it from the client, people can spoof it and change the move being sent. This would let people assign hitboxes for different moves, allowing themselves to have the hitbox of the biggest move.

1 Like

I could recommend using workspace:GetPartBoundsInBox() on the server instead with a set hitbox size for each weapon (use attributes to define the size & CFrame offset)

I would do something like this

local OverlapParameters = OverlapParams.new()
OverlapParameters.FilterDescendantsInstances = {Character}

local HitboxCFrame = HumanoidRootPart.CFrame * Weapon:GetAttribute("CFrameOffset")
local HitboxSize = Weapon:GetAttribute("HitboxSize")
local HitParts = workspace:GetPartBoundsInBox(HitboxCFrame, HitboxSize, OverlapParameters)

-- // HitParts is a table, consisting of all the parts in the said region
-- // Use a for loop to iterate through the parts & find characters
-- // CFrameOffset in my case would be CFrame.new(0, 0, -3), which is 3 studs infront of your character
-- // HitboxSize would be Vector3.new(4, 5, 6)

If you have issues with the fact that the hitbox feels to be late with your movement, you could cast it with a RemoteEvent, which sends the client’s HumanoidRootPart.CFrame

To verify the CFrame isn’t outright impossible, this would work

RemoteEvent.OnServerEvent:Connect(function(Player: Player, RootCFrame: CFrame)
	-- // my approach would be a single remote event which handles every weapon
	-- // based on what you have equipped, but yours could be different
	-- // consider "Weapon" as the tool in question
	-- // "Character" as the tool's holder

	local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
	local ServerRootCFrame = HumanoidRootPart.CFrame

	if typeof(RootCFrame) ~= "CFrame" or RootCFrame ~= RootCFrame
		or (ServerRootCFrame.Position - RootCFrame.Position).Magnitude >= 8
	then
		RootCFrame = ServerRootCFrame
	end
end)

^^^ This would prevent the client from sending abnormal CFrame values & automatically replace it with the place where the server sees you incase something is wrong

2 Likes

actually, all you have to pass is a Vector3 describing to direction of the ray, and then the server will calculate the ray based on the character’s humanoid root part position (read from the server) and then calculate a certain number of studs (this is done on the server) and then detect if the raycast touches any other player. This way all the player can change is the direction of the ray, and they can’t change the length or distance of the ray, they are simply passing a vector3 but are unable to control the length/distance, or in other words, size of the raycast. Hope this helps

1 Like

This is an ideal solution but the problem is that it would result in me using the server for hit detection. I would much rather detect the hit on the client and verify it on the server because it generally feels much better to do so.

What do you mean by “feels much better”?

Instead of your hitboxes being where you where relative to ping (because the hitbox comes from the character on the sever), It comes from your character on the client which makes it feel more responsive.

1 Like

Unfortunately, this is a tradeoff you will have to make. Choose either to create a smooth, responsive combat system for high-ping users (note this will them look like a hacker to low-ping users), or choose the make the game fair and anti-exploitable but also unfair to high-ping users. The decision is yours. Personally I would prefer the latter option because I care about my game being exploit-free more than being friendly to high ping users.

1 Like