Hi! This is my first post on the forum (and I’m somewhat new to programming as a whole) so I apologize if everything isn’t exactly up to code.
I’m making a FNAF-esque fangame and two of the scripts handles the amount of power the player has and how much of it is used. A couple of weeks ago however I’ve noticed that by changing the framerate to higher than 60FPS, the RemoteEvent that sends the rate of consumption does so twice as fast (e.g 120FPS) or higher.
This causes the power to drain really quickly if you’re playing on a higher framerate, and I don’t want to force people to only strictly use 60FPS, so I’ve been trying to figure out a way to limit this rate to be same across all framerates.
I’ve tried to adapt methods using RenderStepped (or PreRender since apparently the former is deprecated) but I’m unsure on how to do it and most attempts just resulted in the same situation, so I’m hoping I can find a solution to this.
Local Script:
local replicatedStorage = game:GetService("ReplicatedStorage")
local powerDecrease = 0.006
local nightBegun = replicatedStorage.nightBegun
while task.wait(powerDecrease) do
if nightBegun.Value then
replicatedStorage.PowerChanged:FireServer(powerTimeDecrease)
-- Calculation of powerTimeDecrease by how many mechanics the player is using (e.g Door, Light, Cameras)
end
end
task.wait()
end
Server Script:
local replicatedStorage = game:GetService("ReplicatedStorage")
local powerValue = replicatedStorage.PowerValue
replicatedStorage.PowerChanged.OnServerEvent:Connect(function(Player, powerTimeDecrease)
powerValue.Value = powerValue.Value - powerTimeDecrease
print(powerValue.Value)
end)
60FPS:
120FPS:
Thank you for reading! I appreciate any and all possible help.
Why don’t you ONLY make a script for the server? You don’t need a localscript to fire to the server when you can just start on the server
Server:
game.Players.PlayerAdded:Once(function()
while true do task.wait() -- <-- runs at a consistent 60 FPS
powerValue.Value -= powerDecrease
end
end)
and if you need anything related to the client from the server. Learn about RemoteFunctions! In short, you can use them to grab for example, a bool from a client VERY easily!
So the usual method of handling variable fps is to use deltatime. Deltatime is the amount of time since the last frame, and with it, you can adjust things like this:
local powerDecreaseRate = 0.36 -- By how much it decreases for 1 second. This should match your current per frame power decrease
local power = 100
while true do
local dt = task.wait() -- dt is short for delta time
power -= powerDecreaseRate * dt -- Longer dt, bigger decrease, shorter dt, smaller decrease
end
Here, I got delta time from task.wait(), but it is also provided when using RenderStepped, Heartbeat, …
However, in your case, it’s a bit different as you are firing a remote to the server every frame. I will not tell you how to get that to work, as you should actually avoid doing it like that, for network and code structure reasons…
So you should put that loop on the server rather than the client. The server runs at a fixed 60 fps, however, that doesn’t mean you can rely on the server being at 60 fps. If the server is particularly busy, it might start to lag, and run slower than 60 fps, so the whole delta time thing is still very much important on the server
If the rate at which the power decreases changes, the client can send a remote to the server telling the change, and the server can adjust it
Sorry for the late reply on this post, I took some time to fix up the Local Script (since I still need it for GUI stuff) and switch the loop to run on a Server Script and this worked perfectly! Every other reply here is also technically correct in using DeltaTime instead but this helped me understand how the framerates work on the server.