[Update] May 25, 2022
Hello Developers,
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.
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!
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!