diff --git a/com.unity.netcode.gameobjects/Components.meta b/com.unity.netcode.gameobjects/Components.meta
new file mode 100644
index 0000000000..d4eb0dae79
--- /dev/null
+++ b/com.unity.netcode.gameobjects/Components.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8b267eb841a574dc083ac248a95d4443
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConfig.cs b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConfig.cs
index 00e7719e4a..741dc16670 100644
--- a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConfig.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConfig.cs
@@ -342,8 +342,8 @@ public ulong GetConfig(bool cache = true)
                 {
                     var sortedDictionary = Prefabs.NetworkPrefabOverrideLinks.OrderBy(x => x.Key);
                     foreach (var sortedEntry in sortedDictionary)
-
                     {
+                        Debug.Log($"[NetworkConfig] - GetConfig - [{sortedEntry.Key}={sortedEntry.Value.Prefab}]");
                         writer.WriteValueSafe(sortedEntry.Key);
                     }
                 }
diff --git a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs
index 6e801f5b61..e438426758 100644
--- a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using TrollKing.Core;
 using UnityEngine;
 
 namespace Unity.Netcode
@@ -13,6 +14,8 @@ namespace Unity.Netcode
     [Serializable]
     public class NetworkPrefabs
     {
+        private static readonly NetworkLogScope k_Log = new NetworkLogScope(nameof(NetworkPrefabs));
+
         /// 
         /// Edit-time scripted object containing a list of NetworkPrefabs.
         /// 
@@ -52,6 +55,7 @@ public class NetworkPrefabs
 
         private void AddTriggeredByNetworkPrefabList(NetworkPrefab networkPrefab)
         {
+            k_Log.Debug(() => $"NetworkPrefabs AddTriggeredByNetworkPrefabList [networkPrefab={networkPrefab}]");
             if (AddPrefabRegistration(networkPrefab))
             {
                 // Don't add this to m_RuntimeAddedPrefabs
@@ -62,6 +66,7 @@ private void AddTriggeredByNetworkPrefabList(NetworkPrefab networkPrefab)
 
         private void RemoveTriggeredByNetworkPrefabList(NetworkPrefab networkPrefab)
         {
+            k_Log.Debug(() => $"NetworkPrefabs RemoveTriggeredByNetworkPrefabList [networkPrefab={networkPrefab}]");
             m_Prefabs.Remove(networkPrefab);
         }
 
@@ -93,6 +98,7 @@ internal void Shutdown()
         /// When true, logs warnings about invalid prefabs that are removed during initialization
         public void Initialize(bool warnInvalid = true)
         {
+            k_Log.Debug(() => $"NetworkPrefabs Initialize [warnInvalid={warnInvalid}]");
             m_Prefabs.Clear();
             foreach (var list in NetworkPrefabsLists)
             {
@@ -111,6 +117,8 @@ public void Initialize(bool warnInvalid = true)
                 {
                     foreach (var networkPrefab in list.PrefabList)
                     {
+                        var netObj = networkPrefab.Prefab.GetComponent();
+                        k_Log.Debug(() => $"NetworkPrefabs Add networkPrefab [networkPrefab={networkPrefab}] [prefab={networkPrefab.Prefab}] [prefabHash={netObj.PrefabIdHash}] [globalHash={netObj.GlobalObjectIdHash}]");
                         prefabs.Add(networkPrefab);
                     }
                 }
@@ -288,9 +296,19 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab)
             {
                 return false;
             }
+
+            var netObj = networkPrefab.Prefab.GetComponent();
+            if (netObj)
+            {
+                k_Log.Debug(() => $"NetworkPrefabs AddPrefabRegistration [prefab={networkPrefab.Prefab.name}] [networkPrefab={networkPrefab}] [hash={netObj.PrefabIdHash}] [global={netObj.GlobalObjectIdHash}]");
+            }
+
+
+
             // Safeguard validation check since this method is called from outside of NetworkConfig and we can't control what's passed in.
             if (!networkPrefab.Validate())
             {
+                Debug.LogError($"NetworkPrefabs AddPrefabRegistration INVALID [networkPrefab={networkPrefab}]");
                 return false;
             }
 
@@ -303,7 +321,7 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab)
                 var networkObject = networkPrefab.Prefab.GetComponent();
 
                 // This should never happen, but in the case it somehow does log an error and remove the duplicate entry
-                Debug.LogError($"{nameof(NetworkPrefab)} ({networkObject.name}) has a duplicate {nameof(NetworkObject.GlobalObjectIdHash)} source entry value of: {source}!");
+                Debug.LogError($"NetworkPrefabs {nameof(NetworkPrefab)} ({networkObject.name}) has a duplicate {nameof(NetworkObject.GlobalObjectIdHash)} source entry value of: {source}!");
                 return false;
             }
 
@@ -311,6 +329,7 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab)
             if (networkPrefab.Override == NetworkPrefabOverride.None)
             {
                 NetworkPrefabOverrideLinks.Add(source, networkPrefab);
+                k_Log.Debug(() => $"NetworkPrefabs AddPrefabRegistration NetworkPrefabOverrideLinks [prefab={networkPrefab.Prefab.name}] [source={source}] [networkPrefab={networkPrefab}]");
                 return true;
             }
 
diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkLogScope.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkLogScope.cs
new file mode 100644
index 0000000000..458c21c899
--- /dev/null
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkLogScope.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace TrollKing.Core
+{
+    public enum NetworkLoggingLevel
+    {
+        Debug,
+        Info,
+        Warn,
+        Error,
+        Exception,
+        None
+    }
+
+    public class NetworkLogScope
+    {
+        private readonly string m_LoggerName;
+        private readonly NetworkLoggingLevel m_Level = NetworkLoggingLevel.Info;
+
+        public NetworkLogScope(string logName, NetworkLoggingLevel logLevel = NetworkLoggingLevel.Info)
+        {
+            m_LoggerName = logName;
+            m_Level = logLevel;
+        }
+
+        public NetworkLoggingLevel GetLevel()
+        {
+            return m_Level;
+        }
+
+        public void Log(Func stringProvider, NetworkLoggingLevel logLevel = NetworkLoggingLevel.Info)
+        {
+            if (logLevel >= m_Level)
+            {
+                string logString = stringProvider.Invoke();
+                DateTime time = DateTime.Now;
+                var shortTime = time.ToString("T");
+
+                switch (logLevel)
+                {
+                    case NetworkLoggingLevel.Debug:
+                        UnityEngine.Debug.Log($"[{shortTime}][DEBUG][{m_LoggerName}] {logString}");
+                        break;
+                    case NetworkLoggingLevel.Info:
+                        UnityEngine.Debug.Log($"[{shortTime}][INFO][{m_LoggerName}] {logString}");
+                        break;
+                    case NetworkLoggingLevel.Warn:
+                        UnityEngine.Debug.LogWarning($"[{shortTime}][WARN][{m_LoggerName}] {logString}");
+                        break;
+                    case NetworkLoggingLevel.Error:
+                        UnityEngine.Debug.LogError($"[{shortTime}][ERROR][{m_LoggerName}] {logString}");
+                        break;
+                    case NetworkLoggingLevel.Exception:
+                        UnityEngine.Debug.LogError($"[{shortTime}][EXCEPTION][{m_LoggerName}] {logString}");
+                        break;
+                    default:
+                        throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null);
+                }
+            }
+        }
+
+        public void Debug(Func logString)
+        {
+            Log(logString, NetworkLoggingLevel.Debug);
+        }
+
+        public void Info(Func logString)
+        {
+            Log(logString, NetworkLoggingLevel.Info);
+        }
+
+        public void Warning(Func logString)
+        {
+            Log(logString, NetworkLoggingLevel.Warn);
+        }
+
+        public void LogWarning(Func logString)
+        {
+            Log(logString, NetworkLoggingLevel.Warn);
+        }
+
+        public void Error(Func logString)
+        {
+            Log(logString, NetworkLoggingLevel.Error);
+        }
+
+        public void LogError(Func logString)
+        {
+            Log(logString, NetworkLoggingLevel.Error);
+        }
+
+        public void LogException(Exception e)
+        {
+            UnityEngine.Debug.LogException(e);
+        }
+
+        public void LogError(Exception e)
+        {
+            UnityEngine.Debug.LogError($"[{m_LoggerName}] {e}");
+            UnityEngine.Debug.LogException(e);
+        }
+    }
+
+    public static class NetworkGameObjectUtility
+    {
+        private static readonly NetworkLogScope Log = new NetworkLogScope(nameof(NetworkGameObjectUtility));
+
+        private static string NetworkGetScenePathRecursive(Transform go, string path)
+        {
+            if (go.parent == null)
+            {
+                return $"{go.gameObject.scene.name}:{go.name}:{path}";
+            }
+
+            return NetworkGetScenePathRecursive(go.parent, $"{go.name}:{path}");
+        }
+
+        // Depth first, we are going all the way down each leg
+        public static void NetworkGetAllHierarchyChildrenRecursive(this GameObject source, ref Queue queue)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            int children = source.transform.childCount;
+            for (int i = 0; i < children; i++)
+            {
+                var child = source.transform.GetChild(i);
+                var go = child.gameObject;
+                Log.Debug(() => $"AddingHierarchyChild {go}");
+                queue.Enqueue(go);
+                NetworkGetAllHierarchyChildrenRecursive(go, ref queue);
+            }
+        }
+
+        public static Queue NetworkGetAllHierarchyChildren(this GameObject root)
+        {
+            var retVal = new Queue();
+            if (root == null)
+            {
+                return retVal;
+            }
+            Log.Debug(() => $"AddingHierarchyParent {root}");
+            retVal.Enqueue(root);
+            root.NetworkGetAllHierarchyChildrenRecursive(ref retVal);
+            return retVal;
+        }
+
+        public static string NetworkGetScenePath(this GameObject go)
+        {
+            return NetworkGetScenePath(go.transform);
+        }
+
+        public static string NetworkGetScenePath(this Transform go)
+        {
+            return NetworkGetScenePathRecursive(go, "");
+        }
+
+        public static string NetworkGetSceneName(this GameObject go)
+        {
+            return go.scene.name;
+        }
+
+        public static bool NetworkTryGetComponentInParent(this GameObject go, out T comp)
+        {
+            var parent = go.transform;
+            while (parent != null && parent.parent != parent)
+            {
+                if (parent.TryGetComponent(out comp))
+                {
+                    return true;
+                }
+                parent = parent.parent;
+            }
+
+            comp = default;
+            return false;
+        }
+    }
+}
diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkLogScope.cs.meta b/com.unity.netcode.gameobjects/Runtime/Core/NetworkLogScope.cs.meta
new file mode 100644
index 0000000000..ea3fdf85eb
--- /dev/null
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkLogScope.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 3b83aae632414713b8843141e3cea71b
+timeCreated: 1695872236
\ No newline at end of file
diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
index f0e388d72e..4838aae9e1 100644
--- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
@@ -1090,7 +1090,7 @@ public int MaximumFragmentedMessageSize
             get => MessageManager.FragmentedMessageMaxSize;
         }
 
-        internal void Initialize(bool server)
+        public virtual void Initialize(bool server)
         {
 #if DEVELOPMENT_BUILD || UNITY_EDITOR
             if (!DisableNotOptimizedSerializedType)
diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs
index 5f60e748be..ea1f8856b2 100644
--- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs
@@ -61,6 +61,7 @@ public enum NetworkUpdateStage : byte
         PostScriptLateUpdate = 8,
         /// 
         /// Updated after the Monobehaviour.LateUpdate for all components is invoked
+        /// and all rendering is complete
         /// 
         PostLateUpdate = 7
     }
@@ -74,12 +75,24 @@ public static class NetworkUpdateLoop
         private static Dictionary s_UpdateSystem_Arrays;
         private const int k_UpdateSystem_InitialArrayCapacity = 1024;
 
+        private static NetworkUpdateStage[] _CACHED_ENUM = null;
+
+        public static NetworkUpdateStage[] GetNetworkUpdateStageEnumValues()
+        {
+            if (_CACHED_ENUM == null)
+            {
+                _CACHED_ENUM = (NetworkUpdateStage[])Enum.GetValues(typeof(NetworkUpdateStage));
+            }
+
+            return _CACHED_ENUM;
+        }
+
         static NetworkUpdateLoop()
         {
             s_UpdateSystem_Sets = new Dictionary>();
             s_UpdateSystem_Arrays = new Dictionary();
 
-            foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
+            foreach (NetworkUpdateStage updateStage in GetNetworkUpdateStageEnumValues())
             {
                 s_UpdateSystem_Sets.Add(updateStage, new HashSet());
                 s_UpdateSystem_Arrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystem_InitialArrayCapacity]);
