/// <summary> /// Saves current game state to the specified save slot. /// </summary> public async Task <GameStateMap> SaveGameAsync(string slotId) { if (rollbackStateStack.Count == 0 || rollbackStateStack.Peek() is null) { Debug.LogError("Failed to save game state: rollback stack is empty."); return(null); } var quick = slotId.StartsWithFast(config.QuickSaveSlotMask.GetBefore("{")); OnGameSaveStarted?.Invoke(new GameSaveLoadArgs(slotId, quick)); var state = new GameStateMap(rollbackStateStack.Peek()); state.SaveDateTime = DateTime.Now; state.Thumbnail = Engine.GetService <CameraManager>().CaptureThumbnail(); if (config.StateRollbackMode == StateRollbackMode.Full && config.SavedRollbackSteps > 0) { state.RollbackStackJson = rollbackStateStack.ToJson(config.SavedRollbackSteps); } await GameStateSlotManager.SaveAsync(slotId, state); // Also save global state on every game save. await SaveGlobalStateAsync(); OnGameSaveFinished?.Invoke(new GameSaveLoadArgs(slotId, quick)); return(state); }
public async UniTask <GameStateMap> SaveGameAsync(string slotId) { if (rollbackStack.Count == 0 || rollbackStack.Peek() is null) { PushRollbackSnapshot(false); } var quick = slotId.StartsWithFast(Configuration.QuickSaveSlotMask.GetBefore("{")); OnGameSaveStarted?.Invoke(new GameSaveLoadArgs(slotId, quick)); var state = new GameStateMap(rollbackStack.Peek()); state.SaveDateTime = DateTime.Now; state.Thumbnail = Engine.GetService <ICameraManager>().CaptureThumbnail(); var lastZero = rollbackStack.FirstOrDefault(s => s.PlaybackSpot.InlineIndex == 0); // Required when changing locale. bool filter(GameStateMap s) => (Configuration.EnableStateRollback && Configuration.SavedRollbackSteps > 0 && s.PlayerRollbackAllowed) || s == lastZero; state.RollbackStackJson = rollbackStack.ToJson(Configuration.SavedRollbackSteps, filter); await GameStateSlotManager.SaveAsync(slotId, state); // Also save global state on every game save. await SaveGlobalStateAsync(); OnGameSaveFinished?.Invoke(new GameSaveLoadArgs(slotId, quick)); return(state); }
public virtual async UniTask <GameStateMap> SaveGameAsync(string slotId) { var quick = slotId.StartsWithFast(Configuration.QuickSaveSlotMask.GetBefore("{")); OnGameSaveStarted?.Invoke(new GameSaveLoadArgs(slotId, quick)); var state = new GameStateMap(); await scriptPlayer.SynchronizeAndDoAsync(DoSaveAfterSync); OnGameSaveFinished?.Invoke(new GameSaveLoadArgs(slotId, quick)); return(state); async UniTask DoSaveAfterSync() { state.SaveDateTime = DateTime.Now; state.Thumbnail = cameraManager.CaptureThumbnail(); SaveAllServicesToState <IStatefulService <GameStateMap>, GameStateMap>(state); PerformOnGameSerializeTasks(state); state.RollbackStackJson = SerializeRollbackStack(); await GameSlotManager.SaveAsync(slotId, state); // Also save global state on every game save. await SaveGlobalAsync(); } }
public virtual async UniTask <GameStateMap> SaveGameAsync(string slotId) { var quick = slotId.StartsWithFast(Configuration.QuickSaveSlotMask.GetBefore("{")); OnGameSaveStarted?.Invoke(new GameSaveLoadArgs(slotId, quick)); var state = new GameStateMap(); await scriptPlayer.SynchronizeAndDoAsync(DoSaveAfterSync); OnGameSaveFinished?.Invoke(new GameSaveLoadArgs(slotId, quick)); return(state); async UniTask DoSaveAfterSync() { state.SaveDateTime = DateTime.Now; state.Thumbnail = cameraManager.CaptureThumbnail(); SaveAllServicesToState <IStatefulService <GameStateMap>, GameStateMap>(state); for (int i = onGameSerializeTasks.Count - 1; i >= 0; i--) { onGameSerializeTasks[i](state); } if (RollbackStack != null) { // Closest spot with zero inline index is used when changing locale (UI/GameSettings/LanguageDropdown.cs). var nearestStartLineSpot = RollbackStack.FirstOrDefault(s => s.PlaybackSpot.InlineIndex == 0); bool SelectSerializedSnapshots(GameStateMap s) => s.PlayerRollbackAllowed || s == nearestStartLineSpot; state.RollbackStackJson = RollbackStack.ToJson(Configuration.SavedRollbackSteps, SelectSerializedSnapshots); } await GameStateSlotManager.SaveAsync(slotId, state); // Also save global state on every game save. await SaveGlobalStateAsync(); } }