[1.10.2-2.8.1.88] Slime chunk display is incorrect
RealGrep opened this issue · 8 comments
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?
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.
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.
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.
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
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.
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
It should be fixed now (Lunatrius/LunatriusCore@57636be). I have copied the formula from the sources.