InGame Info XML

InGame Info XML

25M Downloads

[1.10.2-2.8.1.88] Slime chunk display is incorrect

RealGrep opened this issue · 8 comments

commented

I was trying to prevent slime spawning in my base with the Dark Utilities anti-slime block, but it wasn't working. After some messing around, I've discovered that it's because the slime chunk display is actually incorrect. It's saying some chunks are slime chunks which are not, and vice-versa.

I've checked against online slime chunk finders, as well as Botania's Slime in a Bottle, and Quark's Slime in a Bucket. All disagree with this mod's display. And the fact that they were spawning in other chunks not marked as slime chunks by this mod, but that are in other mods/finders, also shows it's wrong.

Thanks! Let me know if you need anything else. :)

EDIT: Looking at the code here: https://github.com/Lunatrius/LunatriusCore/blob/f037dd939c02ddd9149717769aba31f84fec1447/src/main/java/com/github/lunatrius/core/world/chunk/ChunkHelper.java
Assuming the numbers are correct, I don't see anything about bit shifting, dividing, or otherwise changing the coordinates before feeding into the equation. Could that be it?

commented

What coordinates is your base located at?

I need to check if Java actually casts int to long in that formula, it's most likely overflowing the MAX_INT value. I doubt that Vanilla changed the formula at all and I know that it worked fine when I tested it last time.

commented

Sure, one chunk that is not a slime chunk, but is marked as one is at -857, 36, -632. Not even close to MAX_INT, though I guess you mean the equation in general, with the magic numbers.

Conversely, -889, 36, -648 is a slime chunk, but is not marked as being one.

I'm getting my formula from http://minecraft.gamepedia.com/Slime . I get it, you >> 4 to get the chunk coordinates from the x and y. That makes sense, now.

P.S. The seed is 3610660844093074297.

commented

Ok, ignore previous post (which I deleted). heh
This code works, what's in there now does not:

import java.util.Random;


public class SlimeTest {
    public static void main(String[] args)
    {
        System.out.println(isSlimeChunk(3610660844093074297L, -857 >> 4, -632 >> 4));
        System.out.println(isSlimeChunk(3610660844093074297L, -889 >> 4, -648 >> 4));
    }

    public static final Random RANDOM = new Random();

    public static boolean isSlimeChunk(long seed, int x, int z)
    {
        //RANDOM.setSeed(seed + (x * x * 4987142) + (x * 5947611) + (z * z * 4392871) + (z * 389711) ^ 987234911);
        RANDOM.setSeed(seed + (long)(x * x * 0x4c1906) + (long)(x * 0x5ac0db) + (long)(z * z * 0x4307a7L) + (long)(z * 0x5f24f) ^ 0x3ad8025f);
        return RANDOM.nextInt(10) == 0;
    }
}

I used this formula from that wiki page:

Random rnd = new Random(seed +
                        (long) (xPosition * xPosition * 0x4c1906) +
                        (long) (xPosition * 0x5ac0db) + 
                        (long) (zPosition * zPosition) * 0x4307a7L +
                        (long) (zPosition * 0x5f24f) ^ 0x3ad8025f);
return rnd.nextInt(10) == 0;

Other than the (long) casts, note the L after some of the values.

commented

The coordinates on their own are not large, but the result of the multiplication exceed the MAX_INT value by 11 bits. The values are the same, they're just in hexadecimal notation on the wiki. Fixed in Lunatrius/LunatriusCore@7a81e43

commented

Yeah, exactly, some of them were int inside the parentheses, then were cast to long. The third term, they were cast to long, and multiplied with a long. I checked the int constants, and they're definitely correct.

However, adding your changes to my test program returns false for both coordinates. That still doesn't seem to fix it.

My test code with your calculations as per the patch:

import java.util.Random;


public class SlimeTest {
    public static void main(String[] args)
    {
        System.out.println(isSlimeChunk(3610660844093074297L, -857 >> 4, -632 >> 4));
        System.out.println(isSlimeChunk(3610660844093074297L, -889 >> 4, -648 >> 4));
    }

    public static final Random RANDOM = new Random();

    public static boolean isSlimeChunk(long seed, long x, long z)
    {
        //RANDOM.setSeed(seed + (x * x * 4987142) + (x * 5947611) + (z * z * 4392871) + (z * 389711) ^ 987234911);
        //RANDOM.setSeed(seed + (long)(x * x * 0x4c1906) + (long)(x * 0x5ac0db) + (long)(z * z * 0x4307a7L) + (long)(z * 0x5f24f) ^ 0x3ad8025f);
        RANDOM.setSeed(seed + (x * x * 4987142L) + (x * 5947611L) + (z * z * 4392871L) + (z * 389711L) ^ 987234911L);
        return RANDOM.nextInt(10) == 0;
    }
}

The parameters being longs here should work out the same. And I pasted your line directly from your changed code.

That returns false and false, but should be false and true.

Suggest leaving the x and z as ints, and using this for the equation. It returns the correct values for the test cases. If I make them longs, it breaks it, which implies x and z and some of the parts in parentheses need to be ints:

        RANDOM.setSeed(seed + (long)(x * x * 4987142) + 
                              (long)(x * 5947611) + 
                              (long)(z * z) * 4392871L +
                              (long)(z * 389711) ^ 987234911);

I'm 99.999% sure that above equation is correct.

commented

On the newest version of Lunatrius Core now. Still not working correctly. Definitely need to use the equation I posted, I think. Making things all longs was the first thing I had tried, but just breaks it in different ways. I believe overflow is built into some parts of the equation.

BTW, thanks a lot for looking into this, and for the really nice mods. I do appreciate it! <3

commented

Perfect, corresponds to slime chunks in my base correctly. Thanks! :D

commented

It should be fixed now (Lunatrius/LunatriusCore@57636be). I have copied the formula from the sources.