1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 00:47:24 +08:00
Commit Graph

11 Commits

Author SHA1 Message Date
Bartłomiej Dach
6266af8a56
Fix taiko legacy score simulator not including swell tick score gain into bonus portion
Reported in https://discord.com/channels/188630481301012481/1097318920991559880/1221836384038551613.

Example score: https://osu.ppy.sh/scores/1855965185

The cause of the overestimation was an error in taiko's score simulator.
In lazer taiko, swell ticks don't give any score anymore, while they did
in stable.

For all intents and purposes, swell ticks can be considered "bonus"
objects that "don't give any actual bonus score". Which is to say,
during simulation of a legacy score swell ticks hit should be treated
as bonus, because if they aren't, then otherwise they will be treated
essentially as *normal hits*, meaning that they will be included in
the *accuracy* portion of score, which breaks all sorts of follow-up
assumptions:

- The accuracy portion of the best possible total score becomes
  overinflated in comparison to reality, while the combo portion of
  that maximum score becomes underestimated.

- Because the affected score has low accuracy, the estimated accuracy
  portion of the score (as given by maximmum accuracy portion of score
  times the actual numerical accuracy of the score) is also low.

- However, the next step is estimating the combo portion, which is done
  by taking legacy total score, subtracting the aforementioned
  estimation for accuracy total score from that, and then dividing
  the result by the maximum achievable combo score on the map. Because
  most of actual "combo" score from swell ticks was "moved" into the
  accuracy portion due to the aforementioned error, the maximum
  achievable combo score becomes so small that the estimated combo
  portion exceeds 1.

Instead, this change makes it so that gains from swell ticks are treated
as "bonus", which means that they are excluded from the accuracy portion
of score and instead count into the bonus portion of score, bringing the
scores concerned more in line with expectations - although due to
pessimistic assumptions in the simulation of the swell itself,
the conversion will still overestimate total score for affected scores,
just not by *that* much.
2024-03-25 19:09:38 +01:00
Bartłomiej Dach
7c9adc7ad3
Fix incorrect score conversion on selected beatmaps due to incorrect difficultyPeppyStars rounding
Fixes issue that occurs on *about* 246 beatmaps and was first described
by me on discord:

    https://discord.com/channels/188630481301012481/188630652340404224/1154367700378865715

and then rediscovered again during work on
https://github.com/ppy/osu/pull/26405:

    https://gist.github.com/bdach/414d5289f65b0399fa8f9732245a4f7c#venenog-on-ultmate-end-by-blacky-overdose-631

It so happens that in stable, due to .NET Framework internals, float
math would be performed using x87 registers and opcodes.
.NET (Core) however uses SSE instructions on 32- and 64-bit words.
x87 registers are _80 bits_ wide. Which is notably wider than _both_
float and double. Therefore, on a significant number of beatmaps,
the rounding would not produce correct values due to insufficient
precision.

See following gist for corroboration of the above:

    https://gist.github.com/bdach/dcde58d5a3607b0408faa3aa2b67bf10

Thus, to crudely - but, seemingly accurately, after checking across
all ranked maps - emulate this, use `decimal`, which is slow, but has
bigger precision than `double`. The single known exception beatmap
in whose case this results in an incorrect result is

    https://osu.ppy.sh/beatmapsets/1156087#osu/2625853

which is considered an "acceptable casualty" of sorts.

Doing this requires some fooling of the compiler / runtime (see second
inline comment in new method). To corroborate that this is required,
you can try the following code snippet:

    Console.WriteLine(string.Join(' ', BitConverter.GetBytes(1.3f).Select(x => x.ToString("X2"))));
    Console.WriteLine(string.Join(' ', BitConverter.GetBytes(1.3).Select(x => x.ToString("X2"))));
    Console.WriteLine();

    decimal d1 = (decimal)1.3f;
    decimal d2 = (decimal)1.3;
    decimal d3 = (decimal)(double)1.3f;

    Console.WriteLine(string.Join(' ', decimal.GetBits(d1).SelectMany(BitConverter.GetBytes).Select(x => x.ToString("X2"))));
    Console.WriteLine(string.Join(' ', decimal.GetBits(d2).SelectMany(BitConverter.GetBytes).Select(x => x.ToString("X2"))));
    Console.WriteLine(string.Join(' ', decimal.GetBits(d3).SelectMany(BitConverter.GetBytes).Select(x => x.ToString("X2"))));

which will print

    66 66 A6 3F
    CD CC CC CC CC CC F4 3F

    0D 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
    0D 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
    8C 5D 89 FB 3B 76 00 00 00 00 00 00 00 00 0E 00

Note that despite `d1` being converted from a less-precise floating-
-point value than `d2`, it still is represented 100% accurately as
a decimal number.

After applying this change, recomputation of legacy scoring attributes
for *all* rulesets will be required.
2024-01-10 19:30:18 +01:00
Dan Balasescu
6b4b2a57fc
Expose only as one method 2023-12-21 14:58:23 +09:00
Dan Balasescu
4e3b994142
Relocate HitResult numeric score to ScoreProcessor 2023-12-21 14:52:31 +09:00
Dan Balasescu
30116512ca
Populate MaxCombo scoring attrib for non-osu rulesets 2023-12-18 12:01:51 +09:00
Zyf
71e5654b64 Account for legacyAccScore in score conversion 2023-11-24 23:07:27 +01:00
Dan Balasescu
da2a4681d9 Add method to retrieve legacy score multiplier 2023-10-02 16:52:01 +09:00
Dan Balasescu
19a442a32a Fix incorrect change in taiko score simulator 2023-09-26 17:46:03 +09:00
Dan Balasescu
628517569b Fix another difficulty-specific value 2023-09-08 21:08:09 +09:00
Dan Balasescu
2334be1987 Split legacy scoring attributes into a separate object 2023-09-07 21:10:38 +09:00
Dean Herbert
1629024111 ILegacyScoreProcessor -> ILegacyScoreSimulator 2023-07-04 17:32:54 +09:00