I had an old world of mine that I wanted to re-create. I managed to obtain the world seed, so the Overworld and the Nether were ready, but the End not so much. Even though the island was generated exactly the same, the spikes or pillars were completely different than my original (now lost) world.

Prior to the release 1.9 of Minecraft Java, the End dimension had a randomized number of obsidian spikes, scattered around the main island. With this in mind, I thought their generation was based on the world seed, which, to my surprise, was incorrect.

The file BiomeEndDecorator.java picks the random variable randomGenerator and utilizes the nextInt(int bound) function to return a randomized value from 0 to 15, which is then used to obtain the x and z coordinates with the following equations (x and z are actually var2 and var3, respectively, within the code):

x = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
z = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;

chunk_X and chunk_Z are just the coordinates of the chunk within the End's region files (converted to world coordinates, as chunk coordinates within region files range from 0 to 15, just like how world coordinates use the same range within a chunk).

After obtaining the coordinates, the file WorldGenSpikes.java generates the obsidian pillars or spikes, a bedrock block on top right at the center of the platform and an Ender Crystal entity there too. This whole process uses for loops (two nested ones within each other for the pillars themselves, while the bedrock and the crystals are directly within the main loop). I'm not exactly sure if it's randomized only when generating the End for the first time, or if they randomize with each generation of a new chunk.

Now, there's ways to obtain the seed of random variables in Java, since its built-in randomness algorithm is quite insecure, and it can be easily reversed. However, I found some problems upon obtaining the seed.

My initial and main approach was to obtain the coordinates and then solve the inverted equation to get the initial randomly-generated values, and it seems like the coordinates within the chunk are actually just this.randomGenerator.nextInt(16) + 8, while the chunk coordinates are multiplied by 16. I obtained a seed this way, which was wrong, but it helped me check if I could always get the same spike generation. I tried multiple ways and, with some trial and error, came to the following procedure:

  1. Modify BiomeDecorator.java, adding the two following lines to the randomGenerator section:
protected Random randomGeneratorX = new Random(15384);
protected Random randomGeneratorZ = new Random(15384);
  1. Modify BiomeEndDecorator.java, adding the setSeed to the generator:

    if (this.randomGenerator.nextInt(5) == 0)
                int var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
                int var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;

This works, but I need to reduce the value in nextInt to something smaller, like 2 (which causes a 50% chance of generating an Ender Crystal, unlike the usual 20% with the 5) so I don't get a spikeless End. Unfortunately, if I try putting the setSeed values within the condition, the seed will work but it will pick random values from it, instead of a specific order.

To summarize, I need a function that is able to reverse the coordinates and obtain the seed for the initial randomized values and a way of setting that seed for all worlds, which would obviously imply a modification in the game's code, since there's no way of inputting said seed upon generating the End dimension.

I found some values for the bedrock block coordinates, but it'd be virtually impossible to find an exact seed, considering the game is able to generate spikes outside of the island if there's enough blocks, and the fact that only 13 crystals were generated:

    x (after equation) |  z (after equation)  
    3 ->                 10
    0 ->                  2
    7 ->                  1
   13 ->                  5
    1 ->                  9
New contributor
Alex Laredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.


You must log in to answer this question.