Serious problem in 'my' gunscript

I have a gunscript, the reason I put ‘my’ in quotation marks is because I had them made as a commission for my group. However, I discovered quite a serious problem in the scripts today: the gun bullets only show on the client side, and do not replicate to other clients. Thinking from a battle perspective: the importance of seeing other people’s bullets quickly becomes clear. It helps to know who is shooting at you and from where, hence why I am writing this post.

TL;DR objective of this post: I want to replicate the bullets to every client (instead of only the client that is firing their weapon) so that people can see eachother’s shots.

Gyazo recording of the issue: https://gyazo.com/bcf95aab1c60cc6e27ec9b988f6f9953
On the left: client firing the shot, on the right: client looking at the shots. As you can see it only replicates for the shooter.

As for how much I tried so far, I didn’t really try anything as my knowledge in lua is not this extensive. I don’t know how to program guns which is why I had it commissioned. I am also hesitant because I am afraid to break something important.

Reason why I have not contacted the original scripter: he is unavailable, and I have to get this resolved quickly. My game is already severely delayed.

Scripts:

Weapon serverscript

game.ReplicatedStorage.WeaponEvent.OnServerEvent:Connect(function(Plr,Verify,a,b,c,d,e,f,g)
	if Verify=='Speed'then
		Plr.Character.Humanoid.WalkSpeed=a
	elseif Verify=='Damage'then
		if a.Character.Humanoid.Health>0 then
			a.Character.Humanoid:TakeDamage(b)
		end
	elseif Verify=='Render'then
		a.Ammo.Value=a.Ammo.Value-1
		for _,v in next,game.Players:GetChildren()do
			if v.Name~=Plr.Name then
				game.ReplicatedStorage.WeaponEvent:FireClient(v,a,b,c,d,e,f)
			end
		end
	elseif Verify=='Reload'then
		a.Ammo.Value=a.Ammo.Max.Value
		a.Clips.Value=a.Clips.Value-1
	end
end)

Client weaponscript (responsible for everything clientside)

local Player=game.Players.LocalPlayer
local Mouse=Player:GetMouse()
local Bind=game.ReplicatedStorage.WeaponBind
local Event=game.ReplicatedStorage.WeaponEvent
local Cam=workspace.CurrentCamera
local BulletPart=game.ReplicatedStorage.Bullet
local HitPart=game.ReplicatedStorage.Hit
local Equipped
local Settings
local UI=script.Parent
local Anims={}
local Mouse1Down=false
local Reloading=false
local CanShoot=true
function HitDetect(Hit,Damage,Tirtiary)
	for _,v in next,game.Players:GetChildren()do
		if Hit:IsDescendantOf(v.Character)then
			if Player.TeamColor~=game.Players[v.Name].TeamColor then
				UI.Hitted:Play()
				UI.Hit.Position=UDim2.new(0,Mouse.X-22.5,0,Mouse.Y-22.5)
				Event:FireServer('Damage',v,Damage)
				if Tirtiary~=nil then
					Equipped.Handle.Smack:Play()
				end
				UI.Hit.Visible=true
				wait(.1)
				UI.Hit.Visible=false
			end
			return
		end
	end
end
function CreateHit(Norm,Hit)
	if Hit then
		local HitP=HitPart:Clone()
		HitP.CFrame=Norm
		HitP.PHit1.Color=ColorSequence.new(Hit.Color)
		HitP.Hit:Play()
		if Hit.Material==Enum.Material.Metal or Hit.Material==Enum.Material.Glass then
			HitP.MetalHit:Play()
			HitP.PMetal.Enabled=true
			HitP.MetalLight.Enabled=true
		end
		delay(.2,function()HitP.PHit1.Enabled=false HitP.PMetal.Enabled=false end)
		HitP.Parent=workspace.Rays
		game.Debris:AddItem(HitP,.7)
	end
