Barteks2x / McWorldGenLoop

My attempt to make world generation in minecraft loop around
MIT License
5 stars 1 forks source link

Documentation? #1

Open ryantheleach opened 8 years ago

ryantheleach commented 8 years ago

Just a few quick questions,

  1. How does this work with biome sizes? comparable to vanilla?
  2. How is the wrapping achieved? I know you mentioned using 5d perlin noise in IRC, but how does that end up affecting the biome layouts?
Barteks2x commented 8 years ago

ok, there are a few parts of it. I'm not going to add code comments to it afer all this time so I will explain it here and maybe add it to readme.

There are actually 4 separate parts that need to be done:

  1. Base terrain
  2. Structures & Caves
  3. Biomes
  4. Population

Note: For some reason I made this code full of util classes. I have no idea why. As always when looking at my code: "Did I really write it?".

For some reason github decided to change by numbering to 1, 1, 1, 1, I have no idea how to fix that

  1. Base terrain:

The mod listens for InitNoiseGensEvent. When handling the event, all noise generators are replaced with tileable versions of them

  1. Structures:

This is a bit more hacky. There is no event that allows me to easly replace structure and cave generators. InitNoiseGensEvent are fired before these generators are even created so doing it there is impossible.

So instead, I listen for ReplaceBiomeBlocksEvent where I check if I have already replaced these generators. If they are not replaced yet - I used reflection hacks to do so (note: at that time I decided to avoid hardcoding method names referenced using reflection so instead I searched them by signature).

These new MapGenBase classes are just wrappers over old versions. The actual implementation is in Util class (uh... why did I write it that way!?) - you can find implementation here..It simply has new generate() method that for almost everything behaves the same as vanilla - it just gives different seed values for Random.

  1. Biomes:

This is the part where the fun really begins. It's the biggest part. Each GenLayer has to be separately wrapped. All of this begins when handling WorldTypeEvent.InitBiomeGens. Replacing them is trivial, so I will explain how they are created.

This is all done after they are all constructed and it starts by wrapping the "top" GenLayer. The method that wraps them has special-case for each GenLayer type. And constructor of each wrapper gen layer also wraps it's parent(s) using the same util method it was created in. To allow for configuration, all of them implement TileableGenLayer class with setSizeBits(int bits) method.

The only thing most of GenLayers do differently is generating seed used for biome generation. One exception of this rule is PlainsIslandTileable that in vanilla has some special case near map origin to achieve who-knows-what. This causes discontinuities when I simply change the seed. I @Override the method that did it with this part commenred out. It works fine without it.

  1. Population:

This is trivial compared to all of the above. This is done when handling PopulateChunkEvent.Pre. And once again, it simply replaces the seed.

And that's all. There is nothing more it does.

So to answer your first question: it works as designed. Biome size changes normally, but with very small loop size there is not really much place for them, so the whole world may consist of 1 or 2 biomes.

Note: It also has the farlands with big enough world: screenshot

This is not power of 2 size so that I could see the edge, but for biome looping to work - size must be power of 2.