Intro to Module Scripts

As projects become complex, it becomes important to think how scripts are organized. Good organization practices can ensure code isn't duplicated between scripts, or becomes hard to manage.

A better way to organize and reuse code is with module scripts, a unique type of script that stores a set of functions and variables designed to meet a shared purpose, like managing player money or enemies. Code within module scripts can be used by other scripts. That way, you can call the same function that gives coins from multiple different scripts whenever a player finishes a quest or finds a pickup.

By storing commonly used code in module scripts, it makes maintaining and organizing code easier since changes only need to be made to one module script, rather than updating multiple scripts.

Module Script Basics

Module scripts are actually their own separate object compared to script objects. In Roblox, module scripts can be denoted with a purple icon.

Creating a Module Script

ModuleScripts are commonly placed in ServerScriptService when used by server-side scripts and ReplicatedStorage when used by client-side local scripts (such as GUI interactions).

  1. Create a ModuleScript in ServerStorage.

Structure of Module Scripts

When created, every module script starts out with the code below:


local module = {}
return module

The line local module = {} creates a table, or container of code, where the module's shared functions and variables can be stored. This table should be renamed to the module's purpose, such as RewardManager or ParticleController. As opposed to other variables which are Pascal case (myVariable), module tables are recommended to start capitalized.


local RewardManager = {}
return RewardManager

So other scripts can use a module's non-local functions or variables, every module ends with return myModule. Whenever another script tries to get code from the module, return lets that script access code stored inside the module table.

Adding to Module Scripts

To add a function or variable to the module which can be used in another script, type the module table's name, followed by a dot, and the name of the function or variable, like in TestModule.myVariable. Using the dot operator is another way of adding code into a table, allowing other scripts to access that code whenever the module table is returned.


local TestModule = {}
-- Adds a variable to 'myModule' table
TestModule.myVariable = 100
-- Adds a function to 'myModule' table
function TestModule.doTask(player)
-- Placeholder code
end
return TestModule

Scope in Module Scripts

For a module function or variable to be used in an outside script, don't type local.

Typing local in front of variables and functions means they are only usable by that script. While this is a good practice for most scripts for reducing errors and troubleshooting, you cannot make module script functions and variables local.

Any code used only by that module script should still include local. For instance, the code below includes the local variable difficultyModifier, which can only be used in that module script, and the function getCoinReward(), which can be used in scripts outside the module.


local rewardManager = {}
-- Usable only in the module script
local rewardCoins = 50
-- Usable only in the module script
local difficultyModifier = {
easy = 0.5,
normal = 1,
hard = 2
}
-- Usable in other scripts
function rewardManager.getCoinReward(difficulty)
local coins = difficultyModifier[difficulty] * rewardCoins
return coins
end
return rewardManager

Using Modules In Others Scripts

By itself, a module script can't run code — it needs to be loaded in another script using the keyword require(). The function require() accepts one argument, the location of the module script in the Explorer.

To use a module, in a separate script, set a variable equal to require(moduleScript).


local myModule = require(ServerStorage.ModuleScript)

Now, the variable myModule contains the module table created in that module script. To use functions and variables from that table, type the variable name, followed by a dot, and the exact name of what to use in that module script, like myModule.myFunction(). When the script runs and reaches that line, it'll access that specific function or variable stored in the module table.


local myModule = require(ServerStorage.ModuleScript)
myModule.myFunction()

Example

ModuleScript - RewardManager

local rewardManager = {}
-- Usable only in the module script
local rewardCoins = 50
-- Usable only in the module script
local difficultyModifier = {
easy = 0.5,
normal = 1,
hard = 2
}
-- Usable in other scripts
function rewardManager.getCoinReward(difficulty)
local coins = difficultyModifier[difficulty] * rewardCoins
return coins
end
return rewardManager
Script - TreasureChestScript

local ServerStorage = game:GetService("ServerStorage")
-- Load module script
local RewardManager = require(ServerStorage.RewardManager)
--Calls function from module script
local coins = RewardManager.getCoinReward("easy")
print("Should award " .. coins .. " coins")

General Troubleshooting

Some of the tips here address common issues when working with module scripts. Keep in mind that module scripts can be a complicated topic with more nuance. For more details, see this more technical guide on Module Scripts.

Issue: Get an error message including: "Infinite yield possible" or "not a valid member".

  • Check the spelling of the module script where it's loaded. require() must include the exact path and spelling of the module script, which may be named differently than the module table.

Issue: Get an error message including: "attempt to index global".

  • In any scripts using a module script, make sure it's loaded using the function require(). If not, that script cannot use functions and variables from the module script.

Summary

Module scripts in Roblox are a method coders use to organize and reuse code. A module script is often stored in ServerStorage (or ReplicatedStorage for client-based interactions). From there, other scripts are able to call functions and variables stored in that module script.

For instance, one game may award points to players for collecting objects. A module script can handle code to give points. Then, scripts for different types of objects can just call the module script function. This reduces the need to reuse code between scripts, making code easier to understand and maintain.