Spinners insert their volume control point at non-intuitive time
Splitting this out from https://github.com/ppy/osu/discussions/38787.
Non-bonus spinner ticks don't have samples, and bonus spinner ticks do:
Of note, those spinner ticks also get assigned a start time proportional to their position in the nested objects list, relative to the whole spinner's duration.
In lazer's sample control point machinery, stable-type "green lines" no longer are a thing; samples are assigned to individual objects. For backwards compatibility purposes, they are synthesised on export from objects' samples:
This logic traverses the entire tree of hit objects, down to the most nested one.
All of the above facts combine to the conclusion that during export, a spinner which has different sample settings from the preceding object, will result in a "green line" inserted at the time instant correspondent to the proportionally-computed first bonus tick's start time (which is an arbitrary time value, the user could very well reach the bonus tick earlier or later than that). This is because normal ticks don't have samples and thus can't generate a "green line".
What to do about this is a bit of a quandary. The most direct solution would be to abandon the proportional assignment of start time like so:
diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
index 6f6b848b38..37f2a44f26 100644
--- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
@@ -87,11 +87,9 @@ protected override void CreateNestedHitObjects(CancellationToken cancellationTok
{
cancellationToken.ThrowIfCancellationRequested();
- double startTime = StartTime + (float)(i + 1) / totalSpins * Duration;
-
AddNested(i < SpinsRequiredForBonus
- ? new SpinnerTick { StartTime = startTime, SpinnerDuration = Duration }
- : new SpinnerBonusTick { StartTime = startTime, SpinnerDuration = Duration, Samples = new[] { CreateHitSampleInfo("spinnerbonus") } });
+ ? new SpinnerTick { StartTime = StartTime, SpinnerDuration = Duration }
+ : new SpinnerBonusTick { StartTime = StartTime, SpinnerDuration = Duration, Samples = new[] { CreateHitSampleInfo("spinnerbonus") } });
}
}
I can't find anything in blame that would assign significance to this start time; it first shows up in 05102bc1baf00b4508bf57dfe0e749569944b8ec without any extra commentary. The judging logic is in DrawableSpinner and doesn't appear to inspect the ticks' start times. I ran osu! ruleset tests on a lark with the patch above applied and it still passes - it's still a bit of a risky change nonetheless.
Another angle here is that people wish to be able to change hitsound volume mid-spinner (https://github.com/ppy/osu/issues/9940). Maybe the fact that spinner ticks get proportional start times assigned can be used to implement that. Not sure, it's a subjective call.
@peppy your opinion would be helpful to progress this to a resolution.
Source: ppy/osu