Weird bug with gui and damage

Basically, the damage first of all only works some of the time on the gun.
Secondly, the gui is EXTREMELY buggy
Sometimes it works, but sometimes it just glitches out.
I’m extremely confused as I’ve coded it the way it’s intended to be coded, but it just doesn’t work.

Here are the scripts, I just need to fix the weird irregularity and bugginess of this.

Serverscript

Script:

local replicatedstorage = game:GetService("ReplicatedStorage")
local rt = replicatedstorage:WaitForChild("Shoot")
local serverscriptserver = game:GetService("ServerScriptService")
local module = require(serverscriptserver.DamageModule)
local soundservice = game:GetService("SoundService")
local sound = soundservice["Gun Shot"]
rt.OnServerEvent:Connect(function(plr, mouse, tool,pos, targetfilter, ishooting)
	local muzzle = tool.Effect.MuzzleEffect
	--- print(targetfilter)
	targetfilter = tool.Handle
module.IdentifyGun(tool.Name, mouse, muzzle, plr.Name, sound, plr)
end)
Module

Module:

local damage = {}
local config
function damage.IdentifyGun(gunname, target, muzzleeffect, plr, gunshot, player)
	local character = player.Character or player.CharacterAdded:Wait()
config = script.Configuration
local folder = config:FindFirstChild(gunname)
local damagevar = folder.Damage
local ammovar = folder.Ammo
local counter = 0
local ammo = character:FindFirstChild(gunname .. " ammo")
if ammo == nil then return end
local debounce = character:FindFirstChild(gunname .. " debounce")
local fireratevar = folder.FireRate
local reloadtimevar = folder.ReloadTime
local maxammovar = folder.MaxAmmo
if target == nil then
	return
end
		if ammo.Value > 0 and debounce.Value == false then
			ammo.Value -=1
		debounce.Value = true
		muzzleeffect.Enabled = true
		gunshot:Play()
		task.wait(fireratevar.Value)
		debounce.Value = false
		muzzleeffect.Enabled = false
		if target.Parent:FindFirstChild("Humanoid") then
			target.Parent.Humanoid:TakeDamage(damagevar.Value)
		end
			if ammo.Value == 0 then
				debounce.Value = true
				task.wait(reloadtimevar.Value)
				ammo.Value = maxammovar.Value
				debounce.Value = false
				return
			end
end
end
return damage
Local script

Script:

local remaining = game.ReplicatedStorage.Remaining
local reloadrt = game.ReplicatedStorage.Reload
local tool = script.Parent
local mouse = game.Players.LocalPlayer:GetMouse()
local plr = game:GetService("Players").LocalPlayer
local tool = script.Parent
local playergui = plr.PlayerGui
local firerate = 0.4
local debouncereload = false
local uis = game:GetService("UserInputService")
local is_shooting = false
local debounce = false
local maxammo = 26
local amount = 0
local value = plr.Bulletpack.Bullet
local character = plr.Character or plr.CharacterAdded:Wait()
local ammo_out = false
local rt = game.ReplicatedStorage:FindFirstChild("Shoot")
local yield = 0.1
local ammo = 26
local gui = plr.PlayerGui:WaitForChild("GUIGLOCK")
uis.InputBegan:Connect(function(input, fals)
if input.UserInputType == Enum.UserInputType.MouseButton1 and plr.Character:FindFirstChild(script.Parent.Name) then
		is_shooting = true
		while is_shooting == true and debounce == false do
			if ammo <= 0 then
				gui.Display.Value.Text = "Reloading"
				debounce = true
				task.wait(2)
				debounce = false
				ammo = maxammo
			end
			ammo -= 1
			gui.Display.Value.Text = ammo .. "/".. maxammo
			task.wait(yield)
			rt:FireServer(mouse.Target,script.Parent,mouse.Hit.Position, mouse.TargetFilter, is_shooting)
		end
	end
end)
uis.InputEnded:Connect(function(input, fals)
	if input.UserInputType == Enum.UserInputType.MouseButton1 and  plr.Character:FindFirstChild(script.Parent.Name) then
		is_shooting = false
	end
end)
tool.Equipped:Connect(function()
	gui.Enabled = true
end)
tool.Unequipped:Connect(function()
	gui.Enabled = false
end)
1 Like

Guys? I’ve reposted this three times and not gotten any replies, are people just not seeing my posts?

no we saw your posts but we are just a bit too lazy, sorry but i can’t help with this one

it’s extremely hardcoded and too reliant on instances

this is not a good practice, ur relying on object references being sent from the client to the server. (the tool)

this is prone to failure, and if something as simple as accessing the muzzle effect were to fail, it stops the entire script.

the client shouldnt be sending anything other than the mouse target position

2 Likes

The client’s sending the tool so the server can check what tool is being fired, but I understand this is easily exploitable

yeah like the others said: your code is hard to read, consider looking into code readability

this is the style guide i use for my projects (w/ an example module script) that may also be a bit unecessary for basic projects

-- decriptive name
-- services

-- variables
local default_module = {}
-- settings

-- logic

-- startup functions

-- Initialize function, called first in every script
function default_module:Initialize()
	
end

-- Initiate function, called second in every script
function default_module:Initiate()
	
end


return default_module