@@ -92,7 +105,7 @@ static NetworkUpdateLoop()
         /// The  implementation to register for all network updates
         public static void RegisterAllNetworkUpdates(this INetworkUpdateSystem updateSystem)
         {
-            foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
+            foreach (NetworkUpdateStage updateStage in GetNetworkUpdateStageEnumValues())
             {
                 RegisterNetworkUpdate(updateSystem, updateStage);
             }
@@ -136,7 +149,7 @@ public static void RegisterNetworkUpdate(this INetworkUpdateSystem updateSystem,
         /// The  implementation to deregister from all network updates
         public static void UnregisterAllNetworkUpdates(this INetworkUpdateSystem updateSystem)
         {
-            foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
+            foreach (NetworkUpdateStage updateStage in GetNetworkUpdateStageEnumValues())
             {
                 UnregisterNetworkUpdate(updateSystem, updateStage);
             }
diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs
index 11aa4f35bc..465ec4648d 100644
--- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs
@@ -143,7 +143,7 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int
                 {
                     if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                     {
-                        NetworkLog.LogWarning($"{nameof(NetworkConfig)} mismatch. The configuration between the server and client does not match");
+                        NetworkLog.LogWarning($"{nameof(NetworkConfig)} mismatch. IncomingHash=[{ConfigHash}] OurHash=[{networkManager.NetworkConfig.GetConfig()}] The configuration between the server and client does not match");
                     }
 
                     networkManager.DisconnectClient(context.SenderId);
diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs
index 8db084cd7d..e8d976faf8 100644
--- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs
@@ -188,6 +188,7 @@ public void Serialize(FastBufferWriter writer, int targetVersion)
 
                 var startingSize = writer.Length;
                 var networkVariable = NetworkBehaviour.NetworkVariableFields[i];
+
                 var shouldWrite = networkVariable.IsDirty() &&
                     networkVariable.CanClientRead(TargetClientId) &&
                     (networkManager.IsServer || networkVariable.CanClientWrite(networkManager.LocalClientId)) &&
diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs
index 97fbeabc72..b2f26296aa 100644
--- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs
+++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs
@@ -580,7 +580,8 @@ public void RemoveAt(int index)
             // check write permissions
             if (!CanClientWrite(m_NetworkManager.LocalClientId))
             {
-                throw new InvalidOperationException("Client is not allowed to write to this NetworkList");
+                LogWritePermissionError();
+                return;
             }
 
             var value = m_List[index];
diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/DefaultSceneManagerHandler.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/DefaultSceneManagerHandler.cs
index 01bdff807f..2340327262 100644
--- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/DefaultSceneManagerHandler.cs
+++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/DefaultSceneManagerHandler.cs
@@ -1,6 +1,10 @@
 using System;
 using System.Collections.Generic;
+using TrollKing.Core;
 using UnityEngine;
+using UnityEngine.AddressableAssets;
+using UnityEngine.ResourceManagement.AsyncOperations;
+using UnityEngine.ResourceManagement.ResourceProviders;
 using UnityEngine.SceneManagement;
 
 
@@ -11,6 +15,8 @@ namespace Unity.Netcode
     /// 
     internal class DefaultSceneManagerHandler : ISceneManagerHandler
     {
+        private static NetworkLogScope s_Log = new NetworkLogScope(nameof(DefaultSceneManagerHandler));
+
         private Scene m_InvalidScene = new Scene();
 
         internal struct SceneEntry
@@ -22,18 +28,55 @@ internal struct SceneEntry
 
         internal Dictionary> SceneNameToSceneHandles = new Dictionary>();
 
-        public AsyncOperation LoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress)
+        public AsyncOperationHandle LoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress)
         {
-            var operation = SceneManager.LoadSceneAsync(sceneName, loadSceneMode);
-            sceneEventProgress.SetAsyncOperation(operation);
+            s_Log.Info(() => $"Loading scene '{sceneName}'...");
+            AsyncOperationHandle operation = default;
+            if (loadSceneMode == LoadSceneMode.Single)
+            {
+                operation = Addressables.LoadSceneAsync(sceneName, LoadSceneMode.Additive, false);
+                // Handle the async load
+                operation.Completed += handle =>
+                {
+                    var sceneInstance = handle.Result;
+                    var current = SceneManager.GetActiveScene();
+                    var async = sceneInstance.ActivateAsync();
+                    async.completed += asyncOperation =>
+                    {
+                        var scene = sceneInstance.Scene;
+                        SceneManager.SetActiveScene(scene);
+                        SceneManager.UnloadSceneAsync(current);
+                    };
+
+                };
+                sceneEventProgress.SetAsyncOperation(operation);
+            }
+            else
+            {
+                operation = Addressables.LoadSceneAsync(sceneName, loadSceneMode);
+                sceneEventProgress.SetAsyncOperation(operation);
+            }
+
             return operation;
         }
 
-        public AsyncOperation UnloadSceneAsync(Scene scene, SceneEventProgress sceneEventProgress)
+        public AsyncOperationHandle UnloadSceneAsync(NetworkSceneManager.SceneData scene, SceneEventProgress sceneEventProgress)
         {
-            var operation = SceneManager.UnloadSceneAsync(scene);
-            sceneEventProgress.SetAsyncOperation(operation);
-            return operation;
+            if (scene.SceneInstance.HasValue)
+            {
+                var operation = Addressables.UnloadSceneAsync(scene.SceneInstance.Value);
+                sceneEventProgress.SetAsyncOperation(operation);
+                return operation;
+            }
+            else
+            {
+                s_Log.Error(() => $"Unloaded a scene that wasn't loaded with addressables '{scene.SceneInstance}'");
+                var unloadOp = SceneManager.UnloadSceneAsync(scene.SceneReference);
+                AsyncOperationHandle operation = default;
+                sceneEventProgress.SetAsyncOperation(operation);
+                return operation;
+            }
+
         }
 
         /// 
@@ -168,8 +211,9 @@ public Scene GetSceneFromLoadedScenes(string sceneName, NetworkManager networkMa
         /// same application instance is still running, the same scenes are still loaded on the client, and
         /// upon reconnecting the client doesn't have to unload the scenes and then reload them)
         /// 
-        public void PopulateLoadedScenes(ref Dictionary scenesLoaded, NetworkManager networkManager)
+        public void PopulateLoadedScenes(ref Dictionary scenesLoaded, NetworkManager networkManager)
         {
+            Debug.LogError($"PopulateLoadedScenes START");
             SceneNameToSceneHandles.Clear();
             var sceneCount = SceneManager.sceneCount;
             for (int i = 0; i < sceneCount; i++)
@@ -190,7 +234,7 @@ public void PopulateLoadedScenes(ref Dictionary scenesLoaded, Networ
                     SceneNameToSceneHandles[scene.name].Add(scene.handle, sceneEntry);
                     if (!scenesLoaded.ContainsKey(scene.handle))
                     {
-                        scenesLoaded.Add(scene.handle, scene);
+                        scenesLoaded.Add(scene.handle, new NetworkSceneManager.SceneData(null, scene));
                     }
                 }
                 else
@@ -198,6 +242,7 @@ public void PopulateLoadedScenes(ref Dictionary scenesLoaded, Networ
                     throw new Exception($"[Duplicate Handle] Scene {scene.name} already has scene handle {scene.handle} registered!");
                 }
             }
+            Debug.LogError($"PopulateLoadedScenes END");
         }
 
         private List m_ScenesToUnload = new List();
@@ -373,7 +418,7 @@ public void SetClientSynchronizationMode(ref NetworkManager networkManager, Load
                     // If the scene is not already in the ScenesLoaded list, then add it
                     if (!sceneManager.ScenesLoaded.ContainsKey(scene.handle))
                     {
-                        sceneManager.ScenesLoaded.Add(scene.handle, scene);
+                        sceneManager.ScenesLoaded.Add(scene.handle, new NetworkSceneManager.SceneData(null, scene));
                     }
                 }
             }
diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/ISceneManagerHandler.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/ISceneManagerHandler.cs
index 9cd3ed1ac8..9f52e28da6 100644
--- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/ISceneManagerHandler.cs
+++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/ISceneManagerHandler.cs
@@ -1,5 +1,7 @@
 using System.Collections.Generic;
 using UnityEngine;
+using UnityEngine.ResourceManagement.AsyncOperations;
+using UnityEngine.ResourceManagement.ResourceProviders;
 using UnityEngine.SceneManagement;
 
 namespace Unity.Netcode
@@ -8,13 +10,13 @@ namespace Unity.Netcode
     /// Used to override the LoadSceneAsync and UnloadSceneAsync methods called
     /// within the NetworkSceneManager.
     /// 
-    internal interface ISceneManagerHandler
+    public interface ISceneManagerHandler
     {
-        AsyncOperation LoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress);
+        AsyncOperationHandle LoadSceneAsync(string sceneAssetKey, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress);
 
-        AsyncOperation UnloadSceneAsync(Scene scene, SceneEventProgress sceneEventProgress);
+        AsyncOperationHandle UnloadSceneAsync(NetworkSceneManager.SceneData scene, SceneEventProgress sceneEventProgress);
 
-        void PopulateLoadedScenes(ref Dictionary scenesLoaded, NetworkManager networkManager = null);
+        void PopulateLoadedScenes(ref Dictionary scenesLoaded, NetworkManager networkManager = null);
         Scene GetSceneFromLoadedScenes(string sceneName, NetworkManager networkManager = null);
 
         bool DoesSceneHaveUnassignedEntry(string sceneName, NetworkManager networkManager = null);
diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs
index 331d5ff112..975b065953 100644
--- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs
+++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs
@@ -1,9 +1,15 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using TrollKing.Core;
 using Unity.Collections;
 using UnityEngine;
+using UnityEngine.AddressableAssets;
+using UnityEngine.Profiling;
+using UnityEngine.ResourceManagement.AsyncOperations;
+using UnityEngine.ResourceManagement.ResourceProviders;
 using UnityEngine.SceneManagement;
+using Object = UnityEngine.Object;
 
 
 namespace Unity.Netcode
@@ -27,7 +33,7 @@ public class SceneEvent
         /// /// 
         /// 
-        public AsyncOperation AsyncOperation;
+        public AsyncOperationHandle AsyncOperation;
 
         /// 
         /// Will always be set to the current 
@@ -131,6 +137,8 @@ public class SceneEvent
     /// 
     public class NetworkSceneManager : IDisposable
     {
+        private static readonly NetworkLogScope Log = new NetworkLogScope(nameof(NetworkSceneManager));
+
         private const NetworkDelivery k_DeliveryType = NetworkDelivery.ReliableFragmentedSequenced;
         internal const int InvalidSceneNameOrPath = -1;
 
@@ -181,7 +189,7 @@ public class NetworkSceneManager : IDisposable
         /// name of the scene being processed
         /// the LoadSceneMode mode for the scene being loaded
         /// the associated  that can be used for scene loading progress
-        public delegate void OnLoadDelegateHandler(ulong clientId, string sceneName, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation);
+        public delegate void OnLoadDelegateHandler(ulong clientId, string sceneName, LoadSceneMode loadSceneMode, AsyncOperationHandle asyncOperation);
 
         /// 
         /// Delegate declaration for the OnUnload event.
@@ -191,7 +199,7 @@ public class NetworkSceneManager : IDisposable
         /// the client that is processing this event (the server will receive all of these events for every client and itself)
         /// name of the scene being processed
         /// the associated  that can be used for scene unloading progress
-        public delegate void OnUnloadDelegateHandler(ulong clientId, string sceneName, AsyncOperation asyncOperation);
+        public delegate void OnUnloadDelegateHandler(ulong clientId, string sceneName, AsyncOperationHandle asyncOperation);
 
         /// 
         /// Delegate declaration for the OnSynchronize event.
@@ -394,7 +402,7 @@ public bool ActiveSceneSynchronizationEnabled
         /// 
         /// The SceneManagerHandler implementation
         /// 
-        internal ISceneManagerHandler SceneManagerHandler = new DefaultSceneManagerHandler();
+        public ISceneManagerHandler SceneManagerHandler = new DefaultSceneManagerHandler();
 
         internal readonly Dictionary SceneEventProgressTracking = new Dictionary();
 
@@ -413,6 +421,17 @@ public bool ActiveSceneSynchronizationEnabled
         /// 
         internal Scene SceneBeingSynchronized;
 
+        public class SceneData
+        {
+            public SceneData(SceneInstance? instance, Scene reference)
+            {
+                SceneReference = reference;
+                SceneInstance = instance;
+            }
+            public Scene SceneReference;
+            public SceneInstance? SceneInstance;
+        }
+
         /// 
         /// Used to track which scenes are currently loaded
         /// We store the scenes as [SceneHandle][Scene] in order to handle the loading and unloading of the same scene additively
@@ -421,7 +440,7 @@ public bool ActiveSceneSynchronizationEnabled
         /// The client links the server scene handle to the client local scene handle upon a scene being loaded
         /// 
         /// 
-        internal Dictionary ScenesLoaded = new Dictionary();
+        public Dictionary ScenesLoaded = new Dictionary();
 
         /// 
         /// Returns the currently loaded scenes that are synchronized with the session owner or server depending upon the selected
@@ -432,7 +451,7 @@ public bool ActiveSceneSynchronizationEnabled
         /// synchronized remotely. This can be useful when using scene validation and excluding certain scenes from being synchronized.
         /// 
         /// List of the known synchronized scenes
-        public List GetSynchronizedScenes()
+        public List GetSynchronizedScenes()
         {
             return ScenesLoaded.Values.ToList();
         }
@@ -454,6 +473,7 @@ internal bool UpdateServerClientSceneHandle(int serverHandle, int clientHandle,
         {
             if (!ServerSceneHandleToClientSceneHandle.ContainsKey(serverHandle))
             {
+                Log.Debug(() => $"Adding Server Scene Handle {clientHandle} {localScene.name}");
                 ServerSceneHandleToClientSceneHandle.Add(serverHandle, clientHandle);
             }
             else if (!IsRestoringSession)
@@ -463,6 +483,7 @@ internal bool UpdateServerClientSceneHandle(int serverHandle, int clientHandle,
 
             if (!ClientSceneHandleToServerSceneHandle.ContainsKey(clientHandle))
             {
+                Log.Debug(() => $"Adding Client Scene Handle {clientHandle} {localScene.name}");
                 ClientSceneHandleToServerSceneHandle.Add(clientHandle, serverHandle);
             }
             else if (!IsRestoringSession)
@@ -473,7 +494,7 @@ internal bool UpdateServerClientSceneHandle(int serverHandle, int clientHandle,
             // It is "Ok" if this already has an entry
             if (!ScenesLoaded.ContainsKey(clientHandle))
             {
-                ScenesLoaded.Add(clientHandle, localScene);
+                ScenesLoaded.Add(clientHandle, new SceneData(null, localScene));
             }
 
             return true;
@@ -487,6 +508,7 @@ internal bool RemoveServerClientSceneHandle(int serverHandle, int clientHandle)
         {
             if (ServerSceneHandleToClientSceneHandle.ContainsKey(serverHandle))
             {
+                Log.Debug(() => $"Remove ServerSceneHandleToClientSceneHandle {clientHandle} {serverHandle}");
                 ServerSceneHandleToClientSceneHandle.Remove(serverHandle);
             }
             else
@@ -496,6 +518,7 @@ internal bool RemoveServerClientSceneHandle(int serverHandle, int clientHandle)
 
             if (ClientSceneHandleToServerSceneHandle.ContainsKey(clientHandle))
             {
+                Log.Debug(() => $"Remove ClientSceneHandleToServerSceneHandle {clientHandle} {serverHandle}");
                 ClientSceneHandleToServerSceneHandle.Remove(clientHandle);
             }
             else
@@ -505,6 +528,7 @@ internal bool RemoveServerClientSceneHandle(int serverHandle, int clientHandle)
 
             if (ScenesLoaded.ContainsKey(clientHandle))
             {
+                Log.Debug(() => $"Remove ScenesLoaded {clientHandle} {serverHandle}");
                 ScenesLoaded.Remove(clientHandle);
             }
             else
@@ -515,16 +539,6 @@ internal bool RemoveServerClientSceneHandle(int serverHandle, int clientHandle)
             return true;
         }
 
-        /// 
-        /// Hash to build index lookup table
-        /// 
-        internal Dictionary HashToBuildIndex = new Dictionary();
-
-        /// 
-        /// Build index to hash lookup table
-        /// 
-        internal Dictionary BuildIndexToHash = new Dictionary();
-
         /// 
         /// The Condition: While a scene is asynchronously loaded in single loading scene mode, if any new NetworkObjects are spawned
         /// they need to be moved into the do not destroy temporary scene
@@ -540,10 +554,12 @@ internal bool RemoveServerClientSceneHandle(int serverHandle, int clientHandle)
         /// 
         internal Dictionary SceneEventDataStore;
 
-        internal readonly NetworkManager NetworkManager;
+        internal Dictionary ScenePathsBySceneName;
+
+        private NetworkManager NetworkManager { get; }
 
         // Keep track of this scene until the NetworkSceneManager is destroyed.
-        internal Scene DontDestroyOnLoadScene;
+        public Scene DontDestroyOnLoadScene;
 
         /// 
         /// This setting changes how clients handle scene loading when initially synchronizing with the server.
@@ -558,7 +574,7 @@ internal bool RemoveServerClientSceneHandle(int serverHandle, int clientHandle)
         ///  and, if  is
         /// set,  callback(s).
         /// 
-        public LoadSceneMode ClientSynchronizationMode { get; internal set; }
+        public LoadSceneMode ClientSynchronizationMode { get; set; }
 
         /// 
         /// When true, the  messages will be turned off
@@ -663,104 +679,6 @@ internal bool ShouldDeferCreateObject()
             return (synchronizeEventDetected && ClientSynchronizationMode == LoadSceneMode.Single) || (!synchronizeEventDetected && loadingEventDetected);
         }
 
-        /// 
-        /// Gets the scene name from full path to the scene
-        /// 
-        internal string GetSceneNameFromPath(string scenePath)
-        {
-            var begin = scenePath.LastIndexOf("/", StringComparison.Ordinal) + 1;
-            var end = scenePath.LastIndexOf(".", StringComparison.Ordinal);
-            return scenePath.Substring(begin, end - begin);
-        }
-
-        /// 
-        /// Generates the hash values and associated tables
-        /// for the scenes in build list
-        /// 
-        internal void GenerateScenesInBuild()
-        {
-            // TODO 2023: We could support addressable or asset bundle scenes by
-            // adding a method that would allow users to add scenes to this.
-            // The method would be server-side only and require an additional SceneEventType
-            // that would be used to notify clients of the added scene. This might need
-            // to include information about the addressable or asset bundle (i.e. address to load assets)
-            HashToBuildIndex.Clear();
-            BuildIndexToHash.Clear();
-            for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
-            {
-                var scenePath = SceneUtility.GetScenePathByBuildIndex(i);
-                var hash = XXHash.Hash32(scenePath);
-                var buildIndex = SceneUtility.GetBuildIndexByScenePath(scenePath);
-
-                // In the rare-case scenario where a programmatically generated build has duplicate
-                // scene entries, we will log an error and skip the entry
-                if (!HashToBuildIndex.ContainsKey(hash))
-                {
-                    HashToBuildIndex.Add(hash, buildIndex);
-                    BuildIndexToHash.Add(buildIndex, hash);
-                }
-                else
-                {
-                    Debug.LogError($"{nameof(NetworkSceneManager)} is skipping duplicate scene path entry {scenePath}. Make sure your scenes in build list does not contain duplicates!");
-                }
-            }
-        }
-
-        /// 
-        /// Gets the scene name from a hash value generated from the full scene path
-        /// 
-        internal string SceneNameFromHash(uint sceneHash)
-        {
-            // In the event there is no scene associated with the scene event then just return "No Scene"
-            // This can happen during unit tests when clients first connect and the only scene loaded is the
-            // unit test scene (which is ignored by default) that results in a scene event that has no associated
-            // scene.  Under this specific special case, we just return "No Scene".
-            if (sceneHash == 0)
-            {
-                return "No Scene";
-            }
-            return GetSceneNameFromPath(ScenePathFromHash(sceneHash));
-        }
-
-        /// 
-        /// Gets the full scene path from a hash value
-        /// 
-        internal string ScenePathFromHash(uint sceneHash)
-        {
-            if (HashToBuildIndex.ContainsKey(sceneHash))
-            {
-                return SceneUtility.GetScenePathByBuildIndex(HashToBuildIndex[sceneHash]);
-            }
-            else
-            {
-                throw new Exception($"Scene Hash {sceneHash} does not exist in the {nameof(HashToBuildIndex)} table!  Verify that all scenes requiring" +
-                    $" server to client synchronization are in the scenes in build list.");
-            }
-        }
-
-        /// 
-        /// Gets the associated hash value for the scene name or path
-        /// 
-        internal uint SceneHashFromNameOrPath(string sceneNameOrPath)
-        {
-            var buildIndex = SceneUtility.GetBuildIndexByScenePath(sceneNameOrPath);
-            if (buildIndex >= 0)
-            {
-                if (BuildIndexToHash.ContainsKey(buildIndex))
-                {
-                    return BuildIndexToHash[buildIndex];
-                }
-                else
-                {
-                    throw new Exception($"Scene '{sceneNameOrPath}' has a build index of {buildIndex} that does not exist in the {nameof(BuildIndexToHash)} table!");
-                }
-            }
-            else
-            {
-                throw new Exception($"Scene '{sceneNameOrPath}' couldn't be loaded because it has not been added to the build settings scenes in build list.");
-            }
-        }
-
         /// 
         /// When set to true, this will disable the console warnings about
         /// a scene being invalidated.
@@ -801,9 +719,6 @@ internal NetworkSceneManager(NetworkManager networkManager)
             NetworkManager = networkManager;
             SceneEventDataStore = new Dictionary();
 
-            // Generates the scene name to hash value
-            GenerateScenesInBuild();
-
             // Since NetworkManager is now always migrated to the DDOL we will use this to get the DDOL scene
             DontDestroyOnLoadScene = networkManager.gameObject.scene;
 
@@ -816,7 +731,7 @@ internal NetworkSceneManager(NetworkManager networkManager)
                 for (int i = 0; i < SceneManager.sceneCount; i++)
                 {
                     var loadedScene = SceneManager.GetSceneAt(i);
-                    ScenesLoaded.Add(loadedScene.handle, loadedScene);
+                    ScenesLoaded.Add(loadedScene.handle, new SceneData(null, loadedScene));
                 }
                 SceneManagerHandler.PopulateLoadedScenes(ref ScenesLoaded, NetworkManager);
             }
@@ -868,21 +783,17 @@ private void SceneManager_ActiveSceneChanged(Scene current, Scene next)
                 }
             }
 
-            // If the scene's build index is in the hash table
-            if (BuildIndexToHash.ContainsKey(next.buildIndex))
+            // Notify clients of the change in active scene
+            var sceneEvent = BeginSceneEvent();
+            sceneEvent.SceneEventType = SceneEventType.ActiveSceneChanged;
+            sceneEvent.ActiveSceneAsset = next.name;
+			var sessionOwner = NetworkManager.ServerClientId;
+            if (NetworkManager.DistributedAuthorityMode)
             {
-                // Notify clients of the change in active scene
-                var sceneEvent = BeginSceneEvent();
-                sceneEvent.SceneEventType = SceneEventType.ActiveSceneChanged;
-                sceneEvent.ActiveSceneHash = BuildIndexToHash[next.buildIndex];
-                var sessionOwner = NetworkManager.ServerClientId;
-                if (NetworkManager.DistributedAuthorityMode)
-                {
-                    sessionOwner = NetworkManager.CurrentSessionOwner;
-                }
-                SendSceneEventData(sceneEvent.SceneEventId, NetworkManager.ConnectedClientsIds.Where(c => c != sessionOwner).ToArray());
-                EndSceneEvent(sceneEvent.SceneEventId);
+                sessionOwner = NetworkManager.CurrentSessionOwner;
             }
+            SendSceneEventData(sceneEvent.SceneEventId, NetworkManager.ConnectedClientsIds.Where(c => c != sessionOwner).ToArray());
+            EndSceneEvent(sceneEvent.SceneEventId);
         }
 
         /// 
@@ -893,34 +804,28 @@ private void SceneManager_ActiveSceneChanged(Scene current, Scene next)
         /// index into ScenesInBuild
         /// LoadSceneMode the scene is going to be loaded
         /// true (Valid) or false (Invalid)
-        internal bool ValidateSceneBeforeLoading(uint sceneHash, LoadSceneMode loadSceneMode)
+        internal bool ValidateSceneBeforeLoading(string sceneName, LoadSceneMode loadSceneMode)
         {
-            var sceneName = SceneNameFromHash(sceneHash);
-            var sceneIndex = SceneUtility.GetBuildIndexByScenePath(sceneName);
-            return ValidateSceneBeforeLoading(sceneIndex, sceneName, loadSceneMode);
-        }
+            Log.Debug(() => $"ValidateSceneBeforeLoading {sceneName} {loadSceneMode}");
+            return true;
 
-        /// 
-        /// Overloaded version that is invoked by  and .
-        /// This specifically is to allow runtime generated scenes to be excluded by the server during synchronization.
-        /// 
-        internal bool ValidateSceneBeforeLoading(int sceneIndex, string sceneName, LoadSceneMode loadSceneMode)
-        {
-            var validated = true;
-            if (VerifySceneBeforeLoading != null)
-            {
-                validated = VerifySceneBeforeLoading.Invoke(sceneIndex, sceneName, loadSceneMode);
-            }
-            if (!validated && !m_DisableValidationWarningMessages)
-            {
-                var serverHostorClient = "Client";
-                if (HasSceneAuthority())
-                {
-                    serverHostorClient = NetworkManager.DistributedAuthorityMode ? "Session Owner" : NetworkManager.IsHost ? "Host" : "Server";
-                }
-                Debug.LogWarning($"Scene {sceneName} of Scenes in Build Index {sceneIndex} being loaded in {loadSceneMode} mode failed validation on the {serverHostorClient}!");
-            }
-            return validated;
+            // var validated = true;
+            // var sceneIndex = SceneUtility.GetBuildIndexByScenePath(sceneName);
+            // if (VerifySceneBeforeLoading != null)
+            // {
+            //     validated = VerifySceneBeforeLoading.Invoke(sceneIndex, sceneName, loadSceneMode);
+            // }
+            // if (!validated && !m_DisableValidationWarningMessages)
+            // {
+            //     var serverHostorClient = "Client";
+            //     if (NetworkManager.IsServer)
+            //     {
+            //         serverHostorClient = NetworkManager.IsHost ? "Host" : "Server";
+            //     }
+            //
+            //     Debug.LogWarning($"Scene {sceneName} of Scenes in Build Index {sceneIndex} being loaded in {loadSceneMode} mode failed validation on the {serverHostorClient}!");
+            // }
+            // return validated;
         }
 
         /// 
@@ -953,7 +858,7 @@ internal Scene GetAndAddNewlyLoadedSceneByName(string sceneName)
                     {
                         if (!ScenesLoaded.ContainsKey(sceneLoaded.handle))
                         {
-                            ScenesLoaded.Add(sceneLoaded.handle, sceneLoaded);
+                            ScenesLoaded.Add(sceneLoaded.handle, new SceneData(null, sceneLoaded));
                             SceneManagerHandler.StartTrackingScene(sceneLoaded, true, NetworkManager);
                             return sceneLoaded;
                         }
@@ -987,7 +892,7 @@ internal void SetTheSceneBeingSynchronized(int serverSceneHandle)
                 }
 
                 // Get the scene currently being synchronized
-                SceneBeingSynchronized = ScenesLoaded.ContainsKey(clientSceneHandle) ? ScenesLoaded[clientSceneHandle] : new Scene();
+                SceneBeingSynchronized = ScenesLoaded.ContainsKey(clientSceneHandle) ? ScenesLoaded[clientSceneHandle].SceneReference : new Scene();
 
                 if (!SceneBeingSynchronized.IsValid() || !SceneBeingSynchronized.isLoaded)
                 {
@@ -1066,7 +971,7 @@ private void SendSceneEventData(uint sceneEventId, ulong[] targetClientIds)
                         EventData = sceneEvent,
                     };
                     var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, NetworkManager.ServerClientId);
-                    NetworkManager.NetworkMetrics.TrackSceneEventSent(NetworkManager.ServerClientId, (uint)sceneEvent.SceneEventType, SceneNameFromHash(sceneEvent.SceneHash), size);
+                    NetworkManager.NetworkMetrics.TrackSceneEventSent(NetworkManager.ServerClientId, (uint)sceneEvent.SceneEventType, sceneEvent.SceneAsset, size);
                 }
                 foreach (var clientId in targetClientIds)
                 {
@@ -1076,24 +981,19 @@ private void SendSceneEventData(uint sceneEventId, ulong[] targetClientIds)
                         EventData = sceneEvent,
                     };
                     var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, NetworkManager.ServerClientId);
