So i got into OOP and i want to create a player store table with metatables. When the player joins it creates the object but later on in another script i want to access the metatable without making a new one. Should i just insert the metatable into the module table or what can i do?
A metatable is just a regular table meant to be attached to other tables to provide custom behavior .
If you are creating an object of your class when a player joins your game, and want to access it from another script, you can insert the object into another table and store it there for reference.
--// Store.lua
--// Reduced example without types
local SimpleStore = ({});
SimpleStore.__index = SimpleStore; --// Whenever the object of the metatable SimpleStore is indexed [like Object.Data], it refers to itself (to prevent unexpected behavior)
function SimpleStore.new(): ()
local self = setmetatable({
StoredValue = nil;
}, SimpleStore); --// Creating a new object with `SimpleStore` being the metatable.
return (self);
end;
function SimpleStore:Store(Value: any): ()
self.StoredValue = Value; --// example
end;
return (SimpleStore);
In another script, or a module, you can create something like this:
--// Example.server.lua
local StoredObjects = ({});
Players.OnPlayerAdded:Connect(function(Player: Player): ()
local PlayerObject = SimpleStore.new();
PlayerObject:Store(Player.UserId);
StoredObjects[Player] = PlayerObject;
end);
--// somewhere later in the script, you could access the stores like this-
local SpecificStore = StoredObjects[SpecificPlayer];
--// -or loop over them
for Player, Store in pairs(StoredObjects) do
--// do anything with Player and Store
end
If you intend to use a module to store all the player objects, just return the table at the end of the module
return (StoredObjects);
Edit 1: fixed minor typos
Great thanks, another question ive seen the operator ; used what does it do
;
is just used to mark the end of the statement/line.
It’s not necessary to use in roblox luau (just a habit from my typescript and C++ programming)
Also do i use table.insert? Becsuse i didnt see it in your post i was confused
table.insert
just pushes the value into the table. In my post I’ve done this
instead of table.insert
because I want to be able to get the store using the Player
instead.
If I used table.insert
, it’d be hard for me to figure out which object in the StoredObjects
refers to which player, unless we specify it by using another field like
self.Player = Player; --// self: SimpleStore
p.s. I’m not using types here because I don’t want you to be confused on what those do.
Thanks for this i thought i could just insert the whole table into it. Thanks for your replies
Forgot to mention that ;
can also be used as ,
in tables.
Im back again and im in studio but i cant seem to figure out how to remove it from the table.
btw instead of player stores i did queues
code:
local Queues = {}
Queues.__index = Queues
function Queues.New(Player)
local Queue = {
Owner = Player,
MaxPlayers = 5
}
setmetatable(Queue, Queues)
Queues[Player.Name.." Queue"] = Queue
return Queue
end
function Queues:Remove()
setmetatable(self, nil)
Queues[self] = nil
end
function Queues:AddPlayer()
end
function Queues:RemovePlayer()
end
return Queues
–Server script:
local Queues = require(game.ServerScriptService.Queue)
local Player = game.Players:WaitForChild("Dynamite2479")
local Queue = Queues.New(Player)
print(Queues)
Queue:Remove()
print(Queues)
it prints the exact same thing even after the remove function and it gives no errors
You are setting the key
(think of a key
as name of the data stored in the table) of the table as Player.Name.." Queue"
But when removing the object from the queue you do Queues[self] = nil
which wouldn’t work, as Player.Name.." Queue"
is not equal to the queue object.
Basically when removing something from a dictionary you’d do something like this
function Queues:Remove()
setmetatable(self, nil)
Queues[self.Owner.." Queue"] = nil
end
Or instead of doing this
you could do this aswell:
--// adding to global queues
Queues[Player.Name] = Queue;
--// when removing
Queues[self.Owner.Name] = nil;
sorry for the late reply i had college lol
Also looking at this code, you aren’t using setmetatable
properly.
The logic is correct, just assign it to self
and return it, because right now you are returning the table Queue
and not the object returned by using setmetatable()
function Queues.New(Player)
local Queue = {
Owner = Player,
MaxPlayers = 5
}
local self = setmetatable(Queue, Queues) --// object is now stored in `self`
Queues[Player.Name] = self
return self
end
Thanks alot, sorry if i seem a lil annoying ive been trying to learn for months and couldnt even grasp OOP
No problem.
It’s totally fine, because most of us have been in this state of learning new things.
It can be difficult to understand at first, but thanks to the internet, everything gets simplified.
I’m just trying to help others with understanding concepts, about the engine and what not (mainly coz I learned things the hard way and I don’t want others to go through the same thing)
If you have any more doubts or issues regarding OOP you can contact me on discord @glaphyre
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.