Plugin Ability to "freeze" ChangeHistoryService

As a Roblox developer, it is impossible to disable ChangeHistoryService without it deleting previous waypoints.

Currently I am making a plugin which modifies the user’s place and it takes some time for that modification to be done, for the plugin to work ideally, the user shouldn’t touch anything during that process, including undo-ing and redo-ing stuff.

So I want to “freeze” ChangeHistoryService, meaning that no other script can create a waypoint, and the user can’t undo/redo or add new waypoints, if an unexpected error occurs during the plugin’s process, I want to be able to “unfreeze” ChangeHistoryService and undo the changes.

Currently there is only one option similar to this available and its ChangeHistoryService:SetEnabled(), however unfortunately that deletes all previous waypoints, and once I reenable ChangeHistoryService, I can’t undo the said changes.


I suggest the following APIs to be added to ChangeHistoryService;

ChangeHistoryService:Freeze(status: boolean)

Depending on the status passed, it affects the ability to perform undos, redos, waypoints sets or resets and keeps the previous waypoints.

ChangeHistoryService:GetFrozenStatus(): boolean

Returns whether ChangeHistoryService is currently frozen using the ChangeHistoryService:Freeze() method.

Additionally some API changes could also be made to the already existing APIs, mainly :GetCanUndo() and :GetCanRedo(), which, if the service is frozen should return their first value as false, but also return the last action as the second value.

4 Likes

Thank you for your suggestion. We in the Studio collaboration / version control team have been working on solving issues like the ones you are facing for a while, and something similar came up in our early architecture meetings. There are many problems with what you suggest that we ran into. The hardest issues are what happens with a buggy plugin that freezes but doesn’t unfreeze the service, and how do you deal with collaboration over Team Create.

We are working on an approach for later this year that should solve the kinds of issues you are having with long-running plugins. The CHS itself will soon deprecate the Waypoint concept and use a Recording concept instead. Recordings include a beginning and a commit (or a cancel). The final form of a recording will be context aware - no undo / redo or replication operations to the main DataModel will affect any recordings in progress.

Phase 1 of this process (the API) will be available soon - it won’t help your scenario much yet, but phase 2 (separate contexts + restriction to use the API before making changes) is scheduled for later this year, and it will make your long-running plugin able to operate pseudio-independently of any undo / redo / collaborator changes overlapping with your changes.

A good deal of support infrastructure needs to be changed to make this magic happen, so please be patient.

7 Likes

Thank you for the information,

Collaboration over Team Create didn’t cross my mind not even once while making this post, now that you mention it, there are quite some problems that need to be solved before this becomes a reality, however…

I might be asking pointless questions over here, since I am not exactly sure how these methods are implemented internally, but isn’t that already an issue with plugins and the ChangeHistoryService:SetEnabled() method?

I’m looking forward to Phase 2!

It’s a good point, and I looked up the origins of ChangeHistoryService:SetEnabled(state: boolean).

It is ancient, and likely a vestige left behind from a simpler time when Roblox.exe was both your game client and your editor (or so the sages told me once upon a time). I will consult with said sages about whether it makes sense to remove access to this state from plugins.

2 Likes

I urge you not to remove plugin access to ChangeHistoryService:SetEnabled() until an alternative is released (in this case, until Phase 2 is released).

It would be better to deprecate the method than entirely removing plugin access, as some plugins probably rely on it even though it is an ancient method. Once the Phase 2 API is released, you could probably even redirect ChangeHistoryService:SetEnabled() calls to the new API equivalent.

I believe that ChangeHistoryService:SetEnabled() has some use cases to this day, if :SetEnabled() didn’t remove any previous waypoints I probably wouldn’t even make this post to begin with.

1 Like

I agree. Don’t worry about it.

1 Like