How would I measure a player's connection?

Hello there.
I want to create a player list, where it will show the player’s connection, whether it’s strong or weak.
Like the Minecraft User List, where the connection is shown next to the name.

image

I’ve tied using tick() to calculate the delay of an input, but it didn’t turn out as I wanted, so I deleted it.

Is there a way to calculate the ping?

Any suggestions?

1 Like

Server:

local Remote = Instance.new("RemoteFunction", game.ReplicatedStorage)
Remote.Name = "PingRemote"


function GetPing(player)
	local TS = tick()
	local R = Remote:InvokeClient(player)
	local TS2 = nil
	while true do
		wait()
		if R == true then
			TS2 = tick()
			break
		end
	end
	return math.floor((TS2 - TS) * 1000)
end


while true do
	for i,v in pairs(game.Players:GetPlayers()) do
		local PlayerPing = GetPing(v)
		print("(Server Ping Check) "..v.Name.."'s Ping: "..PlayerPing.."ms")
	end
	wait(5)
end

Client:

local Remote = game.ReplicatedStorage:WaitForChild("PingRemote")
Remote.OnClientInvoke = function()
	return true
end
9 Likes

I am a new scripter, so I didn’t understand much. Could you please explain it with some more detail?

1 Like

A possible solution would be utilizing RemoteEvents and calculating the time it takes between sending and receiving a ping back from the server.

local function ping()
	local send = tick()
	local ping = nil
	
	RemoveEvent:FireServer()
	
	local receive; receive = RemoteEvent.OnClientEvent:Connect(function()
		ping = tick() - send 
	end)
	
	wait(1)
	receive:Disconnect()
	
	return ping and math.floor(ping) or 999
end

print(ping().."ms")
6 Likes

So, I put this into a local script.
There were no errors, but it said I had 999 ms. Which I am sure I don’t…

Make sure you provide an address for the remote event on the client, you also need a server sided script that can receive and send.

RemoteEvent.OnServerEvent:Connect(function(player)
	RemoteEvent:FireClient(player)
end)

Put the remote event in ReplicatedStorage and have something like
local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent")
headlining the client and server script

You’ll also want to loop the ping with a while loop or with RunService to keep the ping updated.

1 Like

Client and server time will be different most of the time by seconds or minutes. It will vary by player and provide inaccurate results based on the client’s clock. Quenty’s Nevermore Engine has the ability to sync server and client clocks but overall comparing one computer’s clock to a different computer’s clock isn’t a good idea

2 Likes

So, I did what you told me and still it prints 999ms. Any suggestions?

Put a remote event in replicated storage

Client:

local replicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = replicatedStorage:WaitForChild("RemoteEvent")

local function ping()
	local send = tick()
	local ping = nil
	
	remoteEvent:FireServer()
	
	local receive; receive = remoteEvent.OnClientEvent:Connect(function()
		ping = tick() - send 
	end)
	
	wait(1)
	receive:Disconnect()
	
	return ping and math.floor(ping) or 999
end

while true do
	print(ping().."ms")
	wait(5)
end

Server:

local replicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = replicatedStorage:WaitForChild("RemoteEvent")

remoteEvent.OnServerEvent:Connect(function(player)
	remoteEvent:FireClient(player)
end)

Let me know if you’re still seeing an issue with this setup. The reason you are getting 999 is because ping is still nil when the return is made. Add more time to the wait above the disconnect if the issue persists, possible that the connection is taking long than a second.

image

3 Likes

Only call :Disconnect() when the event is no longer needed.
In this case, you’d want to loop through it as the ping will change overtime.

1 Like

How many ping is one 1 ms? (30 chars)

That should answer it.

1 Like

But the program prints 0ms, although my wi fi sucks… It’s 5Mbps, so I cant have 0 ping.Screenshot 2020-07-28 at 1.21.26 PM

You’re likely testing in studio where your computer is both the client and the server. If you publish your game and go into a live server and access the console you’ll see a different number depending on latency.

1 Like

Thanks! How would I access the console in game?

Press F9, I think you can type /console into the chat aswell.

2 Likes

Great! Thanks everyone for the help! I appreciate it!

I believe it is also possible to simulate it in studio. Under network settings there is a property called IncommingReplicationLag which does what its name suggests.

2 Likes

The same happens in game… Sorry for the delay @EnkryptionKey

That’s because the number being floored is something like 0.034592985 which will constantly output 0. Ping measurements are in the thousandths place of a second, hence the millisecond(ms). To fix this we need to modify the loop.

Changing it from its original form:

while true do
	print(ping().."ms")
	wait(5)
end

Into this:

while true do
	local ping = ping()
	-- Ping was received by the remote within 1 second
	if ping < 999 then
		ping = tonumber(string.format('%.3f', ping*1000))
	end
	print(math.floor(ping).." ms")
	wait(5)
end

string.format will allow us to take the first three decimals of the number, and then we can multiply by 1000 to give us a nicer visual representation of where our ping is at. This solution to getting a player’s ping isn’t exact by any means but it should give you a close indication.

image

2 Likes