-
Notifications
You must be signed in to change notification settings - Fork 45
[osu!std] Approximate amount of misses + sliderbreaks in a play #131
Conversation
The algorithm is probably not doing what you think it is doing. Let's keep in mind scoring in osu! counts slider breaks as a 100 score, and not as a miss. Let's use your example of 1000 max combo and 200 sliders, and suppose a player gets 400 combo with the score showing 1 miss. You run this algorithm and it gives you a resulting 2 slider breaks. While that is possible, I don't believe that is intended because this implies that there are 3 points in the play that may have reset combo, 2 of which are known given the information (1 miss, 1 slider break), and one uncertain (1 slide break). That one slider break is uncertain because it may or may not have happened: you can still get 400 combo and 1 miss if you have 2 slider breaks in a row, for example, but also if you have only 1 slider break in the play. Combo contains information about misses and slider breaks, and since this approximation uses just combo, it gives you an approximated number of misses and slider breaks. Misses contain information about misses only and not slider breaks. So to get slider breaks you do |
It runs a max between miss count and slider count, so in your example it'd report only 2 misses, not 3. I thought the same thing at first till I checked the code. |
My point is that if it's calculating slider breaks, it's not doing it properly. Misses are not slider breaks.
I have written up a doc that derives the formula for calculating slider breaks here |
The PR is approximately right, but could be more documented and if you're discretizing it, there's no need for the std::pow stuff that gets floored to 0. abraker, you've made some incorrect assumptions and mistakes in your calculations.
The "theoretical" result if you want minimum possible breaks for given max combo (ignoring slider ends) is std::floor(beatmapMaxCombo/(scoreMaxCombo+1)) To see why, consider that each combo has a miss at the end (except maybe the last). One case with minimal miss count would be if every miss is after a combo with length maxCombo, with a smaller combo at the end to finish the map. The number of misses/combo breaks is then the number of (maxCombo+1) sections that fit in the map, i.e. the result above. |
I think @joseph-ireland is correct in saying that @abraker95's formula is relying on a faulty assumption. After reading through the attached doc I think the error is not including the misses in each combo streak section. In fact, if I correct @abraker95's initial assumption to include the fact that a play with For an example of the worst case, consider a play on an 18-hitobject map with 2 streaks of 8 hits followed by a miss. |
BTW, the continuous version in delta_t's rework can be justified like this: Assume optimistically that that their best combo is their average performance on the map, i.e. they miss 1/(maxCombo+1) notes. This gives fairly similar results, but it doesn't give discrete jumps at certain combo values, which seems a bit weird. It does (usually) give you a non-integer estimate of the number of misses though, which could also seem weird |
See, I thought it was supposed to calculate slider break count because @stanriders wrote:
But judging by the comment in the code, I think you are right and it's supposed to be misses + slider breaks. In that case the "Combo breaks to slider breaks" section in my doc is irrelevant to this.
This took a bit to wrap my head around, but I see what you mean. I made a mistake running with instead of
Right, I assumed if there is a combo break then the segment must split, which turns out to be wrong in the case of first and last segment. Since the doc is a good starting point for documentation, I'll make corrections to it. I'll also enable ability for others to make suggestions in it in case other mistakes are found. |
Sorry maybe the last comment wasn't too clear, I read through your corrected document, and I'm not really following the reasoning in there. You still seem to be assuming that the sum of all combos has to equal the maxCombo, which isn't true (misses take away from potential combo), and I'm not following the reasoning after that point. In my example above, the +1 comes from the note that gets missed. For a given combo of length C with a miss at the end, the actual number of notes involved is C+1. For min number of misses you can assume all combos are length maxCombo (except the last with no miss at the end, with 0 <= length <= maxCombo). FWIW for the formulation you created with the sum of all combos being a constant, i think your previous document wasn't far off, i think you needed a ceil rather than a floor, i.e. ceil(beatmapMaxCombo/scoreMaxCombo)-1, which ends up being pretty similar. In that case, you are just calculating (number of combos - 1), you need to round up since the final smaller combo still counts. |
Ohhh, ok. I totally missed that the combo number doesn't include the missed note.
Yea, so it's not really combo I though I was dealing with. If a section is defined to be
As I went over things again, I found out that assuming all combos to be length maxCombo only works if |
f32 beatmapMaxCombo = beatmap.DifficultyAttribute(_mods, Beatmap::MaxCombo); | ||
if (beatmap.NumSliders() > 0) | ||
{ | ||
f32 fullComboThreshold = beatmapMaxCombo - 0.1f * beatmap.NumSliders(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be good to have 0.1f as a PSF like SLIDER_END_RATIO
or something even more explicit.
Also, 0.1f * beatmap.NumSliders()
is used twice and could be stored in a variable ?
(Also, beatmapMaxCombo
seems to only be used inside the if, so you might want to move it inside ?)
This is a port of misses + sliderbreaks approximation that's being used in delta_t's pp rework. It guesses amount of sliderbreaks based on achieved combo.
This change lacks delta's continuous miss curve (I'm flooring miss amount here) due to fact that its not being used in any calculation that requires anything more than an integer
Example miss-per-achieved-combo graph for a beatmap with 1000 max combo and 200 sliders
Part of ppy/osu#11514