Hello, I have been stuck on this for a while and I need help, I’m trying to make an automatic gun with effects, then i created two different threads with while loops, one for the effects and one for the server, but due to unknown, the client shoots more bullets than the server, and thats not good
Why would you separate them into 2 individual threads and 2 individual loops??? What is the point of that?? Why not just leave the increment statement inside the loop that’s firing the remote? You’re just making things more complicated for yourself by doing this.
To answer your question; It is because task.wait uses heartbeat which will be different between client and server. On the server, it should be 60, but on the client, it depends on the player’s FPS. So with your method it will get out of sync really easily based on the player’s FPS which can change because of lag, the use of an FPS unlocker, or performance.
Like I said earlier, just merge the shotsFired += 1 statement with the primary loop that’s actually firing the gun.
A debounce solution works perfectly fine on moderating the fire rate of a player’s gun, I don’t see why the client script needs to be that complicated and redundant.
The following are examples of my perception of an ideal gun system:
--SERVER
local lastFired = {} --instead of storing booleans, store the time a player last fired their gun
-- ^ THIS SHOULD BE INITIALIZED AS 0 FOR EACH PLAYER!!!!!!!!!!!!!!!!
local cooldown = .1 --the inverse of this would be the firerate (per second)
...
fireEvent.OnServerEvent:Connect(function(p)
if os.clock() - lastFired[p] > cooldown then --check the time difference to see if the player has fulfilled their cooldown
... --do stuff
lastFired[p] = os.clock() --last line of script records down the time the gun was fired
end
end)
--CLIENT
local cooldown = .1
if inputState == Enum.UserInputState.Begin then
while keysPressed.Fire do
fireEvent:FireServer()
shotsFired += 1
task.wait(cooldown)
end
end
i would never thought of that, i was just thinking of using debounces, now its working perfectly, thanks! --Nevermind, I tested here and the client still fires more than the server, i fixed it by simply waiting the cooldown on the server minus the runservice.hearbeat:wait()