Settings/GameSettings.cs

Plain serialisable class holding player-adjustable audio settings persisted across sessions. It stores version and four volume multipliers, defaults from GameConfig, and provides Clamp() to bound values to a safe range.

File Access
namespace Coilgarden;

/// <summary>
/// Everything the player can change, persisted across sessions.
/// <para>
/// A plain serialisable class with no engine dependency, mirroring <see cref="HighScoreData"/>:
/// the rules about what a legal value is are testable headlessly, and <see cref="SettingsStore"/>
/// is the only thing that touches the filesystem.
/// </para>
/// <para>
/// Every value here is a group volume multiplier, defaulting to the designer's own balance in
/// <see cref="GameConfig"/>. <see cref="GameAudio"/> and <see cref="MusicDirector"/> read these
/// live rather than carrying their own authored multiplier - one slider should mean one thing,
/// and a component-level override sitting on top of a player's own choice is the kind of thing
/// that quietly undoes it.
/// </para>
/// </summary>
public sealed class GameSettings
{
	/// <summary>
	/// Bumped when the shape of this file changes in a way older builds cannot read. Kept so
	/// a future change has somewhere to hang a migration rather than having to refuse the file.
	/// </summary>
	public int Version { get; set; } = CurrentVersion;

	public const int CurrentVersion = 1;

	public float MasterVolume { get; set; } = GameConfig.MasterVolume;

	public float SfxVolume { get; set; } = GameConfig.SfxVolume;

	public float MusicVolume { get; set; } = GameConfig.MusicVolume;

	public float AmbienceVolume { get; set; } = GameConfig.AmbienceVolume;

	/// <summary>
	/// Forces every value into a range this build considers possible.
	/// <para>
	/// The file is on disk, so it can be hand-edited, truncated, or written by a different
	/// build. A negative volume or one far past the slider's own ceiling should never reach
	/// <see cref="Sandbox.SoundHandle.Volume"/> unexamined.
	/// </para>
	/// </summary>
	public void Clamp()
	{
		Version = CurrentVersion;
		MasterVolume = Math.Clamp( MasterVolume, 0f, GameConfig.MaxSettingsVolume );
		SfxVolume = Math.Clamp( SfxVolume, 0f, GameConfig.MaxSettingsVolume );
		MusicVolume = Math.Clamp( MusicVolume, 0f, GameConfig.MaxSettingsVolume );
		AmbienceVolume = Math.Clamp( AmbienceVolume, 0f, GameConfig.MaxSettingsVolume );
	}
}