-                    NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEvent.SceneEventType, SceneNameFromHash(sceneEvent.SceneHash), size);
+                    NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEvent.SceneEventType, sceneEvent.SceneAsset, size);
                 }
             }
             else
             {
-                // Send to each individual client to assure only the in-scene placed NetworkObjects being observed by the client
-                // is serialized
-                foreach (var clientId in targetClientIds)
+                var message = new SceneEventMessage
                 {
-                    sceneEvent.TargetClientId = clientId;
-                    var message = new SceneEventMessage
-                    {
-                        EventData = sceneEvent,
-                    };
-                    var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, clientId);
-                    NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEvent.SceneEventType, SceneNameFromHash(sceneEvent.SceneHash), size);
-                }
+                    EventData = sceneEvent,
+                };
+                var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, targetClientIds);
+                NetworkManager.NetworkMetrics.TrackSceneEventSent(targetClientIds, (uint)SceneEventDataStore[sceneEventId].SceneEventType, sceneEvent.SceneAsset, size);
             }
+
         }
 
         /// 
@@ -1175,16 +1075,53 @@ private SceneEventProgress ValidateSceneEvent(string sceneName, bool isUnloading
                 return new SceneEventProgress(null, SceneEventProgressStatus.SceneEventInProgress);
             }
 
-            // Return invalid scene name status if the scene name is invalid
-            if (SceneUtility.GetBuildIndexByScenePath(sceneName) == InvalidSceneNameOrPath)
+            // // Return invalid scene name status if the scene name is invalid
+            // if (SceneUtility.GetBuildIndexByScenePath(sceneName) == InvalidSceneNameOrPath)
+            // {
+            //     Debug.LogError($"Scene '{sceneName}' couldn't be loaded because it has not been added to the build settings scenes in build list.");
+            //     return new SceneEventProgress(null, SceneEventProgressStatus.InvalidSceneName);
+            // }
+            var locatorInfo = Addressables.GetLocatorInfo(sceneName);
+
+            var resourceLocationAsync = Addressables.LoadResourceLocationsAsync(sceneName);
+            resourceLocationAsync.WaitForCompletion();
+            if (resourceLocationAsync.Status == AsyncOperationStatus.Succeeded)
             {
-                Debug.LogError($"Scene '{sceneName}' couldn't be loaded because it has not been added to the build settings scenes in build list.");
-                return new SceneEventProgress(null, SceneEventProgressStatus.InvalidSceneName);
+                if (resourceLocationAsync.Result.Count >= 1)
+                {
+                    var location = resourceLocationAsync.Result[0];
+                    var provider = location.ProviderId;
+                    if (!provider.Contains("Scene"))
+                    {
+                        Debug.LogWarning($"Provider is not a scene provider! {provider}");
+                    }
+
+                    var resourceType = location.ResourceType;
+                    if (resourceType != typeof(SceneInstance))
+                    {
+                        throw new Exception($"Scene is not of the SceneInstance type! {resourceType}");
+                    }
+                    if (location.HasDependencies)
+                    {
+                        // Has dependencies!
+                        // download something?
+                        // no! this is just a verification method
+                    }
+
+                    if (location.PrimaryKey != sceneName)
+                    {
+                        throw new Exception($"Scene is not primary key of the scene name! {location.PrimaryKey} {sceneName}");
+                    }
+                }
+            }
+            else
+            {
+                throw new Exception($"Scene '{sceneName}' couldn't be loaded for its resource location.");
             }
 
             var sceneEventProgress = new SceneEventProgress(NetworkManager)
             {
-                SceneHash = SceneHashFromNameOrPath(sceneName)
+                SceneName = sceneName
             };
 
             SceneEventProgressTracking.Add(sceneEventProgress.Guid, sceneEventProgress);