end
function BulletAnim(Distance,Location,Speed,Tool,Norm,Hit,Color)
	local Bullet=BulletPart:Clone()
	Bullet.CFrame=CFrame.new(Tool.Barrel.CFrame.p,Location)*CFrame.new(0,0,-Bullet.Size.Z+1)
	Bullet.Parent=workspace.Rays
	for i=0,Distance-Bullet.Size.Z,Speed do
		wait()
		Bullet.CFrame=Bullet.CFrame*CFrame.new(0,0,-Speed)
	end
	CreateHit(Norm,Hit)
	Bullet:Destroy()
end
function UpdateUI(Tool)
	wait()
	UI.Ammo.GunName.Text=Tool.Name
	UI.Ammo.Ammo.Text=Tool.Ammo.Value
	UI.Ammo.Clips.Text=Tool.Clips.Value
end
function Fire(OtherTool,Color)
	delay(0,function()
		local Tool=OtherTool
		local Char=Tool.Parent
		local Spread=Settings['Spread']
		local Speed=Settings['Speed']
		local Hit,Location,Norm=workspace:FindPartOnRayWithIgnoreList(Ray.new(Char.Head.Position,((Mouse.Hit.Position+Vector3.new(math.random()*Spread-(Spread/2),math.random()*Spread-(Spread/2),math.random()*Spread-(Spread/2)))-Char.Head.Position).unit*999),{Player.Character,workspace.Rays},false,true)
		local Length=(Tool.Barrel.Position-Location).magnitude
		local Orient=CFrame.new(Tool.Barrel.Position,Location)
		Length=Length>999 and 999 or Length
		Anims['Shoot']:Play()
		Event:FireServer('Render',Tool,Speed,Location,Norm,Hit,Color)
		Tool.Barrel.Fire:Play()
		BulletAnim((Tool.Barrel.CFrame.p-Location).magnitude,Location,Speed,Tool,CFrame.new(Location,Location+Norm),Hit,Color)
		if Hit then HitDetect(Hit,Settings['Damage'][Hit.Name]~=nil and Settings['Damage'][Hit.Name]or Settings['Damage']['Base'])end
		UpdateUI(Tool)
	end)
end
Bind.Event:Connect(function(Type,Tool)
	if Type=='Equip'then
		Equipped=Tool
		Mouse.Icon = "http://www.roblox.com/asset?id=330553538"
		Settings=require(Tool.Settings)
		UI.Ammo.Visible=true
		UpdateUI(Tool)
		repeat wait()until Player.Character:FindFirstChild('Humanoid')
		Anims={}
		for _,v in next,Tool.Anims:GetChildren()do
			Anims[v.Name]=Player.Character.Humanoid:LoadAnimation(v)Anims[v.Name].Priority=Enum.AnimationPriority.Action
		end
		Anims['Idle']:Play()
	elseif Type=='UnEquip'then
		Mouse.Icon = ""
		Equipped=nil
		UI.Ammo.Visible=false
		for _,v in next,Anims do
			v:Stop()
		end
		Event:FireServer('Speed',16)
	elseif Type=='Melee'and Equipped then
		HitDetect(Tool,Settings['MeleeDamage'],true)
	end
end)
Mouse.Button1Down:connect(function()
	if Equipped and not Reloading and Equipped.Ammo.Value>0 and not Mouse1Down and CanShoot then
		Mouse1Down=true
		if Anims['Sprint'].IsPlaying then
			Anims['Sprint']:Stop()
			Event:FireServer('Speed',16)
		end
		if Settings['Auto']==true then
			while Mouse1Down and Equipped.Ammo.Value>0 and not Anims['Sprint'].IsPlaying do
				CanShoot=false
				Fire(Equipped,Settings['Color'])
				wait(Settings['Rate'])
			end
		else
			Fire(Equipped,Settings['Color'])
			wait(Settings['Rate'])
		end
		CanShoot=true
		Mouse1Down=false
	end
end)
Mouse.Button1Up:connect(function()
	Mouse1Down=false
end)
game:GetService('UserInputService').InputBegan:connect(function(Key,GPE)
	if not GPE and Equipped then
		local KChar=utf8.char(Key.KeyCode.Value)
		if KChar=='r' and Equipped.Ammo.Value<Equipped.Ammo.Max.Value and not Reloading and not Anims['Sprint'].IsPlaying and not Mouse1Down and Equipped.Clips.Value>0 then
			Reloading=true
			Equipped.Handle.Reload:Play()
			Anims['Reload']:Play()
			Event:FireServer('Reload',Equipped)
			wait(Anims['Reload'].Length)
			if Equipped then
				UpdateUI(Equipped)
			end
			Reloading=false
		elseif KChar=='f'and not Reloading then
			if Anims['Sprint'].IsPlaying then
				Anims['Sprint']:Stop()
				Event:FireServer('Speed',16)
			else
				Anims['Sprint']:Play()
				Event:FireServer('Speed',22)
			end
		elseif KChar=='x'and not Reloading and not Mouse1Down and not Anims['Sprint'].IsPlaying and Equipped.Handle.Melee.Value==false then
			Anims['Melee']:Play()
			Equipped.Handle.Swing:Play()
			Equipped.Handle.Melee.Value=true
			wait(Anims['Melee'].Length)
			Equipped.Handle.Melee.Value=false
		end
	end
end)
Event.OnClientEvent:Connect(function(Tool,Speed,Location,Norm,Hit,Color)
	Tool.Barrel.Fire:Play()
	BulletAnim((Tool.Barrel.CFrame.p-Location).magnitude,Location,0,Speed,Tool,Norm,Hit,Color)
end)

