Camera+ 3.4.3 can crash world generation / save loading due to Unity object access from async long event thread
Camera+ version: 3.4.3.0
RimWorld version: 1.6
After entering a world once, creating/loading another world can repeatedly fail with:
Exception from asynchronous event: UnityEngine.UnityException: ToString can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
[Ref A8B49FDA]
(wrapper managed-to-native) UnityEngine.Object.ToString(UnityEngine.Object)
at UnityEngine.Object.ToString () [0x00001]
at System.String.Format (System.String format, System.Object arg0) [0x00008]
at Verse.MaterialAllocator.Destroy (UnityEngine.Material material) [0x0000d]
at CameraPlus.MarkerCache.Remove (Verse.Pawn pawn) [0x00039]
at CameraPlus.MarkerCache.Clear () [0x0001e]
at CameraPlus.Caches.ClearMarkerState () [0x00023]
at CameraPlus.World_FinalizeInit_Patch.Postfix (RimWorld.Planet.World __instance) [0x0000b]
at RimWorld.Planet.World.FinalizeInit (System.Boolean fromLoad) [0x00017]
at RimWorld.Planet.WorldGenerator.GenerateWorld (...)
at RimWorld.Page_CreateWorldParams.b__20_0 ()
at Verse.LongEventHandler.RunEventFromAnotherThread (System.Action action)
It looks related to commit 3e195a2:
3e195a2
Below are advices by codex:
That commit added Caches.ClearMarkerState() to World_FinalizeInit_Patch.Postfix. In RimWorld, world generation/loading can run
World.FinalizeInit from an async long event thread. ClearMarkerState() reaches MarkerCache.Clear() -> MarkerCache.Remove() -> Verse.MaterialAllocator.Destroy(material), and MaterialAllocator.Destroy formats the Unity Material, which calls
UnityEngine.Object.ToString() off the main thread.
Possible fix: defer marker/material cache cleanup to the main thread, or avoid destroying Unity materials/textures from World.FinalizeInit when
it is running in an async long event thread.
Camera+ 3.4.3 can crash world generation / save loading due to Unity object access from async long event thread
Camera+ version: 3.4.3.0
RimWorld version: 1.6
After entering a world once, creating/loading another world can repeatedly fail with:
Exception from asynchronous event: UnityEngine.UnityException: ToString can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
[Ref A8B49FDA]
(wrapper managed-to-native) UnityEngine.Object.ToString(UnityEngine.Object)
at UnityEngine.Object.ToString () [0x00001]
at System.String.Format (System.String format, System.Object arg0) [0x00008]
at Verse.MaterialAllocator.Destroy (UnityEngine.Material material) [0x0000d]
at CameraPlus.MarkerCache.Remove (Verse.Pawn pawn) [0x00039]
at CameraPlus.MarkerCache.Clear () [0x0001e]
at CameraPlus.Caches.ClearMarkerState () [0x00023]
at CameraPlus.World_FinalizeInit_Patch.Postfix (RimWorld.Planet.World __instance) [0x0000b]
at RimWorld.Planet.World.FinalizeInit (System.Boolean fromLoad) [0x00017]
at RimWorld.Planet.WorldGenerator.GenerateWorld (...)
at RimWorld.Page_CreateWorldParams.b__20_0 ()
at Verse.LongEventHandler.RunEventFromAnotherThread (System.Action action)
It looks related to commit 3e195a2:
3e195a2
Below are advices by codex:
That commit added
Caches.ClearMarkerState()toWorld_FinalizeInit_Patch.Postfix. In RimWorld, world generation/loading can runWorld.FinalizeInitfrom an async long event thread.ClearMarkerState()reachesMarkerCache.Clear() -> MarkerCache.Remove() -> Verse.MaterialAllocator.Destroy(material), andMaterialAllocator.Destroyformats the UnityMaterial, which callsUnityEngine.Object.ToString()off the main thread.Possible fix: defer marker/material cache cleanup to the main thread, or avoid destroying Unity materials/textures from
World.FinalizeInitwhenit is running in an async long event thread.