Would there be a way to make sure renderstep runs 60 times second?
I don’t know for sure but there was something called artificial HB which would make some kind of limiting thing but I don’t know where to find it.
edit: maybe this post can help How can I make RenderStepped lock to a maximum of 60 FPS? - #10 by nooneisback
local Game = game
local RunService = Game:GetService("RunService")
local Time = os.time()
local Frames = 0
local function OnRenderStep(Delta)
if os.time() > Time then
Time = os.time()
Frames = 0
end
Frames += 1
if Frames > 60 then return end
--Do code here.
end
RunService.RenderStepped:Connect(OnRenderStep)
This will prevent the function’s execution past sixty frames in a single second.
(post deleted by author)
(post deleted by author)
What?No, this is terrible practice.
This is a baseless claim, it’s just a way of capping the event loop to sixty executions per second, you seem to have omitted the fact that the ‘Delta’ parameter can be used in the function’s body.
(post deleted by author)
Second of all, yes it is a terrible practice, you should never assume the client is ever running at one specific framerate.
Another erroneous claim, the implementation does not assume that the client has a particular framerate, it’s just ignoring frames past the hard-coded sixty frame cap.
(post deleted by author)
So you’re gonna completely ignore if someone is below 60FPS, which will cause them to experience everything at a slower rate?
The ‘Delta’ parameter is there for a reason, are you unaware of its use?
https://developer.roblox.com/en-us/api-reference/event/RunService/RenderStepped
You should ALWAYS use delta for any number-specific animations or frame-dependent actions.
The implementation does?
I’ve been programming on Roblox for 6 years.
This solution will allow your friend to keep using his fps-unblocker, without it being capped.
For example, take this piece of code, that moves a part 10 studs in the Y direction, across 20 frames:
local runService = game:GetService("RunService")
local camera = workspace.CurrentCamera
local part = workspace.Part
part.Position = Vector3.new(0, 20, 0)
local targetCameraPosition = Vector3.new(-20, 25, 0)
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.new(targetCameraPosition, part.Position)
local iterations = 0
local maxIterations = 20
wait(2) --Studio takes some time to load into client mode, so don't do it right away
runService.RenderStepped:Connect(function(deltaTime)
if iterations < maxIterations then
iterations += 1
part.Position += Vector3.new(0, 0.5, 0)
end
camera.CFrame = CFrame.new(targetCameraPosition, part.Position)
end)
This is what this code looks like at 24 FPS:
At 60 FPS:
At 144 FPS:
What you’ll notice is, as frame rate increases, the animation speed also increases. This is because there is less time between frames. There will also be cases where players will have framerates below 60FPS, in this case, it is going to cause animations to be slower for them, which will make the user experience worse.
The good thing is, every frame an argument is passed through RenderStepped, called Delta
, what this tells us is the time that it took between the last frame and the current frame. This is also called Step
, or shortened to s
in some scripts. For a player who’s running at 24 FPS this will be approximately 1/24th of a second or 0.04166..s
, for a player who’s running at 60 FPS it will be approximately 1/60th of a second, or 0.0166..s
, and at 144 FPS, it will be approximately 0.006944...s
. This will be useful to you as a programmer, as it essentially tells you what fraction of a second has passed, and you can adjust how fast animations happen as a result.
You can read more here:
What this means is, if you wanted to move a part 10 studs, within 1/3rd of a second, you’d say 10 studs * (delta / 1/3 seconds)
, which will move the part the correct amount within the specified time, so that no matter what framerate the player is on, it will look smooth, and will have exactly the same speed.
Here is some example code, which utilizes the Delta
argument:
local runService = game:GetService("RunService")
local camera = workspace.CurrentCamera
local part = workspace.Part
part.Position = Vector3.new(0, 20, 0)
local targetCameraPosition = Vector3.new(-20, 25, 0)
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.new(targetCameraPosition, part.Position)
local studsToMove = 10
local timeToComplete = 3
wait(2) --Studio takes some time to load into client mode, so don't do it right away
local studsMoved = 0
runService.RenderStepped:Connect(function(deltaTime)
if studsMoved <= studsToMove then
local targetStudsToMove = math.min(
studsToMove - studsMoved,
studsToMove * (deltaTime / timeToComplete)
)
part.Position += Vector3.new(0, targetStudsToMove, 0)
studsMoved += targetStudsToMove
end
camera.CFrame = CFrame.new(targetCameraPosition, part.Position)
end)
This is what it looks like at 5 FPS (for exaggeration):
This is what it looks like at 60 FPS:
This is what it looks like at 144 FPS:
You’ll notice that they look exactly the same speed regardless of framerate.
This is the way to go.
Please do not listen to other advice to cap the framerate. It is bad practice.
If you need any specific advice on how to handle delta or frame times, do not hesitate to PM me. I’ll always be willing to be a helping hand .
local part = workspace.Part
Use WaitForChild
to wait for instances to replicate to the client.
camera.CFrame = CFrame.new(targetCameraPosition, part.Position)
Use the CFrame.lookAt
constructor, it’s more readable and expects two ‘Vector3’ values.
https://developer.roblox.com/en-us/api-reference/datatype/CFrame
wait(2)
The wait
global function is deprecated (it throttles), use the task library function of the same name.
https://developer.roblox.com/en-us/api-reference/lua-docs/task
I’d argue that the arbitrary wait isn’t even necessary.
part.Position += Vector3.new(0, targetStudsToMove, 0)
This should be a CFrame property assignment as they are considerably more performant.
part.CFrame *= CFrame.new(0, targetStudsToMove, 0)
A minor nitpick but connect a locally defined function rather than an anonymous one.
Did you seriously recommend someone to frameskip their way out framerate instability? These aren’t the 90s where you needed a dedicated turbo button to prevent your computer from running too fast. This is something even Roblox engine developers warn against, though I won’t go digging for 5 year old posts.
This is honestly the worst practice I can think of related to this problem. Setting an fps lock is a horrible idea
Setting an fps lock is a horrible idea
Why? It’s merely a way of punishing users that inject .dll files in order to increase their framerate without outright kicking/banning them.
But it is also a HUGE disadvantage for low fps users
Disagree with your method of locking FPS, but you sending a Wikipedia article of the Dunning-Kruger effect just made my whole day in response to that quote. That was the best thing I’ve seen today.
Truly, thank you
Also, chill out. You come across as very ignorant and condescending with the whole connotation of your initial statements.
I’m sure I don’t have to explain this to someone with your 6 years of expertise but you’ll have a harder time having people listen to you when you appear as such.
Firstly, rbxfpsunlocker isn’t a DLL injector, but a memory editor. Secondly, Roblox condones it to avoid having to unlock the cap themselves. You’re punishing users for using something they should be allowed to.
Multiply by the DeltaTime to cancel out the higher ammount of frames or create a table that is checked every frame with the mean of the amount of runs compared to the time, if the mean is over 1 then allow the loop to run, something like this can make a renderstepped loop run at <60 fps