@@ -1207,7 +1144,7 @@ private bool OnSceneEventProgressCompleted(SceneEventProgress sceneEventProgress
             var clientsThatCompleted = sceneEventProgress.GetClientsWithStatus(true);
             var clientsThatTimedOut = sceneEventProgress.GetClientsWithStatus(false);
             sceneEventData.SceneEventProgressId = sceneEventProgress.Guid;
-            sceneEventData.SceneHash = sceneEventProgress.SceneHash;
+            sceneEventData.SceneAsset = sceneEventProgress.SceneName;
             sceneEventData.SceneEventType = sceneEventProgress.SceneEventType;
             sceneEventData.ClientsCompleted = clientsThatCompleted;
             sceneEventData.LoadSceneMode = sceneEventProgress.LoadSceneMode;
@@ -1228,7 +1165,7 @@ private bool OnSceneEventProgressCompleted(SceneEventProgress sceneEventProgress
                 NetworkManager.NetworkMetrics.TrackSceneEventSent(
                     NetworkManager.ConnectedClientsIds,
                     (uint)sceneEventProgress.SceneEventType,
-                    SceneNameFromHash(sceneEventProgress.SceneHash),
+                    sceneEventProgress.SceneName,
                     size);
             }
 
@@ -1236,7 +1173,7 @@ private bool OnSceneEventProgressCompleted(SceneEventProgress sceneEventProgress
             OnSceneEvent?.Invoke(new SceneEvent()
             {
                 SceneEventType = sceneEventProgress.SceneEventType,
-                SceneName = SceneNameFromHash(sceneEventProgress.SceneHash),
+                SceneName = sceneEventProgress.SceneName,
                 ClientId = NetworkManager.CurrentSessionOwner,
                 LoadSceneMode = sceneEventProgress.LoadSceneMode,
                 ClientsThatCompleted = clientsThatCompleted,
@@ -1245,11 +1182,11 @@ private bool OnSceneEventProgressCompleted(SceneEventProgress sceneEventProgress
 
             if (sceneEventData.SceneEventType == SceneEventType.LoadEventCompleted)
             {
-                OnLoadEventCompleted?.Invoke(SceneNameFromHash(sceneEventProgress.SceneHash), sceneEventProgress.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
+                OnLoadEventCompleted?.Invoke(sceneEventProgress.SceneName, sceneEventProgress.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
             }
             else
             {
-                OnUnloadEventCompleted?.Invoke(SceneNameFromHash(sceneEventProgress.SceneHash), sceneEventProgress.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
+                OnUnloadEventCompleted?.Invoke(sceneEventProgress.SceneName, sceneEventProgress.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
             }
 
             EndSceneEvent(sceneEventData.SceneEventId);
@@ -1304,7 +1241,7 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
             var sceneEventData = BeginSceneEvent();
             sceneEventData.SceneEventProgressId = sceneEventProgress.Guid;
             sceneEventData.SceneEventType = SceneEventType.Unload;
-            sceneEventData.SceneHash = SceneHashFromNameOrPath(sceneName);
+            sceneEventData.SceneAsset = sceneName;
             sceneEventData.LoadSceneMode = LoadSceneMode.Additive; // The only scenes unloaded are scenes that were additively loaded
             sceneEventData.SceneHandle = sceneHandle;
 
@@ -1316,11 +1253,19 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
 
             if (!RemoveServerClientSceneHandle(sceneEventData.SceneHandle, scene.handle))
             {
-                Debug.LogError($"Failed to remove {SceneNameFromHash(sceneEventData.SceneHash)} scene handles [Server ({sceneEventData.SceneHandle})][Local({scene.handle})]");
+                Debug.LogError($"Failed to remove {sceneEventData.SceneAsset} scene handles [Server ({sceneEventData.SceneHandle})][Local({scene.handle})]");
             }
 
-            var sceneUnload = SceneManagerHandler.UnloadSceneAsync(scene, sceneEventProgress);
-
+            AsyncOperationHandle sceneUnload;
+            if (ScenesLoaded[sceneHandle].SceneInstance.HasValue)
+            {
+                sceneUnload = SceneManagerHandler.UnloadSceneAsync(ScenesLoaded[sceneHandle], sceneEventProgress);
+            }
+            else
+            {
+                throw new Exception("Fuuuuck");
+                sceneUnload = default;
+            }
             // Notify local server that a scene is going to be unloaded
             OnSceneEvent?.Invoke(new SceneEvent()
             {
@@ -1344,7 +1289,7 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
         private void OnClientUnloadScene(uint sceneEventId)
         {
             var sceneEventData = SceneEventDataStore[sceneEventId];
-            var sceneName = SceneNameFromHash(sceneEventData.SceneHash);
+            var sceneName = sceneEventData.SceneAsset;
 
             if (!ServerSceneHandleToClientSceneHandle.ContainsKey(sceneEventData.SceneHandle))
             {
@@ -1368,7 +1313,7 @@ private void OnClientUnloadScene(uint sceneEventId)
             // should be migrated temporarily into the DDOL, once the scene is unloaded they will be migrated into the
             // currently active scene.
             var networkManager = NetworkManager;
-            SceneManagerHandler.MoveObjectsFromSceneToDontDestroyOnLoad(ref networkManager, scene);
+            SceneManagerHandler.MoveObjectsFromSceneToDontDestroyOnLoad(ref networkManager, scene.SceneReference);
             m_IsSceneEventActive = true;
             var sceneEventProgress = new SceneEventProgress(NetworkManager)
             {
@@ -1381,8 +1326,16 @@ private void OnClientUnloadScene(uint sceneEventId)
                 SceneEventProgressTracking.Add(sceneEventData.SceneEventProgressId, sceneEventProgress);
             }
 
-            var sceneUnload = SceneManagerHandler.UnloadSceneAsync(scene, sceneEventProgress);
-
+            AsyncOperationHandle sceneUnload;
+            if (ScenesLoaded[sceneHandle].SceneInstance.HasValue)
+            {
+                sceneUnload = SceneManagerHandler.UnloadSceneAsync(ScenesLoaded[sceneHandle], sceneEventProgress);
+            }
+            else
+            {
+                throw new Exception("Fuuuuck");
+                sceneUnload = default;
+            }
             SceneManagerHandler.StopTrackingScene(sceneHandle, sceneName, NetworkManager);
 
             // Remove our server to scene handle lookup
@@ -1409,7 +1362,7 @@ private void OnClientUnloadScene(uint sceneEventId)
         /// Server and Client:
         /// Invoked when an additively loaded scene is unloaded
         /// 
-        private void OnSceneUnloaded(uint sceneEventId)
+        private void OnSceneUnloaded(uint sceneEventId, string sceneName)
         {
             // If we are shutdown or about to shutdown, then ignore this event
             if (!NetworkManager.IsListening || NetworkManager.ShutdownInProgress)
@@ -1451,11 +1404,11 @@ private void OnSceneUnloaded(uint sceneEventId)
             {
                 SceneEventType = sceneEventData.SceneEventType,
                 LoadSceneMode = sceneEventData.LoadSceneMode,
-                SceneName = SceneNameFromHash(sceneEventData.SceneHash),
+                SceneName = sceneEventData.SceneAsset,
                 ClientId = NetworkManager.LocalClientId,
             });
 
-            OnUnloadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash));
+            OnUnloadComplete?.Invoke(NetworkManager.LocalClientId, sceneEventData.SceneAsset);
 
             if (!HasSceneAuthority())
             {
@@ -1469,14 +1422,14 @@ private void OnSceneUnloaded(uint sceneEventId)
                 // current instance is the DAHost.
                 var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
                 var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
-                NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
+                NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, sceneEventData.SceneAsset, size);
             }
             EndSceneEvent(sceneEventId);
             // This scene event is now considered "complete"
             m_IsSceneEventActive = false;
         }
 
-        private void EmptySceneUnloadedOperation(uint sceneEventId)
+        private void EmptySceneUnloadedOperation(uint sceneEventId, string sceneName)
         {
             // Do nothing (this is a stub call since it is only used to flush all additively loaded scenes)
         }
@@ -1494,7 +1447,7 @@ internal void UnloadAdditivelyLoadedScenes(uint sceneEventId)
             foreach (var keyHandleEntry in ScenesLoaded)
             {
                 // Validate the scene as well as ignore the DDOL (which will have a negative buildIndex)
-                if (currentActiveScene.name != keyHandleEntry.Value.name && keyHandleEntry.Value.buildIndex >= 0)
+                if (currentActiveScene.name != keyHandleEntry.Value.SceneReference.name && keyHandleEntry.Value.SceneReference != DontDestroyOnLoadScene)
                 {
                     var sceneEventProgress = new SceneEventProgress(NetworkManager)
                     {
@@ -1502,16 +1455,17 @@ internal void UnloadAdditivelyLoadedScenes(uint sceneEventId)
                         OnSceneEventCompleted = EmptySceneUnloadedOperation
                     };
 
-                    if (ClientSceneHandleToServerSceneHandle.ContainsKey(keyHandleEntry.Value.handle))
+                    if (ClientSceneHandleToServerSceneHandle.TryGetValue(keyHandleEntry.Value.SceneReference.handle, out var serverSceneHandle))
                     {
-                        var serverSceneHandle = ClientSceneHandleToServerSceneHandle[keyHandleEntry.Value.handle];
                         ServerSceneHandleToClientSceneHandle.Remove(serverSceneHandle);
                     }
-                    ClientSceneHandleToServerSceneHandle.Remove(keyHandleEntry.Value.handle);
+                    Log.Debug(() => $"Remove ClientSceneHandleToServerSceneHandle {keyHandleEntry.Value.SceneReference.handle}");
+                    ClientSceneHandleToServerSceneHandle.Remove(keyHandleEntry.Value.SceneReference.handle);
 
                     var sceneUnload = SceneManagerHandler.UnloadSceneAsync(keyHandleEntry.Value, sceneEventProgress);
 
-                    SceneUnloadEventHandler.RegisterScene(this, keyHandleEntry.Value, LoadSceneMode.Additive, sceneUnload);
+                    SceneUnloadEventHandler.RegisterScene(this, keyHandleEntry.Value.SceneReference, LoadSceneMode.Additive, sceneUnload);
+
                 }
             }
             // clear out our scenes loaded list
@@ -1519,6 +1473,94 @@ internal void UnloadAdditivelyLoadedScenes(uint sceneEventId)
             SceneManagerHandler.ClearSceneTracking(NetworkManager);
         }
 
+        public SceneEventProgress LoadAddressableScene(AssetReference sceneReference, LoadSceneMode loadSceneMode)
+        {
+            var resourceAsync = Addressables.LoadResourceLocationsAsync(sceneReference);
+            resourceAsync.WaitForCompletion();
+
+            var sceneName = "";
+
+            if (resourceAsync.Status == AsyncOperationStatus.Succeeded)
+            {
+                var sceneKey = resourceAsync.Result[0].PrimaryKey;
+                sceneName = sceneKey;
+            }
+            else
+            {
+                throw new Exception($"Failed to load scene from resource {resourceAsync.OperationException}");
+            }
+
+            var sceneEventProgress = ValidateSceneEventLoading(sceneName);
+            if (sceneEventProgress.Status != SceneEventProgressStatus.Started)
+            {
+                return sceneEventProgress;
+            }
+
+            // This will be the message we send to everyone when this scene event sceneEventProgress is complete
+            sceneEventProgress.SceneEventType = SceneEventType.LoadEventCompleted;
+            sceneEventProgress.LoadSceneMode = loadSceneMode;
+
+            var sceneEventData = BeginSceneEvent();
+
+            // Now set up the current scene event
+            sceneEventData.SceneEventProgressId = sceneEventProgress.Guid;
+            sceneEventData.SceneEventType = SceneEventType.Load;
+            sceneEventData.SceneAsset = sceneName;
+            sceneEventData.LoadSceneMode = loadSceneMode;
+            var sceneEventId = sceneEventData.SceneEventId;
+            // This both checks to make sure the scene is valid and if not resets the active scene event
+            m_IsSceneEventActive = ValidateSceneBeforeLoading(sceneEventData.SceneAsset, loadSceneMode);
+            if (!m_IsSceneEventActive)
+            {
+                EndSceneEvent(sceneEventId);
+                sceneEventProgress.Status = SceneEventProgressStatus.SceneFailedVerification;
+                return sceneEventProgress;
+            }
+
+            if (sceneEventData.LoadSceneMode == LoadSceneMode.Single)
+            {
+                // Destroy current scene objects before switching.
+                NetworkManager.SpawnManager.ServerDestroySpawnedSceneObjects();
+
+                // Preserve the objects that should not be destroyed during the scene event
+                MoveObjectsToDontDestroyOnLoad();
+
+                // Now Unload all currently additively loaded scenes
+                UnloadAdditivelyLoadedScenes(sceneEventId);
+
+                // Register the active scene for unload scene event notifications
+                SceneUnloadEventHandler.RegisterScene(this, SceneManager.GetActiveScene(), LoadSceneMode.Single);
+            }
+
+            // Now start loading the scene
+            sceneEventProgress.SceneEventId = sceneEventId;
+            sceneEventProgress.OnSceneEventCompleted = OnSceneLoaded;
+            var sceneLoad = SceneManagerHandler.LoadSceneAsync(sceneName, loadSceneMode, sceneEventProgress);
+
+            // Notify the local server that a scene loading event has begun
+            OnSceneEvent?.Invoke(new SceneEvent()
+            {
+                AsyncOperation = sceneLoad,
+                SceneEventType = sceneEventData.SceneEventType,
+                LoadSceneMode = sceneEventData.LoadSceneMode,
+                SceneName = sceneName,
+                ClientId = NetworkManager.ServerClientId
+            });
+
+            OnLoad?.Invoke(NetworkManager.ServerClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
+
+            //Return our scene progress instance
+            return sceneEventProgress;
+        }
+
+
+        private static Dictionary s_ResourceLocationsBySceneName = new();
+
+        public bool PrepareToLoadScene(string sceneName, Action loaded)
+        {
+            return false;
+        }
+
         /// 
         /// Server side:
         /// Loads the scene name in either additive or single loading mode.
@@ -1527,12 +1569,23 @@ internal void UnloadAdditivelyLoadedScenes(uint sceneEventId)
         /// the name of the scene to be loaded
         /// how the scene will be loaded (single or additive mode)
         ///  ( means it was successful)
-        public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSceneMode)
+        public SceneEventProgress LoadScene(string sceneName, LoadSceneMode loadSceneMode)
         {
+            // Debug.Log($"[NetworkSceneManager] LoadScene sceneName={sceneName}");
+            if (!s_ResourceLocationsBySceneName.TryGetValue(sceneName, out var found))
+            {
+                var resourceLocationAsync = Addressables.LoadResourceLocationsAsync(sceneName);
+                if (!resourceLocationAsync.IsValid())
+                {
+                    return null;
+                }
+            }
+
+            // Debug.Log($"[NetworkSceneManager] LoadScene Finished LoadResources sceneName={sceneName}");
             var sceneEventProgress = ValidateSceneEventLoading(sceneName);
             if (sceneEventProgress.Status != SceneEventProgressStatus.Started)
             {
-                return sceneEventProgress.Status;
+                return sceneEventProgress;
             }
 
             // This will be the message we send to everyone when this scene event sceneEventProgress is complete
@@ -1544,15 +1597,15 @@ public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSc
             // Now set up the current scene event
             sceneEventData.SceneEventProgressId = sceneEventProgress.Guid;
             sceneEventData.SceneEventType = SceneEventType.Load;
-            sceneEventData.SceneHash = SceneHashFromNameOrPath(sceneName);
+            sceneEventData.SceneAsset = sceneName;
             sceneEventData.LoadSceneMode = loadSceneMode;
             var sceneEventId = sceneEventData.SceneEventId;
             // This both checks to make sure the scene is valid and if not resets the active scene event
-            m_IsSceneEventActive = ValidateSceneBeforeLoading(sceneEventData.SceneHash, loadSceneMode);
+            m_IsSceneEventActive = ValidateSceneBeforeLoading(sceneEventData.SceneAsset, loadSceneMode);
             if (!m_IsSceneEventActive)
             {
                 EndSceneEvent(sceneEventId);
-                return SceneEventProgressStatus.SceneFailedVerification;
+                return new SceneEventProgress(NetworkManager.Singleton, SceneEventProgressStatus.SceneFailedVerification);
             }
 
             if (sceneEventData.LoadSceneMode == LoadSceneMode.Single)
@@ -1580,8 +1633,9 @@ public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSc
             // Now start loading the scene
             sceneEventProgress.SceneEventId = sceneEventId;
             sceneEventProgress.OnSceneEventCompleted = OnSceneLoaded;
+            // Debug.Log($"[NetworkSceneManager] BEGIN SceneManagerHandler.LoadSceneAsync sceneName={sceneName} loadSceneMode={loadSceneMode}");
             var sceneLoad = SceneManagerHandler.LoadSceneAsync(sceneName, loadSceneMode, sceneEventProgress);
-
+            // Debug.Log($"[NetworkSceneManager] END SceneManagerHandler.LoadSceneAsync sceneName={sceneName} loadSceneMode={loadSceneMode}");
             // Notify the local server that a scene loading event has begun
             OnSceneEvent?.Invoke(new SceneEvent()
             {
@@ -1594,7 +1648,7 @@ public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSc
             OnLoad?.Invoke(NetworkManager.LocalClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
 
             //Return our scene progress instance
-            return sceneEventProgress.Status;
+            return sceneEventProgress;
         }
 
         /// 
@@ -1605,7 +1659,7 @@ internal class SceneUnloadEventHandler
         {
             private static Dictionary> s_Instances = new Dictionary>();
 
-            internal static void RegisterScene(NetworkSceneManager networkSceneManager, Scene scene, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation = null)
+            internal static void RegisterScene(NetworkSceneManager networkSceneManager, Scene scene, LoadSceneMode loadSceneMode, AsyncOperationHandle asyncOperation = default)
             {
                 var networkManager = networkSceneManager.NetworkManager;
                 if (!s_Instances.ContainsKey(networkManager))
@@ -1650,7 +1704,7 @@ internal static void Shutdown()
             }
 
             private NetworkSceneManager m_NetworkSceneManager;
-            private AsyncOperation m_AsyncOperation;
+            private AsyncOperationHandle m_AsyncOperation;
             private LoadSceneMode m_LoadSceneMode;
             private ulong m_ClientId;
             private Scene m_Scene;
@@ -1683,7 +1737,7 @@ private void SceneUnloaded(Scene scene)
                 }
             }
 
-            private SceneUnloadEventHandler(NetworkSceneManager networkSceneManager, Scene scene, ulong clientId, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation = null)
+            private SceneUnloadEventHandler(NetworkSceneManager networkSceneManager, Scene scene, ulong clientId, LoadSceneMode loadSceneMode, AsyncOperationHandle asyncOperation = default)
             {
                 m_LoadSceneMode = loadSceneMode;
                 m_AsyncOperation = asyncOperation;
@@ -1701,7 +1755,7 @@ private SceneUnloadEventHandler(NetworkSceneManager networkSceneManager, Scene s
                     ClientId = clientId
                 });
 
-                m_NetworkSceneManager.OnUnload?.Invoke(networkSceneManager.NetworkManager.LocalClientId, m_Scene.name, null);
+                m_NetworkSceneManager.OnUnload?.Invoke(networkSceneManager.NetworkManager.LocalClientId, m_Scene.name, default);
             }
         }
 
@@ -1713,10 +1767,10 @@ private SceneUnloadEventHandler(NetworkSceneManager networkSceneManager, Scene s
         private void OnClientSceneLoadingEvent(uint sceneEventId)
         {
             var sceneEventData = SceneEventDataStore[sceneEventId];
-            var sceneName = SceneNameFromHash(sceneEventData.SceneHash);
+            var sceneName = sceneEventData.SceneAsset;
 
             // Run scene validation before loading a scene
-            if (!ValidateSceneBeforeLoading(sceneEventData.SceneHash, sceneEventData.LoadSceneMode))
+            if (!ValidateSceneBeforeLoading(sceneEventData.SceneAsset, sceneEventData.LoadSceneMode))
             {
                 EndSceneEvent(sceneEventId);
                 return;
@@ -1774,7 +1828,7 @@ private void OnClientSceneLoadingEvent(uint sceneEventId)
         /// Client and Server:
         /// Generic on scene loaded callback method to be called upon a scene loading
         /// 
-        private void OnSceneLoaded(uint sceneEventId)
+        private void OnSceneLoaded(uint sceneEventId, string loadedSceneName)
         {
             // If we are shutdown or about to shutdown, then ignore this event
             if (!NetworkManager.IsListening || NetworkManager.ShutdownInProgress)
@@ -1784,11 +1838,12 @@ private void OnSceneLoaded(uint sceneEventId)
             }
 
             var sceneEventData = SceneEventDataStore[sceneEventId];
-            var nextScene = GetAndAddNewlyLoadedSceneByName(SceneNameFromHash(sceneEventData.SceneHash));
-            if (!nextScene.isLoaded || !nextScene.IsValid())
+            var nextScene = GetAndAddNewlyLoadedSceneByName(loadedSceneName);
+            if (!nextScene.IsValid())
             {
                 throw new Exception($"Failed to find valid scene internal Unity.Netcode for {nameof(GameObject)}s error!");
             }
+            // If we async loaded a single scene, the active will activate it
 
             if (sceneEventData.LoadSceneMode == LoadSceneMode.Single)
             {
@@ -1820,6 +1875,8 @@ private void OnSceneLoaded(uint sceneEventId)
                 }
             }
 
+            Log.Debug(() => "OnSceneLoaded");
+
             //Get all NetworkObjects loaded by the scene
             PopulateScenePlacedObjects(nextScene);
 
@@ -1861,6 +1918,8 @@ private void OnSceneLoaded(uint sceneEventId)
         /// 
         private void OnSessionOwnerLoadedScene(uint sceneEventId, Scene scene)
         {
+            // Debug.Log($"NetworkSceneManager - OnServerLoadedScene eventId:{sceneEventId} scene:{scene.name}");
+
             var sceneEventData = SceneEventDataStore[sceneEventId];
             // Register in-scene placed NetworkObjects with spawn manager
             foreach (var keyValuePairByGlobalObjectIdHash in ScenePlacedObjects)
@@ -1910,12 +1969,12 @@ private void OnSessionOwnerLoadedScene(uint sceneEventId, Scene scene)
             {
                 SceneEventType = sceneEventData.SceneEventType,
                 LoadSceneMode = sceneEventData.LoadSceneMode,
-                SceneName = SceneNameFromHash(sceneEventData.SceneHash),
-                ClientId = NetworkManager.LocalClientId,
+                SceneName = sceneEventData.SceneAsset,
+                ClientId = NetworkManager.ServerClientId,
                 Scene = scene,
             });
 
-            OnLoadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
+            OnLoadComplete?.Invoke(NetworkManager.ServerClientId, sceneEventData.SceneAsset, sceneEventData.LoadSceneMode);
 
             //Second, only if we are a host do we want register having loaded for the associated SceneEventProgress
             if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId) && NetworkManager.IsClient)
@@ -1946,7 +2005,7 @@ private void OnClientLoadedScene(uint sceneEventId, Scene scene)
                 };
                 var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
                 var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
-                NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
+                NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, sceneEventData.SceneAsset, size);
             }
             else
             {
@@ -1969,12 +2028,12 @@ private void OnClientLoadedScene(uint sceneEventId, Scene scene)
             {
                 SceneEventType = SceneEventType.LoadComplete,
                 LoadSceneMode = sceneEventData.LoadSceneMode,
-                SceneName = SceneNameFromHash(sceneEventData.SceneHash),
+                SceneName = sceneEventData.SceneAsset,
                 ClientId = NetworkManager.LocalClientId,
                 Scene = scene,
             });
 
-            OnLoadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
+            OnLoadComplete?.Invoke(NetworkManager.LocalClientId, sceneEventData.SceneAsset, sceneEventData.LoadSceneMode);
 
             EndSceneEvent(sceneEventId);
         }
@@ -2036,10 +2095,10 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
             sceneEventData.LoadSceneMode = ClientSynchronizationMode;
             var activeScene = SceneManager.GetActiveScene();
             sceneEventData.SceneEventType = SceneEventType.Synchronize;
-            if (BuildIndexToHash.ContainsKey(activeScene.buildIndex))
-            {
-                sceneEventData.ActiveSceneHash = BuildIndexToHash[activeScene.buildIndex];
-            }
+            // if (BuildIndexToHash.ContainsKey(activeScene.buildIndex))
+            // {
+            //     sceneEventData.ActiveSceneHash = BuildIndexToHash[activeScene.buildIndex];
+            // }
 
             // Organize how (and when) we serialize our NetworkObjects
             for (int i = 0; i < SceneManager.sceneCount; i++)
@@ -2053,6 +2112,7 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
                     continue;
                 }
 
+                var sceneHash = scene.name;
                 if (scene == DontDestroyOnLoadScene)
                 {
                     continue;
@@ -2062,11 +2122,11 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
                 // If we are the base scene, then we set the root scene index;
                 if (activeScene == scene)
                 {
-                    if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, sceneEventData.LoadSceneMode))
+                    if (!ValidateSceneBeforeLoading(sceneHash, sceneEventData.LoadSceneMode))
                     {
                         continue;
                     }
-                    sceneEventData.SceneHash = SceneHashFromNameOrPath(scene.path);
+                    sceneEventData.SceneAsset = scene.name;
 
                     // If we are just a normal client, then always use the server scene handle
                     if (NetworkManager.DistributedAuthorityMode)
@@ -2079,7 +2139,7 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
                         sceneEventData.SceneHandle = scene.handle;
                     }
                 }
-                else if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, LoadSceneMode.Additive))
+                else if (!ValidateSceneBeforeLoading(sceneHash, LoadSceneMode.Additive))
                 {
                     continue;
                 }
@@ -2087,11 +2147,11 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
                 // If we are just a normal client and in distributed authority mode, then always use the known server scene handle
                 if (NetworkManager.DistributedAuthorityMode && !NetworkManager.DAHost)
                 {
-                    sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), ClientSceneHandleToServerSceneHandle[scene.handle]);
+                    sceneEventData.AddSceneToSynchronize(sceneHash, ClientSceneHandleToServerSceneHandle[scene.handle]);
                 }
                 else
                 {
-                    sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), scene.handle);
+                    sceneEventData.AddSceneToSynchronize(sceneHash, scene.handle);
                 }
             }
 
@@ -2136,17 +2196,17 @@ private void OnClientBeginSync(uint sceneEventId)
             var sceneEventData = SceneEventDataStore[sceneEventId];
             var sceneHash = sceneEventData.GetNextSceneSynchronizationHash();
             var sceneHandle = sceneEventData.GetNextSceneSynchronizationHandle();
