ClientSim PlayerObject persistence writes invalid JSON for synced strings containing escaped quotes, causing DataToken.Error on the next Play Mode session
Wing_
Unity: 2022.3.22f1
VRChat SDK - Worlds: 3.10.4
Title: ClientSim corrupts PlayerObject strings containing nested JSON
Environment:
Unity 2022.3.22f1
Worlds SDK 3.10.4
Reproduction:
- Add an Udon-synced string to a PlayerObject.
- Store JSON containing another serialized JSON string:
{"outerKey":"[\"innerValue\"]"}
- Call RequestSerialization() and allow ClientSim to save the PlayerObject.
- Exit and enter Play Mode again.
- ClientSim fails while restoring the saved PlayerObject.
ClientSim saves:
"{\"outerKey\":\"[\\"innerValue\\"]\"}"
It should save:
"{\"outerKey\":\"[\\\"innerValue\\\"]\"}"
The backslash preceding each nested quote is not escaped for the additional ClientSim JSON storage layer. The malformed value is loaded as a DataToken.Error, but ClientSim then accesses it as a DataDictionary in ClientSimNetworkIdHolder.Decode() line 180
As a result, the PlayerObject is not restored and all persistence stored in it appears lost. ClientSim may subsequently overwrite the file with empty/default data.
The same nested JSON persistence seems to works correctly in the real VRChat client, so this appears to be specific to ClientSim’s local PlayerObject save/load implementation.
Trace stack:
InvalidOperationException: Attempted to access Error token as DataDictionary
VRC.SDK3.Data.DataToken.get_DataDictionary () (at <8dae6d6858f2465fad961e5d8ef394cc>:0)
VRC.SDK3.ClientSim.ClientSimNetworkIdHolder.Decode (VRC.SDK3.Data.DataList data) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Networking/ClientSimNetworkIdHolder.cs:180)
VRC.SDK3.ClientSim.ClientSimNetworkingView.Decode (VRC.SDK3.Data.DataList data) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Networking/ClientSimNetworkingView.cs:95)
VRC.SDK3.ClientSim.Persistence.ClientSimPlayerObjectStorage.Decode () (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Player/PlayerPersistence/ClientSimPlayerObjectStorage.cs:165)
VRC.SDK3.ClientSim.Persistence.ClientSimPlayerObjectStorage.OnPlayerJoined (VRC.SDK3.ClientSim.ClientSimOnPlayerJoinedEvent payload) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Player/PlayerPersistence/ClientSimPlayerObjectStorage.cs:102)
VRC.SDK3.ClientSim.ClientSimEventDispatcher.SendEvent[T] (T clientSimEvent) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Events/ClientSimEventDispatcher.cs:62)
VRC.SDK3.ClientSim.ClientSimPlayerManager.DispatchPlayerJoinedEvent (VRC.SDKBase.VRCPlayerApi player) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/System/ClientSimPlayerManager.cs:137)
VRC.SDK3.ClientSim.ClientSimPlayerManager.OnClientSimReady () (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/System/ClientSimPlayerManager.cs:129)
VRC.SDK3.ClientSim.ClientSimMain+<InitializeClientSim>d__45.MoveNext () (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/System/ClientSimMain.cs:399)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <cb81df0c49c643b1a04d9fc6ccca2433>:0)
Log In