PlayerPing - Get client ping times on the Server

This is a pretty nice module but, I have a few critiques, wouldn’t an exploiter want to increase their ping instead of make it seem really low as I don’t really see much use of faking your ping so it seems lower than what it actually is; on the other hand, increasing their ping would allow them to “trick” lag compensation on a server to register a hit allowing them to shoot players who aren’t in sight (one example).

Ping can be easily increased by an exploiter, one way this could be done is by hooking functions so Remote:Fire(...) will yield for a short amount of time before firing (there’s an example below); using a key will probably prevent most exploiters (script kiddies) but, some exploiters will be able to easily get around. Arguments passed through Remote:Fire(...) will be passed to the hooked function which an exploiter can pass through the original function used to fire remotes, rendering the use of keys useless in most cases.

I’ve considered a few alternatives such as using a players position to determine what their ping is but, if a player is stationary, their ping will seem really high. A part that a player has network ownership could be used but, if an exploiter finds out, it might be even easier for them to fake their “ping”.

local FireServer
FireServer = hookfunction("RemoteEvent").FireServer, newcclosure(function(Event, ...)
    if not checkcaller() then
        if Event == [some event] then

    return FireServer(Event, ...)
-- Hookfunction: allows you to hook functions
-- newcclosure: prevents some (if not, all) current detection methods (e.g. environment checks)
-- Checkcaller: checks if a Remote was fired by a game script (if so, it'll return false)

Thanks for sharing this module though, I’m sure it’ll have really nice use cases :+1:


Sending os.clock() instead of GUID would be enough and you would also receive a synced up server time reference on the client. os.clock() is a floating point value and guessing the right one for exploiters would be very tedious already.


Awesome module! Thank you!

Accurately grabbing ping of players was always something I would find hard to write myself <3

I was looking into Postie and discovered a major issue with how old listeners are cleaned up. Essentially, if multiple requests are sent around the same time (as they would be with a system like PlayerPing) and are not returned in the correct order, requests can be “lost”. I have described the issue in detail in the reply linked below as well as uploaded a modified version of Postie that addresses the problem. I’d recommend you to either use that or come up with your own solution.


cant exploit just decompile your script and copy and then disable yours and make there script return what ever they need and the value the server send

Yes but that defeats the point of the check.

The check exists to make sure that an exploiter can’t report their ping as lower than actuality.

is there a limit to how long ping can be delay if not i can just delay it till i did what ever bad action then fire it

Please don’t report for necrobumbing

Few questions/comments

  1. Would :GetNetworkPing or other methods of getting Ping would be more efficient than this?
  2. Are you using wait() on purpose? If not then you should change it to task.wait()
  3. Would multiplying the returned value by 1000 get the ping in ms because I see that this is more common than just in seconds.
  4. Is 3 for UPDATE_FREQUENCY an optimized number for server lag, etc.

Thanks @Tomroblox54321

This is old, as noted by your necrobump. Don’t use it anymore, as :GetNetworkPing() exists now. It did not at the time of this module’s creation.


Ok didn’t know. Thanks a lot for helping again @boatbomber!