Attaching more than one metatable to a table

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.
GAAAH

–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:

OOP2SHEESH

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:

98c2f7477b65b2b631f6eec2a8cf7b33

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?

2 Likes