Destroy() Can Now Replicate to Clients

Yup, exactly!

Please keep in mind that if you have, say, an Instance ReplicatedStorage.X, and you set X.parent = ServerStorage on the Server, then the Server will replicate X.parent = nil to the Client, so you have to be ready for that.

2 Likes

I assume those who clone parts they need like ReplicatedStorage.X:Clone() would have a detached instance? So cleanup on X in replicated storage wouldn’t affect the copies of X made on the client? Only direct references would be affected?

1 Like

That sounds a little spooky so I might opt for the cloning method for a clean detachment. Thanks for the tips!

3 Likes

Yes, exactly! Clones are totally separate instances from the original.

3 Likes

Hey, I’d like to know how exactly does the Debris:AddItem() keeps track of the lifetime? does it simply use the deprecated wait or delay function?
so would something like this task.delay(1, game.Destroy, instance) be a better alternative? assuming that we’re sure that instance exists

2 Likes

If you want predictable timing you should very much be using something like task.delay. The contract of the Debris service is that it may Destroy any number of things you give it earlier than the specified delay in order to maintain the performance level of the game. I.e.: “Cleaning up debris”.

Being an old service from way back in the early days of Roblox, it actually uses an entirely different mechanism than either delay or task.delay.

10 Likes

This is incredibly important advice and should really be documented somewhere.

6 Likes

Nice to see some QoL updates!
Keep up the amazing work @Roblox!

1 Like

Will there ever be a way to schedule a namecall directly, without the overhead of wrapping it in a Lua function? task.delay(1, instance.Destroy, instance) feels very bad.

1 Like

That’s not accurate at all, in fact, that’s the old way of checking and detecting when an object got destroyed. If you create a new Instance, it will be parented to nil by default, we cannot assume that the object is destroyed because is parented to nil. For example:

local Part = Instance.new("Part")
if Part.Parent == nil then
      print("Is destroyed!") --> This is really inaccurate.
end

Part.Parent = workspace
Part.Parent = nil
if Part.Parent == nil then
      print("Is destroyed!") --> This is really inaccurate, the part is not destroyed at all, it was just removed from workspace and parented to nil.
end
Part.Parent = workspace

For this reason, I said we needed a property that sets to true when we call Destroy.

2 Likes

Maybe far in the future. We gave this some though when working on the task library and there’s no great way to do it without special Luau specific syntax so if this does come it will come alongside some significant larger Luau feature.

3 Likes

Could you elaborate on why this is? Does the namecall optimization only work when the call site is generated by the Luau compiler? Or do you just mean a generic way to convert a “namecall method” into a closure that can be spawned normally through task (without incurring the cost of __index)?

1 Like

Is there a difference between “removed” and “destroyed,” because if it is removed on the client, than it would be doing its job, right?

Destroyed means you can’t parent it back to the game, removed means you can.

Here,
destroyed means parent = nil, parent gets locked, connections get cleaned up
removed means parent = nil

so the difference is that if you just remove an Instance, i.e. set it’s parent to nil, all of its connections are still there, and the parent is not locked so you can reparent it down the line.

Documentation for Destroy() here: Instance:Destroy

4 Likes

Oh, so if its parent is nil than it didn’t appear anywhere on screen or in game right?

If an Instance’s parent is nil, then you won’t see it in the game. It could still influence what you see in the game though, via connections it may have.

2 Likes

Sorry if this was already asked but…

Server Workspace
→ Folder X --> Server Script destroys this
  → Folder Y

Client Workspace
→ Folder X
  → Folder Y
    → Part Z --> A LocalScript has created this

What happens to Part Z? You say it won’t be destroyed, so does that mean it will exist despite its parent being nil? What if I don’t handle Folder Y with Destroying to cleanup Part Z?

Please read the post fully before you said that.

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.