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.
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 );
}
}