--[[
			Style guide
			
		Whitespaces
	| Seperate Functions by 2 new lines, potentially with a comment on the second line
	| Comments should have spaces after the initializing dashes
	
		Variable casing:
	| Services should be PascalCase
	| Instances should be PascalCase
	| Primitive values should be camelCase
		| Constants should be SNAKE_CASE
		| Private variables should be _camelCase
	| Functions should be PascalCase
		| Methods should be PascalCase
		| Constructors should be camelCase
	| Tables should be snake_case
	
		Variable naming:
	| Don't abbreviate (ex: Player instead of Plr, RunService instead of RunServ)
	| Don't put types in variable names, if it can be helped
	| Add units to variable name if not inferred by type
	| Names should be more specific than "Util" or "Manager"
]]

(module made to be used with https://www.youtube.com/watch?v=YsXijBUUmmM)

if you rewrite it and don’t end up finding the problem yourself, @ me and ill look at it again

1 Like

Hello,

A couple pieces of advice before we solve your problem:

  1. Formatting - The code written in the original post is extremely difficult to read and understand. Using an organization system similar to @PuffoThePufferfish’s reply would be ideal.

  2. Extra Variables - While recreating your code, there were several unused variables, based on what you have provided us. I am not sure if they are used for other parts that you have left out, but from what we have to work with they are useless.

Aside from advice for the future, I also have a couple of points to make on how the code functions currently.


First, you have values defined in several different spots for the same things. For example, the FireRate, Ammo, and MaxAmmo values are defined in the gun script (client) and in the gun configuration folder (server). This makes it more complicated to create more guns in the future.

Another thing (already mentioned above by @arbitiu) is that the server is in charge of managing everything. A good practice and a habit you should try to get into is only making the server do what it absolutely has to do. All the server needs to make the gun shoot is the position that the bullet needs to hit. The client should manage the muzzle effect and sounds.

Now, time to handle your issue and improve the “buggyness” of your system.


Lets start with the DamageModule. I have updated the code to only manage damaging the player. The function takes in the player who shot, the part the shot hit (if any), and the amount of damage to deal. The module uses all of this to then determine if an object was hit, if the object is a player, and how much damage they should take.

Next, lets take a look at the GunService script. Using the shoot event in ReplicatedStorage, the script takes in the player who shot the gun and the hit position/part. Using this, the server can manage whether the shot is in range and call the Shoot function from the DamageModule.

The updated GunClient script now handles the sounds, muzzle flashes, and the GUI. It also has a few updated configuration settings, including damage.


Here are all of the updated scripts:

DamageModule (module)
-- Damage Module

local damage = {}

function damage.Shoot(player: Player, hitPart: BasePart, damage: number)
	
	local character = player.Character or player.CharacterAdded:Wait()
	
	if hitPart == nil then
		return
	end

	if hitPart.Parent:FindFirstChild("Humanoid") then
		hitPart.Parent.Humanoid:TakeDamage(damage)
	end
	
end

return damage
GunService (server script)
-- Gun Service Script

-- Services
local rs = game:GetService("ReplicatedStorage")
local sss = game:GetService("ServerScriptService")
local ss = game:GetService("SoundService")

-- Variables
local shootEvent = rs:WaitForChild("Shoot")

local module = require(sss.DamageModule)

shootEvent.OnServerEvent:Connect(function(player, hitPart: BasePart, hitPos: Vector3, damage: number)

	module.Shoot(player, hitPart, damage)
	
end)
GunClient (client script)
-- Gun Client Script

-- Config
local fireRate = .2 -- The cooldown between firing (seconds)
local ammo = 26 -- The current ammo amount
local maxAmmo = 26 -- The max ammo amount
local reloadTime = 2 -- Time it takes to reload (seconds)
local damage = 20 -- The amount of damage the gun deals

-- Services
local players = game:GetService("Players")
local uis = game:GetService("UserInputService")
local rs = game:GetService("ReplicatedStorage")

-- Variables
local player = players.LocalPlayer
local mouse = player:GetMouse()
local character = player.Character or player.CharacterAdded:Wait()

local shootEvent = rs:FindFirstChild("Shoot")

local playerGui = player.PlayerGui
local gui = playerGui:FindFirstChild("GUIGLOCK")

local tool = script.Parent

local muzzleEffect = tool.Effect.Muzzle
local shootSound = tool.Handle.Fire

local isShooting = false
local debounce = false
local reloadDebounce = false

-- Functions

uis.InputBegan:Connect(function(input, gp)
	
	if input.UserInputType == Enum.UserInputType.MouseButton1 and character:FindFirstChild(tool.Name) and not isShooting and not debounce and not gp then
		is_shooting = true
		
		while is_shooting == true and reloadDebounce == false do
			debounce = true
			
			if ammo <= 0 then
				gui.Display.Value.Text = "Reloading"
				reloadDebounce = true
				task.wait(2)
				reloadDebounce = false
				ammo = maxAmmo
			end
			
			ammo -= 1
			
			muzzleEffect.Enabled = true
			shootSound:Play()
			
			gui.Display.Value.Text = ammo .. "/".. maxAmmo
			shootEvent:FireServer(mouse.Target, mouse.Hit.Position, damage)
			
			task.wait(fireRate)
			
			muzzleEffect.Enabled = false
			debounce = false
		end
	end
	
end)

uis.InputEnded:Connect(function(input, gp)
	
	if input.UserInputType == Enum.UserInputType.MouseButton1 and character:FindFirstChild(tool.Name) then
		is_shooting = false
	end
	
end)

tool.Equipped:Connect(function()
	gui.Enabled = true
end)

tool.Unequipped:Connect(function()
	gui.Enabled = false
end)

gui.Display.Value.Text = ammo .. "/".. maxAmmo

Lastly, here is a video demonstrating all of this:


I hope this helps you and let me know if you have any questions!

1 Like