Skip to content

Game.SceneFlow.GameManager

Assembly: (Game assembly - Cities: Skylines II)
Namespace: Game.SceneFlow

Type: public class GameManager : MonoBehaviour, ICoroutineHost

Base: UnityEngine.MonoBehaviour, ICoroutineHost

Summary:
GameManager is the central bootstrapping and runtime manager for Cities: Skylines II. It controls application initialization, command-line parsing, UI and platform integration, ECS world creation, asset/prefab loading, save/load workflows, mod registration (PDX/BepInEx), telemetry, and graceful termination. It exposes lifecycle events and utilities used throughout the game and by mods to coordinate boot, loading and runtime behavior.


Fields

  • private Configuration m_Configuration
    Stores the parsed runtime configuration/options (see nested Configuration class). Lazy-created by the configuration property.

  • [SerializeField] private string m_AdditionalCommandLineToggles
    Additional command-line options read from runOnce.txt (user data).

  • private static ILog log
    Logger used by GameManager for boot/runtime logging.

  • private ModManager m_ModManager
    Mod/patch manager, initialized after platform and mod DB registration.

  • private CancellationTokenSource m_Cts
    Cancellation token source used to cancel background tasks on termination.

  • private readonly CancellationTokenSource m_QuitRequested
    Cancellation token source that signals a quit request.

  • private readonly TaskCompletionSource<bool> m_WorldReadySource
    TaskCompletionSource that completes when the world reaches ready state.

  • public GameObject[] m_SettingsDependantObjects
    List of GameObjects that are toggled/activated once settings are applied.

  • private int m_MainThreadId
    Managed thread id of the main Unity thread (set in Awake).

  • private State m_State
    Current GameManager.State (Booting, UIReady, WorldReady, Loading, Quitting, Terminated, etc).

  • private OverlayScreen m_InitialEngagementScreen
    Initial engagement overlay (controller pairing, engagement, etc).

  • private bool m_IsEngagementStarted
    Whether initial engagement (platform user flow) has started.

  • private bool m_StartUpTelemetryFired
    Flag to avoid firing startup telemetry multiple times.

  • [SerializeField] private string m_UILocation
    Root UI content location used by UserInterface.

  • private UIManager m_UIManager
    UI manager wrapper (cohtml integration + UISystems).

  • private UIInputSystem m_UIInputSystem
    Input system for the UI.

  • private readonly ConcurrentDictionary<Guid, Func<bool>> m_Updaters
    Collection of registered one-shot / polling updaters that GameManager will call each Update.

  • private LayerMask m_DefaultCullingMask
    Stored camera culling mask for disabling/enabling camera during boot.

  • private LayerMask m_DefaultVolumeLayerMask
    Stored HDRP volume layer mask used while camera rendering is disabled.

  • private ConsoleWindow m_Console
    Optional console window for stdout capture.

  • private static string s_ModdingRuntime
    Detected modding runtime name (e.g., BepInEx version or Builtin).

  • private World m_World
    ECS World instance (Unity.Entities World).

  • private UpdateSystem m_UpdateSystem
    Reference to the game's update ECS system.

  • private LoadGameSystem m_DeserializationSystem
    ECS system used for deserializing/loading a saved simulation.

  • private SaveGameSystem m_SerializationSystem
    ECS system used for saving/serializing simulation state.

  • private PrefabSystem m_PrefabSystem
    System that manages prefab registration and availability.

(There are other private fields used for task handling, asset & thumbnail caches and platform integrations. Above are the most commonly used ones.)


