Changing ObjectValue.Value to an instance all clients can see then changing it to a selectively replicated instance will cause a situation where clients that cannot see the selectively replicated instance will have an outdated value (the instance that all clients can see).
The correct behavior is that ObjectValue.Value should be nil if the current value is not known to the client. It should not keep an outdated value.
Reproduction:
- Create a place file with code that selectively replicates some object (e.g. a Part in ServerStorage) to one player. See below for some code which does this.
- Start a local server with two players (one called “Player Yes” who has the Part, and one who doesn’t called “Player No”).
- On the server, create an ObjectValue in Workspace and set its Value to the selectively replicated Part.
- Observe that Player Yes’s client can see ObjectValue.Value == Part and on Player No’s client they can see ObjectValue.Value == nil.
- Change ObjectValue.Value to some instance both clients can see, e.g. another part or model in workspace, let’s just say this is a Model.
- Observe that both players’ clients can see ObjectValue.Value == Model.
- Change ObjectValue.Value back to the selectively replicated Part.
- Observe that Player Yes’s client correctly sees ObjectValue.Value == Part, and Player No’s client incorrectly sees ObjectValue.Value == Model. The issue is that Player No is still seeing a wrong and outdated value when really they should be seeing nil.
Code
Server:
local P = Instance.new("Part")
P.Name = "SelectivePart"
P.Anchored = true
P.Parent = game.ServerStorage
local M = Instance.new("Model")
M.Parent = workspace
local R = Instance.new("RemoteEvent")
R.Parent = game.ReplicatedStorage
local O = Instance.new("ObjectValue")
O.Name = "ObjectValue"
O.Parent = workspace
local Switch = false
local function PlayerAdded(Player)
Switch = not Switch
Player:SetAttribute("Replicate", Switch)
end
game.Players.PlayerAdded:Connect(PlayerAdded)
for _, Player in game.Players:GetPlayers() do
PlayerAdded(Player)
end
R.OnServerEvent:Connect(function(Player)
local PlayerGui = Player.PlayerGui
local ScreenGui = Instance.new("ScreenGui")
ScreenGui.ResetOnSpawn = false
local OriginalParent = P.Parent
P.Parent = ScreenGui
ScreenGui.Parent = PlayerGui
R:FireClient(Player, P)
P.Parent = OriginalParent
ScreenGui:Destroy()
end)
Client:
local O = workspace:WaitForChild("ObjectValue")
O:GetPropertyChangedSignal("Value"):Connect(function()
print("ObjectValue changed to", if O.Value then O.Value:GetFullName() else nil)
end)
local R = game.ReplicatedStorage:WaitForChild("RemoteEvent")
R.OnClientEvent:Connect(function(P)
P.Parent = workspace
end)
local Player = game.Players.LocalPlayer
while Player:GetAttribute("Replicate") == nil do task.wait() end
if Player:GetAttribute("Replicate") then
R:FireServer()
end