Help and Feedback with a gun script

So, I recently made a gun by using remote events.

I think that if I fire remote events repeatedly, the script will exhaust. If I add debounce to the server script, other clients with the same gun will experience a delay when using the gun. (I added a debounce and it will have a slight delay for the clients when using the gun)

So is there a best way to do it? And I also need suggestions for the script! (Is it better also to put a script/ a local script inside of a tool?)

This is the local script I put inside the Tool’s (Gun) Handle, which is in the StarterPack

local RS = game:GetService("ReplicatedStorage")
local GunEvent = RS:WaitForChild("GunEvent")

local Tool = script.Parent

local Handle = Tool:WaitForChild("Handle")

local Players = game:GetService("Players")

local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")

local Sound = Handle:WaitForChild("Activate")

local mouse = player:GetMouse()

Tool.Activated:Connect(function()
	if humanoid.Health > 0 then
		Sound.Playing = true
		Sound:Play()
		local mousePosition = mouse.Hit.Position
		local mouseTarget = mouse.Target
		GunEvent:FireServer(mousePosition, mouseTarget)
		print("RemoteEvent has been fired")
	end
end)

And this is the server script I put inside of the ServerScriptService

local RS = game:GetService("ReplicatedStorage")
local GunEvent = RS:WaitForChild("GunEvent")

local Debounce = false

GunEvent.OnServerEvent:Connect(function(player, mousePos, mouseTarget)
	
	if Debounce == false then
		Debounce = true
		local char = player.Character
		local humanoid = char:WaitForChild("Humanoid")

		if humanoid.Health > 0 then
			if mouseTarget and mouseTarget ~= nil then
				if mouseTarget.Parent and mouseTarget.Parent ~= nil then
					local EnemyHumanoid = mouseTarget.Parent:FindFirstChildOfClass("Humanoid")
					if EnemyHumanoid and EnemyHumanoid.Health > 0 then
						EnemyHumanoid.Health -= 20
					end
				end
			end
		end
		task.wait(0.1)
		Debounce = false
	end
end)
3 Likes

You shouldn’t be debouncing on the server because you’ll end up rejecting multiple events if a lot of players are firing the remote.

In theory you should be handling debouncing/rates on the client and verifying on the server the player is allowed to use the gun.

2 Likes

But like, if hackers were to change stuff in that local script, they can fire remote events repeatedly to the server and exhaust the server script right?

An exploiter can fire a remote an infinite amount of times regardless of the content of a LocalScript.

Your concern falls under this umbrella. If you have a player that is firing remotes and does not have the tool equipped that indicates they are most likely exploiting, and you can handle that programmatically from the server.

1 Like

Oh so like regardless of what you do, exploiters can always fire many remote events to the server? (like that will crash games) and that is why like most of the gun script tutorial on Youtube I’ve seen never include debounce in their script. Remote events in general, tutorials on Youtube never use debounces. I mean it make sense if we do the debounce on the client.

Also, my gun is usable for everyone so it isn’t like a gamepass or something. So, how would I stop the exploiters from crashing the game?

Some people encountered script exhaustion, because of remote events firing too frequent. How would you handle that situation?

Script exhaustion is rare with RemoteEvents. You can fire a RemoteEvent in RunService.RenderStepped infinitely without causing performance issues and/or reaching the script exhaustion limit.

2 Likes

So like, we don’t need debounces in remote events? And what are the differences between RunService and a While loop, because I dont know anything about RunService. The only thing I know is that it is an event, there are stuff like hearbeat, renderstepped (What are those)

Debouncing RemoteEvents really depends on the use case.


RenderStepped will run the code inside every single frame, but it runs prior to the frame actually being rendered.
Heartbeat runs every single frame after physics simulation completes.
They both run every single frame, but at slightly different times in the frame. RenderStepped can only be used in LocalScripts, but Heartbeat can be used in both local and server scripts