-            var sceneName = SceneNameFromHash(sceneHash);
+            var sceneName = sceneHash;
             var activeScene = SceneManager.GetActiveScene();
 
-            var loadSceneMode = sceneHash == sceneEventData.SceneHash ? sceneEventData.LoadSceneMode : LoadSceneMode.Additive;
+            var loadSceneMode = sceneHash == sceneEventData.SceneAsset ? sceneEventData.LoadSceneMode : LoadSceneMode.Additive;
 
             // Store the sceneHandle and hash
             sceneEventData.NetworkSceneHandle = sceneHandle;
-            sceneEventData.ClientSceneHash = sceneHash;
+            sceneEventData.SceneAsset = sceneHash;
 
             // If this is the beginning of the synchronization event, then send client a notification that synchronization has begun
-            if (sceneHash == sceneEventData.SceneHash)
+            if (sceneHash == sceneEventData.SceneAsset)
             {
                 OnSceneEvent?.Invoke(new SceneEvent()
                 {
@@ -2168,14 +2228,14 @@ private void OnClientBeginSync(uint sceneEventId)
                 return;
             }
 
-            var sceneLoad = (AsyncOperation)null;
+            var sceneLoad = (AsyncOperationHandle)default;
 
             // Determines if the client has the scene to be loaded already loaded, if so will return true and the client will skip loading this scene
             // For ClientSynchronizationMode LoadSceneMode.Single, we pass in whether the scene being loaded is the first/primary active scene and if it is already loaded
             // it should pass through to post load processing (ClientLoadedSynchronization).
             // For ClientSynchronizationMode LoadSceneMode.Additive, if the scene is already loaded or the active scene is the scene to be loaded (does not require it to
             // be the initial primary scene) then go ahead and pass through to post load processing (ClientLoadedSynchronization).
-            var shouldPassThrough = SceneManagerHandler.ClientShouldPassThrough(sceneName, sceneHash == sceneEventData.SceneHash, ClientSynchronizationMode, NetworkManager);
+            var shouldPassThrough = SceneManagerHandler.ClientShouldPassThrough(sceneName, sceneName == sceneEventData.SceneAsset, ClientSynchronizationMode, NetworkManager);
 
             if (!shouldPassThrough)
             {
@@ -2185,7 +2245,9 @@ private void OnClientBeginSync(uint sceneEventId)
                     SceneEventId = sceneEventId,
                     OnSceneEventCompleted = ClientLoadedSynchronization
                 };
+                // Debug.Log($"[NetworkSceneManager] OnClientBeginSync BEGIN SceneManagerHandler.LoadSceneAsync sceneName={sceneName} loadSceneMode={loadSceneMode}");
                 sceneLoad = SceneManagerHandler.LoadSceneAsync(sceneName, loadSceneMode, sceneEventProgress);
+                // Debug.Log($"[NetworkSceneManager] OnClientBeginSync END SceneManagerHandler.LoadSceneAsync sceneName={sceneName} loadSceneMode={loadSceneMode}");
 
                 // Notify local client that a scene load has begun
                 OnSceneEvent?.Invoke(new SceneEvent()
@@ -2202,7 +2264,7 @@ private void OnClientBeginSync(uint sceneEventId)
             else
             {
                 // If so, then pass through
-                ClientLoadedSynchronization(sceneEventId);
+                ClientLoadedSynchronization(sceneEventId, sceneName);
             }
         }
 
@@ -2211,10 +2273,9 @@ private void OnClientBeginSync(uint sceneEventId)
         /// This handles all of the in-scene and dynamically spawned NetworkObject synchronization
         /// 
         /// Netcode scene index that was loaded
-        private void ClientLoadedSynchronization(uint sceneEventId)
+        private void ClientLoadedSynchronization(uint sceneEventId, string sceneName)
         {
             var sceneEventData = SceneEventDataStore[sceneEventId];
-            var sceneName = SceneNameFromHash(sceneEventData.ClientSceneHash);
             var nextScene = SceneManagerHandler.GetSceneFromLoadedScenes(sceneName, NetworkManager);
             if (!nextScene.IsValid())
             {
@@ -2226,7 +2287,7 @@ private void ClientLoadedSynchronization(uint sceneEventId)
                 throw new Exception($"Failed to find valid scene internal Unity.Netcode for {nameof(GameObject)}s error!");
             }
 
-            var loadSceneMode = (sceneEventData.ClientSceneHash == sceneEventData.SceneHash ? sceneEventData.LoadSceneMode : LoadSceneMode.Additive);
+            var loadSceneMode = (sceneEventData.ClientSceneName == sceneEventData.SceneAsset ? sceneEventData.LoadSceneMode : LoadSceneMode.Additive);
 
             // For now, during a synchronization event, we will make the first scene the "base/master" scene that denotes a "complete scene switch"
             if (loadSceneMode == LoadSceneMode.Single)
@@ -2241,6 +2302,8 @@ private void ClientLoadedSynchronization(uint sceneEventId)
                 throw new Exception($"Server Scene Handle ({sceneEventData.SceneHandle}) already exist!  Happened during scene load of {nextScene.name} with Client Handle ({nextScene.handle})");
             }
 
+            Log.Debug(() => $"ClientLoadedSynchronization sceneName={sceneName}");
+
             // Apply all in-scene placed NetworkObjects loaded by the scene
             PopulateScenePlacedObjects(nextScene, false);
 
@@ -2248,7 +2311,7 @@ private void ClientLoadedSynchronization(uint sceneEventId)
             var responseSceneEventData = BeginSceneEvent();
             responseSceneEventData.LoadSceneMode = loadSceneMode;
             responseSceneEventData.SceneEventType = SceneEventType.LoadComplete;
-            responseSceneEventData.SceneHash = sceneEventData.ClientSceneHash;
+            responseSceneEventData.SceneAsset = sceneEventData.ClientSceneName;
 
             var target = NetworkManager.ServerClientId;
             if (NetworkManager.DistributedAuthorityMode)
@@ -2308,12 +2371,12 @@ private void SynchronizeNetworkObjectScene()
                         if (ScenesLoaded.ContainsKey(networkObject.SceneOriginHandle))
                         {
                             var scene = ScenesLoaded[networkObject.SceneOriginHandle];
-                            if (scene == DontDestroyOnLoadScene)
+                            if (scene.SceneReference == DontDestroyOnLoadScene)
                             {
                                 Debug.Log($"{networkObject.gameObject.name} migrating into DDOL!");
                             }
 
-                            SceneManager.MoveGameObjectToScene(networkObject.gameObject, scene);
+                            SceneManager.MoveGameObjectToScene(networkObject.gameObject, scene.SceneReference);
                         }
                         else if (NetworkManager.LogLevel <= LogLevel.Normal)
                         {
@@ -2337,13 +2400,10 @@ private void HandleClientSceneEvent(uint sceneEventId)
             {
                 case SceneEventType.ActiveSceneChanged:
                     {
-                        if (HashToBuildIndex.ContainsKey(sceneEventData.ActiveSceneHash))
+                        var scene = SceneManager.GetSceneByName(sceneEventData.ClientSceneName);
+                        if (scene.isLoaded)
                         {
-                            var scene = SceneManager.GetSceneByBuildIndex(HashToBuildIndex[sceneEventData.ActiveSceneHash]);
-                            if (scene.isLoaded)
-                            {
-                                SceneManager.SetActiveScene(scene);
-                            }
+                            SceneManager.SetActiveScene(scene);
                         }
                         EndSceneEvent(sceneEventId);
                         break;
@@ -2371,17 +2431,16 @@ private void HandleClientSceneEvent(uint sceneEventId)
                         }
                         else
                         {
+                            Log.Debug(() => $"SceneEventType.Synchronize sceneName={sceneEventData.ClientSceneName}");
+
                             // Include anything in the DDOL scene
                             PopulateScenePlacedObjects(DontDestroyOnLoadScene, false);
 
                             // If needed, set the currently active scene
-                            if (HashToBuildIndex.ContainsKey(sceneEventData.ActiveSceneHash))
+                            var targetActiveScene = SceneManager.GetSceneByName(sceneEventData.ClientSceneName);
+                            if (targetActiveScene.isLoaded && targetActiveScene.handle != SceneManager.GetActiveScene().handle)
                             {
-                                var targetActiveScene = SceneManager.GetSceneByBuildIndex(HashToBuildIndex[sceneEventData.ActiveSceneHash]);
-                                if (targetActiveScene.isLoaded && targetActiveScene.handle != SceneManager.GetActiveScene().handle)
-                                {
-                                    SceneManager.SetActiveScene(targetActiveScene);
-                                }
+                                SceneManager.SetActiveScene(targetActiveScene);
                             }
 
                             // Spawn and Synchronize all NetworkObjects
@@ -2412,7 +2471,7 @@ private void HandleClientSceneEvent(uint sceneEventId)
                                         };
                                         var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
                                         var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
-                                        NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
+                                        NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, sceneEventData.SceneAsset, size);
                                     }
                                 }
                                 else
@@ -2425,7 +2484,7 @@ private void HandleClientSceneEvent(uint sceneEventId)
                                     };
                                     var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
                                     var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
-                                    NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
+                                    NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, sceneEventData.SceneAsset, size);
                                 }
                             }
                             else
@@ -2506,7 +2565,7 @@ private void HandleClientSceneEvent(uint sceneEventId)
                         {
                             SceneEventType = sceneEventData.SceneEventType,
                             LoadSceneMode = sceneEventData.LoadSceneMode,
-                            SceneName = SceneNameFromHash(sceneEventData.SceneHash),
+                            SceneName = sceneEventData.SceneAsset,
                             ClientId = NetworkManager.ServerClientId,
                             ClientsThatCompleted = sceneEventData.ClientsCompleted,
                             ClientsThatTimedOut = sceneEventData.ClientsTimedOut,
@@ -2514,11 +2573,11 @@ private void HandleClientSceneEvent(uint sceneEventId)
 
                         if (sceneEventData.SceneEventType == SceneEventType.LoadEventCompleted)
                         {
-                            OnLoadEventCompleted?.Invoke(SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
+                            OnLoadEventCompleted?.Invoke(sceneEventData.SceneAsset, sceneEventData.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
                         }
                         else
                         {
-                            OnUnloadEventCompleted?.Invoke(SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
+                            OnUnloadEventCompleted?.Invoke(sceneEventData.SceneAsset, sceneEventData.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
                         }
 
                         EndSceneEvent(sceneEventId);
@@ -2549,11 +2608,11 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
                         {
                             SceneEventType = sceneEventData.SceneEventType,
                             LoadSceneMode = sceneEventData.LoadSceneMode,
-                            SceneName = SceneNameFromHash(sceneEventData.SceneHash),
+                            SceneName = sceneEventData.SceneAsset,
                             ClientId = clientId
                         });
 
-                        OnLoadComplete?.Invoke(clientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
+                        OnLoadComplete?.Invoke(clientId, sceneEventData.SceneAsset, sceneEventData.LoadSceneMode);
 
                         if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId))
                         {
@@ -2573,11 +2632,11 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
                         {
                             SceneEventType = sceneEventData.SceneEventType,
                             LoadSceneMode = sceneEventData.LoadSceneMode,
-                            SceneName = SceneNameFromHash(sceneEventData.SceneHash),
+                            SceneName = sceneEventData.SceneAsset,
                             ClientId = clientId
                         });
 
-                        OnUnloadComplete?.Invoke(clientId, SceneNameFromHash(sceneEventData.SceneHash));
+                        OnUnloadComplete?.Invoke(clientId, sceneEventData.SceneAsset);
 
                         EndSceneEvent(sceneEventId);
                         break;
@@ -2772,7 +2831,7 @@ internal void HandleSceneEvent(ulong clientId, FastBufferReader reader)
                 }
 
                 NetworkManager.NetworkMetrics.TrackSceneEventReceived(
-                   clientId, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), reader.Length);
+                   clientId, (uint)sceneEventData.SceneEventType, sceneEventData.SceneAsset, reader.Length);
 
                 if (sceneEventData.IsSceneEventClientSide())
                 {
@@ -2839,11 +2898,23 @@ internal void MoveObjectsToDontDestroyOnLoad()
                     // Only move dynamically spawned NetworkObjects with no parent as the children will follow
                     if (networkObject.gameObject.transform.parent == null && networkObject.IsSceneObject != null && !networkObject.IsSceneObject.Value)
                     {
-                        UnityEngine.Object.DontDestroyOnLoad(networkObject.gameObject);
-                        // When temporarily migrating to the DDOL, adjust the network and origin scene handles so no messages are generated
-                        // about objects being moved to a new scene.
-                        networkObject.NetworkSceneHandle = ClientSceneHandleToServerSceneHandle[networkObject.gameObject.scene.handle];
-                        networkObject.SceneOriginHandle = networkObject.gameObject.scene.handle;
+                        try
+                        {
+                            Object.DontDestroyOnLoad(networkObject.gameObject);
+                            // When temporarily migrating to the DDOL, adjust the network and origin scene handles so no messages are generated
+                            // about objects being moved to a new scene.
+                            networkObject.NetworkSceneHandle = ClientSceneHandleToServerSceneHandle[networkObject.gameObject.scene.handle];
+                            networkObject.SceneOriginHandle = networkObject.gameObject.scene.handle;
+                        }
+                        catch (Exception e)
+                        {
+                            string allEntities = "";
+                            foreach (var kvp in ClientSceneHandleToServerSceneHandle)
+                            {
+                                allEntities += $"{kvp.Key}={kvp.Value},";
+                            }
+                            Log.Error(() => $"Failed to move object={networkObject} to DDOL [{allEntities}] e={e}");
+                        }
                     }
                 }
                 else if (networkObject.HasAuthority)
