As you start building more complex Roblox games, you’ll quickly find that having all your code in one script becomes messy and hard to manage. That’s where modules and object-oriented programming (OOP) come in! These concepts might sound intimidating, but they’re actually just smart ways to organize your code so it’s easier to use and reuse.
In this tutorial, we’ll learn how to create modules that work like blueprints for objects in your game. Think of it like creating a recipe that you can follow multiple times to make similar things with different details each time.
What is a Module?
A ModuleScript is a special type of script in Roblox that stores code you want to reuse in multiple places. Unlike regular scripts that run automatically, modules only run when another script asks them to. This makes them perfect for storing functions, data, or even whole systems you want to access from different parts of your game.
To create a module, add a ModuleScript to ServerScriptService (or anywhere you prefer), and you’ll see it comes with this default code:
local module = {}
return module
That empty table {} is what we’ll fill with our code. The return statement sends whatever we’ve created back to any script that requires this module.
Creating Your First OOP Module
Let’s create a Weapon module that acts as a blueprint for creating different weapons in your game. This is where object-oriented programming shines—we can use the same blueprint to create a sword, a laser gun, or a magic wand, each with different properties.
Create a ModuleScript named “Weapon” and add this code:
local Weapon = {}
Weapon.__index = Weapon
function Weapon.new(name, damage, cooldown)
local self = setmetatable({}, Weapon)
self.Name = name
self.Damage = damage
self.Cooldown = cooldown
self.IsReady = true
return self
end
function Weapon:Attack()
if not self.IsReady then
print(self.Name .. " is cooling down!")
return
end
print(self.Name .. " attacks for " .. self.Damage .. " damage!")
self.IsReady = false
task.wait(self.Cooldown)
self.IsReady = true
print(self.Name .. " is ready again!")
end
return Weapon
Breaking Down the Code
Let’s understand what each part does and why it matters:
Weapon.__index = Weapon– This line tells Lua that when we create a new weapon object, it should look for functions inside the Weapon table. This is what allows our created weapons to use methods likeAttack().Weapon.new()– This is our constructor function. It’s like a factory that creates new weapon objects. We pass in the specific details (name, damage, cooldown) for each weapon we want to make.setmetatable({}, Weapon)– This creates a new table and connects it to our Weapon blueprint, giving it access to all the functions we define.self– Refers to the specific weapon object we’re working with. Each weapon has its ownself.Name,self.Damage, etc.function Weapon:Attack()– The colon:syntax automatically passesselfas the first parameter, making it easier to work with object methods.
Using Your Module
Now comes the exciting part—using our Weapon module to create actual weapons! In a ServerScript, write:
local Weapon = require(game.ServerScriptService.Weapon)
-- Create different weapons
local sword = Weapon.new("Sword", 25, 1.5)
local laser = Weapon.new("Laser Gun", 40, 3)
-- Use them independently
sword:Attack()
laser:Attack()
Notice how we use the same Weapon.new() function to create two completely different weapons? Each one has its own stats and cooldown timer. They’re independent objects created from the same blueprint—that’s the magic of OOP!
Why Use This Approach?
You might be wondering, “Why not just create separate functions for each weapon?” Here’s why this method is better:
- Reusability – Write the attack logic once, use it for dozens of weapons
- Organization – All weapon-related code lives in one place
- Scalability – Adding new weapon types is easy—just call
Weapon.new()with different values - Maintenance – If you need to change how attacks work, you only update one module
Recap and Next Steps
Congratulations! You’ve just learned the basics of object-oriented programming with modules in Roblox. You now know how to create a ModuleScript that acts as a blueprint, use constructor functions to create objects, and give those objects their own methods and properties.
The key takeaway is this: modules help you organize code into reusable pieces, and OOP helps you create multiple objects from the same template.
Ready to level up? Try expanding your Weapon module by adding more methods like :Reload() or :Upgrade(). You could also create other OOP modules like Enemy, Player, or Vehicle. The possibilities are endless once you understand this powerful pattern!