Hello, I’m Mega and this is my very first community tutorial!
So I have seen many people who want their custom methods on Instances but are not sure how they would make it work efficiently being global.
Metatables are great and we can utilize them here.
Lets try to make a system in which you can use services along with your custom functions and properties!
Step 1
Firstly lets start by making a service handler that would act as the middleman.
You could have it as a module script in ServerScriptService
.
Now we can add some code that will let us retrieve Roblox Services, with or without our custom methods.
local module = {}
function module:GetService(serviceName)
if script:FindFirstChild(serviceName) then
return require(script[serviceName])
end
return game:GetService(serviceName)
end
return module
What this does is, returns the Custom Service module if it exists being a child of the script, if not it would return the roblox service.
Step 2
Time to make some custom methods for a service!
Lets make one for the Players
service.
Start by making a module script inside our Services
module. We will store all our custom methods in this module, make sure its called exactly the name of the service as that’s what our main script expects!
Now we’ll add some custom properties first.
If we wanted to store a value that could be accessed by all ServerScripts,
we could make ValueBases
and update them.
However, we will try doing that by making a property that would let us efficiently retrieve it in any ServerScript.
Lets add it in our Players
module script.
local module = {
A = "This is a custom property!"
}
return setmetatable(module, {__index = game:GetService("Players")})
Detailed Explanation
As you may know, ModuleScripts
are basically Tables. The way you would make a dictionary using the Key/Value
pairs. We did the same thing here.
A
would be the key or the name of the property, the value which is "This is a custom property!"
could be called as the property’s default value, and don’t worry we can change it later!
Now, at the part where we return, you might be very confused.
Lets break it down,
You can set a so called metatable
to an existing table, it basically allows us to extend its functionalities. setmetatable()
is a function that takes 2 parameters, first would be the table we want to add it to, second would be the metatable itself with predefined events (You could call them that). These events are known as meta-methods
.
The __index
is one of them which fires whenever the main table gets indexed with something that is non-existant or nil
. It has been set to the Roblox Service of Players so if we try to call a method on the module that doesnt exist, it would redirect it to the Players
Service.
Now lets try this!
Insert a script in server script service
--I put this server script in Server Script Service.
local Services = require(script.Parent.Services)
local Players = Services:GetService("Players") --we actually retrieved the module straight as we had called `require()` at the time of returning!
print(Players.Name) --Players (As we didnt define `.Name` in our module, it took that from the actual players service)
print(Players.A) --Yes it will print our value that we stored
Lets improve it further by making our own functions or methods
-- Our Players module
local module = {
A = "This is a custom property!";
}
function module:KickAllPlayers()
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
player:Kick()
end
end
return setmetatable(module, {__index = game:GetService("Players")})
And yes, you would basically call it like any other function in a module script
--Our server script
local Services = require(script.Parent.Services)
local Players = Services:GetService("Players") --we actually retrieved the module straight as we had called `require()` at the time of returning!
print(Players.Name) --Players (As we didnt define `.Name` in our module, it took that from the actual players service)
print(Players.A) --Yes it will print our value that we stored
Players.PlayerAdded:Connect(function(plr)
Players:KickAllPlayers()
end)
Other things to note
- The values won’t be accessible by the client in our current setup, you could add it to replicated storage but that wont replicate the values
- This can be done for any service, infact, for any Instance. Services have been used as an example.
Links
https://developer.roblox.com/en-us/api-reference/class/ModuleScript
I hope you learned something from this tutorial, I tried my best to make it as beginner friendly as possible,
Please let me know if you have any concerns or suggestion,
Thank you for reading!