@@ -2865,6 +2936,7 @@ internal void MoveObjectsToDontDestroyOnLoad()
         /// 
         internal void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearScenePlacedObjects = true)
         {
+            Log.Debug(() => $"PopulateScenePlacedObjects Scene={sceneToFilterBy.name} clearScenePlacedObjects={clearScenePlacedObjects}");
             if (clearScenePlacedObjects)
             {
                 ScenePlacedObjects.Clear();
@@ -2884,6 +2956,7 @@ internal void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearSceneP
             {
                 var globalObjectIdHash = networkObjectInstance.GlobalObjectIdHash;
                 var sceneHandle = networkObjectInstance.gameObject.scene.handle;
+                Log.Debug(() => $"PopulateScenePlacedObjects object={networkObjectInstance.gameObject} sceneHandle={sceneHandle} hash={globalObjectIdHash}");
                 // We check to make sure the NetworkManager instance is the same one to be "NetcodeIntegrationTestHelpers" compatible and filter the list on a per scene basis (for additive scenes)
                 if (networkObjectInstance.IsSceneObject != false && (networkObjectInstance.NetworkManager == NetworkManager ||
                     networkObjectInstance.NetworkManagerOwner == null) && sceneHandle == sceneToFilterBy.handle)
@@ -2899,9 +2972,11 @@ internal void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearSceneP
                     }
                     else
                     {
+                        Log.Error(() => $"Duplicate hash ids from object={ScenePlacedObjects[globalObjectIdHash][sceneHandle].gameObject.NetworkGetScenePath()}");
                         var exitingEntryName = ScenePlacedObjects[globalObjectIdHash][sceneHandle] != null ? ScenePlacedObjects[globalObjectIdHash][sceneHandle].name : "Null Entry";
-                        throw new Exception($"{networkObjectInstance.name} tried to registered with {nameof(ScenePlacedObjects)} which already contains " +
+                        string expStr = ($"{networkObjectInstance.name} tried to registered with {nameof(ScenePlacedObjects)} which already contains " +
                             $"the same {nameof(NetworkObject.GlobalObjectIdHash)} value {globalObjectIdHash} for {exitingEntryName}!");
+                        Log.Error(() => expStr);
                     }
                 }
             }
@@ -3029,7 +3104,7 @@ internal void NotifyNetworkObjectSceneChanged(NetworkObject networkObject)
         /// or invoked by  when a client finishes
         /// synchronization.
         /// 
-        internal void MigrateNetworkObjectsIntoScenes()
+        public void MigrateNetworkObjectsIntoScenes()
         {
             try
             {
@@ -3049,9 +3124,9 @@ internal void MigrateNetworkObjectsIntoScenes()
                                 var scene = ScenesLoaded[clientSceneHandle];
                                 foreach (var networkObject in ownerEntry.Value)
                                 {
-                                    SceneManager.MoveGameObjectToScene(networkObject.gameObject, scene);
+                                    SceneManager.MoveGameObjectToScene(networkObject.gameObject, scene.SceneReference);
                                     networkObject.NetworkSceneHandle = sceneEntry.Key;
-                                    networkObject.SceneOriginHandle = scene.handle;
+                                    networkObject.SceneOriginHandle = scene.SceneReference.handle;
                                 }
                             }
                         }
@@ -3280,7 +3355,7 @@ public List GetSceneMapping(MapTypes mapType)
             {
                 foreach (var entry in ServerSceneHandleToClientSceneHandle)
                 {
-                    var scene = ScenesLoaded[entry.Value];
+                    var scene = ScenesLoaded[entry.Value].SceneReference;
                     var sceneIsPresent = scene.IsValid() && scene.isLoaded;
                     var sceneMap = new SceneMap()
                     {
@@ -3299,7 +3374,7 @@ public List GetSceneMapping(MapTypes mapType)
             {
                 foreach (var entry in ClientSceneHandleToServerSceneHandle)
                 {
-                    var scene = ScenesLoaded[entry.Key];
+                    var scene = ScenesLoaded[entry.Key].SceneReference;
                     var sceneIsPresent = scene.IsValid() && scene.isLoaded;
                     var sceneMap = new SceneMap()
                     {
diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs
index 943f54aff2..d0eff4ee43 100644
--- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs
+++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs
@@ -3,6 +3,7 @@
 using System.Linq;
 using System.Text;
 using Unity.Collections;
+using UnityEngine;
 using UnityEngine.SceneManagement;
 
 namespace Unity.Netcode
@@ -105,12 +106,12 @@ internal class SceneEventData : IDisposable
         internal ForceNetworkSerializeByMemcpy SceneEventProgressId;
         internal uint SceneEventId;
 
-        internal uint ActiveSceneHash;
-        internal uint SceneHash;
+        internal string ActiveSceneAsset;
+        internal string SceneAsset;
         internal int SceneHandle;
 
         // Used by the client during synchronization
-        internal uint ClientSceneHash;
+        internal string ClientSceneName;
         internal int NetworkSceneHandle;
 
         /// Only used for  scene events, this assures permissions when writing
@@ -150,7 +151,7 @@ internal class SceneEventData : IDisposable
         internal List ClientsCompleted;
         internal List ClientsTimedOut;
 
-        internal Queue ScenesToSynchronize;
+        internal Queue ScenesToSynchronize;
         internal Queue SceneHandlesToSynchronize;
 
         internal LoadSceneMode ClientSynchronizationMode;
@@ -170,7 +171,7 @@ internal class SceneEventData : IDisposable
         /// 
         /// 
         /// 
-        internal void AddSceneToSynchronize(uint sceneHash, int sceneHandle)
+        internal void AddSceneToSynchronize(string sceneHash, int sceneHandle)
         {
             ScenesToSynchronize.Enqueue(sceneHash);
             SceneHandlesToSynchronize.Enqueue((uint)sceneHandle);
@@ -181,7 +182,7 @@ internal void AddSceneToSynchronize(uint sceneHash, int sceneHandle)
         /// Gets the next scene hash to be loaded for approval and/or late joining
         /// 
         /// 
-        internal uint GetNextSceneSynchronizationHash()
+        internal string GetNextSceneSynchronizationHash()
         {
             return ScenesToSynchronize.Dequeue();
         }
@@ -232,7 +233,7 @@ internal void InitializeForSynch()
 
             if (ScenesToSynchronize == null)
             {
-                ScenesToSynchronize = new Queue();
+                ScenesToSynchronize = new Queue();
             }
             else
             {
@@ -491,7 +492,7 @@ internal void Serialize(FastBufferWriter writer)
 
             if (SceneEventType == SceneEventType.ActiveSceneChanged)
             {
-                writer.WriteValueSafe(ActiveSceneHash);
+                writer.WriteValueSafe(ActiveSceneAsset);
                 return;
             }
 
@@ -515,15 +516,21 @@ internal void Serialize(FastBufferWriter writer)
             }
 
             // Write the scene index and handle
-            writer.WriteValueSafe(SceneHash);
+            var sceneName = SceneAsset ?? "";
+            writer.WriteValueSafe(sceneName);
             writer.WriteValueSafe(SceneHandle);
 
             switch (SceneEventType)
             {
                 case SceneEventType.Synchronize:
                     {
-                        writer.WriteValueSafe(ActiveSceneHash);
+                        if (ActiveSceneAsset == null)
+                        {
+                            Debug.LogError($"Synchronizing - ActiveSceneAsset but it hasn't been initialized yet");
+                            ActiveSceneAsset = "";
+                        }
 
+                        writer.WriteValueSafe(ActiveSceneAsset);
                         WriteSceneSynchronizationData(writer);
 
                         if (EnableSerializationLogs)
@@ -582,7 +589,13 @@ internal void WriteSceneSynchronizationData(FastBufferWriter writer)
                 builder.AppendLine($"[Write][Synchronize-Start][WPos: {writer.Position}] Begin:");
             }
             // Write the scenes we want to load, in the order we want to load them
-            writer.WriteValueSafe(ScenesToSynchronize.ToArray());
+            var valArray = ScenesToSynchronize.ToArray();
+            writer.WriteValueSafe(valArray.Length);
+            foreach (var v in valArray)
+            {
+                writer.WriteValueSafe(v);
+            }
+
             writer.WriteValueSafe(SceneHandlesToSynchronize.ToArray());
             // Store our current position in the stream to come back and say how much data we have written
             var positionStart = writer.Position;
@@ -737,7 +750,7 @@ internal void Deserialize(FastBufferReader reader)
 
             if (SceneEventType == SceneEventType.ActiveSceneChanged)
             {
-                reader.ReadValueSafe(out ActiveSceneHash);
+                reader.ReadValueSafe(out ActiveSceneAsset);
                 return;
             }
 
@@ -767,14 +780,14 @@ internal void Deserialize(FastBufferReader reader)
                 reader.ReadValueSafe(out ClientSynchronizationMode);
             }
 
-            reader.ReadValueSafe(out SceneHash);
+            reader.ReadValueSafe(out SceneAsset);
             reader.ReadValueSafe(out SceneHandle);
 
             switch (SceneEventType)
             {
                 case SceneEventType.Synchronize:
                     {
-                        reader.ReadValueSafe(out ActiveSceneHash);
+                        reader.ReadValueSafe(out ActiveSceneAsset);
                         if (EnableSerializationLogs)
                         {
                             LogArray(reader.ToArray(), 0, reader.Length);
@@ -824,9 +837,15 @@ internal void Deserialize(FastBufferReader reader)
         internal void CopySceneSynchronizationData(FastBufferReader reader)
         {
             m_NetworkObjectsSync.Clear();
-            reader.ReadValueSafe(out uint[] scenesToSynchronize);
+            reader.ReadValueSafe(out int sceneCount);
+            ScenesToSynchronize = new Queue();
+            for (int i = 0; i < sceneCount; i++)
+            {
+                reader.ReadValueSafe(out string s);
+                ScenesToSynchronize.Enqueue(s);
+            }
+
             reader.ReadValueSafe(out uint[] sceneHandlesToSynchronize);
-            ScenesToSynchronize = new Queue(scenesToSynchronize);
             SceneHandlesToSynchronize = new Queue(sceneHandlesToSynchronize);
 
             // is not packed!
diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventProgress.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventProgress.cs
index e9b52a218e..5b1858b362 100644
--- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventProgress.cs
+++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventProgress.cs
@@ -1,7 +1,11 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Threading.Tasks;
+using TrollKing.Core;
 using UnityEngine;
+using UnityEngine.ResourceManagement.AsyncOperations;
+using UnityEngine.ResourceManagement.ResourceProviders;
 using UnityEngine.SceneManagement;
 using AsyncOperation = UnityEngine.AsyncOperation;
 
@@ -65,8 +69,10 @@ public enum SceneEventProgressStatus
     /// Server side only:
     /// This tracks the progress of clients during a load or unload scene event
     /// 
-    internal class SceneEventProgress
+    public class SceneEventProgress
     {
+        private static NetworkLogScope Log = new NetworkLogScope(nameof(SceneEventProgress));
+
         /// 
         /// List of clientIds of those clients that is done loading the scene.
         /// 
@@ -81,14 +87,14 @@ internal class SceneEventProgress
         /// 
         /// Delegate type for when the switch scene progress is completed. Either by all clients done loading the scene or by time out.
         /// 
-        internal delegate bool OnCompletedDelegate(SceneEventProgress sceneEventProgress);
+        public delegate bool OnCompletedDelegate(SceneEventProgress sceneEventProgress);
 
         /// 
         /// The callback invoked when the switch scene progress is completed. Either by all clients done loading the scene or by time out.
         /// 
-        internal OnCompletedDelegate OnComplete;
+        public OnCompletedDelegate OnComplete;
 
-        internal Action OnSceneEventCompleted;
+        public Action OnSceneEventCompleted;
 
         /// 
         /// This will make sure that we only have timed out if we never completed
@@ -101,17 +107,17 @@ internal bool HasTimedOut()
         /// 
         /// The hash value generated from the full scene path
         /// 
-        internal uint SceneHash { get; set; }
+        internal string SceneName { get; set; }
 
         internal Guid Guid { get; } = Guid.NewGuid();
         internal uint SceneEventId;
 
         private Coroutine m_TimeOutCoroutine;
-        private AsyncOperation m_AsyncOperation;
+        private AsyncOperationHandle m_AsyncOperation;
 
         private NetworkManager m_NetworkManager { get; }
 
-        internal SceneEventProgressStatus Status { get; set; }
+        public SceneEventProgressStatus Status { get; set; }
 
         internal SceneEventType SceneEventType { get; set; }
 
@@ -124,7 +130,7 @@ internal List GetClientsWithStatus(bool completedSceneEvent)
             {
                 // If we are the host, then add the host-client to the list
                 // of clients that completed if the AsyncOperation is done.
-                if (m_NetworkManager.IsHost && m_AsyncOperation.isDone)
+                if (m_NetworkManager.IsHost && m_AsyncOperation.IsDone)
                 {
                     clients.Add(m_NetworkManager.LocalClientId);
                 }
@@ -143,7 +149,7 @@ internal List GetClientsWithStatus(bool completedSceneEvent)
                 // If we are the host, then add the host-client to the list
                 // of clients that did not complete if the AsyncOperation is
                 // not done.
-                if (m_NetworkManager.IsHost && !m_AsyncOperation.isDone)
+                if (m_NetworkManager.IsHost && !m_AsyncOperation.IsDone)
                 {
                     clients.Add(m_NetworkManager.LocalClientId);
                 }
@@ -254,22 +260,65 @@ private bool HasFinished()
             // Note: Integration tests process scene loading through a queue
             // and the AsyncOperation could not be assigned for several
             // network tick periods. Return false if that is the case.
-            return m_AsyncOperation == null ? false : m_AsyncOperation.isDone;
+
+            // If we're async loading a scene that we tell not to activate, we need to check that the downstream scene has been activated before calling out
+            var initialValid = m_AsyncOperation.IsValid() && m_AsyncOperation.IsDone;
+            if (initialValid)
+            {
+                var res = m_AsyncOperation.Result;
+                return res.Scene.isLoaded;
+            }
+
+            return false;
+        }
+
+        public AsyncOperationHandle GetHandle()
+        {
+            return m_AsyncOperation;
         }
 
         /// 
         /// Sets the AsyncOperation for the scene load/unload event
         /// 
-        internal void SetAsyncOperation(AsyncOperation asyncOperation)
+        public void SetAsyncOperation(AsyncOperationHandle asyncOperation)
         {
+            if (!asyncOperation.IsValid())
+            {
+                Log.Error(() => $"Async Operation handle is invalid!");
+                return;
+            }
+
+            // Debug.Log($"[SceneEventProgress] SetAsyncOperation ");
             m_AsyncOperation = asyncOperation;
-            m_AsyncOperation.completed += new Action(asyncOp2 =>
+            m_AsyncOperation.Completed += new Action>(asyncOp2 =>
             {
                 // Don't invoke the callback if the network session is disconnected
                 // during a SceneEventProgress
-                if (IsNetworkSessionActive())
+                if (asyncOp2.Status == AsyncOperationStatus.Succeeded)
+                {
+                    var sceneInstance = asyncOp2.Result;
+                    if (!sceneInstance.Scene.isLoaded)
+                    {
+                        var asyncLoad = sceneInstance.ActivateAsync();
+                        asyncLoad.completed += operation =>
+                        {
+                            if (IsNetworkSessionActive())
+                            {
+                                OnSceneEventCompleted?.Invoke(SceneEventId, asyncOp2.Result.Scene.name);
+                            }
+                        };
+                    }
+                    else
+                    {
+                        if (IsNetworkSessionActive())
+                        {
+                            OnSceneEventCompleted?.Invoke(SceneEventId, asyncOp2.Result.Scene.name);
+                        }
+                    }
+                }
+                else
                 {
-                    OnSceneEventCompleted?.Invoke(SceneEventId);
+                    Debug.LogError($"Failed to load async scene: {asyncOp2.OperationException}");
                 }
 
                 // Go ahead and try finishing even if the network session is terminated/terminating
diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs
index fe0dd270e9..3b39eb8938 100644
--- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using TrollKing.Core;
 using UnityEngine;
 
 namespace Unity.Netcode
@@ -50,6 +51,8 @@ public interface INetworkPrefabInstanceHandler
     /// 
     public class NetworkPrefabHandler
     {
+        private static readonly NetworkLogScope k_Log = new NetworkLogScope(nameof(NetworkPrefabHandler));
+
         private NetworkManager m_NetworkManager;
 
         /// 
@@ -315,7 +318,12 @@ public GameObject GetNetworkPrefabOverride(GameObject gameObject)
                         case NetworkPrefabOverride.Hash:
                         case NetworkPrefabOverride.Prefab:
                             {
-                                return m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[networkObject.GlobalObjectIdHash].OverridingTargetPrefab;
+                                var res = m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[networkObject.GlobalObjectIdHash].OverridingTargetPrefab;
+                                k_Log.Debug(() => $"NetworkPrefabHandler GetNetworkPrefabOverride [gameObject={gameObject.name}] [networkPrefab={networkObject.GlobalObjectIdHash}]" +
+                                          $"[overrideType={m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[networkObject.GlobalObjectIdHash].Override}]" +
+                                          $"[overrideObj={m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[networkObject.GlobalObjectIdHash].OverridingTargetPrefab}]");
+
+                                return res;
                             }
                     }
                 }
@@ -360,12 +368,18 @@ public void AddNetworkPrefab(GameObject prefab)
 
             var networkPrefab = new NetworkPrefab { Prefab = prefab };
             bool added = m_NetworkManager.NetworkConfig.Prefabs.Add(networkPrefab);
+            k_Log.Debug(() => $"NetworkPrefabHandler AddNetworkPrefab prefab={prefab.name} hash={networkObject.GlobalObjectIdHash}");
             if (m_NetworkManager.IsListening && added)
             {
                 m_NetworkManager.DeferredMessageManager.ProcessTriggers(IDeferredNetworkMessageManager.TriggerType.OnAddPrefab, networkObject.GlobalObjectIdHash);
             }
         }
 
+        public IReadOnlyList GetPrefabs()
+        {
+            return m_NetworkManager.NetworkConfig.Prefabs.Prefabs;
+        }
+
         /// 
         /// Remove a prefab from the prefab list.
         /// As with AddNetworkPrefab, this is specific to the client it's called on -
@@ -406,6 +420,7 @@ internal void RegisterPlayerPrefab()
                     //In the event there is no NetworkPrefab entry (i.e. no override for default player prefab)
                     if (!networkConfig.Prefabs.NetworkPrefabOverrideLinks.ContainsKey(playerPrefabNetworkObject.GlobalObjectIdHash))
                     {
+                        k_Log.Debug(() => $"[NetworkPrefabHandler] RegisterPlayerPrefab - PlayerPrefab={networkConfig.PlayerPrefab.name} hash={playerPrefabNetworkObject.GlobalObjectIdHash}");
                         //Then add a new entry for the player prefab
                         AddNetworkPrefab(networkConfig.PlayerPrefab);
                     }
diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs
index 19227c82ba..86a116ee0d 100644
--- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs
@@ -4,6 +4,7 @@
 using System.Linq;
 using System.Text;
 using UnityEngine;
+using TrollKing.Core;
 
 namespace Unity.Netcode
 {
@@ -12,6 +13,7 @@ namespace Unity.Netcode
     /// 
     public class NetworkSpawnManager
     {
+        private static readonly NetworkLogScope Log = new NetworkLogScope(nameof(NetworkSpawnManager));
         // Stores the objects that need to be shown at end-of-frame
         internal Dictionary> ObjectsToShowToClient = new Dictionary>();
 
@@ -1512,12 +1514,14 @@ internal void ServerSpawnSceneObjectsOnStartSweep()
                 }
             }
 
+            Log.Info(() => "ServerSpawnSceneObjectsOnStartSweep");
+
             // Since we are spawing in-scene placed NetworkObjects for already loaded scenes,
             // we need to add any in-scene placed NetworkObject to our tracking table
             var clearFirst = true;
             foreach (var sceneLoaded in NetworkManager.SceneManager.ScenesLoaded)
             {
-                NetworkManager.SceneManager.PopulateScenePlacedObjects(sceneLoaded.Value, clearFirst);
+                NetworkManager.SceneManager.PopulateScenePlacedObjects(sceneLoaded.Value.SceneReference, clearFirst);
                 clearFirst = false;
             }
 
diff --git a/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef b/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef
index d68a562768..ba65fbd7f2 100644
--- a/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef
+++ b/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef
@@ -13,7 +13,9 @@
         "Unity.Networking.Transport",
         "Unity.Collections",
         "Unity.Burst",
-        "Unity.Mathematics"
+        "Unity.Mathematics",
+        "Unity.ResourceManager",
+        "Unity.Addressables"
     ],
     "includePlatforms": [],
     "excludePlatforms": [],
diff --git a/com.unity.netcode.gameobjects/Samples~/Bootstrap/Prefabs/BootstrapPlayer.prefab b/com.unity.netcode.gameobjects/Samples~/Bootstrap/Prefabs/BootstrapPlayer.prefab
index 5b7b44713f..34fd335d94 100644
--- a/com.unity.netcode.gameobjects/Samples~/Bootstrap/Prefabs/BootstrapPlayer.prefab
+++ b/com.unity.netcode.gameobjects/Samples~/Bootstrap/Prefabs/BootstrapPlayer.prefab
@@ -29,12 +29,13 @@ Transform:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 3439633038736912633}
+  serializedVersion: 2
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
   m_LocalPosition: {x: 0, y: 0, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
   m_Children: []
   m_Father: {fileID: 0}
-  m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!33 &3439633038736913157
 MeshFilter:
@@ -55,11 +56,15 @@ MeshRenderer:
   m_CastShadows: 1
   m_ReceiveShadows: 1
   m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
   m_MotionVectors: 1
   m_LightProbeUsage: 1
   m_ReflectionProbeUsage: 1
   m_RayTracingMode: 2
   m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
   m_RenderingLayerMask: 1
   m_RendererPriority: 0
   m_Materials:
@@ -93,9 +98,17 @@ SphereCollider:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 3439633038736912633}
   m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
   m_IsTrigger: 0
+  m_ProvidesContacts: 0
   m_Enabled: 1
-  serializedVersion: 2
+  serializedVersion: 3
   m_Radius: 0.5
   m_Center: {x: 0, y: 0, z: 0}
 --- !u!114 &3439633038736912634
@@ -110,8 +123,12 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  GlobalObjectIdHash: 951099334
+  GlobalObjectIdHash: 2131729030
   AlwaysReplicateAsRoot: 0
+  SynchronizeTransform: 1
+  ActiveSceneSynchronization: 0
+  SceneMigrationSynchronization: 1
+  SpawnWithObservers: 1
   DontDestroyWithOwner: 0
   AutoObjectParentSync: 1
 --- !u!114 &2776227185612554462
@@ -138,9 +155,12 @@ MonoBehaviour:
   PositionThreshold: 0
   RotAngleThreshold: 0
   ScaleThreshold: 0
+  UseQuaternionSynchronization: 0
+  UseQuaternionCompression: 0
+  UseHalfFloatPrecision: 0
   InLocalSpace: 0
   Interpolate: 1
-  FixedSendsPerSecond: 30
+  SlerpPosition: 0
 --- !u!114 &6046305264893698362
 MonoBehaviour:
   m_ObjectHideFlags: 0
diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/IntegrationTestSceneHandler.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/IntegrationTestSceneHandler.cs
index a023bc1d65..a97454a5d3 100644
--- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/IntegrationTestSceneHandler.cs
+++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/IntegrationTestSceneHandler.cs
@@ -3,6 +3,9 @@
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
+using UnityEngine.AddressableAssets;
+using UnityEngine.ResourceManagement.AsyncOperations;
+using UnityEngine.ResourceManagement.ResourceProviders;
 using UnityEngine.SceneManagement;
 using Object = UnityEngine.Object;
 
@@ -59,7 +62,7 @@ public enum JobTypes
             }
             public JobTypes JobType;
             public string SceneName;
-            public Scene Scene;
+            public SceneInstance Scene;
             public SceneEventProgress SceneEventProgress;
             public IntegrationTestSceneHandler IntegrationTestSceneHandler;
         }
@@ -118,7 +121,8 @@ internal static IEnumerator ProcessLoadingSceneJob(QueuedSceneJob queuedSceneJob
 
             SceneManager.sceneLoaded += SceneManager_sceneLoaded;
             // We always load additively for all scenes during integration tests
-            var asyncOperation = SceneManager.LoadSceneAsync(queuedSceneJob.SceneName, LoadSceneMode.Additive);
+            var asyncOperation = Addressables.LoadSceneAsync(queuedSceneJob.SceneName, LoadSceneMode.Additive);
+
             queuedSceneJob.SceneEventProgress.SetAsyncOperation(asyncOperation);
 
             // Wait for it to finish
@@ -208,9 +212,9 @@ internal static IEnumerator ProcessUnloadingSceneJob(QueuedSceneJob queuedSceneJ
             }
 
             SceneManager.sceneUnloaded += SceneManager_sceneUnloaded;
-            if (queuedSceneJob.Scene.IsValid() && queuedSceneJob.Scene.isLoaded && !queuedSceneJob.Scene.name.Contains(NetcodeIntegrationTestHelpers.FirstPartOfTestRunnerSceneName))
+            if (queuedSceneJob.Scene.Scene.IsValid() && queuedSceneJob.Scene.Scene.isLoaded && !queuedSceneJob.Scene.Scene.name.Contains(NetcodeIntegrationTestHelpers.FirstPartOfTestRunnerSceneName))
             {
-                var asyncOperation = SceneManager.UnloadSceneAsync(queuedSceneJob.Scene);
+                var asyncOperation = Addressables.UnloadSceneAsync(queuedSceneJob.Scene);
                 queuedSceneJob.SceneEventProgress.SetAsyncOperation(asyncOperation);
             }
             else
@@ -230,7 +234,7 @@ internal static IEnumerator ProcessUnloadingSceneJob(QueuedSceneJob queuedSceneJ
         /// 
         private static void SceneManager_sceneUnloaded(Scene scene)
         {
-            if (CurrentQueuedSceneJob.JobType != QueuedSceneJob.JobTypes.Completed && CurrentQueuedSceneJob.Scene.name == scene.name)
+            if (CurrentQueuedSceneJob.JobType != QueuedSceneJob.JobTypes.Completed && CurrentQueuedSceneJob.Scene.Scene.name == scene.name)
             {
                 SceneManager.sceneUnloaded -= SceneManager_sceneUnloaded;
 
@@ -280,15 +284,15 @@ private void AddJobToQueue(QueuedSceneJob queuedSceneJob)
         /// 
         /// Server always loads like it normally would
         /// 
-        public AsyncOperation GenericLoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress)
+        public AsyncOperationHandle GenericLoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress)
         {
             m_ServerSceneBeingLoaded = sceneName;
             if (NetcodeIntegrationTest.IsRunning)
             {
                 SceneManager.sceneLoaded += Sever_SceneLoaded;
             }
-            var operation = SceneManager.LoadSceneAsync(sceneName, loadSceneMode);
-            sceneEventProgress.SetAsyncOperation(operation);
+            var operation = Addressables.LoadSceneAsync(sceneName, loadSceneMode);
+            // sceneEventProgress.SetAsyncOperation(operation);
             return operation;
         }
 
@@ -304,42 +308,42 @@ private void Sever_SceneLoaded(Scene scene, LoadSceneMode arg1)
         /// 
         /// Server always unloads like it normally would
         /// 
-        public AsyncOperation GenericUnloadSceneAsync(Scene scene, SceneEventProgress sceneEventProgress)
+        public AsyncOperationHandle GenericUnloadSceneAsync(SceneInstance scene, SceneEventProgress sceneEventProgress)
         {
-            var operation = SceneManager.UnloadSceneAsync(scene);
+            var operation = Addressables.UnloadSceneAsync(scene);
             sceneEventProgress.SetAsyncOperation(operation);
             return operation;
         }
 
 
-        public AsyncOperation LoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress)
+        public AsyncOperationHandle LoadSceneAsync(string sceneAssetKey, LoadSceneMode loadSceneMode, SceneEventProgress sceneEventProgress)
         {
             // Server and non NetcodeIntegrationTest tests use the generic load scene method
             if (!NetcodeIntegrationTest.IsRunning)
             {
-                return GenericLoadSceneAsync(sceneName, loadSceneMode, sceneEventProgress);
+                return GenericLoadSceneAsync(sceneAssetKey, loadSceneMode, sceneEventProgress);
             }
             else // NetcodeIntegrationTest Clients always get added to the jobs queue
             {
-                AddJobToQueue(new QueuedSceneJob() { IntegrationTestSceneHandler = this, SceneName = sceneName, SceneEventProgress = sceneEventProgress, JobType = QueuedSceneJob.JobTypes.Loading });
+                AddJobToQueue(new QueuedSceneJob() { IntegrationTestSceneHandler = this, SceneName = sceneAssetKey, SceneEventProgress = sceneEventProgress, JobType = QueuedSceneJob.JobTypes.Loading });
             }
 
-            return null;
+            return default;
         }
 
-        public AsyncOperation UnloadSceneAsync(Scene scene, SceneEventProgress sceneEventProgress)
+        public AsyncOperationHandle UnloadSceneAsync(NetworkSceneManager.SceneData scene, SceneEventProgress sceneEventProgress)
         {
             // Server and non NetcodeIntegrationTest tests use the generic unload scene method
             if (!NetcodeIntegrationTest.IsRunning)
             {
-                return GenericUnloadSceneAsync(scene, sceneEventProgress);
+                return GenericUnloadSceneAsync(scene.SceneInstance.Value, sceneEventProgress);
             }
             else // NetcodeIntegrationTest Clients always get added to the jobs queue
             {
-                AddJobToQueue(new QueuedSceneJob() { IntegrationTestSceneHandler = this, Scene = scene, SceneEventProgress = sceneEventProgress, JobType = QueuedSceneJob.JobTypes.Unloading });
+                AddJobToQueue(new QueuedSceneJob() { IntegrationTestSceneHandler = this, Scene = scene.SceneInstance.Value, SceneEventProgress = sceneEventProgress, JobType = QueuedSceneJob.JobTypes.Unloading });
             }
             // This is OK to return a "nothing" AsyncOperation since we are simulating client loading
-            return null;
+            return default;
         }
 
         /// 
@@ -381,7 +385,7 @@ internal Scene GetAndAddNewlyLoadedSceneByName(string sceneName)
                         {
                             continue;
                         }
-                        NetworkManager.SceneManager.ScenesLoaded.Add(sceneLoaded.handle, sceneLoaded);
+                        NetworkManager.SceneManager.ScenesLoaded.Add(sceneLoaded.handle, new NetworkSceneManager.SceneData(null, sceneLoaded));
                         StartTrackingScene(sceneLoaded, true, NetworkManager);
                         return sceneLoaded;
                     }
@@ -594,7 +598,7 @@ public Scene GetSceneFromLoadedScenes(string sceneName, NetworkManager networkMa
             return m_InvalidScene;
         }
 
-        public void PopulateLoadedScenes(ref Dictionary scenesLoaded, NetworkManager networkManager)
+        public void PopulateLoadedScenes(ref Dictionary scenesLoaded, NetworkManager networkManager)
         {
             if (!SceneNameToSceneHandles.ContainsKey(networkManager))
             {
@@ -632,7 +636,7 @@ public void PopulateLoadedScenes(ref Dictionary scenesLoaded, Networ
                     SceneNameToSceneHandles[networkManager][scene.name].Add(scene.handle, sceneEntry);
                     if (!scenesLoaded.ContainsKey(scene.handle))
                     {
-                        scenesLoaded.Add(scene.handle, scene);
+                        scenesLoaded.Add(scene.handle, new NetworkSceneManager.SceneData(null, scene));
                     }
                 }
                 else
@@ -861,7 +865,7 @@ public void SetClientSynchronizationMode(ref NetworkManager networkManager, Load
                     if (!sceneManager.ScenesLoaded.ContainsKey(scene.handle))
                     {
                         StartTrackingScene(scene, true, networkManager);
-                        sceneManager.ScenesLoaded.Add(scene.handle, scene);
+                        sceneManager.ScenesLoaded.Add(scene.handle, new NetworkSceneManager.SceneData(null, scene));
                     }
                 }
             }
diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs
index 2f5f975ecd..789ef2d494 100644
--- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs
+++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs
@@ -421,7 +421,7 @@ private static void SceneManagerValidationAndTestRunnerInitialization(NetworkMan
                 // with the clients.
                 if (!networkManager.SceneManager.ScenesLoaded.ContainsKey(scene.handle))
                 {
-                    networkManager.SceneManager.ScenesLoaded.Add(scene.handle, scene);
+                    networkManager.SceneManager.ScenesLoaded.Add(scene.handle, new NetworkSceneManager.SceneData(null, scene));
                 }
                 // In distributed authority we need to check if this scene is already added
                 if (networkManager.DistributedAuthorityMode)
diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/com.unity.netcode.testhelpers.runtime.asmdef b/com.unity.netcode.gameobjects/TestHelpers/Runtime/com.unity.netcode.testhelpers.runtime.asmdef
index 2fb107c79f..14fad83862 100644
--- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/com.unity.netcode.testhelpers.runtime.asmdef
+++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/com.unity.netcode.testhelpers.runtime.asmdef
@@ -6,7 +6,9 @@
         "Unity.Multiplayer.MetricTypes",
         "Unity.Multiplayer.NetStats",
         "Unity.Multiplayer.Tools.MetricTypes",
-        "Unity.Multiplayer.Tools.NetStats"
+        "Unity.Multiplayer.Tools.NetStats",
+        "Unity.ResourceManager",
+        "Unity.Addressables"
     ],
     "optionalUnityReferences": [
         "TestAssemblies"
diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageCorruptionTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageCorruptionTests.cs
index eb2ed8a18d..2403402701 100644
--- a/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageCorruptionTests.cs
+++ b/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageCorruptionTests.cs
@@ -90,11 +90,16 @@ public unsafe void Send(ulong clientId, NetworkDelivery delivery, FastBufferWrit
                             break;
                         }
                     case TypeOfCorruption.CorruptBytes:
-                        batchData.Seek(batchData.Length - 2);
-                        var currentByte = batchData.GetUnsafePtr()[0];
-                        batchData.WriteByteSafe((byte)(currentByte == 0 ? 1 : 0));
-                        MessageQueue.Add(batchData.ToArray());
-                        break;
+                        {
+                            batchData.Seek(batchData.Length - 4);
+                            for (int i = 0; i < 4; i++)
+                            {
+                                var currentByte = batchData.GetUnsafePtr()[i];
+                                batchData.WriteByteSafe((byte)(currentByte == 0 ? 1 : 0));
+                                MessageQueue.Add(batchData.ToArray());
+                            }
+                            break;
+                        }
                     case TypeOfCorruption.Truncated:
                         batchData.Truncate(batchData.Length - 1);
                         MessageQueue.Add(batchData.ToArray());
diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs
index af69df9aa8..2a89327bc4 100644
--- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs
+++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs
@@ -347,7 +347,7 @@ public IEnumerator SceneEventMessageLoad()
                 SceneEventType = SceneEventType.Load,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -373,7 +373,7 @@ public IEnumerator SceneEventMessageLoadWithObjects()
                 SceneEventType = SceneEventType.Load,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -393,7 +393,7 @@ public IEnumerator SceneEventMessageUnload()
                 SceneEventType = SceneEventType.Unload,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -413,7 +413,7 @@ public IEnumerator SceneEventMessageLoadComplete()
                 SceneEventType = SceneEventType.LoadComplete,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -433,7 +433,7 @@ public IEnumerator SceneEventMessageUnloadComplete()
                 SceneEventType = SceneEventType.UnloadComplete,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -453,7 +453,7 @@ public IEnumerator SceneEventMessageLoadCompleted()
                 SceneEventType = SceneEventType.LoadEventCompleted,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
                 ClientsCompleted = new List() { k_ClientId },
                 ClientsTimedOut = new List() { 123456789 },
@@ -475,7 +475,7 @@ public IEnumerator SceneEventMessageUnloadLoadCompleted()
                 SceneEventType = SceneEventType.UnloadEventCompleted,
                 LoadSceneMode = LoadSceneMode.Single,
                 SceneEventProgressId = Guid.NewGuid(),
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
                 ClientsCompleted = new List() { k_ClientId },
                 ClientsTimedOut = new List() { 123456789 },
@@ -497,11 +497,11 @@ public IEnumerator SceneEventMessageSynchronize()
                 SceneEventType = SceneEventType.Synchronize,
                 LoadSceneMode = LoadSceneMode.Single,
                 ClientSynchronizationMode = LoadSceneMode.Single,
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
-                ScenesToSynchronize = new Queue()
+                ScenesToSynchronize = new Queue()
             };
-            eventData.ScenesToSynchronize.Enqueue(101);
+            eventData.ScenesToSynchronize.Enqueue("SomeRandomSceneName2");
             eventData.SceneHandlesToSynchronize = new Queue();
             eventData.SceneHandlesToSynchronize.Enqueue(202);
 
@@ -522,7 +522,7 @@ public IEnumerator SceneEventMessageReSynchronize()
                 SceneEventType = SceneEventType.ReSynchronize,
                 LoadSceneMode = LoadSceneMode.Single,
                 ClientSynchronizationMode = LoadSceneMode.Single,
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -542,7 +542,7 @@ public IEnumerator SceneEventMessageSynchronizeComplete()
                 SceneEventType = SceneEventType.ReSynchronize,
                 LoadSceneMode = LoadSceneMode.Single,
                 ClientSynchronizationMode = LoadSceneMode.Single,
-                SceneHash = XXHash.Hash32("SomeRandomSceneName"),
+                SceneAsset = "SomeRandomSceneName",
                 SceneHandle = 23456,
             };
 
@@ -560,7 +560,7 @@ public IEnumerator SceneEventMessageActiveSceneChanged()
             var eventData = new SceneEventData(Client)
             {
                 SceneEventType = SceneEventType.ActiveSceneChanged,
-                ActiveSceneHash = XXHash.Hash32("ActiveScene")
+                ActiveSceneAsset = "SomeRandomSceneName"
             };
 
             var message = new SceneEventMessage()
diff --git a/minimalproject/ProjectSettings/MemorySettings.asset b/minimalproject/ProjectSettings/MemorySettings.asset
new file mode 100644
index 0000000000..5b5facecac
--- /dev/null
+++ b/minimalproject/ProjectSettings/MemorySettings.asset
@@ -0,0 +1,35 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!387306366 &1
+MemorySettings:
+  m_ObjectHideFlags: 0
+  m_EditorMemorySettings:
+    m_MainAllocatorBlockSize: -1
+    m_ThreadAllocatorBlockSize: -1
+    m_MainGfxBlockSize: -1
+    m_ThreadGfxBlockSize: -1
+    m_CacheBlockSize: -1
+    m_TypetreeBlockSize: -1
+    m_ProfilerBlockSize: -1
+    m_ProfilerEditorBlockSize: -1
+    m_BucketAllocatorGranularity: -1
+    m_BucketAllocatorBucketsCount: -1
+    m_BucketAllocatorBlockSize: -1
+    m_BucketAllocatorBlockCount: -1
+    m_ProfilerBucketAllocatorGranularity: -1
+    m_ProfilerBucketAllocatorBucketsCount: -1
+    m_ProfilerBucketAllocatorBlockSize: -1
+    m_ProfilerBucketAllocatorBlockCount: -1
+    m_TempAllocatorSizeMain: -1
+    m_JobTempAllocatorBlockSize: -1
+    m_BackgroundJobTempAllocatorBlockSize: -1
+    m_JobTempAllocatorReducedBlockSize: -1
+    m_TempAllocatorSizeGIBakingWorker: -1
+    m_TempAllocatorSizeNavMeshWorker: -1
+    m_TempAllocatorSizeAudioWorker: -1
+    m_TempAllocatorSizeCloudWorker: -1
+    m_TempAllocatorSizeGfx: -1
+    m_TempAllocatorSizeJobWorker: -1
+    m_TempAllocatorSizeBackgroundWorker: -1
+    m_TempAllocatorSizePreloadManager: -1
+  m_PlatformMemorySettings: {}
diff --git a/minimalproject/ProjectSettings/boot.config b/minimalproject/ProjectSettings/boot.config
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/pvp-exemptions.json b/pvp-exemptions.json
new file mode 100644
index 0000000000..6c53ec94ca
--- /dev/null
+++ b/pvp-exemptions.json
@@ -0,0 +1,2835 @@
+{
+  "per_package": {
+    "com.unity.netcode.gameobjects@1": {
+      "exempts": {
+        "PVP-31-1": {
+          "errors": [
+            "LICENSE.md: license must match regex: ^(?.*?) copyright \\u00a9 \\d+ \\S(.*\\S)?(?:\\r?\\n|$)"
+          ]
+        },
+        "PVP-40-1": {
+          "errors": [
+            "CHANGELOG.md: line 196: header must match regex: ^\\[(?.*)\\]( - (?\\d{4}-\\d{2}-\\d{2}))?$"
+          ]
+        },
+        "PVP-41-1": {
+          "errors": [
+            "CHANGELOG.md: line 9: Unreleased section is not allowed for public release"
+          ]
+        },
+        "PVP-150-1": {
+          "errors": [
+            "Unity.Netcode.Components.AnticipatedNetworkTransform:  in list item context (only allowed in block or inline context)",
+            "Unity.Netcode.Components.AnticipatedNetworkTransform:  in list item context (only allowed in block or inline context)",
+            "Unity.Netcode.Components.AnticipatedNetworkTransform: void AnticipateMove(Vector3): empty  tag",
+            "Unity.Netcode.Components.AnticipatedNetworkTransform: void AnticipateRotate(Quaternion): empty  tag",
+            "Unity.Netcode.Components.AnticipatedNetworkTransform: void AnticipateScale(Vector3): empty  tag",
+            "Unity.Netcode.Components.AnticipatedNetworkTransform: void AnticipateState(TransformState): empty  tag",
+            "Unity.Netcode.Components.AnticipatedNetworkTransform: void Smooth(TransformState, TransformState, float): empty  tag",
+            "Unity.Netcode.AnticipatedNetworkVariable:  in list item context (only allowed in block or inline context)",
+            "Unity.Netcode.AnticipatedNetworkVariable:  in list item context (only allowed in block or inline context)",
+            "Unity.Netcode.AnticipatedNetworkVariable: void Anticipate(T): empty  tag",
+            "Unity.Netcode.AnticipatedNetworkVariable: void Smooth(in T, in T, float, AnticipatedNetworkVariable.SmoothDelegate): empty  tag",
+            "Unity.Netcode.RuntimeTests.BufferDataValidationComponent: bool IsTestComplete(): empty  tag",
+            "Unity.Netcode.BufferedLinearInterpolatorVector3: XML is not well-formed: Missing closing quotation mark for string literal",
+            "Unity.Netcode.BufferSerializer: void SerializeValue(ref NativeArray, Allocator): unexpected ",
+            "Unity.Netcode.BufferSerializer: bool PreCheck(int): empty  tag",
+            "Unity.Netcode.BufferSerializer: bool PreCheck(int): empty  tag",
+            "Unity.Netcode.BytePacker:  in block context; use  instead",
+            "Unity.Netcode.ByteUnpacker:  in block context; use  instead",
+            "Unity.Netcode.ByteUnpacker: void ReadValuePacked(FastBufferReader, out string): empty  tag",
+            "Unity.Netcode.FastBufferReader:  in block context; use  instead",
+            "Unity.Netcode.FastBufferReader: .ctor(NativeArray, Allocator, int, int, Allocator):  in block context (only allowed in top-level context)",
+            "Unity.Netcode.FastBufferReader: .ctor(NativeArray, Allocator, int, int, Allocator): empty  tag",
+            "Unity.Netcode.FastBufferReader: .ctor(byte*, Allocator, int, int, Allocator):  in block context (only allowed in top-level context)",
+            "Unity.Netcode.FastBufferReader: .ctor(byte*, Allocator, int, int, Allocator): empty  tag",
+            "Unity.Netcode.FastBufferReader: .ctor(FastBufferWriter, Allocator, int, int, Allocator):  in block context (only allowed in top-level context)",
+            "Unity.Netcode.FastBufferReader: .ctor(FastBufferWriter, Allocator, int, int, Allocator): empty  tag",
+            "Unity.Netcode.FastBufferReader: .ctor(FastBufferReader, Allocator, int, int, Allocator):  in block context (only allowed in top-level context)",
+            "Unity.Netcode.FastBufferReader: .ctor(FastBufferReader, Allocator, int, int, Allocator): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadNetworkSerializable(out T): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadNetworkSerializable(out T): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadNetworkSerializable(out T[]): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadNetworkSerializable(out NativeArray, Allocator): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadNetworkSerializableInPlace(ref T): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadNetworkSerializableInPlace(ref T): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadPartialValue(out T, int, int): empty  tag",
+            "Unity.Netcode.FastBufferReader: void ReadValueSafe(out NativeArray, Allocator): unexpected ",
+            "Unity.Netcode.FastBufferReader: void ReadValueSafeTemp(out NativeArray): unexpected ",
+            "Unity.Netcode.FastBufferWriter:  in block context; use  instead",
+            "Unity.Netcode.FastBufferWriter: bool TryBeginWriteInternal(int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: bool TryBeginWriteInternal(int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: bool TryBeginWriteInternal(int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: byte[] ToArray(): empty  tag",
+            "Unity.Netcode.FastBufferWriter: byte* GetUnsafePtr(): empty  tag",
+            "Unity.Netcode.FastBufferWriter: byte* GetUnsafePtrAtCurrentPosition(): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(string, bool): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WriteNetworkSerializable(in T): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WriteNetworkSerializable(T[], int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WriteNetworkSerializable(T[], int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WriteNetworkSerializable(NativeArray, int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WriteNetworkSerializable(NativeArray, int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(T[], int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(T[], int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(NativeArray, int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(NativeArray, int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WritePartialValue(T, int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WritePartialValue(T, int, int): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in T, ForStructs): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in T, ForStructs): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in T, ForStructs): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in T): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in T): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in T): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in NativeArray): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in NativeArray): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(in NativeArray): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(): empty  tag",
+            "Unity.Netcode.FastBufferWriter: int GetWriteSize(): empty  tag",
+            "Unity.Netcode.FastBufferWriter: void WriteValueSafe(in NativeArray): unexpected ",
+            "Unity.Netcode.ForceNetworkSerializeByMemcpy: empty  tag",
+            "Unity.Netcode.GenerateSerializationForGenericParameterAttribute: tag inside ",
+            "Unity.Netcode.GenerateSerializationForGenericParameterAttribute: mixed block and inline content in ; wrap inline content in ",
+            "Unity.Netcode.Components.HalfVector3: XML is not well-formed: End tag 'remarks' does not match the start tag 'ushort'",
+            "Unity.Netcode.Components.HalfVector3: .ctor(Vector3, bool3): unexpected ",
+            "Unity.Netcode.Components.HalfVector4: XML is not well-formed: End tag 'remarks' does not match the start tag 'ushort'",
+            "Unity.Netcode.InvalidParentException: .ctor(string): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.InvalidParentException: .ctor(string): empty  tag",
+            "Unity.Netcode.InvalidParentException: .ctor(string, Exception): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.InvalidParentException: .ctor(string, Exception): empty  tag",
+            "Unity.Netcode.IReaderWriter: void SerializeValue(ref NativeArray, Allocator): unexpected ",
+            "Unity.Netcode.IReaderWriter: bool PreCheck(int): empty  tag",
+            "Unity.Netcode.IReaderWriter: bool PreCheck(int): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void VerboseDebug(string): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void CreateServerAndClients(int): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: .ctor(HostOrServer): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void TimeTravel(double, int): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: bool CreateNewClients(int, out NetworkManager[], bool): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void StopOneClient(NetworkManager, bool): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void StartOneClient(NetworkManager): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: bool Start(bool, NetworkManager, NetworkManager[], BeforeClientStartCallback): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForClientConnected(NetworkManager, ResultWrapper, float): unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForClientsConnected(NetworkManager[], ResultWrapper, float): XML is not well-formed: An identifier was expected",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForClientConnectedToServer(NetworkManager, ResultWrapper, float): unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForClientsConnectedToServer(NetworkManager, int, ResultWrapper, float): unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator GetNetworkObjectByRepresentation(ulong, NetworkManager, ResultWrapper, bool, float): unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator GetNetworkObjectByRepresentation(Func, NetworkManager, ResultWrapper, bool, float): unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void GetNetworkObjectByRepresentationWithTimeTravel(Func, NetworkManager, ResultWrapper, bool, int): unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForCondition(Func, ResultWrapper, float, int): unexpected ",
+            "Unity.Netcode.NetworkBehaviour: NetworkObject: text or XML content outside a top-level tag",
+            "Unity.Netcode.NetworkBehaviour: NetworkObject GetNetworkObject(ulong): empty  tag",
+            "Unity.Netcode.NetworkBehaviour: NetworkObject GetNetworkObject(ulong): empty  tag",
+            "Unity.Netcode.NetworkBehaviour: void OnSynchronize(ref BufferSerializer): unexpected ",
+            "Unity.Netcode.NetworkBehaviourReference: .ctor(NetworkBehaviour): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetVarContainer: GameObject CreatePrefabGameObject(NetVarCombinationTypes): empty  tag",
+            "Unity.Netcode.NetworkConfig: string ToBase64(): empty  tag",
+            "Unity.Netcode.NetworkConfig: ulong GetConfig(bool): empty  tag",
+            "Unity.Netcode.NetworkConfig: ulong GetConfig(bool): empty  tag",
+            "Unity.Netcode.NetworkConfig: bool CompareConfig(ulong): empty  tag",
+            "Unity.Netcode.NetworkConfig: bool CompareConfig(ulong): empty  tag",
+            "Unity.Netcode.NetworkList: .ctor(IEnumerable, NetworkVariableReadPermission, NetworkVariableWritePermission): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: .ctor(IEnumerable, NetworkVariableReadPermission, NetworkVariableWritePermission): empty  tag",
+            "Unity.Netcode.NetworkList: IEnumerator GetEnumerator(): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: void Add(T): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: void Clear(): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: bool Contains(T): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: bool Remove(T): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: Count: cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: int IndexOf(T): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: void Insert(int, T): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: void RemoveAt(int): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkList: this[int]: cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.NetworkManager: OnServerStopped: unexpected ",
+            "Unity.Netcode.NetworkManager: OnClientStopped: unexpected ",
+            "Unity.Netcode.NetworkManager: void AddNetworkPrefab(GameObject): empty  tag",
+            "Unity.Netcode.NetworkManager: void AddNetworkPrefab(GameObject): empty  tag",
+            "Unity.Netcode.NetworkManager: void RemoveNetworkPrefab(GameObject): empty  tag",
+            "Unity.Netcode.NetworkManager: MaximumTransmissionUnitSize: empty  tag",
+            "Unity.Netcode.NetworkManager: MaximumTransmissionUnitSize: unexpected ",
+            "Unity.Netcode.NetworkManager: void SetPeerMTU(ulong, int): empty  tag",
+            "Unity.Netcode.NetworkManager: int GetPeerMTU(ulong): empty  tag",
+            "Unity.Netcode.NetworkManager: int GetPeerMTU(ulong): empty  tag",
+            "Unity.Netcode.NetworkManager: MaximumFragmentedMessageSize: empty  tag",
+            "Unity.Netcode.NetworkManager: MaximumFragmentedMessageSize: unexpected ",
+            "Unity.Netcode.TestHelpers.Runtime.NetworkManagerHelper: Guid AddGameNetworkObject(string): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetworkManagerHelper: T AddComponentToObject(Guid): empty  tag",
+            "Unity.Netcode.NetworkObject: bool TryRemoveParent(bool): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkObjectDestroyTests: IEnumerator TestNetworkObjectServerDestroy(): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkObjectOnSpawnTests: IEnumerator TestOnNetworkSpawnCallbacks(): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkObjectPropertyTests: void TestPrefabHashIdPropertyIsAPrefab(): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkObjectPropertyTests: void TestPrefabHashIdPropertyIsAPrefab(): unexpected ",
+            "Unity.Netcode.NetworkObjectReference: .ctor(NetworkObject): empty  tag",
+            "Unity.Netcode.NetworkObjectReference: .ctor(GameObject): empty  tag",
+            "Unity.Netcode.INetworkPrefabInstanceHandler: NetworkObject Instantiate(ulong, Vector3, Quaternion): empty  tag",
+            "Unity.Netcode.NetworkPrefabHandler: bool AddHandler(NetworkObject, INetworkPrefabInstanceHandler): empty  tag",
+            "Unity.Netcode.NetworkPrefabHandler: bool AddHandler(uint, INetworkPrefabInstanceHandler): empty  tag",
+            "Unity.Netcode.NetworkPrefabHandler: void AddNetworkPrefab(GameObject): empty  tag",
+            "Unity.Netcode.NetworkPrefabHandler: void AddNetworkPrefab(GameObject): empty  tag",
+            "Unity.Netcode.NetworkPrefabHandler: void RemoveNetworkPrefab(GameObject): empty  tag",
+            "Unity.Netcode.NetworkPrefabsList: void Add(NetworkPrefab): empty  tag",
+            "Unity.Netcode.NetworkPrefabsList: void Remove(NetworkPrefab): empty  tag",
+            "Unity.Netcode.SceneEvent:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager: void SetClientSynchronizationMode(LoadSceneMode): XML is not well-formed: Expected an end tag for element 'summary'",
+            "Unity.Netcode.NetworkSceneManager: SceneEventProgressStatus UnloadScene(Scene): empty  tag",
+            "Unity.Netcode.NetworkSceneManager.SceneEventDelegate:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.SceneEventDelegate: empty  tag",
+            "Unity.Netcode.NetworkSceneManager.OnLoadDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.OnUnloadDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.OnSynchronizeDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.OnEventCompletedDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.OnLoadCompleteDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.OnUnloadCompleteDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkSceneManager.OnSynchronizeCompleteDelegateHandler:  in block context; use  instead",
+            "Unity.Netcode.NetworkTime: NetworkTime TimeTicksAgo(int): empty  tag",
+            "Unity.Netcode.NetworkTimeSystem: bool Advance(double): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkTimeSystemTests: IEnumerator PlayerLoopFixedTimeTest(): XML is not well-formed: End tag 'summary' does not match the start tag 'see'",
+            "Unity.Netcode.RuntimeTests.NetworkTimeSystemTests: IEnumerator PlayerLoopTimeTest_WithDifferentTimeScale(float): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkTimeSystemTests: IEnumerator CorrectAmountTicksTest(): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void OnSynchronize(ref BufferSerializer): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void OnSynchronize(ref BufferSerializer): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void OnSynchronize(ref BufferSerializer): unexpected ",
+            "Unity.Netcode.Components.NetworkTransform: void OnInitialize(ref NetworkVariable): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void SetState(Vector3?, Quaternion?, Vector3?, bool): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void SetState(Vector3?, Quaternion?, Vector3?, bool): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void SetState(Vector3?, Quaternion?, Vector3?, bool): text or XML content outside a top-level tag",
+            "Unity.Netcode.Components.NetworkTransform: void Update(): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.Components.NetworkTransform: void Teleport(Vector3, Quaternion, Vector3): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void Teleport(Vector3, Quaternion, Vector3): empty  tag",
+            "Unity.Netcode.Components.NetworkTransform: void Teleport(Vector3, Quaternion, Vector3): text or XML content outside a top-level tag",
+            "Unity.Netcode.RuntimeTests.NetworkTransformBase: int OnNumberOfClients(): empty  tag",
+            "Unity.Netcode.RuntimeTests.NetworkTransformBase: bool AllChildObjectInstancesAreSpawned(): empty  tag",
+            "Unity.Netcode.Editor.NetworkTransformEditor: void OnEnable(): cannot auto-inheritdoc (not an override or interface implementation);  must specify 'cref'",
+            "Unity.Netcode.RuntimeTests.NetworkTransformPacketLossTests: void NetworkTransformMultipleChangesOverTime(TransformSpace, Axis): XML is not well-formed: An identifier was expected",
+            "Unity.Netcode.RuntimeTests.NetworkTransformTests: void NetworkTransformMultipleChangesOverTime(TransformSpace, OverrideState, Axis): XML is not well-formed: An identifier was expected",
+            "Unity.Netcode.NetworkTransport:  in block context; use  instead",
+            "Unity.Netcode.NetworkTransport: void Initialize(NetworkManager): suspicious '///' triple-slash inside XmlDoc comment",
+            "Unity.Netcode.NetworkTransport: void Initialize(NetworkManager): text or XML content outside a top-level tag",
+            "Unity.Netcode.NetworkVariableBase: void SetUpdateTraits(NetworkVariableUpdateTraits): empty  tag",
+            "Unity.Netcode.NetworkVariableBase: bool ExceedsDirtinessThreshold(): empty  tag",
+            "Unity.Netcode.TestHelpers.Runtime.NetworkVariableHelper: XML is not well-formed: End tag 'summary' does not match the start tag 'T'",
+            "Unity.Netcode.UserNetworkVariableSerialization: empty  tag",
+            "Unity.Netcode.UserNetworkVariableSerialization.DuplicateValueDelegate: unexpected ",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_UnmanagedByMemcpy(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_UnmanagedByMemcpyArray(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_List(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_HashSet(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_Dictionary(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_Dictionary(): unexpected ",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_UnmanagedINetworkSerializable(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_UnmanagedINetworkSerializableArray(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_ManagedINetworkSerializable(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_FixedString(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeSerializer_FixedStringArray(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_ManagedIEquatable(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_UnmanagedIEquatable(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_UnmanagedIEquatableArray(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_List(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_HashSet(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_Dictionary(): empty  tag",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_Dictionary(): unexpected ",
+            "Unity.Netcode.NetworkVariableSerializationTypes: void InitializeEqualityChecker_UnmanagedValueEquals(): empty