using System.Text.Json; using Godot; using Mr.BrickAdventures.scripts.State; namespace Mr.BrickAdventures.Autoloads; /// /// Save system that serializes POCOs directly to JSON. /// public partial class SaveSystem : Node { [Export] public string SavePath { get; set; } = "user://savegame.json"; [Export] public int Version { get; set; } = 2; // Bumped version for new format private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; public override void _Ready() { // No longer needs GameManager reference - works with GameStateStore directly } public void SaveGame() { var store = GameStateStore.Instance; if (store == null) { GD.PrintErr("SaveSystem: GameStateStore not available."); return; } var saveData = new SaveData { Version = Version, Player = store.Player, CurrentLevel = store.Session.CurrentLevel }; try { var json = JsonSerializer.Serialize(saveData, JsonOptions); using var file = FileAccess.Open(SavePath, FileAccess.ModeFlags.Write); file.StoreString(json); GD.Print("Game saved to: ", SavePath); EventBus.EmitGameSaved(); } catch (System.Exception e) { GD.PrintErr($"SaveSystem: Failed to save game: {e.Message}"); } } public bool LoadGame() { if (!FileAccess.FileExists(SavePath)) { GD.Print("SaveSystem: No save file found."); return false; } try { using var file = FileAccess.Open(SavePath, FileAccess.ModeFlags.Read); var json = file.GetAsText(); var saveData = JsonSerializer.Deserialize(json, JsonOptions); if (saveData == null) { GD.PrintErr("SaveSystem: Failed to deserialize save data."); return false; } if (saveData.Version != Version) { GD.PrintErr($"SaveSystem: Version mismatch. Expected {Version}, found {saveData.Version}"); return false; } var store = GameStateStore.Instance; if (store == null) { GD.PrintErr("SaveSystem: GameStateStore not available."); return false; } // Apply loaded state store.Player = saveData.Player ?? new PlayerState(); store.Session.CurrentLevel = saveData.CurrentLevel; GD.Print("Game loaded from: ", SavePath); return true; } catch (System.Exception e) { GD.PrintErr($"SaveSystem: Failed to load game: {e.Message}"); return false; } } public bool CheckSaveExists() => FileAccess.FileExists(SavePath); public void DeleteSave() { if (FileAccess.FileExists(SavePath)) { DirAccess.RemoveAbsolute(ProjectSettings.GlobalizePath(SavePath)); GD.Print("Save file deleted."); } } } /// /// Container for save data. /// public class SaveData { public int Version { get; set; } public PlayerState Player { get; set; } public int CurrentLevel { get; set; } }