Properties

  • public string[] cmdLine { get; private set; }
    Command-line arguments after merging additional toggles.

  • public Configuration configuration { get; }
    Lazy-initialized Configuration instance (holds parsed command line flags, profiler target, modding toggles, etc).

  • public static GameManager instance { get; private set; }
    Singleton instance of GameManager (set in Awake).

  • public bool isMainThread => Thread.CurrentThread.ManagedThreadId == m_MainThreadId
    Utility to detect if current thread is the main Unity thread.

  • public GameMode gameMode { get; private set; } = GameMode.Other
    Current logical game mode (MainMenu, Game, Editor, Other).

  • public bool isGameLoading { get; }
    True while the manager is in loading state or during boot.

  • public SharedSettings settings { get; private set; }
    Reference to shared/launcher settings used by the UI and systems.

  • public ModManager modManager => m_ModManager
    Access to the mod manager instance.

  • public CancellationToken terminationToken { get; }
    CancellationToken that becomes active when the GameManager is terminating (safe to pass to async ops).

  • public State state => m_State
    Current lifecycle state.

  • public bool shouldUpdateManager => m_State >= State.UIReady
    Indicates whether manager-level update tick should run.

  • public bool shouldUpdateWorld => m_State >= State.WorldReady
    Indicates whether world/ECS simulation updates should run.

  • public static UIInputSystem UIInputSystem => instance?.m_UIInputSystem
    Static accessor for the UIInputSystem.

  • public LocalizationManager localizationManager { get; private set; }
    Localization manager instance.

  • public UserInterface userInterface { get; private set; }
    UserInterface wrapper (UI bindings, menus).

  • public ThumbnailCache thumbnailCache { get; private set; }
    Thumbnail cache instance used for asset previews.

  • public event EventGameSaveLoad onGameSaveLoad
    Event fired before/after save operations.

  • public event EventGamePreload onGamePreload
    Event fired before simulation preload begins.

  • public event EventGamePreload onGameLoadingComplete
    Event fired when loading completes.

  • public event EventCallback onWorldReady
    Invoked when the world is ready (after boot setup and prefabs loaded).


Constructors

  • public GameManager()
    Default MonoBehaviour constructor. GameManager performs initialization in Awake() — it is not expected to be constructed directly by user code.

{{ YOUR_INFO }}
GameManager is a MonoBehaviour and uses Awake()/Initialize() for bootstrapping. Do not attempt complex init in the constructor; use Awake / Start / the exposed async initialization methods.


