Way to get accurate player ping

Hello, I recently wondered how to get an accurate or very close to the truth value of a player’s ping. The real ping is shown in the panel when you press the key combination Shift+F3.

After reading some topics about this, I learned several common methods, such as:
  • Using the GetNetworkPing() method, which returns the value in seconds (to get the real ping in ms you need to multiply by 1000). The “main problem” with this method is that it does not give the “accurate” value that we are used to seeing on the panel when pressing Shift+F3. In fact, this is not quite so… Read the post from @ramblinwrek if you want to know why. (The “error” of these measurements with the real ping according to my calculations was 20-30 ms)
  • By using RemoteEvent or RemoteFunction by transmitting timestamps from the client to the server and vice versa, or waiting for a response from the server, also receiving timestamps with the calculation of the difference between them on the client, which will be the ping. (The error of these measurements with the real ping according to my calculations was 5-10 ms)

I took the idea from this post from @CDDevelopment literally translating his words into code… (The error of these measurements with the real ping according to my calculations was less than 1-3 ms)

Let’s create a RemoteEvent or UnreliableRemoteEvent (which is much better than the first) in ReplicatedStorage and name it PingEvent. After that, we will create LocalScript in ReplicatedFirst and Script in ServerScriptService. Finally, create a NumberValue in Workspace, naming it PingDT.

Place the code below in LocalScript:

if not game:IsLoaded() then
	game.Loaded:Wait()
end

local PingDT = workspace.PingDT
local PingEvent = game:GetService('ReplicatedStorage').PingEvent

PingEvent.OnClientEvent:Connect(function(LastServerPingDT: number)
	task.wait()
	local DTDifference = PingDT.Value-LastServerPingDT
	PingEvent:FireServer(DTDifference, PingDT.Value)
end)

Place the code below in Script:

local PingDT = workspace.PingDT
local RunService = game:GetService('RunService')
local PingEvent = game:GetService('ReplicatedStorage').PingEvent

RunService.Heartbeat:Connect(function(DT)
	PingDT.Value += DT
end)

PingEvent.OnServerEvent:Connect(function(Player, DTDifference: number, LastClientPingDT: number)
	local Ping = math.floor((PingDT.Value-LastClientPingDT+DTDifference)*100000)/100
	print('Ping: '..Ping..' ms')
end)

while task.wait(.5) do
	PingEvent:FireAllClients(PingDT.Value)
end

Congratulations, you now have a system for determining a accurate player’s ping!

Demonstration

Perhaps you will ask the question, where is the declared high measurement accuracy and why in some moments the error is extremely high? This is due to the fact that I was recording a video and perhaps this somehow affected the quality of the Internet connection. Also used RemoteEvent instead of UnreliableRemoteEvent, which was not a very good decision…

11 Likes

Use UnreliableRemoteEvent instead
Please :pray: Its literally that time when it fits perfectly

2 Likes

Okay, I’ll try your suggestion and I’ll post it if it works! Привет от ФГОТа)

You could use workspace:GetServerTimeNow() to check the difference in ping.
Since the value is time epoc so it can be used to check the difference in time between the server and client similliar to how you checked the difference with PingDt. This will give an accurate ping difference between the server and the client :+1:.

I’ve done some tests on your suggestion to replace RemoteEvent with UnreliableRemoteEvent, I found out that the player’s ping results remain roughly the same everywhere (maybe there’s not much difference since the game isn’t heavily loaded).
But I noticed another difference! It is that there are significantly fewer sharp jumps when measuring ping!

Look at these screenshots:

RemoteEvent

UnreliableRemoteEvent

I definitely recommend your offer! Thank you.

I already wrote about this in the second usual method of getting ping and it gives an error of 5-10 ms. The method that I suggested, and also @Yarik_superpro corrected, gives results much more accurately…

1 Like

Just a note, but when constantly firing events to clients, you might wanna suggest using a networking library to prevent issues and ensure network stability.

1 Like

Thanks for the suggestion, I’ll read more about it and take it into account for future developments of this system. I’ll probably update this tutorial with more optimized methods if I can.

1 Like

For the case of measuring ping, you do not want to do this. Most of the networking libraries available on roblox use optimizations such as ratelimiting that may cause bad results.

Anyways there’s barely and data being send so optimizing this is useless in general

(@XxNEWBIE_OFFICIALxX )

Maybe I don’t get something, but why do you need to even have any calculations on the client?..

Send from server current value, clients sends it back, server gets value back when he has value + 2 * delay

And maybe you can consider using Stepped because it appears more often?

To be honest, this system seems a bit confusing to me too and I can’t explain all its subtleties. (как говорилось: “нет времени объяснять … а дальше ты знаешь :face_with_hand_over_mouth:”) The main thing is that it works and shows a fairly accurate player ping.
As I said earlier, I simply translated his words into code and that’s it… If you have any questions, I recommend contacting the creator @CDDevelopment of the original post.

Don’t laugh here! If you can help him, then help him.

Give us a better solution then bruh

1 Like