mojira.dev
MC-239059

Java Random reimplemented incorrectly

A few members of our community have been studying the latest snapshot code and they claim to have found an issue in the class LegacyRandomSource.
Java documentation specifies that Next(bits) should return (int)(seed >>> (48 - bits)). However, current code seems to return (int)(seed >> (48 - bits)).
This could cause future issues related to nextInt returning negative numbers in rare cases, and incomplete parity with Bedrock.

Members that confirmed this issue in our community: cortex and MrSpike.

Attachments

Comments 8

[media]

Using this code, it's possible to see that Mojang's implementation does not produce the same results as Java's default implementation (which would be the results produced in Bedrock editions):

Seed: 4398074666259 | Java: 30 | Mojang: 19
Seed: 39032724456376 | Java: 50 | Mojang: 9
Seed: 39032784013762 | Java: 47 | Mojang: 13
Seed: 39032805695460 | Java: 12 | Mojang: 17
Seed: 11613744092361 | Java: 5 | Mojang: 2
Seed: 165764713 | Java: 12 | Mojang: 2
Seed: 11613765769747 | Java: 2 | Mojang: 6
Seed: 223209395 | Java: 9 | Mojang: 6

Would fixing this change the seed features?

Can confirm in 1.18 Pre-release 1.

This issue isn't relevant anymore, as LegacyRandomSource is not being used in any important place of the game anymore, except for stronghold layouts, which can't be affected by that problem. (Mojang switched to XoroShiro128++ for features in pre-release 1)

It looks like LegacyRandomSource is still used (MC-249933).

Mojang's code in `next` looks like this:

public int next(int i) {
    long m;
    long l = this.seed.get();
    if (!this.seed.compareAndSet(l, m = l * 25214903917L + 11L & 0xFFFFFFFFFFFFL)) {
        throw ThreadingDetector.makeThreadingException("LegacyRandomSource", null);
    }
    return (int)(m >> 48 - i);
}

So isn't `m` always positive here? I don't see where the difference between >> and >>> in this case

I cannot reproduce using MC@h Matt 's repro instructions. I can only assume that their JavaRnd implementation is not equivalent to Mojang's RandomSource, or maybe that Mojang fixed it since the issue was reported. Here's the code I ran using Mojang's actual RandomSource:

 

Random rand = new Random(4398074666259L);
System.out.println(rand.nextInt(53));

RandomSource rand2 = RandomSource.create(4398074666259L);
System.out.println(rand2.nextInt(53));

 

And the output:

 

30
30

I think this issue can be closed.

 

MC@h Matt

(Unassigned)

Community Consensus

Platform

Low

World generation

21w41a, 1.18 Pre-release 1, 1.18 Release Candidate 1, 1.18.1 Release Candidate 2, 22w11a, 22w14a

Retrieved