How should I create a modular weapon framework?

Hello! I am currently revamping my game by changing the weapons framework to a modular system, since the method I was using(which is copy and pasting the scripts) was pretty bad.

In my first attempt, I did a simple main module to make a gun deal damage and some placeholder nil variables which would be replaced when the function is fired at my server script, but that did not work, it kept giving me index nil errors…

My main question is, how should I approach that modular framework? should I do a main module script for every weapon(every main module with the same code), a settings module which will be required in the main module, a local script to detect when the player clicks, and a server script which will require the main module and fire the function when a remote event is fired from the local script.
or should I do something like my first attempt, the module does the shoot function with nil variables, which are only given a value when the code is fired on the server script?

If the second option is the best alternative, how could I replicate that? I have no clue how to make placeholder variables which will only be given their actual values when called at the server script.

Also I am sorry if this is the wrong category.

This is most likely because of the variable being set to nil

If thats the case, how could I make placeholder values to replace them when the script is fired in the server script?

local Variable1
local Variable2

But I believe this will make them nil, but might not, could give it a go sorry if this doesn’t help

I don’t really have any experience with making modules for gun frameworks etc

1 Like

That will just give a nil value, so it will break my script

Also, it’s okay, you don’t need to be sorry :slight_smile:

Yeah I thought it would just set it to nil aswell since it has no assigned value lol, goodluck

If I understand this correctly you are unsure of how to change the variable on the module script?

No, I was unsure how to do a placeholder in the module script which would be replaced when the function is fired on the server, however, I figured out that is not possible.

Another question im having is how could I do a framework with the least amount of module scripts?
for example, having one main module script in replicated storage and a settings module script for every weapon.

Can you give me an example because I can’t understand what you are talking about.

Oh, im sorry.

the placeholder variable im talking about is a nil variable which when called at the server, will become something not nil.
for example, in the module script, that variable is the model of the gun, but the script still doesn’t know which gun yet, so I keep it nil until the function is called.

however, that script doesn’t work, because I can’t make a nil variable placeholder.

Oh you still don’t understand how to fully utilize modulescript.
You can just create a class.

I’ve heard about them before. I searched some topics about it and I still don’t get it.
Do you mind giving me an example?

Its actually pretty simple and easy to understand you can practically make anything with it, even connection like the :Connect(function()), there are multiple ways on creating a class it’s up to you on how to use them.

local class = {} -- you can use any variable
class.__index = {}

function class.new() -- you can use any function name .new .create .etc.
	local self = setmetatable({"You can add anything in here array or dictionary"}, index) -- you can use any variable 

	return self
end

function class.idk()
	local self= setmetatable({}, index)
	
	return self
end

function class:Trigger()
	self.Test = 0 -- self is based on the variable that you have created with either the new or the idk
	-- local new = class.new()
	--new:Trigger()

	--local idk = class.idk()
	--idk:Tigger
end

return class
local class = {} 

function class.new() -- or classs:new()
	local self = {} -- in this case you don't need the metatable since this one is different we don't need to access the entire table

	function self:Trigger()
		self.Test = 0
	end

	return self
end

return class
1 Like

I still have some questions, somehow…

First of all, If I wish to create a variable that is unknown to the module(like the gun model example I gave earlier) I should do this, right?

Gun = {}

function Gun.new(Model)
local newgun = {}
setmetatable(newgun, Gun)
newgun.Model = Model
end

Second, Do you mind explaining what does the quote below means, I didn’t quite get it…

That an empty table you can add anything inside the table.

And yes that is correct you can even just add it later on the script if you want, but it’s better to just pass the weapon on the function.

local class = require(...)
local new = class.new()
new.Model = Weapon
1 Like

Alright, thank you, I hope this works on my game!

Hey, Just tried to test that code and it gave me a nil error…

I don’t really see what’s wrong here…

--Module
local Gun = {}
function Gun.new(Model)
	local newgun = {}
	setmetatable(newgun, Gun)
	newgun.Model = Model
end

function Gun:Print()
print(self.Model)
end
return Gun
--Local
local M = require(game.ReplicatedStorage.Modules.MainGunModuleScript)
local G = M:new()
G.Model = "Model"

M:Print()

You forgot to return the newgun.

1 Like

Oh, right, sorry for bothering you.