Game/PlayerPreferences.cs

A static class that manages and persists player settings for CitySim, handling the loading and saving of configuration data via engine cookies.

namespace CitySim;

/// <summary>Small per-device preferences, saved by the engine between sessions.</summary>
public static class PlayerPreferences
{
	const string Key="citysim.preferences.v2";
	const string LegacyKey="citysim.preferences.v1";
	public sealed record Data(int EffectsLevel=4,bool ReduceShake=false,bool ReduceFlashing=false,bool HintsDismissed=false,int UiScale=100);
	static Data current=new();
	public static Data Current => current;
	// The authored UI uses the original 80% renderer scale as its 100% visual baseline.
	public static float UiScale => 0.8f * current.UiScale/100f;
	// Keep major surface limits at the 100% visual baseline while controls scale.
	public static string SurfacePixels(float value) => FormattableString.Invariant($"{value * 0.8f / UiScale:0.###}px");
	public static float EffectsVolume => current.EffectsLevel/4f;
	public static string EffectsLabel => new[] {GameText.Get("ui.player_preferences.muted"),GameText.Get("ui.player_preferences.low"),GameText.Get("ui.player_preferences.medium"),GameText.Get("ui.player_preferences.high"),GameText.Get("ui.player_preferences.full")}[current.EffectsLevel];
	public static void Load()
	{
		try
		{
			var saved=Game.Cookies.Get(Key,(Data)null);
			var legacy=saved == null ? Game.Cookies.Get(LegacyKey,(Data)null) : null;
			current=saved ?? legacy ?? new Data();
			if (legacy != null && (current.UiScale == 80 || current.UiScale == 0)) current=current with {UiScale=100};
			current=current with {EffectsLevel=Math.Clamp(current.EffectsLevel,0,4),UiScale=Math.Clamp(current.UiScale == 0 ? 100 : current.UiScale,60,120)};
			if (legacy != null) { try { Game.Cookies.Set(Key,current); } catch (Exception e) { Log.Warning($"Could not migrate City Sim preferences: {e.Message}"); } }
		}
		catch (Exception) { current=new Data(); }
	}

	public static void Set(Data value)
	{
		current=value with {EffectsLevel=Math.Clamp(value.EffectsLevel,0,4),UiScale=Math.Clamp(value.UiScale,60,120)};
		try { Game.Cookies.Set(Key,current); } catch (Exception e) { Log.Warning($"Could not save City Sim preferences: {e.Message}"); }
	}
}