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