1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-20 13:20:21 +08:00

Enhance ranked play stage countdown timer SFX (#37524)

- adjust the warning stopwatch sample to start from when the timer shows
10.xxx s instead of 9.xxx s
- add an additional 'time almost up' sample that layers on top for the
last 3s
- re-add the 'time ran out' audio cue, with an updated sample

in context, with bgm:


https://github.com/user-attachments/assets/11f105e9-2baa-4d23-bdbc-ac7d16e3d7d8

without bgm:


https://github.com/user-attachments/assets/006d6b5a-398c-4e4b-a74e-10889ac6b922

I'm not 100% on the 'time ran out' sample, but at least it sounds
deliberate now, unlike the previous buzzer which could have been
mistaken for an audio glitch.

---
- [x] depends on ppy/osu-resources#420

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
Jamie Taylor
2026-04-27 18:40:03 +09:00
committed by GitHub
Unverified
parent 34deaad718
commit 428af047f9
2 changed files with 39 additions and 4 deletions
@@ -24,7 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay
public partial class PickScreen : RankedPlaySubScreen
{
// When the 'time running out' warning sample starts to play (in remaining seconds)
private const int warning_time_threshold = 10;
private const int warning_time_threshold = 11;
public CardFlow CenterRow { get; private set; } = null!;
@@ -46,6 +46,12 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay
private Sample? timeRunningOutSample;
private SampleChannel? timeRunningOutSampleChannel;
private Sample? finalCountdownSample;
private double? lastFinalCountdownSamplePlayback;
private Sample? timeUpSample;
private bool finalBuzzerPlayed;
private DateTimeOffset stageEndTime;
private TimeSpan stageDuration;
@@ -106,6 +112,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay
cardPlaySamples[i] = audio.Samples.Get($@"Multiplayer/Matchmaking/Ranked/card-play-{1 + i}");
timeRunningOutSample = audio.Samples.Get(@"Multiplayer/Matchmaking/Ranked/time-running-out");
finalCountdownSample = audio.Samples.Get(@"Multiplayer/Matchmaking/Ranked/time-running-out-final");
timeUpSample = audio.Samples.Get(@"Multiplayer/Matchmaking/Ranked/time-up");
}
protected override void LoadComplete()
@@ -124,16 +132,42 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay
}
}
private bool shouldPlayWarningSample
private bool warningSamplesEnabled
=> matchInfo.Stage.Value == RankedPlayStage.CardPlay
&& stageDuration > TimeSpan.FromSeconds(warning_time_threshold)
&& stageEndTime - DateTimeOffset.Now < TimeSpan.FromSeconds(warning_time_threshold)
&& !hasPlayedCard;
private bool shouldPlayWarningSample
=> warningSamplesEnabled
&& stageEndTime - DateTimeOffset.Now > TimeSpan.FromSeconds(0)
&& stageEndTime - DateTimeOffset.Now <= TimeSpan.FromSeconds(warning_time_threshold);
private bool shouldPlayFinalWarningSamples
=> warningSamplesEnabled
&& stageEndTime - DateTimeOffset.Now > TimeSpan.FromSeconds(0)
&& stageEndTime - DateTimeOffset.Now < TimeSpan.FromSeconds(4);
private bool shouldPlayFinalBuzzer
=> warningSamplesEnabled
&& !finalBuzzerPlayed
&& stageEndTime - DateTimeOffset.Now <= TimeSpan.FromSeconds(0);
protected override void Update()
{
base.Update();
if (shouldPlayFinalWarningSamples && (lastFinalCountdownSamplePlayback == null || Time.Current - lastFinalCountdownSamplePlayback > 1000))
{
finalCountdownSample?.Play();
lastFinalCountdownSamplePlayback = Time.Current;
}
if (shouldPlayFinalBuzzer)
{
timeUpSample?.Play();
finalBuzzerPlayed = true;
}
if (shouldPlayWarningSample)
{
timeRunningOutSampleChannel ??= timeRunningOutSample?.GetChannel();
@@ -207,6 +241,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay
stageEndTime = DateTimeOffset.Now + countdown.TimeRemaining;
stageDuration = countdown.TimeRemaining;
finalBuzzerPlayed = false;
});
private void onCountdownStopped(MultiplayerCountdown countdown) => Scheduler.Add(() =>
+1 -1
View File
@@ -40,7 +40,7 @@
</PackageReference>
<PackageReference Include="Realm" Version="20.1.0" />
<PackageReference Include="ppy.osu.Framework" Version="2026.416.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2026.423.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2026.427.0" />
<PackageReference Include="Sentry" Version="6.2.0" />
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
<PackageReference Include="SharpCompress" Version="0.47.0" />