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 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.

7 Likes