How do I go About Making a Custom Weapon System?

I’m making a game where, in summary, players are forced to equip random tools to fight one another. Currently, I’m planning to have a Surface GUI button that, when clicked, fires to the server which consumes the required currency and grants the player the choice to switch from their old item to a random item selected by the server until the server switches or unequips the weapon for them (regardless of how many times they die with the weapon). Below is some code outline for a module script that handles equipping and unequipping items:

local repStorage = game:GetService'ReplicatedStorage';
local models, remotes = repStorage.models, repStorage.remotes;
local equip, input = remotes.equip, remotes.input;

local methods, data, temp = {}, {}, {}; --data stores the name of the item each player has equipped and the rbxscriptconnection for giving them the weapon again whenever they respawn
--temp stores any items that should be cleaned up once the tool is unequipped (such as the tool itself or a motor6d it required)

local function tag(plr, ...) --put any objects passed into the tuple into the player's temp table
	local tbl = {...};
	
	for i = 1, #tbl do
		temp[plr][#temp[plr] + 1] = tbl[i];
	end
	
	return ...;
end

local items = {
	['pistol'] = function(plr, chr)
		--copy the pistol model from storage and parent it to the character yada yada yada and tag it to ensure it gets deleted in cleanup, the same with other parts
		--also create a function that fires according input's onserverevent to deal damage/bullet physics when the player clicks, etc. this should be disconnected once the tool is unequipped so it should be referenced in temp[plr]
	end
};

function methods.equip(plr, item)
	data[plr] = data[plr] or {};
	temp[plr] = temp[plr] or {};
	if data[plr].item then methods.unequip(plr); end
	data[plr].item = item;
	
	equip:FireClient(plr, data[plr]);
	temp[plr][#temp[plr] + 1] = plr.CharacterAdded:Connect(function(chr) items[item](plr, chr); end)
	items[item](plr, plr.Character);
end

function methods.unequip(plr)
	equip:FireClient(plr);
	data[plr].setup:Disconnect();
	for i = 1, #temp[plr] do
		local debris = temp[plr][i];
		if typeof(debris) == 'RBXScriptConnection' then
			debris:Disconnect();
		else
			temp[plr][i]:Destroy();
		end
	end
	data[plr].item = nil;
end

return methods;

In the client, there will be a similar module that gets referenced when the equip RemoteEvent is called and causes a function correlating to the equipped item to fire every frame and fire back to the server through the input RemoteEvent every time the player presses an essential key and a client debounce succeeds (using tick()). The server will also perform a debounce of its own for measure against exploitation also using tick().

So is this system good? Should I make any alternations/optimizations? Or perhaps rethink the system entirely? Any feedback would be very appreciated.

1 Like

If no one has any suggestions or feedback whatsoever I’ll just go through with this idea. Thanks to those who read this post.

3 Likes