[Plugin] How would I destroy something that can be undo without using Instance:Destroy()?

In the plugin, I have a set hotkey that would destroy something if I pressed a hotkey. Imagine this function:

function destroyInst(inst)
 inst:Destroy()
end

But then, you can’t undo your change. There is a plugin called Building Tools by F3X. I cannot tell what function they used to actually destroy something and being able to undo the change. Any guesses?

3 Likes

You would want to use ChangeHistoryService for this

2 Likes

Wouldn’t that not allow you to undo? I can’t do Ctrl + Z to undo any changes from the Plugin.

1 Like

ChangeHistoryService is exactly what you want. It allows you to implement custom “waypoints” for Ctrl+Z.

SetWaypoint documentation shows a simple example implementing it.

2 Likes

You can store it in somewhere else, like serverstorage
Or you can clone a object in serverstorage and destroy it
it matters about what type of game you want to create

1 Like

He is creating a plugin, not a game. Read the post.

As the above said, ChangeHistoryService allows you to set waypoints which give plugins access to undo and redo functionality.

1 Like

Sorry about that, I should read much carefully from later on
(This is quite irrelevent to the question… but for a apologize)

1 Like

You can write something like this:

function destroyInst(inst)
 inst.Parent = nil
end
function AddInst(inst)
 inst.Parent = workspace
end

If you don’t care about using deprecated stuff, use :Remove() then. But I don’t recommend it too much.

2 Likes
local ChangeHistoryService = game:GetService("ChangeHistoryService") -- Gets ChangeHistoryService
function destroyInst(inst)
     inst:Destroy()
     ChangeHistoryService:SetWaypoint("Destroyed "..inst.Name) -- Sets a waypoint
end
1 Like

Realizing that once an instance has been destroyed, it cannot be undone. However, making it nil is a good way and have the ability to undo itself. In this case, I now found the perfect solution.

1 Like

You should be able to use ChangeHistoryService to set an undo point, like three replies have said. The Building Tools By F3X Plugin probably uses ChangeHistoryService to allow users to undo (and subsequently, redo) their changes.

CHS:SetWaypoint("Undo waypoint")
Ins:Destroy()
CHS:SetWaypoint("Redo waypoint")
1 Like

Actually try to do this yourself. It won’t let you undo since the parent property of the instance is locked.

2 Likes

Wait, since when was that the case? I’ll try this tomorrow but I swear CHS could have been used to undo deletions (at least in command lines I used it as a safe guard when I was mass deleting certain instances, and it seemed to work for deletions).

1 Like

Deleting with the delete key just sets the parent of the thing you deleted to nil, as far as I can tell.

2 Likes

Nono, I meant I would call CHS:SetWaypoint, followed by some sort of loop or other logic to :Destroy a certain group of parts, followed by another CHS:SetWaypoint, and the undo and redo points worked fine

1 Like

That hasn’t been the case for as long as I can remember.

Anyway, if you need concrete proof that ChangeHistoryService can’t undo parts that were :Destroy()ed, run the following snippet on an empty baseplate in the command bar:

local ChangeHistoryService = game:GetService("ChangeHistoryService")

local part = Instance.new("Part")
part.Parent = workspace
ChangeHistoryService:SetWaypoint("blah")
part:Destroy()
ChangeHistoryService:SetWaypoint("blah")

If you try to undo with Ctrl + Z, the following message will appear in the output:

22:32:51.071 - The Parent property of Part is locked, current parent: NULL, new parent Workspace
2 Likes

I might try that tomorrow but I otherwise belive you, I just swear that this used to work.

Huh, guess the other solutions above work.

1 Like

Fine. I’ll see how the ChangeHistoryService works. I’ve never heard of it quite before. Yet, this is just my first time making a plugin. So, I’ll see how every one of your solutions would solve. :slight_smile:

Hey there, I know this topic is old, but if anyone happens to find it, looking for a solution, my solution is to set the parent to nil.

This will hide the object, making it look like it’s been destroyed, and still be accessible, allowing you to undo/redo.

The downside? Probably memory leaks. Since the instance isn’t destroyed, but instead parented to nil, the instance still exists and is stored in nil. So using the plugin too much will cause memory usage to increase. Taken to an extreme, studio might crash (Unless the user is using an autoclicker, this shouldn’t happen). Have in mind that I haven’t verified this leak, and it’s just a hypothesis.

Something that I have verified though, is that this won’t be a problem for published games. When saving the file, the instance completely disappears, it’ll be nowhere to be found in the file, so it’ll not persist through different studio sessions, and these instances will not be in the published game either. It’ll sweep itself away :broom:

So if you want to have undo/redo compatibility, just set the parent to nil.

EDIT:
So I tested around, and I didn’t notice the memory going up. The only thing I did notice was CPU usage going up, but it immediately went down after I stopped clicking.

2 Likes