TeamRizu / OutFox

The Bug Reporting Repository for OutFox LTS 0.4, Alpha V and Steam Early Access Builds
https://projectoutfox.com
Apache License 2.0
178 stars 3 forks source link

[BUG] 1 in 10,000 chance of miss with perfect AutoplayCPU #736

Open bonimy opened 1 month ago

bonimy commented 1 month ago

Is there an existing issue for this?

Operating System

Windows 10

CPU

Intel

GPU

gefore 3080 ti

Storage

2TB SSD

Game Version

5.0.0-042

Game Mode

dance

Theme

No response

Describe the problem

If you create a perfect autoplay CPU, there's a 0.01% chance of a miss still happening. This bug has existed since SM3.9. I finally broke and traced the issue in PlayerAI.cpp

TapNoteScore GetTapNoteScore()
{
    float fRand = randomf(0,1);
    float fCumulativePercent = 0;
    for( int i=0; i<=TNS_W1; i++ )
    {
        fCumulativePercent += fPercent[i];
        if( fRand <= fCumulativePercent+1e-4 ) // rounding error
            return (TapNoteScore)i;
    }
    // the fCumulativePercents must sum to 1.0, so we should never get here!
    ASSERT_M( 0, ssprintf("%f,%f",fRand,fCumulativePercent) );
    return TNS_W1;
}

Specifically here

if( fRand <= fCumulativePercent+1e-4 ) // rounding error

fRand is any value from 0 inclusive to 1 exclusive (some bugs here too, but not worth the discussion). If we get a really low roll, the rounding error will say "hey, this is the note we want". And this check starts at a miss, and works to TNS_W1 (or whatever it would be in outfox now). So the rounding error is short-circuiting and telling autoplayCPU to miss at around 1 in 10,000 chance.

Describe what should happen

Suggestion 1 to fix:

if( fPercent[i] > 0 && fRand <= fCumulativePercent+1e-15 )

Don't set notes that have zero weight, and reduce the error by several orders of magnitude

Suggestion 2: Change the data type of fPercent from floating type to integer type. Advantage is that rounding error is eliminated, disadvantage is that weights are forced to 32-bit integer types, which some people may dislike. Probably not the best choice, but just a thought.

I implemented the Suggestion 1 fix in SM5 and it seems to have fixed the issue: image

After 54,000 notes, at a 1:10000 chance of miss, at least one miss occurring has a 99.55% probability, so I would say this fix works.

Please implement, or make me a developer, so I can stop being annoyed at these random misses.

Thank you for your time -SWR

Relevant Log output

No response