namespace Mr.BrickAdventures.Progression; /// /// Lives remaining in a Playthrough. Never negative. /// /// /// Decrementing at zero floors rather than failing — unlike , where a shortfall /// is a game rule the caller must handle. Flooring here is purely defensive; the invariant that one /// death costs exactly one life is enforced by the Attempt's outcome, not by this type. /// public readonly struct Lives { public int Value { get; } private Lives(int value) => Value = value; public static Lives Of(int value) => value < 0 ? throw new ArgumentOutOfRangeException(nameof(value), value, "Lives cannot be negative.") : new Lives(value); public bool IsExhausted => Value == 0; public Lives Decrement() => new(Value == 0 ? 0 : Value - 1); }