Client script (Supposing this is checking for tools and making them compatible with the gunscripts)

local Player=game.Players.LocalPlayer
local Bind=game.ReplicatedStorage.WeaponBind
local Connect={}
local Tools={}
local Melee=false
repeat wait()until Player:FindFirstChild('Backpack')
function FindTool(Item)
	for _,v in next,Tools do
		if v==Item then
			return true
		end
	end
	return false
end
function FuncHandler(Item)
	if Item:IsA('Tool')then
		if Item.ToolTip=='Ranged'and not FindTool(Item)then
			table.insert(Tools,Item)
			table.insert(Connect,Item.Equipped:Connect(function()Bind:Fire('Equip',Item)end))
			table.insert(Connect,Item.Unequipped:Connect(function()Bind:Fire('UnEquip',Item)end))
			repeat wait()until Item:FindFirstChild('Handle')
			table.insert(Connect,Item.Handle.Touched:Connect(function(Hit)if Item.Parent==Player.Character and not Hit:IsDescendantOf(Player.Character)and Item.Handle.Melee.Value==true and not Melee then Melee=true Bind:Fire('Melee',Hit)wait(.2)Melee=false end end))
		end
	end
end
Player.Backpack.ChildAdded:connect(function(Item) 
	wait()
	FuncHandler(Item)
end)
for _,v in next,Player.Backpack:GetChildren()do
	FuncHandler(v)
end

Thank you for reading, and apologies if I forgot about anything in the post, if I did forget something: please do remind me.

This method may not be the most optimal in terms of performance but it would certainly fix your immediate issue of replication.

When I create my gun systems, I handle each bullet on each client individually. For example, the player will click, a signal is sent to the server that a player has clicked, the server will create then fire to all clients that that particular player has clicked, and the clients will deal with the creation and projection of each bullet.

I know that when reading that and getting your head around that concept, it seems extremely latent and very poor optimisation however I have done extensive tests on games that use this system and there is no noticeable delay.

This video is an example of one of my gun mechanics that uses the above system: https://youtu.be/h4dNLe3P2p0

You can see for yourself at Tank Up! - Roblox
(I created that game, it’s under my uncle’s account, see the description for more details).

I hope this helps shed some light on a potential solution, however I am eager to hear whether others have any more elegant solutions.
-Tom :slight_smile:

I appreciate the input, sadly I have no way to implement this because I have no coding example to follow. As I said my knowledge on this field is (very) limited.

The problem is resolved! The problem was a typo in the Weaponscript causing the bullet not to replicate to other clients. When this typo was removed, it replicated perfectly.