Static helper for saving and loading game state to FileSystem.Data. It serializes various systems into a SaveData instance on save, writes JSON, and reads/validates the save then applies it to subsystems on load.
namespace NoChillquarium;
/// <summary>
/// Persist wallet + tank fish to FileSystem.Data.
/// </summary>
public static class SaveGame
{
public static bool HasSave
{
get
{
try
{
return FileSystem.Data.FileExists( SaveData.FileName );
}
catch
{
return false;
}
}
}
/// <param name="quiet">When true (autosave), skip console chatter.</param>
public static bool TrySave( bool quiet = false )
{
if ( !TankSim.IsActive )
return false;
try
{
var data = new SaveData
{
Version = SaveData.CurrentVersion
};
Economy.WriteToSave( data );
Chaos.WriteToSave( data );
Karma.WriteToSave( data );
Shop.WriteInventory( data );
Achievements.WriteToSave( data );
FeedSystem.WriteToSave( data );
TrainingSystem.WriteToSave( data );
MethRush.WriteToSave( data );
BattleSystem.WriteToSave( data );
SharkSystem.WriteToSave( data );
EndingSystem.WriteToSave( data );
TankSim.WriteToSave( data );
FileSystem.Data.WriteJson( SaveData.FileName, data );
if ( !quiet )
Log.Info( $"[NO-CHILLquarium] Saved. Ð{Economy.BalanceText} · {TankSim.FishCount} fish." );
return true;
}
catch ( Exception e )
{
Log.Warning( $"[NO-CHILLquarium] Save failed: {e.Message}" );
return false;
}
}
public static bool TryLoad( out SaveData data )
{
data = null;
try
{
if ( !FileSystem.Data.FileExists( SaveData.FileName ) )
return false;
data = FileSystem.Data.ReadJsonOrDefault<SaveData>( SaveData.FileName, null );
if ( data is null )
return false;
var hasFish =
(data.FreshFish is { Count: > 0 })
|| (data.SaltFish is { Count: > 0 })
|| (data.Fish is { Count: > 0 });
// Allow empty-but-valid dual-tank unlock saves.
if ( !hasFish && !data.SaltUnlocked && data.Dogecoin <= 0 )
return false;
return true;
}
catch ( Exception e )
{
Log.Warning( $"[NO-CHILLquarium] Load failed: {e.Message}" );
data = null;
return false;
}
}
public static bool ApplyLoadedSave()
{
if ( !TryLoad( out var data ) )
return false;
Economy.LoadFromSave( data );
Chaos.LoadFromSave( data );
Karma.LoadFromSave( data );
Shop.LoadInventory( data.MethBags, data.M80Bags );
Achievements.Load( data.Achievements, data.LifetimeExplodes, data.TimesFed, data.TimesMeth, data.DecorPlaced );
FeedSystem.Load( data.UnlockedFoods, data.SelectedFoodId );
TrainingSystem.Load( data.Syringes );
MethRush.Load( data.TankCracks );
BattleSystem.Load( data.BattleWins, data.BattleLosses, data.BattlesBeaten, data.PrizeHabitatsWon );
SharkSystem.Load( data.SharkKills, data.SharkEaten, data.SharkEverSpawned );
EndingSystem.Load( data.HasWmd, data.HasWhale, data.EndingReached );
TankSim.LoadFromSave( data );
return TankSim.IsActive;
}
/// <summary>Menu-only peek so Achievements list reflects the save without loading the tank.</summary>
public static void PrefetchAchievementsForMenu()
{
if ( !TryLoad( out var data ) )
return;
Achievements.Load( data.Achievements, data.LifetimeExplodes, data.TimesFed, data.TimesMeth, data.DecorPlaced );
}
}