Alright, I’m going to try to go as in-depth as possible on this one, so bare with me. Through my testing and research, I’ve found it possible to attach more then just one metatable to a table. However, it comes with some bugs/unintended glitches.
Before I proceed I would like to list what I am looking to accomplish. I’m looking to create a layout for my client-sided framework as so:
Local Script Containing Table with all Variables relating to player →
Module Scripts that will use these variables that all have there own specific functions, etc →
Then Cross Module Script Communication with the help of the use of metatables.
I know I could easily emulate this effect with the use of Bindable Events and Bindable Functions, as well as just not linking everything together and have everything using there own variables. But this is a sort of self-inflicted challenge that I’m using to help progress myself.
Now, let me post the code that I currently have, and some screenshots of my layout.

–THIS IS THE FIRST STEP, ITS A SCRIPT CALLED LAUNCH IN STARTERPLAYERSCRIPTS.
local Player = game.Players.LocalPlayer
local ReplicatedStorage = game.ReplicatedStorage
local ClientInstallations = ReplicatedStorage.ClientInstallations
local Installations = {
__call = function(self, Key)
if Key == self.Player then return print("You are installation locked.") end
print("Currently Installing")
self.Player = Key
self.Player.CharacterAdded:Connect(function(Character)
self.Player = Key
self.Character = Character
self.Humanoid = Character:WaitForChild("Humanoid")
self.Head = Character:WaitForChild("Head")
self.Root = Character:WaitForChild("HumanoidRootPart")
self.Torso = Character:WaitForChild("Torso")
self.CharacterHasSpawned = true
end)
repeat wait() until self.CharacterHasSpawned
--GENERAL VARIABLES//
self.Camera = workspace.Camera
--REGION VARIABLES//
self.Region = "The City"
--CONTROL VARIABLES//
self["CombatActive"] = false
--MENU VARIABLES//
--MAIN INSTALLATION PROCESSES//
local RD = require(self.RegionDetectorClass)
local CON = require(self.ControlsClass)
local CAM = require(self.CameraClass)
for ind,v in pairs({_RD = RD, --[[_M = M,]] _CON = CON, _CAM = CAM,}) do
self[ind] = v.new(self)
end
end,
}
Installations.__index = Installations
local Driver = setmetatable({
RegionDetectorClass = ClientInstallations.RegionDetector,
MenuClass = ClientInstallations.Menu,
ControlsClass = ClientInstallations.Controls,
CameraClass = ClientInstallations.CustomCamera,
DefaultControlClassEvent = Player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"):WaitForChild("ControlModule"):WaitForChild("Event"),
UserInputService = game:GetService("UserInputService"),
ContextActionService = game:GetService("ContextActionService")
}, Installations)
Driver(game.Players.LocalPlayer)
print(getmetatable(Driver))
As you can see this attaches this “Driver” metatable onto other METATABLES. I’m basically trying to create a tree filled with branches, that are freely moving, able to connect to anything whenever they want.
–EXAMPLE OF ONE OF THE MODULES I LOAD UP
local Controls = {}
Controls.__index = Controls
function Controls.new(Driver)
local self = setmetatable(Driver, Controls)
return self
end
return Controls
Now this all looks like standard OOP, which it’s supposed to be. Unfortunately, it doesn’t really go as planned. when I print getmetatable on that Driver metatable, it only returns the Control Module:

This obviously means that it’s physically impossible for me to set more than one metatable to another metatable/table…Normally that is…
This problem is inhibiting me from accessing even the functions in my other classes, as when I try it returns this:

So this is where you guys come in… I need help thinking about how I could create the type of framework that I’m looking for, any suggestions?