I’m working on a custom environment. I want to proxy the method, workspace::GetChildren(), which I do successfully via the below code:
local oldworkspace = workspace
local env = getfenv()
local Workspace = setmetatable({}, {
__index = function(self, i)
if i == "GetChildren" then
return function(self)
print("Running through proxied function!")
end
end
local index = oldworkspace[i]
if type(index) == "function" then
return setmetatable({}, {
__call = function(self, ...)
index(oldworkspace, table.unpack({...}))
end,
})
end
return index
end,
})
env.workspace = Workspace
setfenv(1, env)
workspace:GetChildren() --// Running through proxied function!
However, an issue arises. How can I let users using my environment reliably set the Parent property of instances to my own Workspace metatable?
For example, when running the below code in my custom environment,
local Part = Instance.new("Part")
Part.Parent = workspace
an error occurs: invalid argument #3 (Instance expected, got table)
My goal is to let users set the Parent property of any instance to my custom Workspace metatable - and make it actually parent to the real Workspace. How can I achieve this, without changing any syntax on the user end?
There is no way to do this, because there are no ways to overwrite how a property is set. You would have to add a key for the real workspace (i.e. Part.Parent = workspace.Real)
Just don’t do this. You lose performance, type checking, autocomplete and syntax highlighting when try to override Roblox API. Just have a normal GetChildren function that applies what you want onto the normal workspace/GetChildren.
Since there’s “no” way to do this a normal way, I’m going to have to create a metatable/proxy for every new Instance mentioned in the script, and set a __newindex metamethod (for “Parent”). This means proxying Instance.new, variables, and more. I made this post to see if there was a better, less “hacky” way of approaching this.
I have to, haha. No reason I’d want to do this if it wasn’t necessary!
All I can say is that I’m making a custom environment, and I want to create my own workspace::GetChildren() method to return what I want. I also want it to be possible to use regular syntax to set the Parent of instances to workspace.
Map = {}
Map.__index = Map
function Map.new(mapModel)
local self = setmetatable({}, Map)
self.Instance = mapModel
return self
end
function Map:GetChildren()
-- Here u can add what ever you would like
-- Generic example
return self.Instance:GetChildren()
end
Then u can easily create new worlds like this
local MapModule = require(wtv.Map)
local newMap = MapModule.new()