Ping/FPS Displayer

Hey guys! In this tutorial, you’ll learn how to make something like this:


Firstly, create:

  • RemoteFunction called Ping
  • RemoteEvent called PingFPS

And put them in ReplicatedStorage.

Next, we’ll move onto the script. I’ll explain everything in the comments.

This LocalScript should be placed in StarterPlayerScripts, but you can make your own judgement.

local fps = 0 -- set the variable
local RemoteFunction = game:GetService("ReplicatedStorage").Ping -- get the function to send the ping

local rs = game:GetService("RunService") -- get run service so we can use renderstepped
rs.RenderStepped:Connect(function() -- runs every client frame
    fps = fps + 1 -- every frame, increment FPS variable by one
end)

while wait(1) do
    local t = tick() -- get current tick
    RemoteFunction:InvokeServer() -- sends a ping to the server and pauses the script until we get a response back
    local ping = math.floor(((tick() - t) / 2) * 1000) -- explained on lines below
-- take the current tick and subtract it from the previously recorded one
-- half it so we only get the time it takes to receive instead of send AND receive
-- multiply it by 1000 (to convert to milliseconds)
    
    game:GetService("ReplicatedStorage").PingFPS:FireServer(fps,ping) -- send the information to the server to update
    fps = 0 -- reset FPS
end

Then, create a script and place it in ServerScriptService.

game.Players.PlayerAdded:Connect(function(player) -- when a player joins

    ------- create leaderstats -------
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player
    
    local ping = Instance.new("StringValue")
    ping.Name = "Ping"
    ping.Value = "0"
    ping.Parent = leaderstats
    
    local fps = Instance.new("StringValue")
    fps.Name = "FPS"
    fps.Value = "0"
    fps.Parent = leaderstats
    ------- create leaderstats -------
end)

game:GetService("ReplicatedStorage").PingFPS.OnServerEvent:Connect(function(plr,fps,ping) -- once we get a response from the localscript
    local player = game.Players[plr.Name] -- get player instance (you could use plr parameter but i prefer this way for some reason)
    
    player.leaderstats:WaitForChild("FPS").Value = fps -- changes the FPS value to what we sent from the localscript
    player.leaderstats:WaitForChild("Ping").Value = ping -- changes the ping value to what we sent from the localscript
-- NOTE THAT THE WAITFORCHILD IS NECESSARY SO WE DONT REQUEST A NIL INSTANCE CAUSING AN ERROR
end)

local RemoteFunction = game:GetService("ReplicatedStorage").Ping -- get the remotefunction

RemoteFunction.OnServerInvoke = function(player)
    return "received"
end
-- this is only to tell the localscript that the server actually sent something

Basically, long story short:

FPS

We’re increasing a variable by 1 every frame and resetting it every second to get the frames every second.

Ping

We’re “poking” the server to get a response and we check how long it took.

After

We send this information through a RemoteEvent so we can update the leaderboard.

Please let me know if you found this interesting/helpful!

7 Likes

Before I get comments about it:

Yes updating it every single second is excessive resource consumption but this is only the first step of the staircase, I’m not doing this whole thing for you to use. You can experiment as you wish!

1 Like

You might be interested in knowing that Player objects have a new function called “GetNewtworkPing.”

https://developer.roblox.com/en-us/api-reference/function/Player/GetNetworkPing
it’s pretty pog, and I assume more efficient since it’s written in C++

8 Likes

Slightly annoying since I went through so much to get that current system working haha.

3 Likes

You’re awesome, I completely missed this and you’ve now made my day and my upcoming project easier lol.

2 Likes

:GetNetworkPing is more efficient than the ping thing I believe. Just multiply it by 1000 and you will get your ping