Methods

  • private void Awake()
    Main entry point for GameManager. Registers coroutine host, parses CLI options, prepares persistent storage, checks capabilities, detects modding runtime, initializes logging/console, disables camera rendering during boot, creates the singleton instance and calls Initialize() to continue asynchronous initialization. Handles fatal exceptions and will call QuitGame on unrecoverable errors.

  • private async void Initialize()
    Async continuation after Awake. Performs the heavy boot sequence: platform initialization, UI initialization, asset caching, prefab loading, thumbnail initialization, mod manager initialization, world/systems creation and sets state to WorldReady. Triggers onWorldReady and may auto-load a save/start a game based on configuration.

  • private Task CheckCapabilities()
    Wrapper to asynchronously cache/check platform/game capabilities.

  • private void OnMainMenuReached(Purpose purpose, GameMode mode)
    Internal callback to notify automation when the main menu is reached.

  • public async Task<bool> MainMenu()
    Convenience method to load the main menu (Load with GameMode.MainMenu & Purpose.Cleanup). Also resets audio and plays main menu music when reached.

  • public Task<bool> Load(GameMode mode, Purpose purpose, IAssetData asset = null)
    Public overload to load by asset metadata (SaveGameMetadata, MapMetadata, SaveGameData, MapData or null). Internally resolves AsyncReadDescriptor and delegates to the main Load(...) implementation.

  • private async Task<bool> Load(GameMode mode, Purpose purpose, AsyncReadDescriptor descriptor, Colossal.Hash128 instigatorGuid, Guid sessionGuid)
    Core load routine. Sets up progress trackers, optionally runs deserialization pipeline (LoadSimulationData), adjusts UI state and telemetry, calls onGameLoadingComplete and returns success state. Manages GameMode specific behavior (open/close telemetry session, set cursor etc).

  • private Task LoadSimulationData(Colossal.Serialization.Entities.Context context, AsyncReadDescriptor dataDescriptor)
    Invokes onGamePreload, cleans memory then runs the LoadGameSystem to deserialize simulation data.

  • public Task<bool> Save(string saveName, SaveInfo meta, ILocalAssetDatabase database, Texture savePreview)
    Convenience overload — wraps Texture into ScreenCaptureHelper.AsyncRequest and calls the async Save method.

  • public async Task<bool> Save(string saveName, SaveInfo meta, ILocalAssetDatabase database, ScreenCaptureHelper.AsyncRequest previewRequest)
    Saves the simulation: runs SaveGameSystem to serialize simulation state, writes preview texture if provided, writes metadata and packages the transient save database into the target ILocalAssetDatabase. Triggers onGameSaveLoad start/end callbacks.

  • private void Update()
    Main per-frame update. If shouldUpdateManager and not terminating: updates input, UI input dispatch, world update, UI update and post-update processing. Also runs registered updaters and platform updates.

  • private void LateUpdate()
    Calls LateUpdateWorld if not terminating.

  • private void UpdateWorld()
    Updates m_UpdateSystem for the MainLoop phase (ECS update) if shouldUpdateWorld.

  • private void PostUpdateWorld()
    Runs cleanup phase updates.

  • private void LateUpdateWorld()
    Runs LateUpdate and DebugGizmos phases and CORuntimeApplication.Update().

  • private void OnGUI()
    Renders any in-game debug UI (e.g. TerrainDebugSystem) when world is ready.

  • public static void QuitGame()
    Wrapper calling Application.Quit().

  • private bool WantsToQuit()
    Hooked into Application.wantsToQuit; triggers TerminateGame and prevents immediate quit until termination completes.

  • private async Task TerminateGame()
    Shuts down the game gracefully: cancels tokens, completes pending save/load, saves settings, disposes mod manager, tears down ECS world, disposes thumbnails, unregisters platform integrations and UI, and finally calls QuitGame. Includes timeouts and logs termination success/failure.

  • private void OnDestroy()
    Removes the wantsToQuit hook.

  • private void PreparePersistentStorage()
    Registers special EnvPath locations for save/map metadata & data and clears temporary paths.

  • private void InitializeLocalization()
    Creates the LocalizationManager and loads available locales.

  • private void CreateWorld()
    Creates ECS world, initializes CORuntimeApplication, sets World.DefaultGameObjectInjectionWorld and gets core systems (PrefabSystem, UpdateSystem, LoadGameSystem, SaveGameSystem).

  • private void CreateSystems()
    Initializes system ordering, telemetry gameplay data and connects UI audio source.

  • private void DestroyWorld()
    Disposes worlds and shuts down CORuntimeApplication.

  • private void InitializeUI()
    Bootstraps the UIManager/cohtml system, creates the UISystem(s), registers UI host locations from assets, prepares UserInterface, and sets GameManager state to UIReady.

  • private void ReleaseUI()
    Disposes userInterface, m_UIInputSystem and m_UIManager.

  • public Task SetScreenActive<T>() where T : IScreenState, new()
    Helper that creates and executes a screen state (IScreenState.Execute) with GameManager context and cancellation token.

  • public Guid RegisterUpdater(Func<bool> func)
    Registers a polling updater; GameManager will call it each Update and if it returns true it will be unregistered. Returns a Guid to refer to the updater.

  • public Guid RegisterUpdater(Action action)
    Convenience wrapper that registers a single-run action (returns true immediately after executing).

  • public bool UnregisterUpdater(Guid guid)
    Removes a previously registered updater.

  • private void UpdateUpdaters()
    Internal loop to invoke updaters and auto-unregister ones that return true.

  • public string[] GetAvailablePrerequisitesNames()
    Returns names of content prerequisites available via PrefabSystem.

  • public bool ArePrerequisitesMet(string[] contentPrerequisites)
    Checks if content prerequisites (ContentPrefab names) are available/installed.

  • public bool ArePrerequisitesMet<T>(Metadata<T> meta) where T : IContentPrerequisite
    Generic wrapper which extracts contentPrerequisites from metadata and calls ArePrerequisitesMet.

  • private void ReportBootProgress(float progress)
    Reports boot progress (ProgressTracker group Boot).

  • private void NotifyProgress(string identifier, int progress)
    Pushes notifications for asset caching/long-running tasks and pops when progress reaches 100.

  • private void InitializeThumbnails()
    Initializes the thumbnail cache.

  • private void DisposeThumbnails()
    Disposes thumbnail cache.

  • private Task LoadUnityPrefabs()
    Starts async loading of built-in Unity AssetLibrary that contains in-game prefabs.

  • private void LoadPrefabs()
    Synchronous scan of AssetDatabase for PrefabAssets to load into PrefabSystem.

  • private async Task<AssetLibrary> LoadAssetLibraryAsync()
    Loads "GameAssetLibrary" resource asynchronously and applies it to m_PrefabSystem.

  • private void DisableCameraRendering() / private void EnableCameraRendering()
    Temporarily disable camera culling/volume layers during boot and restore them when ready.

  • private void InitConsole() / private void ReleaseConsole()
    Initialize and release optional console window based on configuration.captureStdout.

  • private void TryCatchUnhandledExceptions()
    Wires TaskScheduler.UnobservedTaskException and AppDomain.CurrentDomain.UnhandledException to log critical issues.

  • private bool CheckValidity()
    Checks the GameManager instance validity (singleton enforcement), prevents double-instantiation and early destroy scenarios.

  • public async Task<bool> WaitForReadyState()
    Awaitable helper that completes when the world reaches ready state or is cancelled.

  • public void RunOnMainThread(Action action)
    If already on main thread, invoke immediately; otherwise register as an updater to be executed on the main thread.

  • public void TakeScreenshot() / private IEnumerator CaptureScreenshot()`
    Utility to take a screenshot at end of frame.

  • private static void DetectModdingRuntime() / private static string DetectModdingRuntimeName()
    Detects whether a known modding runtime (e.g., BepInEx) is present and logs it.

  • private static void ListHarmonyPatches() and related helpers (PrintPatchDetails, PrintIndividualPatches)
    Inspect loaded Harmony assemblies and print discovered method patches to modding log (useful for debugging mod conflicts).

  • (... many additional helper/private methods used for PDX SDK registration, platform registration, GDK/GdkCloud DB handling, user/device event handlers, telemetry readiness, asset DB registration callbacks ...)

{{ YOUR_INFO }}
This class is large and contains many platform- and engine-specific private helpers; the above list focuses on the main surface a modder or integrator would interact with. Use public methods/events for integration, and prefer RunOnMainThread / RegisterUpdater to schedule actions into the main update loop.


Usage Example

// Typical usage from a mod or UI integration:

// 1) Wait until GameManager/world is ready:
await GameManager.instance.WaitForReadyState();

// 2) Run code on main thread
GameManager.instance.RunOnMainThread(() => {
    // safe to interact with Unity objects and game systems
    Debug.Log("Running on main thread");
});

// 3) Register a one-shot updater to poll for a condition:
Guid updaterId = GameManager.instance.RegisterUpdater(() => {
    bool ready = SomeDependency.IsReady();
    if (ready) {
        // perform initialization
    }
    return ready; // returning true will unregister this updater
});

// 4) Start main menu or load a save (from metadata guid)
await GameManager.instance.MainMenu();
// or
await GameManager.instance.Load(GameMode.Game, Purpose.LoadGame, mySaveMeta);

Notes: - Use GameManager.instance only after Awake has executed. Many mod-loading hooks happen during boot; consider subscribing to onWorldReady or awaiting WaitForReadyState(). - For save/load integration, prefer using Save/Load overloads that accept metadata (MapMetadata/SaveGameMetadata) so session GUID and preview handling is correct. - Avoid blocking the main thread. Use the async methods and pass CancellationToken from GameManager.terminationToken when appropriate.