diff --git a/SVSim.BattleEngine/Shim/UnityEngine/UnityShim.cs b/SVSim.BattleEngine/Shim/UnityEngine/UnityShim.cs index 40fa4b9..1d3a2ae 100644 --- a/SVSim.BattleEngine/Shim/UnityEngine/UnityShim.cs +++ b/SVSim.BattleEngine/Shim/UnityEngine/UnityShim.cs @@ -225,6 +225,10 @@ namespace UnityEngine var fresh = new System.Collections.Concurrent.ConcurrentDictionary(); map = System.Threading.Interlocked.CompareExchange(ref _components, fresh, null) ?? fresh; } + // GetOrAdd may invoke the factory more than once under contention; only one result wins. + // Safe here: the discarded instance has its _go set to `this` (private write to a soon- + // unreachable object) and WireComponentFields only assigns to the new tree's own private + // fields. The shared _noopViewMaterial sentinel below is read-only. No global state leaks. return map.GetOrAdd(t, ty => { object inst;