Every number cubiomes generates — from continent shapes to structure positions — originates from one of two random number generators. Versions up to MC 1.17 use a C implementation of Java’sDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Cubitect/cubiomes/llms.txt
Use this file to discover all available pages before exploring further.
java.util.Random, a 48-bit linear congruential generator (LCG). Starting with MC 1.18, Minecraft switched to a Xoroshiro 128 algorithm for noise generation. Both implementations live in rng.h as inline functions, so there is no separate compilation unit to link.
Java Random (LCG)
Java’sRandom uses the recurrence seed = (seed * 0x5deece66d + 0xb) & ((1 << 48) - 1). cubiomes exposes this as a set of inline functions operating on a uint64_t seed variable passed by pointer.
Initialization
setSeed transforms the input value with the standard Java XOR initializer and masks it to 48 bits. All subsequent calls read and write through the same pointer.
Generating values
| Function | Return type | Description |
|---|---|---|
next(seed, bits) | int | Advances the seed and returns the top bits bits (1–32) |
nextInt(seed, n) | int | Returns a uniform integer in [0, n) using Java’s rejection-sampling algorithm |
nextLong(seed) | uint64_t | Calls next(32) twice and combines the results |
nextFloat(seed) | float | Returns a value in [0.0, 1.0) using 24 bits of randomness |
nextDouble(seed) | double | Returns a value in [0.0, 1.0) using 53 bits of randomness |
Skipping ahead with skipNextN
You do not have to advance the seed one step at a time.skipNextN jumps forward by an arbitrary number of next() calls in O(log n) time using the fast-forward formula for LCGs:
Xoroshiro 128
Minecraft 1.18 upgraded its world generation RNG to Xoroshiro 128+. cubiomes implements it in theXoroshiro struct with a 128-bit state split into lo and hi.
Initialization
Generating values
| Function | Return type | Description |
|---|---|---|
xNextLong(xr) | uint64_t | Core output; advances the 128-bit state and returns a 64-bit value |
xNextInt(xr, n) | int | Returns a uniform integer in [0, n) |
xNextDouble(xr) | double | Returns a value in [0.0, 1.0) using the top 53 bits of xNextLong |
xNextFloat(xr) | float | Returns a value in [0.0, 1.0) using the top 24 bits of xNextLong |
xNextLongJ and xNextIntJ provide Java-compatible variants that replicate Minecraft’s specific way of combining two 32-bit halves when the full 64-bit output must match Java semantics exactly.
MC seed helpers
The layer seed pipeline translates a world seed into per-chunk random states. It is used by the layer stack (MC ≤ 1.17) and structure generation.The seed pipeline
Function signatures
| Function | Description |
|---|---|
mcStepSeed(s, salt) | Single LCG step mixing in a salt value |
mcFirstInt(cs, mod) | Extracts the first random integer from a chunk seed |
mcFirstIsZero(cs, mod) | Returns 1 if mcFirstInt(cs, mod) == 0 (avoids a branch) |
getChunkSeed(ss, x, z) | Derives a chunk seed from a start seed and block/chunk coordinates |
getLayerSalt(n) | Converts a layer’s base salt integer into its processed layer salt |
getStartSalt(ws, ls) | Derives the start salt from a world seed and layer salt |
getStartSeed(ws, ls) | Derives the start seed; used as input to getChunkSeed |
Practical example: isSlimeChunk
Slime chunk detection is a direct application of the Java LCG. Minecraft mixes the world seed with the chunk coordinates using a series of arithmetic operations, then checks whether the first random integer modulo 10 equals zero. This function is defined infinders.h:
Mix coordinates into the seed
The world seed is combined with
chunkX and chunkZ using fixed multipliers that match Minecraft’s slime chunk formula.XOR with the slime constant
The accumulated value is XORed with
0x3ad8025f — Minecraft’s hard-coded slime salt.Why is -fwrapv required?
Why is -fwrapv required?
The LCG multiplier
0x5deece66d and the nextInt rejection-sampling code rely on signed 32-bit integer overflow wrapping to match Java’s behavior. C does not guarantee this by default — signed overflow is undefined behavior. The -fwrapv flag tells GCC and Clang to use two’s-complement wrapping, making the C code numerically identical to Java.What is the difference between xNextLong and xNextLongJ?
What is the difference between xNextLong and xNextLongJ?
xNextLong returns the raw 64-bit output of the Xoroshiro state. xNextLongJ calls xNextLong twice and combines the top 32 bits of each call, replicating the way Java’s Random.nextLong() combines two 32-bit halves. Use xNextLongJ when you need results that match Java’s exact integer sequence.Can I use Xoroshiro functions for MC 1.17 and earlier?
Can I use Xoroshiro functions for MC 1.17 and earlier?
Technically the functions are available regardless of version, but Minecraft did not use Xoroshiro before 1.18. Using them for older versions will not reproduce correct game behavior. Use the Java LCG functions (
setSeed, nextInt, etc.) for any version up to 1.17.What units are used for chunk coordinates in getChunkSeed?
What units are used for chunk coordinates in getChunkSeed?
getChunkSeed expects chunk coordinates, not block coordinates. Divide block coordinates by 16 (rounding toward negative infinity) to obtain chunk coordinates: chunkX = blockX >> 4.Noise and layer systems
See how PerlinNoise and OctaveNoise consume the RNG output.
Biome generation
Understand the full generation pipeline from seed to biome ID.