Help understanding modules

So, i know that module scripts typically optimize games by just having one function that controls multiple parts. What im wondering is how this works, when should i use it, how should i use it?

Any explanations are helpful since i want to incorperate modules but also want to learn more about them.

2 Likes

Use them when you need to reuse pieces of a script across multiple script, sort of like what you’d do with functions.

2 Likes

Modules are ways for you to organize data and functions in a readable way. What you need to know is that modules cannot run by themselves, they need either a server or local script to function. I will answer each of your questions here:

When you want to get the functions and data out of a module script, you use the ‘require’ function to access everything the module script owns. EX:local Module = require(script.ModuleScript) Module.PrintHi() -- After requiring the script, you can use its functions :)

Use module scripts when you want to store data and functions that can be reused or keeps everything simple. EX: I have a crafting system where I can only craft an item if i have sufficient materials. I can use a module script to store the details of the crafting, which keeps everything organized and readable. The table can also be required by other scripts in case they need a reference to the table

You should use module scripts only to store important functions and code that needs to be used by other scripts as well, EX: I have a pathfinding module that needs to be applied to every NPC in my game, I can require the module’s functions using the scripts in the NPC, improving performance in the end.

2 Likes

Thanks, but how would i do that? Would I, for example, have a folder in the workspace called killparts and then use folder:GetChildren() in a .Touched event?

1 Like

Thanks a ton, this helps a lot! I’ll be rereading this post often for reference

1 Like

CollectionService is useful for ensuring only one script exists when multiple models or parts that do the same thing need a script to work (such as doors, kill bricks, lights, etc.).

However, there is no difference performance-wise if you do CollectionService instead of iterating over all the instances in a folder or model with a for loop to connect to each instances’ .Touched events. CollectionService just serves as an easier way to access instances with the tag globally.

CollectionService Documentation
CollectionService in a nutshell

Here’s an example of how CollectionService works for making parts that damage the player by 15 points on touch. More complicated scripts can be made, but this is a simple one that can be recreated easily.

local CollectionService = game:GetService("CollectionService")
local KillBrickTag = "KillBrick"

for i, v in CollectionService:GetTagged(KillBrickTag) do
	v.Touched:Connect(function(hitPart)
		if hitPart.Parent:FindFirstChild("Humanoid") then
			hitPart.Parent.Humanoid:TakeDamage(15)
		end
	end)
end
1 Like

Thanks man, this helped me understand a lot better

Modules are used to stop breaking the DRY (Don’t Repeat Yourself) principle. That is the simple definition.

However, if you want to maximize the use of modules, I would recommend learning about metatables, which is commonly used to mimic OOP.

You can also use it for storing things (to be organized). For example, if you are gonna use ProfileService for data storage, you might want your profile template in a module. If I need to add something to the template, I know exactly where to go.

It’s really late a night and I am too lazy to type, but there are a lot of resources on this topic.

1 Like

Coming back to this topic 13 days later with a question: can you use the collectionservice and stuff within a normal script? If so, then why use modules for this?

I’m still trying to learn about modules, so just wondering

yes but it’s good to use it in a small portion of a different script so that your main script (the server script, not the module) can be used for handling the rest of your code. the module script is supposed to hold functions that you can call from the server. hope that makes sense! :heart::heart:

1 Like

Okay thanks, i think i understand :+1:

1 Like

here’s an example for you:

i’m currently working on a minigame system and this is the module script that controls functions i keep in there for it to be nice and organized.

local RoundModule = {}

function RoundModule.NewRound()
	for i, Player in pairs(game:GetService("Players"):GetPlayers()) do
		Player:LoadCharacter()
		print("Reset round.")
		
		local CurrentMinigames = game:GetService("Workspace").CurrentMinigames
		for i, Minigame in pairs(CurrentMinigames:GetChildren()) do
			if Minigame:IsA("Model") then
				Minigame:Destroy()
			end
		end
	end
end

function RoundModule.LockFirstPerson()
	local InGameFolder = game:GetService("Workspace").InGameFolder
	
	for i, Player in pairs(game:GetService("Players"):GetPlayers(InGameFolder:GetChildren())) do
		Player.CameraMode = Enum.CameraMode.LockFirstPerson
	end
end

function RoundModule.UnlockFirstPerson()
	local InGameFolder = game:GetService("Workspace").InGameFolder

	for i, Player in pairs(game:GetService("Players"):GetPlayers(InGameFolder:GetChildren())) do
		Player.CameraMode = Enum.CameraMode.Classic
	end
end

return RoundModule

i call each of these through the main script (the server script) and the game runs pretty damn smoothly.

1 Like

Wow thanks, this will help! And module functions can be used by other scripts as long as they are local functions, correct?

Yes! You’d call a module script function like

Module.YourFunction() -- assuming this is a function that does things
or
BoolValue = Module.YourReturningFunction(any) -- assuming this would return true/false based on whatever you give it

Module scripts are purely there to keep your main server/client scripts from being cluttered, they can be used for things like

  • Creating a new minigame, such as like a folder with lots of module scripts or just 1 module with different minigame types, and if you were to call it then it’d create the minigame
  • Creating raycasts as those can sometimes fill up 15+ lines so the main script would just have 1 line instead
  • Changing leaderstats with custom functions
  • Spawning NPC’s or other objects
  • Math related things that are too ugly to be seen regularly

It is really just to not have 1k+ lined server/client scripts and they keep things organized

When I made a settings menu I had a module script filled with correlating names to the buttons so all I did was

-- local script
Button.MouseButton1Down:Connect(function()
 local func = ModuleSettings[Button.Name] -- assuming the Button name is "NightMode", this would activate the single local function below
 func()
end)


-- module script
local Module = {}

local function NightMode()
end

local settings = {
["NightMode"] = NightMode,
}

return Module
2 Likes

Thanks a ton! Glad to finally be understanding modules

1 Like