The title is self-explanatory. I’m doing an anti-teleport system, but I keep failing to detect laggy players. Is it even possible to??
type plrPositions = {
[Model] : {
HumanoidRootPart : BasePart,
Player : Player,
Last : Vector3,
CanTeleport : boolean,
}
}
local plrs = game:GetService("Players")
local RS = game:GetService("RunService")
local tp1 = workspace.TP1
local tp2 = workspace.TP2
local maxDistance = 5
local lastTime = os.clock()
local plrPositions : plrPositions = {}
type plrPosition = typeof(plrPositions[Instance.new("Model")])
local function watchPlayerPosition(char : Model, data : plrPosition, elapsed : number) : ()
local canTeleport = data.CanTeleport
if not char:IsDescendantOf(game) then
plrPositions[char] = nil
return
end
local HRP = data.HumanoidRootPart
local plr = data.Player
local current = HRP.Position
if not canTeleport then
local ping = plr:GetNetworkPing()
local velocity = HRP.AssemblyLinearVelocity
local verticalSpeed = velocity.Y
local difference = current - data.Last
local expectedMaxDistance = velocity.Magnitude * (elapsed + (1 + ping * 5))
local fallbackMaxDistance = maxDistance * (1 + ping * 5)
local possibleSuspiciousMovement = (velocity.Magnitude < 1 and verticalSpeed > -1)
local bigJump = difference.Magnitude > fallbackMaxDistance
local movedTooFar = difference.Magnitude > expectedMaxDistance
if (possibleSuspiciousMovement or movedTooFar) and bigJump then
HRP.Anchored = false
HRP.CFrame = CFrame.new(data.Last)
return
end
end
data.Last = current
end
local function watchPositions(elapsed : number) : ()
for char, data in plrPositions do
task.spawn(pcall, watchPlayerPosition, char, data, elapsed)
end
end
local function watchPlayer(char : Model, plr : Player) : ()
local HRP = char:WaitForChild("HumanoidRootPart") :: BasePart
plrPositions[char] = {
HumanoidRootPart = HRP,
Player = plr,
Last = HRP.Position,
CanTeleport = false,
}
end
local function wormholeTouched(hit : BasePart, wormhole : BasePart) : ()
local model = hit:FindFirstAncestorOfClass("Model")
if not model then return end
local HRP = model:FindFirstChild("HumanoidRootPart")
if not HRP then return end
local target = wormhole == tp1 and tp2 or tp1
plrPositions[model].CanTeleport = true
model:PivotTo(CFrame.new(target.Position) * CFrame.new(5, 0, 5))
RS.Heartbeat:Wait()
task.wait()
plrPositions[model].CanTeleport = false
end
local function onPlayerAdded(plr : Player) : ()
plr.CharacterAdded:Connect(function(char)
watchPlayer(char, plr)
end)
end
plrs.PlayerAdded:Connect(onPlayerAdded)
RS.Heartbeat:Connect(watchPositions)
tp1.Touched:Connect(function(hit)
wormholeTouched(hit, tp1)
end)
tp2.Touched:Connect(function(hit)
wormholeTouched(hit, tp2)
end)
2 Likes
You could do a violation based system to count how many times it is violated and only act if a user has persistently violated the anti-teleport so many times and you would obviously only do this for small magnitude changes to consider laggy players.
1 Like
Maybe, but that may not work since I could have 2K ping, and I would be punished after some violations, no?
You could loosen the security for player’s with high ping.
Read: Player | Documentation - Roblox Creator Hub
Just realised you are already doing something like this - if you detect insane ping you could provide more buffer.
Yea, but that’s the problem I’m facing.
It’s not precise; it doesn’t return the replication lag itself, which would be expected.
You could create your own replication lag detection system manually using a remote event and a local script to calculate (server sends ping, detects when client returns pong and do this repeatedly).
Although then exploiters would be able to make it seem like they are lagging.
yes, exploiters could easily do anything they want /:
i was thinking about an average position magnitude system
Possible but it still doesn’t prevent teleporting if a cheater moves in intervals consistently and won’t that mean laggy players could still be effected if they freeze or get a massive movement update when they stop lagging.
yea, so is there any way at all?? I can’t think of anything because laggy players are already really similar enough to exploiters, about TPing to places
I think in some way you would have to just trust the client.
You could do the replication lag detection idea and try to secure it using obfuscation (not just the script but renaming remotes or mixing in junk data or encoding the payload - just to try make it harder) and handshaking.
I would use a RemoteFunction and the server sends a request to the client with the current timestamp and a nonce and then the client immediately responds with both values and then the server compares the difference and the nonce and the frequency of the late responses to detect fake lag.
1 Like
If I somehow get the replication lag, what should I do with it?
But, indeed, I could get it and compare with the server one to see if it’s not that different
Take that into consideration instead of GetNetworkPing() since it’s more reliable.
I would honestly also compare GetNetworkPing and the replication lag since there will be some kind of pattern (again to prevent exploiters faking lag).
1 Like
But would that consider laggy players then?
EDIT: Are there any formulas I can use to make it more certain that it is a laggy player
I believe so since you said the only problem with :GetNetworkPing() is it doesn’t take into account replication lag.
So I would use your own replication lag system to ensure it is accurate.
And then obviously do something on the server-end to ensure that exploiters aren’t just faking replication lag in order to teleport by comparing it to the player’s network ping.
Something like:
local expectedPing = player:GetNetworkPing() / 2 -- / 2 because we're using a one way system
local collectedPing = serverTime / clientEchoTime
local difference = math.abs(expectedPing - collectedPing)
if difference > 0.3 then -- 300ms
print("difference is over 300ms - client could be faking lag")
end
2 Likes
Also, I’ve noticed that if you go to the wormhole and gets teleported, I wanted to make it so it doesn’t flag and the player gets teleported normally
but if the player is laggy, it would still flag because the “CanTeleport” would be false before they actually teleported
If the teleporting actually occurs on the server (the server script is modifying the CFrame of the player) then it shouldn’t be a problem.
If you’re doing it on the client then change it to fire a remote event to teleport which automatically toggles off the anti teleport system, moves them and re-enables the anti-teleport.
Yes, but sometimes the player is not “teleported fast enough” until “CanTeleport” is false. It’s something like:
Players goes to wormhole → Due to lag, they don’t get positioned before CanTeleport is set to false → CanTeleport is set to false → They teleport, it consider as exploiting
But if you’re doing the checks on the server end and the server end is moving their CFrame it shouldn’t be a problem - I believe?
If not you could add a grace period based on their replication lag and network ping.
yes but apparently it’s still error’ing. Let me show you a video of someone testing it:
Uploading: 0800_15072025_033825.mp4…
EDIT: The video bugged, but anyway…