Destroy() Can Now Replicate to Clients

Yes, it still exists even though the parent is nil because it didn’t lock the parent property.

If you don’t handle Folder Y to cleanup Part Z, the same thing I said just now.

Wouldn’t that create a memory leak for the client? Perhaps I added a client-created part into a server-created model, and the server destroys the model (but obviously not the part). Would that not cause eventual issues if the client-created part never gets cleaned up?

That is correct. Because the server never handled this, it will cause memory leaks in which this case you have to implement your own way to deal with it. I believe Roblox did this just to prevent interference with client logic.

2 Likes

Not a scalable solution! There’s already too many of these flags under workspace. There should be a separate window similar to the way beta features are enabled describing what each one does

5 Likes

Lua doesn’t exactly support OOP / classes, which is why using the colon operator exists in the first place, to automatically fill in self. Metatables are individual, and calling setmetatable just points the “object” table’s metatable to it. Since they’re individual, they have no way of knowing what table indexed their function. With the colon operator, it fills it in as the first parameter automatically, it’s just “invisible” and hidden behind self. Their implementation would probably have to mimic the colon behavior when called with ., which is a big behavior change in it’s own

I think this also solves your problem with Instance’s __namecall optimization too but please get back to me if i misunderstood your question

  • If you have no script code that references Part Z: Part Z will be garbage collected by the engine at the next opportunity, and there won’t be any issue.

  • If you have scripts that reference Part Z, especially if you connect to any events of Part Z: Part Z might get garbage collected if you’re lucky but you will have to be extra careful that you aren’t doing something that will cause a memory leak (see this post).

1 Like

The actual __namecall metamethod is only used when using namecall on userdata. Tables have the method retrieved via __index and then called as normal.

table:method(1, 2, 3) desugars to table.method(table, 1, 2, 3), where table is only evaluated once.

userdata:method(1, 2, 3) desugars (assuming mt is the userdata’s metatable) to mt.__namecall(userdata, 1, 2, 3), where the name of the method is held in an internal structure (the calling thread/coroutine) for C methods to access.

This is why userdata.method(userdata, 1, 2, 3) is slower - because that’s not what namecall usually desugars to. __index is also slower than __namecall in general because the field name has to be pushed to the Lua stack wrapped in a TValue (also, in this case its return value has to be pushed to the stack and called again).

I’m not sure why you’re trying to explain metatables to me but hopefully that clears up any misconception you thought I had.

1 Like

Very lit, This can clean up unknown memory leaks from connected events! I still wonder why Destroy doesn’t automatically clear up all references to an object. Then again pro scripters can just use a Maid class…

Just was trying to point out why they would have to use their own Luau implementation — I mean, even then, __namecall is exclusive to Instances and most primitive types, so some changes might need to have been made there. It was my own insight why @.tnavarts said that they will have to release this namecall-colonoperator-esque feature along with several other significant changes

__namecall is also used by CFrames and Vector3s (native vector type now, which come to think of it, also has namecall - maybe everything except table?), since both have namecall methods.

Edit: Yes, __namecall works on everything except tables. So theoretically primitives like string could have it as well, but string only has an __index pointing to the global string table.

Fun fact: you can implement __namecall yourself on proxies:

local proxy = newproxy(true)
local mt = getmetatable(proxy)

mt.__namecall = print

proxy:Hi('Hello world')

What do you mean by this?

2 Likes

Will edit that part of the post


I was piggybacking off of what @.tnavarts said earlier:

there’s no great way to do it without special Luau specific syntax


Neat, makes enough sense since users can’t necessarily access the C/C++ code (through Roblox scripts) which is what __namecall is supposed to have optimized access to


Interesting functionality!

Technically you can abuse existing userdata namecalls and their error messages to extract the namecall method that way.

local dummyInstance = Instance.new('Folder')
local dummyCFrame = CFrame.new()

local instanceNamecall, cframeNamecall

xpcall(
    function() dummyInstance:Hi() end,
    function() instanceNamecall = debug.info(2, 'f') end
)

xpcall(
    function() dummyCFrame:Hi() end,
    function() cframeNamecall = debug.info(2, 'f') end
)

local proxy = newproxy(true)
local mt = getmetatable(proxy)

mt.__namecall = function(self, ...)
    local success, err = pcall(instanceNamecall, dummyInstance)
    local success2, err2 = pcall(cframeNamecall, dummyCFrame)
    local instanceGood = not success and string.find(err, 'is not a valid member of', 1, true)
    local cframeGood = not success2 and string.find(err2, 'is not a valid member of', 1, true)
    local msg = if instanceGood then err elseif cframeGood then err2 else nil

    if not msg then
        error('internal error fetching namecall method', 2)
    end
 
    local method = string.match(msg, '%S+')

    print('Namecall method:', method)
end

proxy:Hi()
proxy:Hello()
proxy:IsA()
proxy:ToObjectSpace()
proxy:NamecallMethod()

But who would do that? Right…?

2 Likes

Don’t worry about it, it’s all in the name of science! Roblox probably doesn’t expect it’s users to dig this deep into Lua’s more technical functions anyways, since they’ve already done most of the technical stuff themselves

1 Like

Honestly I didn’t know that it didn’t replicate to the client, I am glad that you guys added it though because I can see myself getting extremely frustrated at problems caused by it not replicating.

Yeah, I realize this. I’m just saying it should’ve worked this way from the very beginning.

1 Like

Does game.Debris:AddItem work the same way as destroy (as in not replicating to the client)?

Will there ever be an update where we can tell the engine that the client shouldn’t replicate / the server shouldn’t listen to replications of properties for certain instances? I.E., the physics simulating client can only replicate properties for BaseParts etc? It’s seem rather ridiculous the client can delete server-scripts if it’s in their character model.

1 Like

I think it would only be benefitical to exploiters.

1 Like

Man, This update sounds awesome since I think it will actually save client memory wich will make physics based games faster since those ussually spawn in stuff and need to be cleared once they are no longer used.

In what way? Read my post carefuly.