Fertile Radius

Home --> Programming Projects --> Fractal Block Engine --> Fertile Radius

What is the Fertile Radius?

If you have not already, read this page about the level radius.

Recall that every level has a radius R (its level radius). Basically, chunks that are <= R from the center are added to the active chunk tree, chunks there are >= R+2 away from the center are removed from the active chunk tree, and we don't add or remove chunks that are exactly R+1 away from the center. Here when we talk about distance, we mean the "L infinity" norm (the "max norm").

In addition to a level radius, each level has a fertile radius. Chunks that are within the fertile radius from the center contain all sorts of entities and can be interacted with normally. On the other hand, chunks that are outside the fertile radius only contain blocks. Their main purpose is to allow a larger rendering radius, without causing more monsters to load which would change gameplay.

Good values for the fertile radius

The fertile radius of a level should always be less than or equal to the level radius, with the exception that we require (for safety) that the fertile radius always be at least 1.

We recommend a level radius of 4 and a fertile radius of 3 (for the finest level). Note that making the fertile radius lower would (probably) make speed runs easier, and is perhaps cheating.

Determining when a chunk is fertile

Let F be the fertile radius of the current level.

When a chunk is first created, we let D be the L infinity distance of the chunk from the center chunk of that level. We update whether or not a chunk is fertile whenever the viewer centric position (VCP) of the chunk changes. When this happens, let D be the L infinity distance of the chunk from the center chunk of that level. The reason for the strange D <= F and D >= F+2 conditions is because we do not want the player to be able to quickly walk back and forth causing a chunk to oscillate between being fertile and non-fertile. This would be abuse of the game.

A word of advice

For anyone making their own engine like this, we highly recommend figuring out how to render the world without having to clear the depth buffer mid render. Clearing the depth buffer causes much complexity, some of which is described in this page. Fractal Block World, in its current form, clears the depth buffer mid render.

Fertile Limbo Percolation

A chunk is in fertile limbo precisely when is is F+1 (in terms of the L infinity norm) away from the center chunk, where F is the fertile radius. When such a chunk is made to be fertile, we go to all closer (with respect to the L1 norm) chunks that are also in fertile limbo and we make them fertile. Note here we are using the L1 norm instead of the L infinity norm.

The reason for this procedure is that if L is a line segment from the camera to a point in a fertile chunk, then all other points in L must also be in fertile chunks. Here we are only talking about chunks on the same level. That is, we do not want a chunk that is fertile to be rendered behind a chunk that is non-fertile. This would cause a problem with the way we are using the depth buffer.

If the reader has a system where they do not need to clear the depth buffer mid render, then this "Fertile Limbo Percolation" procedure does not need to be performed at all.

Fertile Limbo Percolation is a recursive procedure.

The Revised Population Procedure

Recall that when a chunk is first created, it is a "proto chunk" (an empty shell, a chunk that has not been "populated" with any game data). A request is made to the procedural world generation system, and that system creates the data to populate the chunk. This "populate data" is passed to the chunk and it is populated, making it no longer a proto chunk.

Here is how we revise this procedure to accommodate the fertile radius. The procedural world generation system still generates all the populate data in one object. However only the block data is used to populate the chunk (if the chunk is non-fertile). The chunk holds onto the populate data (although it can delete the block data from the populate data object) for the entire life of the chunk. Once the chunk becomes fertile, the chunk takes the populate data object and uses it to complete the population procedure. If the chunk goes from being fertile to non-fertile, all non-block data is removed from the chunk itself but the chunk holds onto the populate data object in case it becomes fertile again later on.

What about moving entities?

When a moving entity passes into a chunk C that is non-fertile, it is actually passed to the parent of C.

This cases a serious problem, because up until this point we have been saying that each level is rendered, and then the depth buffer is cleared. So if a rocket passes over the ground of a non-fertile chunk, then the ground would be drawn on top of the rocket, which is wrong. That is, if the non-fertile chunk is on level L, then when the rocket enters the chunk it would be passed to the parent chunk, on level L-1. So the rocket would be rendered on level L-1, the depth buffer would be cleared, then the non fertile chunk on level L would be rendered on top of the rocket.

So, we need to revise the way we clear the depth buffer. See the next section about revising the rendering procedure.

The Revised Rendering Procedure

Here is the old rendering procedure: Here is the new rendering procedure. Note that non fertile chunks do not have any alpha (transparent) components for rendering. Again, if the reader has a system where they do not need to clear the depth buffer in the middle of rendering, then this procedure is greatly simplified.