General Info
The [ChangedHistoryService] (ChangeHistoryService | Documentation - Roblox Creator Hub), responsible for undo/redo functionality in Roblox Studio, experiences issues when undoing the actions of plugins. The issue can be reproduced universally on all Roblox experiences and does not require reproduction files or system information.
Reproduction of issue
- Open any Roblox experience within Roblox.
- Run a plugin that creates or removes parts.
- Manually move a part right after the plugin does these actions.
- Undo the actions
Result (main bug)
Both the part you manually moved and the actions done by the plugin will be undone.
Main concerns
Many plugins, particularly those that manage critical and delicate information, such as its files, when users do actions, can have their actions undone unless multiple manual interactions have been done. This can lead to data loss within plugins, which can make them unstable and/or delete developer progress within the realm of the plugin.
Likely reason this happens
Its likely that ChangedHistoryService has issues with indexing the redo/undo actions once a plugin does an action. I believe it may be merging the actions done by the plugin with the manual action afterward as a single index, so that when the developer undoes them, it considers them both as the same action.
Test plugin
I have gone ahead and created this basic plugin to help you reproduce the issue.
- Copy and paste the code into a script.
- Right-click the script and select “save as local plugin.”
- Click the plugin button within the “plugins” section of Roblox named “test bug.”
- Manually move a separate part and watch it merge both actions by you and the plugin as one.
local toolbar = plugin:CreateToolbar("test bug")
local pluginButton = toolbar:CreateButton("test bug", "test bug", "rbxthumb://type=Asset&id=6810376207&w=150&h=150")
pluginButton.Click:Connect(function()
local part = Instance.new("Part")
part.Name = "bugTest"
part.Parent = workspace
part.Size = Vector3.new(5,5,5)
warn("a part has been created at 0,0,0. Please inspect and review ChangedHistoryService's behavior.")
end)
BASIC EXAMPLE
- I clicked the plugin button, creating a block by the plugin.
- I duplicated baseplate to represent a manual action.
- I pressed control Z to undo the action.
- Roblox merged these actions together as the index never increased, causing them both to be undone when I Pressed Control Z.
its highly likely that ChangedHistoryService records plugin actions, but only increases the index within ChangedHistoryService actions that are done manually by developers, causing plugin actions to share the same index as manual interactions.
SIGNIFICANT DATA LOSS
- I created many tasks using my task creator plugin. The plugins stores user data by creating folders, which gets stored within ChangedHistoryService under the same index as roblox doesnt increase the index for plugin actions
- I duplicated baseplate to represent a manual interaction.
- I pressed control Z to undo the baseplate deletion, but it also deleted all of the work I just did within my plugin.
This is an example of how this issue can significantly affect developers experiences in the realm of plugins, leading to significant data loss and progress.