Keeping track of ammo on server and client

I’ve been working on a gun system since last week and I recently rearranged my code to have effects done on the client and have the server go through validating the player’s shots.

Now, I’m trying to think of how to save ammo on the client as well as the server to add more protection. Right now, I keep track of ammo on the client as well as the logic to reloading. I use attributes to save the gun’s ammo locally.

I’ve looked at threads in the forum and stumbled across this one and that one. Both talked about how the ammo should be saved on the client and on the server, but also how the client should not pass any of its ammo data to the server and instead have the server send information back to the client to adjust its ammo.

This confuses me because I have everything kept on the client right now, so I’m having trouble on what to move around or what to add or remove to make this work in a secure way. (Would I need any remotes? Should I reload on the server? Should I save ammo data on the server and pass data to the client?) Any help would be appreciated!

Client Code
local ammo = gun:GetAttribute("CurrentAmmo")
local ammoReserve = gun:GetAttribute("CurrentAmmoReserve")

-- Used every time the player shoots or reloads or drops the gun
local function updateAmmo()
	gun:SetAttribute("CurrentAmmo",ammo)
	gun:SetAttribute("CurrentAmmoReserve",ammoReserve)
end

local function fire()
	local character = player.Character or player.CharacterAdded:wait()
	if gun.Enabled and not isReloading and character then
	
		-- Checks
		
		if ammo > 0 then
			gun.Enabled = false

			-- Raycast and remote fire to server

			ammo -= 1
			updateAmmo()
			-- Effects
			wait(FIRE_RATE)
			gun.Enabled = true
		else
			clickSound:Play()
		end
	end
end

local function reload()
	isReloading = true
	-- Sounds and animations
	reloadAmmo()
	updateAmmo()
	-- Gui updates
	isReloading = false
end
1 Like

Personally I always do ammo on the client, a big system I know only does it on the client but if you want it on the server as well which is understandable I would do it like this;

Player clicks R or the gun runs out of ammo and sends reload request to server, server checks if the ammo for that player is valid, ammo value is returned and the guns reloads.

Client request → server handles logic → Client receives data → Client performs action.

Or you could reload the players gun via the server for extra security.

Client request → server handles logic and reloads gun.

There’s a lot of ways to do it personally I would do

Client request → server handles logic → Client receives data → Client performs action.

2 Likes

if you set currentammo/currentammoreserve as a attribute and depend on it using only the local script it can easily be exploited

I personally don’t do anything on the client. Roblox is so easy to exploit. I only gather input data from the client. I personally have never had any issues with this, but small desync could happen if the client’s internet is slower. With all of this in a local script, all an exploiter has to do is change 2 values and have infinite ammo and fire with no delay and never reload. I’d take small desync over the possibility of some exploiter ruining the game any day myself.

But honestly to answer the question, FastCast is really good, and its example use is well written with many comments to explain it, adding ammo would be super easy.

2 Likes

That’s true, I think a lot of the bad practices we see (Including mine) is due to the clanners out there, if they even have 0.1 seconds of desync for reloading they’ll scream at the developers, so yeah it should defo be done at the server if he wants the most secure system, personally I haven’t seen anyone exploiting ammo in my own guns or the bigger system I referred to earlier but it is certainly a possibility.

1 Like

Thank you for all your responses. I really wish I didn’t have to make a choice between exploiters and desynchronization, as they both ruin the experience. That’s why I think having both the client and server handle ammo would make it harder for it to exploit and lower the chance of delay. (Then handle exploiters through other ways)

I’ve looked at it before, but since this is my first gun system I’d like to learn from what I can do.

Thank you for this, I think I have a better idea of what to do. I think updating the attributes on the server would be a good start and then have a remote to send ammo data from the server. (and still keep track of ammo locally) I’ll put in what I come up with later.