How to make universal module controller, instead of a bunch of local scripts? (For tools)

Im wondering how I could have one module control a bunch of tools, sorta like a universal controller. Currently my tools work by using local scripts, which are quite long. I feel like having one universal module control all of these, instead of multiple different local scripts is better, because it would be cleaner and standardized code. My first thought was to have a local script in each tool which would require this module, but im not sure how to move on from that point. I already tried this approach and for some reason only one tool was able to use the module. Requiring the module while another tool was using it would break the tool.

1 Like

I want to create a script that controls all of them, like a module script. My plan was to require these in a local script in each tool along with the config of said tool, then id let the module create the gun for me, with settings according to the config i sent over while requiring

Well; I would use a system that encompasses some BindEvents for this, so you can transfer values from one LocalScript to another and link them together, or even link all the objects you want to the LocalScript that will manage them.

I thought of using one module script that has a constructor, and in that constructor i require the tool config, the tool instance and whatever else i need

I thought about that too, but I didn’t know that all your LocalScript’s were the same, so I didn’t suggest this possibility.

The problem is i tried this once, and while it worked, it only worked with one tool. If i had more than one tool require this module and run the gun function no other tool would work. Only one. Do you think you have an idea on how I could make this work?

Well… I think the best idea for this is the one I commented on earlier: Create a table with the items, do a for _, instance in ipairs() do (for loop) and connect the functions you want, on the required events.
Then whenever you need to change the code, you would only need to change one function.

In order to do this, you can create a universal tool manager that uses OOP to hook up modules with the tool’s names to the actual tool object itself.

A tool module could look like:


local tool = {}
tool.__index = tool

function tool:Equip()
	print('equipped!')
	print('cool variable: '..self.CoolVariableIGuess)
end

function tool:Unequip()
	print('Unequipped!')
end

function tool.new(toolObject)
	local self = {}
	self.ToolObject = toolObject
	self.CoolVariableIGuess = 'Hello World!'
	
	setmetatable(self, tool)
	
	return self
end

return tool

While the main tool manager could use this toolmodule like this:

local tools = {}
player.Backpack.ChildAdded:Connect(function(child)
	if child:IsA('Tool') and not tools[child] then
		local module = require(modules:FindFirstChild(child.Name)) --or where ever you store the tool modules
		tools[child] = module.new()
		
		child.Equipped:Connect(function()
			tools[child]:Equip()
		end)
		
		child.Unequipped:Connect(function()
			tools[child]:Unequip()
		end)
	end
end)
8 Likes

Could you elaborate further on this? What if i wanted to add simple userinput functions, how would i connect those to the gun?

You can add a :OnInputBegan() function, similar to the :Equip() function of the tool module. In the main tool manager, whenever the tool is equipped it can make a connection to UserInputService.InputBegan and call the function. When the tool is unequipped, it can disconnect this connection.

For some reason, this approach only allows me using one tool always. Its like its saving the position and everything from the old tool, its weird to explain. Using a different tool while another one is currently ‘using’ this module completely breaks it. This is an issue that ive always been met with when making these sorts of gun modules.

are you using metamethods? it’s important to allow for the OOP-style of the tool module

im using metamethods, it seems to only use the properties of one tool though so i dont quite understand

Send me your code, if possible.

Moved all the equipped, unequipped, userinputservice functions into the tool.new() function and now it works, weird

I think that means you werent returning the data after you setmetatable