From e712601602bc3e347931e2cae02741be958511a1 Mon Sep 17 00:00:00 2001 From: phosit Date: Thu, 30 Jul 2026 18:16:59 +0200 Subject: [PATCH] PreInitGame and InitGame in the Loader This makes the frame before the simulation starts less stuttery. Doing it in the Loader also allows to make the progressbar more acurate. --- source/ps/Game.cpp | 39 +++++++++++++++++++++++---------------- source/ps/Game.h | 3 +-- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 5c360a9258..eb30de3a16 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -90,7 +90,6 @@ CGame::CGame(bool replayLog, const SimulationDebugOptions debugOptions): m_SimRate(1.0f), m_PlayerID(-1), m_ViewedPlayerID(-1), - m_IsSavedGame(false), m_IsVisualReplay(false), m_ReplayStream(NULL) { @@ -224,7 +223,7 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved const Script::Interface& scriptInterface = m_Simulation2->GetScriptInterface(); Script::Request rq(scriptInterface); - m_IsSavedGame = !savedState.empty(); + const bool isSavedGame{!savedState.empty()}; m_Simulation2->SetInitAttributes(attribs); @@ -285,7 +284,7 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved co_return g_Renderer.GetSceneRenderer().GetWaterManager().LoadWaterTextures(); }, L"LoadWaterTextures", 80); - if (m_IsSavedGame) + if (isSavedGame) PS::Loader::Register(std::bind_front( [](CGame* game, const std::string& state) -> PS::Loader::Task { @@ -298,13 +297,32 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved co_return game->LoadVisualReplayData(); }, this), L"Loading visual replay data", 1000); + // Call the script function InitGame only for new games, not saved games + if (!isSavedGame) + { + // Perform some simulation initializations (replace skirmish entities, explore territories, etc.) + // that needs to be done before setting up the AI and shouldn't be done in Atlas + if (!g_AtlasGameLoop->running) + { + PS::Loader::Register(std::bind_front([](CGame* game) -> PS::Loader::Task + { + game->m_Simulation2->PreInitGame(); + co_return 0; + }, this), L"PreInitGame", 5000); + } + + PS::Loader::Register(std::bind_front([](CGame* game) -> PS::Loader::Task + { + game->m_Simulation2->InitGame(); + co_return 0; + }, this), L"InitGame", 4000); + } + PS::Loader::EndRegistering(); } int CGame::LoadInitialState(const std::string& savedState) { - ENSURE(m_IsSavedGame); - std::stringstream stream(savedState); bool ok = m_Simulation2->DeserializeState(stream); @@ -324,17 +342,6 @@ int CGame::LoadInitialState(const std::string& savedState) **/ PSRETURN CGame::ReallyStartGame() { - // Call the script function InitGame only for new games, not saved games - if (!m_IsSavedGame) - { - // Perform some simulation initializations (replace skirmish entities, explore territories, etc.) - // that needs to be done before setting up the AI and shouldn't be done in Atlas - if (!g_AtlasGameLoop->running) - m_Simulation2->PreInitGame(); - - m_Simulation2->InitGame(); - } - // We need to do an initial Interpolate call to set up all the models etc, // because Update might never interpolate (e.g. if the game starts paused) // and we could end up rendering before having set up any models (so they'd diff --git a/source/ps/Game.h b/source/ps/Game.h index 6fcb45b44e..d10e3b3dd1 100644 --- a/source/ps/Game.h +++ b/source/ps/Game.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -226,7 +226,6 @@ private: std::vector m_PlayerColors; int LoadInitialState(const std::string& savedState); - bool m_IsSavedGame; // true if loading a saved game; false for a new game bool m_CheatsEnabled;