So, I’m making an anti-cheat to prevent hitbox extenders for a soccer game I’m making, and since I’m using client hit detection and sending the info about the hit to the server, I noticed that there is a significant delay, for example, on my client it appears that the ball would roughly be like 2 studs away from my character, meanwhile on the server when I check it can get up to 16 studs away !!
This is a big problem because it means that exploiters would be able to have 16 studs of reach, obviously I have thought about ways to get around this but a lot of them are very complicated. So is there any way to combat this delay? like a velocity prediction for the ball of some sort? I just need some help on where to get started,
I think I may have found a solution to this, using a post I found that talks about predicting a part’s velocity using newton’s law, I found this comment:
This actually gives me very accurate results, only 1-5 studs away from the client’s position which is SO much better.
You could try recording “old” cframes of the soccer ball at a rate of 30 to 60 Hz. Then the cframe the player should be reacting to is their ping time old (Player:GetNetworkPing()). Since the player is also sending their own character cframe, the timing should be ping time old soccer ball and current time character.
I assume you are using an Unrel for the reaction signal.
local Players = game:GetService("Players")
local RS = game:GetService("RunService")
local SoccerBall = workspace.SoccerBall
local SoccerBallCFrames = {}
local MaxAge = 12 -- 6 frames per 100ms
for i=1,MaxAge do
SoccerBallCFrames[i] = CFrame.identity
end
RS.Heartbeat:Connect(function()
-- heartbeat should be final render of the soccer ball's cframe
-- , which is likely replicated afterwards
-- remove oldest cframe
table.remove(SoccerBallCFrames, MaxAge)
-- insert at position 1
table.insert(SoccerBallCFrames, 1, SoccerBall.CFrame)
end)
local function GetSoccerBallCFrame(Player)
-- ping / 0.2 * 12 + 1
-- = ping * 60 + 1
local pos = math.round(Player:GetNetworkPing() * 60 + 1)
return SoccerBallCFrames[ math.clamp(pos,1,MaxAge) ]
end
-- when you get a reaction signal from a
-- UnreliableRemoteEvent or RemoteEvent(slow)
-- then you check their character cframe and GetSoccerBallCFrame(Player)
Thanks, but this doesn’t exactly provide me with the most accurate results, I would consider this to be too large of a distance to be validated as a hit.
However, I will say that this is actually really accurate on high pings compared to other solutions Ive tried, unfortunately I’ve tried adjusting the settings but I believe that the gap is just too big when hitting it normally
Yeah, I tested in-game, still the same results, nothing interesting that happened.
Overall, I’d agree your system is more precise but it is less accurate than my old solution. I’ll keep trying to adjust any values if it helps, I’m just not sure what to change.
It’s for sure not a bad system, like I said, it is precise and there are not any visuals that appear to be super off
Yeah it’s hard to tell. If your ping is steady, the theory should work.
Server sends soccer ball cframe → player reacts to the ball → server recieves character cframe and react signal
The cframe the character reacted to is ping time old.