While loops will constantly repeat the code inside of it as long as a certain condition is true. When the condition it is looking for is no longer true, it will stop the loop. The loop will also stop when break is called somewhere inside of it.
A big difference is depending on how it is setup, just like with for loops, a while loop will be stuck in the loop until it exits. You can allow a while loop to run alongside other code using either a coroutine.wrap(function() or task.spawn(function()


RunService - RenderStepped
RunService - Heartbeat

1 Like

I mean debouncing should be like on the client, debouncing on the server is not needed. Am I right? Bc Debouncing on the server will cause other clients to experience a delay while using the tool

Debouncing should be done on the client. The server will reject other requests from other clients if you debounce in the server.

1 Like

oh and also is it better to store a local script/ a server script inside tools?

And so what kinds of stuff should we put inside client-side script. Some people said that we shouldn’t store the important things in a client-side script.

Example:
Can we change a character’s WalkSpeed inside a local script, or should it be done only on the server? I mean even if the hacker changed his/ her speed, it would only affect themselves and other players won’t be able to see it.

Or Another Example:
If I wanted to make an npc chase a player, but client-sided. So the npc will appear differently on each player’s screen, like based on where the player is at. So if I do this, I would fire a remote event from the server to the client (FireAllClients). I would also do checks on the server first. The client will have the onclientevent connected too the function and it will access the model from the replicated storage and parent it to the workspace. This is done in a local script, is it fine to do this? (like considering if it can be exploited and stuff)

I mean sometimes we parent models to the worskpace from a server script, in this case it’s different.

1 Like

Only things you want to change for a player should be in LocalScripts, like GUI handling and whatnot. As said, no important things should be put in LocalScripts since exploiters can very easily change them.


This is not true. Any changes made to a player’s humanoid in their character on the client is replicated to the server, so the server and all of the other players will see their speed change. This is why magnitude checks are very common and best to use for an anti-exploit system.


This would not work to begin with. If you’re controlling some sort of NPC, it should be done on a server script else it won’t work.

2 Likes

Wait so what are the things that gets replicated to the sever besides a character’s humanoid? Server scripts obviously gets replicated to the server.

And like I mean if you tween on client-side, all you have to do is do it in a local script? or using a remote event to do FireClients() or FireAllClients() ?

Ok, So there’s this game you might know called Escape Papa Pizza’s Pizzeria! (SCARY OBBY) created by PlatinumFalls

Game link: Escape Papa Pizza's Pizzeria! (SCARY OBBY) - Roblox

This elevator thing is tweened on the client-side, players will experience them differently. Depends on their current position

and this chasing part is also on the client side, every player will see it differently depends on they’re current position

So How did the dev make them?

Yes, to achieve a Tween on client side, do it in a Local Script, the player who holds that script, will see the Tween.
Using the Remote depends on your system. You want the server to trigger the Tween on the client? or you want the client directly start the tween themeselves?
If you have a piece of code in a local script which is activated by a button on client side, no need the remote, if you want to run that piece of code when server says it should run, then you fire the remote to the player you want to experience the tween, or all the players by FireAllClients()

If you want to move a NPC client sided, the NPC should be created by the client side too, or if its created by the server then setting NetworkOwnership to the player, so it behaves normally. But once you give NetworkOwnership to the player, the changes that the client does to the NPC will replicate to server, so others will see the same that client is seeing.

If you create the NPC via a local script, that wont replicate to server, so nobody will see the character only the client who created it, and that client can manipulate that NPC as they wish. Including exploiting.

If you control the NPC on server side, that will replicate to all players.


I never played that game, idk if thats really controlled client sided. Theres a chance that the NPC is controlled by server, but, the visibility of the NPCs is one per client, so you dont see the other NPCs that are chasing the other players, server is only letting you to see the NPC that is following you, and server is controlling that NPC, so that would be server sided. Im not saying thats the best approach, Im just pointing out posibilities.

For the elevator, yeah, could be totally client sided, the client can tween the model from their local script, and only the client see the changes.


Keeping server control over important things in game that exploiters could play with is important I think. Just make sure your elevator and NPC chasing is not crucial for the game, otherwise if you are controlling those entirely from client side will leave a door open to exploiters to take advantage. Just find a way to include server to do checks that the crucial stuff still normal.

But If I tween things client-sided, then it’s exploitable, So sometimes I consider using remote events

And if for the NPC chasing part, I sometimes see other players running but I don’t see the NPC chasing them, So I assume the NPC is controlled Client-sided. It probably could get exploited.

So the NPC that chases other players are invisible to me and other players also can’t see the NPC chasing me. So they would think that I’m running randomly without a purpose.

Btw thx for the info.

1 Like

I also wanna know why if, for example I create a local script that could change a Local Player’s WalkSpeed. I wonder why it gets replicated to the server and let’s say a hacker changes it’s value to 100. Therefore, everyone and the server itself can see the hacker walking at a speed of 100.

And what other things besides changing the humanoid property of a certain player gets replicated from the client to the server.

Btw are you sure that remote events fired excessively won’t exhaust scripts or even affect the game performance? I’m feeling skeptical about that

Lets bring it down to the root issue.
The Character model, which contains the humanoid, my body parts etc, is replicated to Server if I do changes from ClientSide.

  • I am a client, I have a script injector, I can inject any code I want to run it on client side.
  • I dont care about your local script which is changing my WalkSpeed. I just inject a line of code that changes my WalkSpeed to 50 in a infinite quick loop.
  • If you inject me a local script that change my WalkSpeed to 16, my speed goes down to 16 but imediately my local script turns it to 50.
  • If you set my WalkSpeed on a ServerScript, same, I will have 50 walkspeed at the end.

So exploiters dont even need the local scripts you created for them, they can delete them and run their own code, change some properties of their characters (some, not all) and replicate to server, inject a remote spammer on a quick loop, etc.

Thats why for velocity exploits, is widely used a system that tracks the previous position and the current position of character on serverSide, to check the distance traveled over time to ensure the player is walking at the right speed.

As far as I know, Roblox itself handles a throttling system for remotes.
So remote calls wont exhaust a script, will be queued and discarded. Plus, you can check when a client is firing exesive remote calls, so you can know player is exploiting and decide what to do with the player.