Hello Developers!
In May 2022, we attempted to release a fix for De-Sync with Instance Replication. Unfortunately, we discovered that the fix had some bad interactions with other areas of the Engine, and rolled it back.
We have gone through and fixed these issues, and are ready to release the feature!
Like before, we will release this change on Studio first, and then globally for all experiences over the next week. Please test this behavior out on your experience and tell us what you think!
[Update] November 3, 2022
Previous DevForum Post:
We will soon roll out a change to replication: when a Server/Client receives an Instance, it will remove all of its replicated children. This will correct various DataModel de-sync bugs.
What does this mean?
Letâs go through an example!
When an Instance gets added to the DataModel, we expect it to replicate as normal. For example, if the server adds a part named âPartAâ to Workspace, we expect that to replicate to clients, so everyone sees:
Workspace
â PartA
Similarly, if another Instance (say, folder) gets added under PartA, we expect everyone to see that too:
Workspace
â PartA
â Folder
Now, suppose the server does the following in a script:
local partA = workspace.PartA
local folder = partA.Folder
-- set parent of PartA to nil, removing it from the DataModel
partA.Parent = nil
-- set the parent of Folder to nil, removing it from under PartA
folder.Parent = nil
-- set the parent of PartA back to Workspace
partA.Parent = workspace
After this script runs, we would expect everyone to see:
Workspace
â PartA
This is not the case. Letâs go over how it works in its current form.
Current Behavior
Suppose the client had created a LocalScript like so:
local partA = workspace.PartA
print(partA.Name)
When the Server removes PartA from the DataModel, the client will remove PartA too. However, because of the lingering reference to PartA in the LocalScript, it wonât delete PartA and its subtree from memory! So, PartA and PartA.Folder will be floating along somewhere in the Clientâs Ether of Memoryâ˘ď¸.
So now, when the server brings PartA back under Workspace, the client will grab the PartA that it already has in memory, and parent PartA to workspace. The problem is, folder comes along for the ride, resulting in the server seeing:
Workspace
â PartA
While the client sees this:
Workspace
â PartA
â Folder
New Behavior
The change we are releasing will prevent de-syncs of DataModels by having the client remove all children of PartA upon receiving it from the server.
To get more specific, when the server adds PartA back to Workspace, the client will:
-
Remove all children from PartA (remove folder)
-
All relevant signals like ChildRemoved signal will still fire
-
Parent PartA to the Workspace
-
Children of PartA that do still exist on the Server will replicate to the Client again
Resulting in both the server and client having the consistent view:
Workspace
â PartA
What about Instances LocalScripts created and added that the client never replicates? As these Instances are not known by the Server, we believe it doesnât make sense for the server to modify them. By this logic, we decided that the new behavior will ignore local, unreplicated Instances.
However, if the client has replicated the locally created instance to the server (e.g. a Tool weld), that instance is eligible for removal with this new behavior.
Thanks so much and let us know if you have any feedback or questions!