How to make a FPS Counter

Your point is correct, however I still yet to see other scripters to follow that kind of code.

2 Likes

Thank you for that. If Im being honest, This will help with my Game’s Optimization.

2 Likes

Wouldn’t it be better to have an array of the DT’s over the last second then add them up divide by how many there are then put that as the fps instead of doing it based on one frame as that way it’d be more accurate as an fps counter and not just a frame time viewer

3 Likes

should look a little bit like this

local RunService = game:GetService("RunService")
local FrameQueue = table.create(60)

local function getTotalDT()
	local total = 0
	for index, dt in ipairs(FrameQueue) do
		total += 1/dt
	end
	total /= #FrameQueue
	return total
end

RunService.RenderStepped:Connect(function(dt)
	if #FrameQueue == 60 then
		table.remove(FrameQueue, 1)
	end
	table.insert(FrameQueue, dt)
	script.Parent.Text = math.floor(getTotalDT() * 10)/10
end)
2 Likes

What this code does is whenever the RenderStepped event of RunService is fired, we add the frames variable with 1. Now since RenderStepped fires multiple times a second, the frames variable would add according to the amount of times the RenderStepped event is fired. And then we set frames to 0 every 1 second since fps is Frames Per Second.

4 Likes

That is the average fps, not fps.

Average framerate isn’t really useful unless you include it with a standard fps counter, 0.1% lows, max, etc. Let alone replacing frames per second.

Edit: Also that code sample has a bit of an efficiency problem; you’re doing table.remove at the first element, which will cause all 59 other elements to perform a downwards shift, whereas you could just remove the top element (60) and no shifting will occur every frame and it still works the exact same.

3 Likes

You’re right in saying I got the fps confused with the average fps as that was what the other guy was doing but I’ll put a reply to this post with an fps one

To address that edit, it wouldn’t be representative of the average FPS or the FPS at all as all the starting values for when you join the game will remain constant and would lead to the fps counter not updating properly.
Proof as to why its wrong:
https://gyazo.com/ffc2b9781fa54aeb7d91390bd9dfa858

2 Likes
local RunService = game:GetService("RunService")

local FrameQueue = table.create(100)

RunService.RenderStepped:Connect(function(dt)

table.insert(FrameQueue, 1)

task.wait(1)

table.remove(FrameQueue, 1)

script.Parent.Text = #FrameQueue

end)
2 Likes

Why so there two periods between frames and “FPS””

2 Likes

.. is the string concatenation operator.

local frames = 10

local str = frames .. " FPS"
print(str) -->> "10 FPS"
4 Likes

-- 1 / dT

local gui = script.Parent
local format = "FPS: %.1f"

game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	script.Parent.Text = string.format(format, 1 / deltaTime)
end)
-- frames += 1

local gui = script.Parent
local format = "FPS: %.1f"

local frames = 0

game:GetService("RunService").RenderStepped:Connect(function()
	frames += 1
end)

while task.wait(1) do
	gui.Text = string.format(format, frames)
	
	frames = 0
end
-- average fps (yours + slight tweaking)

local gui = script.Parent
local format = "FPS: %.1f"

local frameHistory = table.create(60, 0)
local index = 0

local function ComputeAverage()
	local average = 0

	for _, deltaTime in ipairs(frameHistory) do
		average += deltaTime
	end

	return average / 60
end

game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	index = (index + 1) % 61
	
	frameHistory[index] = deltaTime
	
	gui.Text = string.format(format, 1 / ComputeAverage())
end)

The scripts used for each gui are shown above, based on these results, we can draw a few conclusions:

  • 1 / dT is so bizarre it doesn’t even pick up the frame throttling that studio does by default when you unfocus the window, extending beyond studio and into a place where a player is experiencing a frame dip, they may not even know because their sporadic frame counter is saying 60 and 50, so it must be fine right?

  • Counting the frames seems to be the most accurate & readable at any given frame, and is efficient enough

  • Using the average framerate shows dip trends quicker, but less accurately about what’s going on in the current frame, and also may increase frametime on devices with weaker processors with all the table shifting going around just to count frames.

Also sorry about the quality of the video, that’s the best my recorder can go without freezing lol

20 Likes

I’ll keep this in mind! Thankyou so much! :happy2:

2 Likes

Glad that I could help! Have a amazing day. :happy3:

1 Like

Glad I could help with your game. :happy3:

I’m sorry if anyone had a problem or concern with this. I just tried to help some people that needed a quick minute Fps Counter. I know this isn’t the best and I’ll sure make it better next time. :happy1:

1 Like

Still I wanna see AN EXAMPLE of a module using this.

1 Like

Your FPS Counter is not that accurate. You could easily make it more accurate by using task.wait(1) instead. I will come back with a better solution a little bit later when I have access to Studio.

1 Like

Or you know, using actually reliable methods of counting fps?
There’s tons of posts that describe those more reliable methods. There’s even a official way of seeing your in-game fps that don’t rely on less reliable methods.
Also, wait() isn’t as evil as all of those ““top devs”” say.

2 Likes

Thank You, This Really Helps Me! THANK YOU!

1 Like

I’m confused…
why over-complicate this instead of just using

https://developer.roblox.com/en-us/api-reference/function/Workspace/GetRealPhysicsFPS

1 Like