BindableEvent can't return metatables after firing

  1. Well… I need to find replacement or a fix for this issue written below.

  2. BindableEvent can’t return metatables. Everytime i use :Fire() with metatable as first argument, i get table from it. But it isn’t metatable.

  3. i wrote small script to demonstrate this, and i couldn’t found solution for this elsewhere. So i asking for help.

local b = Instance.new("BindableEvent")
local m = setmetatable({},{
	__index = {
		Test = function()
			print("yeah it working.")
		end,
	}
})

print(getmetatable(m)) -- {__index ={Test = "function"}}
m:Test() -- yeah it working.

b.Event:connect(function(self)
	print(getmetatable(self)) -- nil
	self:Test() -- welp it doesn't.
	-- attempt to call a nil value
end)
b:Fire(m)

Please look on the developer documentation first before posting something:

(yes I am aware it is at the remote functions and events page, but the same is for bindables)

I think they will appreciate your reply if you can tell them that passing tables having meta methods or metatables will be lost during transfer.

Well, I think it is more important for a person to find it out themselves before asking. It has been proven you would learn more doing so. So whenever I see a question which is obviously or even a little tiny bit hidden on the roblox documentation website, I get frustrated, because if they tried searching on their own first, they’d know and didn’t have to ask. But yeah, I guess that’s my bad.

2 Likes

From my point of view you sent the proof that firing event with metatables is a useless idea. But i need any replacement for this then.

You would either have functions on both scripts or include the function inside the table instead of the metatable. (I’m not too sure why you’re using a metatable.)
As for functions on both scripts, you could always use modulescripts for shared functions instead.

1 Like

I’m trying to make something like AI, which should depends on the main functions. After they spawn i tried to detect it with the help of BindableEvent, but i settled on the fact, that i can’t interract with metatable directly.
About your idea, i’ll think about it untill i finish work on this anyway, so thanks for help in any case!

1 Like

You’d need to recreate and set the metatable again for the received table value. You could also transmit the metatable itself in some capacity as an additional argument.

bruh, i didn’t wanted to hear it until the very end. I really want to believe, that it isn’t necessary action, but it also a solution!

That’s why i’m not so happy of this sollution:

local mt = {
	Test = function()
		print("but it works tho.")
	end,
}
mt.__index = mt
local m = setmetatable({},mt) -- first setmetatable

local b = Instance.new("BindableEvent")
b.Event:connect(function(self)
	self = setmetatable(self,mt) -- second setmetatable
	print(getmetatable(self)) -- but it works tho.
	self:Test()
end)
b:Fire(m)

I have solved my problem with this ModuleScript:

local Module = {}

function Module:connect(func)
	table.insert(self._conns, func)
end

function Module:Fire(...)
	local args = table.pack(...)
	for _, func in pairs(self._conns) do
		task.spawn(func, table.unpack(args))
	end
end
function Module.new()
	return setmetatable({_conns={}}, {__index = Module})
end
return Module

There’s example to test it:

local SignalModule = require(8085956603)
local signal = SignalModule.new()
signal:connect(function(m)
	print(type(getmetatable(m))=="table" and "solved!" or "...")
end)
signal:Fire(setmetatable({},{}))

I have saves it to Roblox already, so if anyone needs it here’s the link:

2 Likes