What is the lowest chance that can be represented by a predicate's random_chance condition?
Solution 1:
Parsing the advancement
The advancements are stored in JSON format which is a standard format. The format itself does support scientific notation. Minecraft Java Edition uses the gson library to parse json. This library supports double precision floating point format for numbers, which can hold pretty broad range of values (in the orders of +/-1e+/-308). When Minecraft gets the parsed value from the library, it takes it as a single precision floating point value, which can hold a smaller range of values (+/-1e+/-38). This is still more than enough precision to hold 1.33333333e-13
.
When the advancement is checked it generates a random single precision number and checks if it is less than the change
property. There is no other processing, rounding, capping etc.
Calculating the probability
The way you are calculating the probability right now is not correct. Take as a simple example a dice roll where you want to roll 6 and you have N rolls: (1/6 probability)×(N times)
gives incorrect answer since if N = 12
you'll get probability = 2, which is clearly wrong. In the same way your formula above says that if you wait long enough you can reach a probability > 1.
To calculate the probability of some number of events happening in a number of subsequent tests, you need to use binomial distribution. There is also a more intuitive way to think about that: we can calculate the probability of NOT getting the advancement after N ticks. For a single dice roll, the probability of not rolling a 6 is (1 - 1/6) = 5/6
. For two dice rolls the probability of not rolling a 6 on both rolls is 5/6 × 5/6
. We can generalise the probability of not rolling a 6 after N rolls is 5/6 ^ N
(to the power of N). Then if we want to see the probability of rolling a 6 we just calculate 1 - 5/6 ^ N
Going back to the advancement, the probability of getting the advancement after N ticks is 1 - (1 - 1 / 7.5e12) ^ N
. Since N is equal to the number of predicate tests performed on the server this means we need to multiply by the number of players as well. I assume you have 10 players with roughly the same playtime, no bot or camera accounts that are always online. Then, if N = (20 ticks per second)×(3600 seconds per hour)×(66 hours of playtime)×(10 players)
, we get... roughly ... 6.336e-6
:D. Well, it turns out that the correct way of calculating the probability does not give a different result for low number of hours of playtime.
Conclusion
It seems the way you setup the advancement aligns with your intentions and there is nothing funky going on in the advancement calculation. You (that is, your server) either got very lucky or the advancement is somehow calculated more times than we predict. More data is needed to be able to settle the question.