A new run replaces the saved run only once it has staged; a failed start says why and leaves the saved run
Launch cleared the run store before generating, and a generation or staging failure only reached the log: the Generating Galaxy dialog stayed up, StartGame threw, and the saved run was already gone. RunSave.Replace runs a start with the saved run still stored: when it returns a staged run the saved run's records go, and when it returns null or throws, only the records it wrote (the arena's orbits and bodies) go. StartGame's new-run branch is StartScenario, chosen by PendingScenario rather than by the absence of a SavedGame; it mints into an empty ledger, and a failed start clears CurrentGalaxy (so quitting saves nothing) and refuses on the main menu with every failure. Launch no longer clears; a galaxy that throws is refused on the title menu. The menu offers Continue whenever no run is live, which replaces MainMenu.InGame (cut, with its prefab value and scene override), so a failed start can resume the saved run in place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
02e7fd4b7e
commit
8a1e205cf0
6 changed files with 132 additions and 38 deletions
|
|
@ -17,7 +17,6 @@ public class MainMenu : MonoBehaviour
|
|||
public VolumeCloudRenderer CloudRenderer;
|
||||
public GameSettings Settings;
|
||||
public ConfirmationDialog Dialog;
|
||||
public bool InGame;
|
||||
public Prototype PanelPrototype;
|
||||
public float FadeTime = .5f;
|
||||
public float FadeDistance = 512;
|
||||
|
|
@ -92,9 +91,10 @@ public class MainMenu : MonoBehaviour
|
|||
{
|
||||
_nextMenu.panel.Clear();
|
||||
_nextMenu.panel.Title.text = TitleSubtitle("aetheria", "terminus");
|
||||
if (!InGame)
|
||||
if (ActionGameManager.CurrentGalaxy == null)
|
||||
{
|
||||
// A run exists only as the run store's SavedGame global.
|
||||
// No run is live: at the title, after death, or after a new run failed to start. A saved run exists only as
|
||||
// the run store's SavedGame global.
|
||||
var cache = ActionGameManager.CultCache;
|
||||
if (ActionGameManager.ModExclusions.Length > 0 && !_exclusionsShown)
|
||||
{
|
||||
|
|
@ -156,11 +156,11 @@ public class MainMenu : MonoBehaviour
|
|||
}
|
||||
}
|
||||
|
||||
// The only way into a new run: clears the saved run, generates the scenario's galaxy off the main thread, and
|
||||
// enters the game, where StartGame has RunStart stage it.
|
||||
// The only way into a new run: generates the scenario's galaxy off the main thread and enters the game, where
|
||||
// StartGame has RunStart stage it and only then replaces the saved run. A galaxy that cannot generate is refused
|
||||
// here, with the saved run untouched.
|
||||
private void Launch(Scenario scenario)
|
||||
{
|
||||
RunSave.Clear(ActionGameManager.CultCache);
|
||||
var generatorState = "Loading Database Contents";
|
||||
|
||||
Fade(true);
|
||||
|
|
@ -181,16 +181,21 @@ public class MainMenu : MonoBehaviour
|
|||
ActionGameManager.GameDataDirectory.CreateSubdirectory("Narrative"),
|
||||
Debug.Log,
|
||||
state => generatorState = state);
|
||||
Task.Run(() =>
|
||||
{
|
||||
var galaxy = RunStart.Generate(scenario, stage);
|
||||
Task.Run(() => RunStart.Generate(scenario, stage)).ContinueWith(generation =>
|
||||
Observable.NextFrame().Subscribe(_ =>
|
||||
{
|
||||
ActionGameManager.CurrentGalaxy = galaxy;
|
||||
if (generation.IsFaulted)
|
||||
{
|
||||
Debug.LogException(generation.Exception);
|
||||
ShowMain();
|
||||
Fade(false);
|
||||
Refuse($"{scenario.Name} could not generate its galaxy", generation.Exception.GetBaseException().Message);
|
||||
return;
|
||||
}
|
||||
ActionGameManager.CurrentGalaxy = generation.Result;
|
||||
ActionGameManager.PendingScenario = scenario;
|
||||
EnterGame();
|
||||
});
|
||||
}).ContinueWith(t => Debug.LogException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);
|
||||
}));
|
||||
}
|
||||
|
||||
// The one way into the game scene. Mod ship prototypes import asynchronously at boot, so the scene waits for them,
|
||||
|
|
@ -209,7 +214,7 @@ public class MainMenu : MonoBehaviour
|
|||
SceneManager.LoadScene("ARPG");
|
||||
}
|
||||
|
||||
private void Refuse(string title, string reason)
|
||||
public void Refuse(string title, string reason)
|
||||
{
|
||||
Debug.LogError($"{title}: {reason}");
|
||||
Dialog.Clear();
|
||||
|
|
|
|||
Loading…
Reference in a new issue