Allows to clearly see what the failure is:
TearDown : System.TimeoutException : "friend score is pink" timed out: Expected: some item equal to "#FF549A"
But was: < "#FFFFFF", "#7FCC33", "#444444" >
The #7FCC33 colour is used for the first score on the leaderboard.
The full-stack test using the whole 9 `OsuGameTest` yards is unusable
for rapid development. I don't really get how you could ever design
anything using it without tossing your computer out the window.
`TestSceneScoring` included a local simulation of stable's Score V1
algorithm. One of the parts of said algorithm is a mysterious
"score multiplier", influenced by - among others - the beatmap's drain
rate, overall difficulty, circle size, object count, drain length,
and active mods. (An implementation of this already exists in lazer
source, in `OsuLegacyScoreSimulator`, but more on this later.)
However, `TestSceneScoring` had this multiplier in _two_ places, with
_two_ distinct values, one of which being 1 (i.e. basically off).
Unfortunately, the place that had 1 as the multiplier was the wrong one.
Stable calculates the score increase for every hit in two stages;
first, it takes the raw numerical value of the judgement, but then
applies a combo-based bonus on top of it:
scoreIncrease += (int)(Math.Max(0, ComboCounter.HitCombo - 1) * (scoreIncrease / 25 * ScoreMultiplier));
On the face of it, it may appear that the `ScoreMultiplier` factor
can be factored out and applied at the end only when returning total
score. However, once the above formula is rewritten as:
scoreIncrease = scoreIncrease + (int)(Math.Max(0, ComboCounter.HitCombo - 1) * (scoreIncrease / 25 * ScoreMultiplier));
= scoreIncrease * (1 + (Math.Max(0, ComboCounter.HitCombo - 1) / 25 * ScoreMultiplier))
it becomes clear that that assumption is actually _incorrect_,
and the `ScoreMultiplier` _must_ be applied to every score increase
individually.
The above was cross-checked experimentally against stable source
on an example test map with 100 objects, and a replay hitting them
perfectly.