Destroy() Can Now Replicate to Clients

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.

Very interested about this! Didn’t know that connections still stayed even after calling Destroy on the server, glad to know that’ll be different soon.


+1 support

3 Likes

This has been brought up in the past by a since-anonymized user, but never got any replies.

1 Like

I assume Destroy() is not called on characters when the player leave? Because I keep a reference to their characters and I was able to reparent their character, after they left, despite having this new setting enabled.

Since destroy can now replicate to clients which is great, how would I destroy it on the server after it’s deleted in the client?

also it’s pretty simple to make this system

Clients don’t replicate to the server. Unless the instance that it destroyed was inside their character… But in all other cases, a client destroying something won’t affect the server.

Sure, that’s definitely correct that such a check will throw a false positive on a newly created instance, and on paper that’s a problem. But the thing i have to ask is when would this actually matter? I’m having trouble thinking of a case of where you specifically need to see when an object was called via :Destroy().

Furthermore, while I understand this won’t fit every case it should fit most of them, which is a change in approach; instead of checking if the instance is destroyed yet, you can switch to a more linear design and hook onto the .Destroyed event and then run whatever behavior was meant to happen after checking if it was destroyed or not.

I will give you an example, I literally don’t like when people come at me and say that a feature is just NOT needed just because they don’t see the use case for it. When developers don’t see why it would be useful to have it is because they haven’t come across a situation where is needed.

This property in my opinion should be easy to implement and is better to have it available than the developer itself connecting to destroying and then changing a variable to true to know when the object is destroyed.


Here Are Some of The Use Cases:

  • You have a loop that uses a certain Instance, this loop runs every 60 seconds. You want to terminate this loop when the object is destroyed. (Currently you will have to check if the parent is nil which is not accurate)
  • You have a table on client full of objects that can be destroyed at any time from the server. Then you have a for loop on the client that iterates through this table and is required to check if the object is destroyed before executing some code, else just remove the object from the table. (Weak tables don’t work with Instances and I am also not willing to connect to Destroying for a bunch of objects, assume you have like 500)
  • You want to update how a Gui looks like if is not destroyed, if is destroyed then do nothing.(Currently you will have to check if the parent is nil which is not accurate)
  • Do some stuff to an object while is not destroyed, for example, you want an arrow to point at the object. You make this arrow point at it while is parented to Workspace, if not then remove, if is added back then point at it again. (If you were to check if this object is parented to nil to assume is destroyed it will stop the arrow from pointing at the object when is parented back to workspace, you might say, focasds just parent the object somewhere else, yes I can do that, but I prefer just parenting to nil).

Now I won’t make any feature request because I can’t create topics and because this is something that should have been done when Destroy() was first added.

I use the IsDestroyed method (a function I use to know if an object is destroyed which basically is a wrapper to check if is not a descendant of game) 167 times in my game:
image

That said I will really appreciate a property provided by default to know when an Instance is already destroyed.

4 Likes

I honestly thought this was already a thing. I was thinking only a few hours ago on how I could utilize this for one of my games, and now I know it will be a thing!

Oh man, I didn’t know this wasn’t already the case. That explains some memory problems I was having before

Sure, exploiters will take advantage of the ability for the server to free up some of its bandwidth. To that exploiter.

I found a bug with this new feature, previously had this bug happening when calling :Destroy() on the character on the client and we fixed it by moving the :Destroy() over to the server (should’ve done that in the first place anyways i guess)

but now that it replicates the char:Destroy() to the client the warning is back
Player:Move called, but player currently has no humanoid.

how to replicate:
disable characterautoloads and then on a server script:

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		wait(10)
		char:Destroy()
		wait(10)
		player:LoadCharacter()
	end)
	wait()
	player:LoadCharacter()
end)

it would spam the warning every 10 seconds

4 Likes

Just use a closure

task.delay(1, function()
   obj:Destroy();
end);

Someone correct me if I’m wrong but using an anonymous function for something like this in Luau is supposedly cheap compared to regular Lua. The only reason I could ever think of doing what you’re suggesting is to cut down on file size … which should not be an issue if you’re modularizing properly

You’re correct. The Luau implementation does a substantially better job of making small lambdas like that cheap. Using such a lambda will generally only incur a single memory allocation compared to it incurring several in vanilla Lua.

Awesome! The moment I first heard that this behavior existed my immediate thought was why it hadn’t already been addressed as it didn’t seem like the type of behavior that developers really depended on or knew of in the first place and I’m pretty glad that I’m not part of the team responsible for rolling out these sorts of changes as I would have definitely inadvertently squandered a lot of people’s hard work put into making custom replication. Really awesome to see you guys considering even the most obscure use cases here and a big kudos to how carefully this change is being rolled out. Great job.

I realize that this reply isn’t entirely necessary but I felt that the praise was needed.

I do.

I’m curious, would removing the upvalue and using a function argument instead have a smaller cost? (i.e. task.delay(1, function(obj) obj:Destroy() end, obj))

Yes indeed, that will allow the Luau VM to avoid any memory allocation in most cases, but it’s generally not worth the reduced readability.

1 Like