mojira.dev
MC-99092

World seed of 0 generator bug

When playing around with creating default worlds with different seeds, I found a weird quirk in the seed calculation algorithm. From what I can tell, it works like so:

If the seed string can be parsed into a long, it uses that long as the seed.
Otherwise, it uses the hash code of the seed string.

So far, this isn't weird. The weird part is determining whether or not to generate the seed randomly.

As we all know, leaving the seed string blank generates the seed randomly. However, entering a seed of 0 also generates the seed randomly. This is unexpected, but it makes sense; the hash code of the empty string is zero. The really weird bit happens when entering a non-empty string with a hash code of zero, for example, the string f5a5a608. One would expect that it generates the seed randomly. However it actually proceeds to generate a world with a seed of 0.

This is an inconsistency in the seed calculation algorithm and there seems to be no purpose for it. Either the seed of 0 shouldn't be generating the seed randomly, or nonempty strings with a hash code of 0 should be generating the seed randomly.

Comments 6

This is not a duplicate. This refers to two possible unintended behaviours.

From the comments there:

We've now defined '0' as special. It will indicate a random seed. Many games use 0 as 'random' or 'infinite' or 'do not care' flag when providing options.

You may be interested in MC-94025.

This is unexpected, but it makes sense; the hash code of the empty string is zero.

This makes sense indeed but it is not the way it is done.
In the decompiled version of Minecraft 1.9 using MCP 9.24 beta the code looks like this:

long i = (new Random()).nextLong();
String s = this.worldSeedField.getText();

if (!StringUtils.isEmpty(s))
{
    try
    {
        long j = Long.parseLong(s);

        if (j != 0L)
        {
            i = j;
        }
    }
    catch (NumberFormatException var7)
    {
        i = (long)s.hashCode();
    }
}
long i = (new Random()).nextLong();
String s = this.worldSeedField.getText();

if (!StringUtils.isEmpty(s))
{
    try
    {
        long j = Long.parseLong(s);

        if (j != 0L)
        {
            i = j;
        }
    }
    catch (NumberFormatException var7)
    {
        i = (long)s.hashCode();
    }
}

Ah. Now I can isolate the problem. That if statement should be checking for a nonzero hashcode instead of a nonempty string. That way, a world with seed of 0 will be impossible to create.

That probably would not work as the hash code of "0" is 48.

That's fine. It's checking for a nonzero hashcode. "0" would be handled in the try block.

The only problem would be if there were a valid nonzero long that had a hashcode of 0.

Ely G

(Unassigned)

Unconfirmed

Minecraft 1.9

Retrieved