Hello,
I was wondering if anybody here knew how to measure a player’s ping accurately. All help would be appreciated!
EDIT: The actual script is in Reply #1, but I made a simple order of operations error which was solved in Reply #14
Hello,
I was wondering if anybody here knew how to measure a player’s ping accurately. All help would be appreciated!
EDIT: The actual script is in Reply #1, but I made a simple order of operations error which was solved in Reply #14
An easy way to do this is to set up a RemoteFunction that just returns immediately. You then measure the time it took to get a response:
-- Server:
local rf = Instance.new("RemoteFunction")
rf.Name = "Ping"
rf.Parent = game:GetService("ReplicatedStorage")
rf.OnServerInvoke = function() end
-- Client:
local pingRf = game:GetService("ReplicatedStorage"):WaitForChild("Ping")
local start = time()
pingRf:InvokeServer()
local ping = (time() - start)
-- 'ping' is in seconds. Multiply by 1000 if you want milliseconds.
If you need the server to track player ping, don’t do this in reverse using InvokeClient
(InvokeClient
is evil). Instead, have the client fire a RemoteEvent with the ping. The server can listen to that RemoteEvent and store the player’s ping somewhere.
Some other tips:
Thanks! I’ll check it out. (Also, hi sleitnick!)
@sleitnick I’m not as familiar with the time() function. Does it return as accurate a time as tick()? I know tick() measures a very accurate time (within thousandths of a second) . Although these times can differ between server and client, this is not a problem in this case.
Also, @BasicBan, you would probably want to evaluate some sort of average for a more accurate idea of what the ping is like for a specific client.
tick()
returns the amount of time in seconds since the UNIX epoch. time()
returns the amount of time the current Roblox session has been running. (server or client depending on who calls the function)
time()
is basically tick()
offset from the time the server started. Considering that tick()
may be deprecated in the near future, time()
is preferred. You could also use os.clock()
, but that’s better for benchmarking.
does tick()
return the same value as time()
on server?
When i multiply it my 1000, it just turns into like 7859.48578297923748 and if I use math.floor() it just turns into 7859 and increases by my actual amount of ping (which is 2000, don’t question it lol). (I know it is inaccurate because i checked the average ping in the f9 console and it was nothing even close to that.)
i think i know the issue, its because you only run it once when the player joins, and i think there is some lag when the player just joins, try adding a wait before it or insert it into a loop
It was already in a while wait(1)
loop
Can I see the full local script?
wait(5)
while wait(1) do
local start = time()
script.Ping:InvokeServer()
local ping = (time() - start*1000)
script.Parent.Text = "Ping: "..math.floor(ping).. "ms"
end
Looks like an order of operations issue.
wait(5)
while wait(1) do
local start = time()
script.Ping:InvokeServer()
local ping = ((time() - start)*1000)
script.Parent.Text = "Ping: "..math.floor(ping).. "ms"
end
Thank you! I didn’t notice that, you are a real lifesaver!
Why is InvokeClient evil? Bad paradigm or bad technically?
Its cause in general you want to follow a server side authentication model, and invoke client kinda defeats the point