From 7cb7089d2f3512d7a415876d95b54c0017c006e4 Mon Sep 17 00:00:00 2001 From: Sebastian Bularca Date: Thu, 18 Jun 2026 23:53:51 +0200 Subject: [PATCH] Platform should be initialized in the Boot, before everything else. Got rid of the coroutines --- .../Splash_MainMenu_GameStates.asset | 2 +- Assets/Code/Core/Boot.cs | 43 ++++++++++-- Assets/Code/Core/EntryPoint.cs | 68 ++++--------------- Assets/Code/Core/GameModeGameState.cs | 15 ++-- Assets/Code/Core/GameStateRunner.cs | 5 +- Assets/Code/Core/SplashGameState.cs | 3 +- Assets/Code/Platform/DesktopPlatform.cs | 5 +- Assets/Code/Platform/IPlatform.cs | 3 +- Assets/Code/Platform/UnityEditorPlatform.cs | 6 +- 9 files changed, 71 insertions(+), 79 deletions(-) diff --git a/Assets/AddressableAssetsData/AssetGroups/Splash_MainMenu_GameStates.asset b/Assets/AddressableAssetsData/AssetGroups/Splash_MainMenu_GameStates.asset index 2badf78..3982bf3 100644 --- a/Assets/AddressableAssetsData/AssetGroups/Splash_MainMenu_GameStates.asset +++ b/Assets/AddressableAssetsData/AssetGroups/Splash_MainMenu_GameStates.asset @@ -56,7 +56,7 @@ MonoBehaviour: m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 - m_GUID: b487ee33dc82a43d48013b2331278664 - m_Address: Assets/Database/Core/InitializerSettingsFile.asset + m_Address: InitializerSettingsFile m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 diff --git a/Assets/Code/Core/Boot.cs b/Assets/Code/Core/Boot.cs index 7e3bc54..ca1bf39 100644 --- a/Assets/Code/Core/Boot.cs +++ b/Assets/Code/Core/Boot.cs @@ -1,13 +1,15 @@ using Nox.EditorCode; using System; -using Unity.VectorGraphics; -using UnityEditor; +using System.Threading.Tasks; +using Nox.Input; +using Nox.Platform; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.SceneManagement; namespace Nox.Core { public class Boot { + private static readonly AssetReferenceT InitializerSettingsFile = new ("InitializerSettingsFile"); /// /// The is the first method called when the game starts. It will load the Initializer prefab which will initialize the project /// @@ -18,7 +20,7 @@ namespace Nox.Core { case BootType.UnityDefault: return; case BootType.SceneBoot: - Addressables.InstantiateAsync("Initializer").WaitForCompletion(); + InitializeEntrypoint(); break; case BootType.FullBoot: var loadOperation = SceneManager.LoadSceneAsync("Startup", LoadSceneMode.Single); @@ -30,13 +32,44 @@ namespace Nox.Core { throw new ArgumentOutOfRangeException(); } #else - Addressables.InstantiateAsync("Initializer").WaitForCompletion(); + InitializeEntrypoint(); #endif } private static void OnCompleted(AsyncOperation obj) { obj.allowSceneActivation = true; - Addressables.InstantiateAsync("Initializer").WaitForCompletion(); + InitializeEntrypoint(); + } + + private static void InitializeEntrypoint() { + var entryPoint = Addressables.InstantiateAsync("Initializer").WaitForCompletion().GetComponent(); + + _ = CreatePlatformFactory(entryPoint); + } + + private static async Task CreatePlatformFactory(EntryPoint entryPoint) { + var gameDataState = new GameDataState { + platformSelector = new PlatformSelector(PlatformSelector.GetDevicePlatform(), PlatformSelector.GetPlatformDefaultInputMode()), + }; + + var initSettingsHandle = Addressables.LoadAssetAsync(InitializerSettingsFile); + await initSettingsHandle.Task; + var initializerSettings = initSettingsHandle.Result; + + var devicePlatform = gameDataState.platformSelector.devicePlatform; + IPlatform platform = devicePlatform switch { + DevicePlatform.Desktop => new DesktopPlatform(initializerSettings.desktopPlatformSettings), + DevicePlatform.UnityEditor => new UnityEditorPlatform(initializerSettings.unityEditorPlatformSettings), + _ => null + }; + + if(!Equals(gameDataState.platformSelector.devicePlatform, DevicePlatform.Desktop) && + PlatformSelector.GetPlatformDefaultInputMode() == InputMode.Desktop) { + platform = new DesktopPlatform(initializerSettings.desktopPlatformSettings); + } + await platform?.Initialize(gameDataState)!; + + _ = entryPoint.StartGame(gameDataState,initializerSettings, platform); } } } diff --git a/Assets/Code/Core/EntryPoint.cs b/Assets/Code/Core/EntryPoint.cs index 339c36b..1dd328b 100644 --- a/Assets/Code/Core/EntryPoint.cs +++ b/Assets/Code/Core/EntryPoint.cs @@ -1,96 +1,58 @@ -using System.Collections; using System.Collections.Generic; +using System.Threading.Tasks; using Nox.Game; using Nox.Game.UI; -using Nox.Input; using Nox.Platform; using Jovian.SaveSystem; using Jovian.InGameLogging; -using Nox.EditorCode; using Unity.Profiling; using UnityEngine; using UnityEngine.AddressableAssets; -using UnityEngine.ResourceManagement.AsyncOperations; namespace Nox.Core { /// /// The main boot class which is initializing the project, loads the platforms settings, initializes the platforms and creates the game states /// public class EntryPoint : MonoBehaviour { - public AssetReferenceT initializerSettingsFile; - - private IPlatform platform; - private GameDataState gameDataState; private Dictionary applicationStates; - private ProfilerMarker createApplicationStateMarker = new ProfilerMarker("createApplicationState"); private ISceneTransition sceneTransition; private ISaveSystem saveSystem; private IGameLogStore gameLogStore; - - private InitializerSettingsFile initializerSettings; + private BootstrapReferences bootstrapReferences; private MenuGameStateData menuGameStateData; - public IEnumerator Start() { + public async Task StartGame(GameDataState gameDataState, InitializerSettingsFile initializerSettings, IPlatform selectedPlatform) { DontDestroyOnLoad(this); - // scene authoring is helping with making each scene stand-alone playable var activeSceneReference = FindFirstObjectByType(); - if(activeSceneReference == null) { + if(!activeSceneReference) { Debug.LogWarning("The scene has no SceneReference script. Will start by default in Splash Application State"); var sceneRef = new GameObject { name = "Scene Reference" }; activeSceneReference = sceneRef.AddComponent(); activeSceneReference.gameState = GameState.BootState; - yield return null; + await Task.Yield(); } - - // Initialize platform - gameDataState = new GameDataState { - platformSelector = new PlatformSelector(PlatformSelector.GetDevicePlatform(), PlatformSelector.GetPlatformDefaultInputMode()), - }; + gameDataState.ChangeGameState(activeSceneReference.gameState); - // Load Initialization Settings - var initSettingsHandle = Addressables.LoadAssetAsync(initializerSettingsFile); - yield return new WaitUntil(() => initSettingsHandle.IsDone); - initializerSettings = initSettingsHandle.Result; - yield return CreatePlatformFactory(); - var bootStrapsSettingsHandle = Addressables.LoadAssetAsync(initializerSettings.bootstrapSettings); - yield return new WaitUntil(() => bootStrapsSettingsHandle.IsDone); + await bootStrapsSettingsHandle.Task; bootstrapReferences = bootStrapsSettingsHandle.Result; menuGameStateData = new MenuGameStateData(); var fadeObject = new GameObject("ScreenFadeTransition"); sceneTransition = fadeObject.AddComponent(); - CreateApplicationStates(); + CreateApplicationStates(gameDataState, selectedPlatform); var gameStateRunner = gameObject.AddComponent(); - gameStateRunner.Initialize(applicationStates, gameDataState, platform, sceneTransition); + gameStateRunner.Initialize(applicationStates, gameDataState, selectedPlatform, sceneTransition); } - private IEnumerator CreatePlatformFactory() { - platform = null; - var devicePlatform = gameDataState.platformSelector.devicePlatform; - platform = devicePlatform switch { - DevicePlatform.Desktop => new DesktopPlatform(initializerSettings.desktopPlatformSettings), - DevicePlatform.UnityEditor => new UnityEditorPlatform(initializerSettings.unityEditorPlatformSettings), - _ => platform - }; - - if(!Equals(gameDataState.platformSelector.devicePlatform, DevicePlatform.Desktop) && - PlatformSelector.GetPlatformDefaultInputMode() == InputMode.Desktop) { - platform = new DesktopPlatform(initializerSettings.desktopPlatformSettings); - } - yield return platform?.Initialize(gameDataState); - } - - private void CreateApplicationStates() { - createApplicationStateMarker.Begin(); - + private void CreateApplicationStates(GameDataState gameDataState, IPlatform selectedPlatform) { // Save System var saveSettings = SaveSystemSettings.Load(); ISaveSerializer saveSerializer = saveSettings.saveFormat == SaveFormat.Json @@ -104,12 +66,10 @@ namespace Nox.Core { var adventureData = new AdventureData(); - applicationStates = new Dictionary { - [GameState.BootState] = new SplashGameState(bootstrapReferences, gameDataState), - [GameState.MainMenu] = new MainMenuGameState(gameDataState, menuGameStateData, bootstrapReferences, saveSystem, adventureData, gameLogStore), - [GameState.GameMode] = new GameModeGameState(gameDataState, bootstrapReferences, platform.PlatformSettings, saveSystem, sceneTransition, adventureData, gameLogStore), - }; - createApplicationStateMarker.End(); + applicationStates = new Dictionary(); + applicationStates.TryAdd(GameState.BootState, new SplashGameState(bootstrapReferences, gameDataState)); + applicationStates.TryAdd(GameState.MainMenu, new MainMenuGameState(gameDataState, menuGameStateData, bootstrapReferences, saveSystem, adventureData, gameLogStore)); + applicationStates.TryAdd(GameState.GameMode, new GameModeGameState(gameDataState, bootstrapReferences, selectedPlatform.PlatformSettings, saveSystem, sceneTransition, adventureData, gameLogStore)); } } } diff --git a/Assets/Code/Core/GameModeGameState.cs b/Assets/Code/Core/GameModeGameState.cs index c1a63f5..5428ac2 100644 --- a/Assets/Code/Core/GameModeGameState.cs +++ b/Assets/Code/Core/GameModeGameState.cs @@ -17,8 +17,8 @@ namespace Nox.Core { /// public class GameModeGameState : IGameState { private readonly GameDataState gameDataState; + private readonly BootstrapReferences bootstrapReferences; private readonly PlatformSettings platformSettings; - private readonly PlayModeSettings bootstrapSettings; private readonly ISaveSystem saveSystem; private readonly ISceneTransition sceneTransition; private readonly AdventureData adventureData; @@ -35,10 +35,9 @@ namespace Nox.Core { private bool stateEntered; private AsyncOperationHandle advSettingsHandler; private AdventureSettings? adventureSettings; + private PlayModeSettings? playModeSettings; - public bool IsGameStateInitialized { - get => stateEntered && (playMode == null || playMode.IsGameModeInitialized); - } + public bool IsGameStateInitialized => stateEntered && (playMode == null || playMode.IsGameModeInitialized); public GameModeGameState(GameDataState gameDataState, BootstrapReferences bootstrapReferences, @@ -48,19 +47,19 @@ namespace Nox.Core { AdventureData adventureData, IGameLogStore gameLogStore) { this.gameDataState = gameDataState; + this.bootstrapReferences = bootstrapReferences; this.platformSettings = platformSettings; this.saveSystem = saveSystem; this.sceneTransition = sceneTransition; this.adventureData = adventureData; this.gameLogStore = gameLogStore; - - bootstrapSettings = Addressables.LoadAssetAsync(bootstrapReferences.playModeSettings).WaitForCompletion(); } public void EnterGameState() { + playModeSettings ??= Addressables.LoadAssetAsync(bootstrapReferences.playModeSettings).WaitForCompletion(); if(gameDataState.ActivePlayMode == PlayMode.None) { var sceneReference = Object.FindFirstObjectByType(); - if(bootstrapSettings.gameModeData.AsValueEnumerable().Any(g => g.playMode == sceneReference.playMode)) { + if(playModeSettings.gameModeData.AsValueEnumerable().Any(g => g.playMode == sceneReference.playMode)) { gameDataState.ChangePlayMode(sceneReference.playMode); } } @@ -108,7 +107,7 @@ namespace Nox.Core { } playMode = gameDataState.ActivePlayMode switch { - PlayMode.Adventure => new AdventurePlayMode(platformSettings, activeParty, bootstrapSettings, gameDataState, saveSystem, adventureSettings, adventureData), + PlayMode.Adventure => new AdventurePlayMode(platformSettings, activeParty, playModeSettings, gameDataState, saveSystem, adventureSettings, adventureData), PlayMode.PauseMenu => new PauseMenuPlayMode(platformSettings, gameDataState, pauseMenuView!), PlayMode.Town => new TownPlayMode(platformSettings, activeParty), PlayMode.Rest => new RestPlayMode(platformSettings, activeParty), diff --git a/Assets/Code/Core/GameStateRunner.cs b/Assets/Code/Core/GameStateRunner.cs index a378cb1..fedcf14 100644 --- a/Assets/Code/Core/GameStateRunner.cs +++ b/Assets/Code/Core/GameStateRunner.cs @@ -95,10 +95,7 @@ namespace Nox.Core { } private void ChangeApplicationState(GameState newGameState) { - if(currentState != null) { - currentState.ExitGameState(); - } - + currentState?.ExitGameState(); currentState = applicationStates[newGameState]; currentState.EnterGameState(); currentStateType = newGameState; diff --git a/Assets/Code/Core/SplashGameState.cs b/Assets/Code/Core/SplashGameState.cs index d56a9e0..e24edb7 100644 --- a/Assets/Code/Core/SplashGameState.cs +++ b/Assets/Code/Core/SplashGameState.cs @@ -19,7 +19,8 @@ namespace Nox.Core { } public void EnterGameState() { - DisclaimerReference gdprReference = Addressables.InstantiateAsync(bootStrapInitializer.splashUIReference).WaitForCompletion().GetComponent(); + DisclaimerReference gdprReference = Addressables.InstantiateAsync(bootStrapInitializer.splashUIReference) + .WaitForCompletion().GetComponent(); gdprReference.continueButton.onClick.AddListener(() => { gameDataState.ChangeGameState(GameState.MainMenu); Object.Destroy(gdprReference.gameObject); diff --git a/Assets/Code/Platform/DesktopPlatform.cs b/Assets/Code/Platform/DesktopPlatform.cs index 62d07d6..e594b80 100644 --- a/Assets/Code/Platform/DesktopPlatform.cs +++ b/Assets/Code/Platform/DesktopPlatform.cs @@ -1,5 +1,6 @@ using Nox.Input; using System.Collections; +using System.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; @@ -14,9 +15,9 @@ namespace Nox.Platform { } public PlatformSettings PlatformSettings => desktopPlatformSettings; - public IEnumerator Initialize(object applicationData) { + public async Task Initialize(object applicationData) { var handle = Addressables.LoadAssetAsync(assetReference); - yield return new WaitUntil(() => handle.IsDone); + await handle.Task; desktopPlatformSettings = handle.Result; Debug.Log($"Device Platform {desktopPlatformSettings.devicePlatform} initialized"); InitializeInput(); diff --git a/Assets/Code/Platform/IPlatform.cs b/Assets/Code/Platform/IPlatform.cs index 423be47..929e7cd 100644 --- a/Assets/Code/Platform/IPlatform.cs +++ b/Assets/Code/Platform/IPlatform.cs @@ -1,5 +1,6 @@ using Nox.Input; using System.Collections; +using System.Threading.Tasks; namespace Nox.Platform { @@ -16,7 +17,7 @@ namespace Nox.Platform { /// public interface IPlatform { PlatformSettings PlatformSettings { get; } - IEnumerator Initialize(object applicationData); + Task Initialize(object applicationData); IInput InitializeInput(); void Tick(); void Dispose(); diff --git a/Assets/Code/Platform/UnityEditorPlatform.cs b/Assets/Code/Platform/UnityEditorPlatform.cs index 55b257d..4f73b6f 100644 --- a/Assets/Code/Platform/UnityEditorPlatform.cs +++ b/Assets/Code/Platform/UnityEditorPlatform.cs @@ -1,5 +1,5 @@ using Nox.Input; -using System.Collections; +using System.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; @@ -12,9 +12,9 @@ namespace Nox.Platform { this.assetReference = assetReference; } public PlatformSettings PlatformSettings => editorPlatformSettings; - public IEnumerator Initialize(object applicationData) { + public async Task Initialize(object applicationData) { var handle = Addressables.LoadAssetAsync(assetReference); - yield return new WaitUntil(() => handle.IsDone); + await handle.Task; editorPlatformSettings = handle.Result; Debug.Log($"Device Platform {editorPlatformSettings.devicePlatform} initialized"); InitializeInput();