12
\$\begingroup\$

I'm trying to understand how chunk generation works in a deep level and all the information I found does not explain how the villages are generated properly without visual glitches during generation.


I mean, if you are in an area where you should see some buildings from a village, how does Minecraft know that they must be rendered? Minecraft generates villages from a main "structure" that probably it is not generated yet.

This video explains the village's generation properly.

So with that in main what should happen is that you could see builds appear from time to time when the "village center" of a village is generated in a new-generated chunk.

Here you have a visual representation of the circumstances I'm describing. The buildings inside the loaded area shouldn't be shown if the village is not generated yet:

Diagram showing village center building outside player's loaded bounds


The only explanation I can think about is that Minecraft generates way more chunks than the ones that are visually loaded to avoid this problem.

If this what happens, what is the generation area compared to the visual loaded area?

\$\endgroup\$
23
\$\begingroup\$

Yes, it generates more chunks (or at least more of the village tree) than you think it does. This is what I call "area of interest" in my voxel code. There are two kinds of area of interest:

  1. Logical (which is what we're discussing here)
  2. Rendering (which is typically be smaller in radius than the logical area)

Remember that the only way your renderer can have access to part of the complete picture, deterministically, is to generate the entire village's tree structure, topographically, from its root (the village centre). This is because even if your rendering view area only nominally overlaps the village boundaries, full generation still has to be done to get the sequential hash required for the next step.

Every chunk's generation is affected by some combination of:

  • Chunk's coordinates within world
  • Its neighbours terrain & layout
  • The process which is mentioned in that video, which is the generation of a maximum n-deep tree of buildings and streets, which MUST be completed in its entirety to be true to the same form that you will see when walking into the centre of that village. At every step of that generation, it may be that a hash is taken from the combined current state of the village - thereby pseudo-randomly determining the next step - note what he says at 3:08 in that video.

...So really, from a determinism point of view, there are no shortcuts here.

This is undoubtedly computationally expensive, especially as if you are only on edge of the of the horizon near to the outermost borders of a village, still the game must generate the village in its entirety, even if it renders very little or none of that.

| improve this answer | |
\$\endgroup\$
  • 5
    \$\begingroup\$ Theoretically the game doesn't have to generate the whole village, it only has to generate enough metadata to know which parts of the village it needs to generate right now. The metadata could generate buildingtype + location for the buildings (3 bytes?) and then only really flesh out the details for the part that's fully loaded. It's harder, but improves performance. \$\endgroup\$ – Mooing Duck Mar 26 at 21:46
  • 1
    \$\begingroup\$ @MooingDuck Yet it still has to expand the entire tree, even if it does not flesh out every detail of that tree. Topography doesn't matter; what matters is the current (incomplete) topology of the tree, which provides the state/hash used to pseudo-randomly generate the next node. \$\endgroup\$ – Engineer Mar 27 at 8:34
  • \$\begingroup\$ @Engineer you have to generate the whole tree if (roughly speaking) node generation refers to a sibling nodes, but if you can manage to generate nodes in strictly top-down manner, each node accessing only the state of its parent, you can get away with partial tree generation. \$\endgroup\$ – toolforger Mar 27 at 11:40
  • 2
    \$\begingroup\$ Having looked at the Minecraft source code, I'm fairly certain that this is not how the game actually handles this logic. I could be mistaken, as the code is very complicated and, frankly, confusing, but it seems to me that the generation of a village doesn't need to have any area of interest, since the SEED functionality of Minecraft guarantees that every part of the world generation only needs to know the Seed to know that there should be a village where it is now, with a center at XYZ, irrespective of future generation. The same goes for biome and other generation. \$\endgroup\$ – Onyz Mar 27 at 14:46
8
\$\begingroup\$

Technical stuff

During Minecraft's chunk generation a chunk passes several stages before it is done and can be rendered.

These stages, in order, are as follows:

  • EMPTY: Just as indicated, the chunk barely exists and is empty.

  • STRUCTURE_STARTS: Here world generation decides whether a chunk might be the origin of a structure, and if so, it also generates the basic layout (e.g. for a village: which houses to include, where to place them and how to connect them). This is handled on a very abstract level (every piece of a structure is just a cuboid bounding box).

    This stage basically chooses structure pieces and aligns them with jigsaw blocks (as explained in the video).

  • STRUCTURE_REFERENCES: Other nearby chunks might be the origin of a structure, and if so, it might influence this chunk, so references get added.

  • BIOMES: Generates exact biome data for the chunk.

  • NOISE: Initializes noise data (populates some rough height maps). If structures are present, they get included in calculations (but remain unchanged themselves).

  • SURFACE: As the name suggests, this step generates a biome-specific raw surface (e.g. plains: bedrock, stone, top layer of grass/dirt) using the height map from the previous step.

  • CARVERS: Carves caves into the chunk.

  • LIQUID_CARVERS: Carves underwater caves into the chunk.

  • FEATURES: This is where all the detailing work happens. Ore generation happens here, as well as tree placement, or the actual structure manifestation.

    This stage generates the actual houses from the predetermined structure files and randomizes them a bit. It also generates the connecting paths (which adhere more strictly to the generated terrain.)

  • LIGHT: Light everything appropriately.

  • SPAWN: Spawn entities (animals, villagers, drowned, ...)

  • HEIGHTMAPS: Calculate some very detailed height maps for various purposes.

  • FULL: Finalize chunk generation. Once this step is complete the chunk is ready for rendering. (whether it will be rendered depends on other factors.)

Do note that chunks are not generated in isolation: Other chunks nearby exist in different stages of generation. Without this, stages like STRUCTURE_REFERENCES would make no sense, as where would those references refer to? Before a chunk can enter the stage STRUCTURE_REFERENCES, all chunks in region around it must first finish stage STRUCTURE_START. (This is the main bottleneck in the generation process, later stages can be processed quite independently.)

Back to the question

You have drawn some hard borders around the "loaded chunks" area. This is, as already explained above, not really what happens behind the scenes: The "loaded chunks" area has a much softer border of several partially loaded chunks. Among these partially generated chunks is the village center - which is how chunks inside the hard border knew that they should generate some village buildings.

Fun fact: some of this is visualized by the animation you get to see when generating a new world:

  • The black outside area represents empty chunks
  • The light gray area represents chunks that passed the stage STRUCTURES_START
  • The white chunks are finished
  • The green chunks are somewhere in between (after LIQUID_CARVERS)
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.