Multiple players in server causes script to clone part into Workspace twice

I am making a game and have a cannon ball launcher tool with client and server scripts that put the cannon ball into the workspace and add BodyVelocity etc.

It works perfectly fine when testing solo in Studio and in-game, but as soon as someone joins or if I start a 2 player simulation, it sends two cannon balls instead of one. I have gone over every script in my entire project and have toubleshooted? troubleshot? in every way imaginable for the last 3 hours.

Here are my scripts for sending and controlling the rocket:

ShootClient – Local Script

local tool = script.Parent
local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera

local db = false

local RS = game:GetService("ReplicatedStorage")

local cannonAssetsFolder = RS.Stasis.CannonAssets

tool.Activated:Connect(function()
	if db == true then return end
		db = true

	-- Get camera look direction (center of the screen)
	local direction = camera.CFrame.LookVector.unit

	local CastPart = tool.Handle.CastPart

	cannonAssetsFolder.ShootEvent:FireServer(direction, CastPart)
	
	task.wait(1)
	
	db = false

end)

ShootServer – Normal Script

local rocketSpeed = 1 -- Speed of the rocket

local RS = game:GetService("ReplicatedStorage")

local cannonAssetsFolder = RS.Stasis.CannonAssets

local db = false

local onCD = false

cannonAssetsFolder.ShootEvent.OnServerEvent:Connect(function(player, direction, CastPart)
	if db == true then return end
		db = true
		
	onCD = true
	cannonAssetsFolder.ShootEvent:FireClient(player, onCD)
	
	-- Define shootSFX
	local shootSFX = game.ReplicatedStorage.Stasis.CannonAssets.ShootSFX:Clone()
	shootSFX.Parent = CastPart
	shootSFX:Play()
	
	CastPart.Parent.MuzzleFlash.Decal.Transparency = 0
	CastPart.Parent.MuzzleFlash.PointLight.Enabled = true
	
	-- Define rocket
	local rocket = cannonAssetsFolder.CannonBall:Clone()

	-- There is a delay before the BV is actually applied, that's why I want to use LV
	local bodyVelocity = Instance.new("BodyVelocity")
	bodyVelocity.MaxForce = Vector3.new(1, 1, 1) * math.huge
	bodyVelocity.Velocity = direction * rocketSpeed
	bodyVelocity.Parent = rocket
	
	rocket.Parent = game.Workspace
	
	print("rocket parented to workspace")
	
	rocket:SetNetworkOwner(nil)
	rocket.Position = CastPart.Position
	
	rocket.Name = "testRocket"

	task.wait(0.15)
	
	CastPart.Parent.MuzzleFlash.Decal.Transparency = 1
	CastPart.Parent.MuzzleFlash.PointLight.Enabled = false

	task.wait(0.85)
	
	db = false
	
end)

If you know how to fix it or need me to troubleshoot in any way, just let me know!
Thank you!

EDIT: Sent wrong script for ShootServer

I added a print function just below where the rocket gets parented to the Workspace, and it even sends twice when there are more than one player in the game.

Which means the script is being run twice even with double debounces…

I’m stumped.

its not working because since there are two players and the same remoteevent is being accessed by multiple players, and the tool is in each seperate player with the global remote being accessed by 2 scripts, on one player shooting the OTHER players tool and their own tool detects that its sending the rocket.

EASY FIX: make the tool itself have a remoteevent inside it and make the script detect that one instead of the global one

1 Like

that explanation was horrible mbbbb i hope u understand tho

I understand what you mean, but why would the other player’s tool detect that a rocket has been sent? The only time I have the server script fire a client, it fires the client of the player who sent the request originally. Additionally, it doesn’t multiply with the amount of players in the game. It’s only one rocket being sent if solo, and two being sent if there is more than one player.

since the event is accessed by all players (since its in replicatedstorage) and the reciever script is inside the tool, on another client firing the event, BOTH reciever scripts recieve the event and respond to it

1 Like

Thank you so much! For some reason my brain wasn’t piecing that together :man_facepalming:

Fixed it by adding this at the top of the OnServerEvent function inside of the Tool’s server script (ShootServer)

if player.Name ~= script.Parent.Parent.Name then return end

This will force the script to stop what it’s doing and reset if the RemoteEvent request it received doesn’t correspond to the player.