Jump to content

[1.7.10] How to detect chunks that have just finished being (entirely) populated?


Recommended Posts

Posted

In an attempt to hyper-optimize worldgen I need to run a certain function (foo(x, z) in this SSCCE) for every chunk as soon as it is completely populated. By "completely populated" I mean "will never be affected by population of neighbour chunks ever again". What I try to do is listen for net.minecraftforge.event.terraingen.PopulateChunkEvent.Post events and check all nearby chunks to see if any of them satisfy the condition that their -X, -Z and -XZ neighbours have been the subject of this event previously. The spoiler explains why this makes sense:

Spoiler

According to this resource, when the PopulateChunkEvent.Post event is fired for a chunk at (x, z) effectively the chunks at { (x, z); (x+1, z); (x, z+1); (x+1, z+1) } (its "upper neighbours") are affected. This event is only fired once per chunk when all those chunks have been generated. This means that the only chunks that may trigger changes in the chunk at (x, z) are { (x, z); (x-1, z); (x, z-1); (x-1, z-1) } (its "lower neighbours"). This implies that whenever I spot a chunk whose lower neighbour has just finished population and whose other lower neighbours have already been populated, such a chunk is completely populated. I also think that this method will signal each chunk once and once only.

This is an SSCCE that replicates my current code:

@SubscribeEvent (priority = EventPriority.LOWEST)
public void onChunkFinishedPopulating(PopulateChunkEvent.Post event) {
	int x = event.chunkX, z = event.chunkZ;
	// For every upper neighbour
	for (int dx = 0; dx <= 1; ++dx) {
		for (int dz = 0; dz <= 1; ++dz) {
			if (isChunkReady(event.world, x + dx, z + dz)) {
				foo(x + dx, z + dz);
			}
		}
	}
}

private static boolean isChunkReady(World world, int x, int z) {
	IChunkProvider provider = world.getChunkProvider();
	// For every lower neighbour
	for (int dx = -1; dx <= 0; ++dx) {
		for (int dz = -1; dz <= 0; ++dz) {
			if (!provider.chunkExists(x + dx, z + dz)) {
				return false;
			}
			if (!provider.provideChunk(x + dx, z + dz).isTerrainPopulated) {
				return false;
			}
		}
	}
	return true;
}

However, sometimes chunks that have never been supplied to foo(x, z) appear on the map. For example, this image generated during one of the tests displays chunks that have been supplied in green and chunks that have been the subject of the aforementioned event in white. The three white spots should not have appeared.

I ran many tests with a utility that emulates Minecraft generating and populating random chunks and then runs this algorithm to find completely populated chunks. It has never failed so far, including random tests, manual tests and tests with chunk generation sequence copied from actual gameplay (the code commented out).

 

Any idea what might be causing this?

  • Guest locked this topic
Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.