Chunk Lifecycle

Modified on Wed, 12 May 2021 at 09:23 AM

A chunk represent a portion of the world. Each chunk contains a voxel[] array of 16x16x16 voxels. So a chunk represents an area of 16x16x16 meters in world space (or 32x32x32 depending on the Voxel Play Environment setting).


All chunks belongs to a "chunk pool" which is a preallocated array of chunks which is filled at start up. When Voxel Play needs a new chunk for rendering, the chunk is fetched from the pool (and no new memory allocations are made). When there're no more available chunks in the pool, existing chunks in the scene are reused (their contents are cleared).


The lifecycle of a chunk follows this graph:





Chunk Pool Initialization


Chunk Pool is initialized during start and memory for each chunk is reserved. The amount of chunks in the pool is defined by the Voxel Play Environment "Chunks Pool Size" property.


The Chunk Pool Size should be equal or greater than the Recommended value. This value depends on view distance.
The Prewarm In Editor only is useful while developing inside Unity Editor. It's the amount o chunks that will be initialized before completing the initialization. While developing and testing you probably don't need to have the full pool size allocated, so this setting produces a faster start.


When Voxel Play has finished initialization, it raises the event OnInitialize.

 


Chunk Loading


When the area of a chunk needs to be rendered, the chunk first needs to be fetched from the chunks pool and filled with initial content.


If the current session is loaded from a savegame file, the chunk contents are loaded from the savegame file during start automatically.


Also, when chunk is nearer than the Forced or View Distance with respect to the Anchor (the anchor is usually the camera in first person controller or the character in third person controller), it's loaded. These properties are set in the Voxel Play Environment.


Finally, you can call ChunkCheckArea method to ensure all chunks within a bounds are loaded.


When a chunk is loaded, the event OnChunkBeforeCreate triggers just before the Terrain Generator is called. You can use this event to pre-populate contents of the chunk. Then, the terrain generator and any other detail generator are called and passed the chunk so they can add content. Finally the OnChunkAfterCreate event is called.



Chunk Modifications


When a chunk is modified (ie. a voxel is placed or destroyed), the OnChunkChanged event is triggered.

Also the chunk.modified flag is set to true. This flag is critical to VP and is used to determine which chunks can be reused and saved. This flag is automatically set by VP when a chunk is modified using its API. For example, when a voxel is placed or destroyed, this flag is set, so usually you don't need to worry about this flag. However if you modify manually the contents of the voxel[] array of a chunk, you can manually set this flag to indicate that this chunk must be preserved and saved along a savegame.


If you want to avoid chunks being marked as modified when calling an API, use env.captureChunkChanges = false before calling the API. Doing so will produce the modifications you want but the chunk won't be marked as modified thus it won't be included in a savegame (unless it has been marked as modified by other means). Remember to set env.captureChunkChanges = true just after calling the API so other modifications are annotated!



Chunk Meshing


Whenever a chunk is visible in the frustum and needs to be rendered for the first time or after changes in its contents, the meshing occurs. Meshing refers to the process of generating meshes and assigning materials.This process happens in multiple threads in the background and can occur multiple times, for example, due to light spreading and bouncing from one chunk to another.


The geometry mesh is always generated. If "Enable Colliders" option is true, then this process also generated optimized collider meshes for solid/opaque voxels. If "Enable NavMesh" option is true, navigation meshes are also generated for all voxels with Navigatable property set to true.


When the meshing process finishes for the first time, the event OnChunkAfterFirstRender is triggered. 

Whenever a chunk mesh is generated, including the first time, the event OnChunkRender is triggered.



Chunk Unload & Reuse


There's a difference between unloading and reusing a chunk:


Unloading a chunk occurs when a chunk exits the Visible Distance value set in Voxel Play Environment inspector and the Unload Far Chunks option is enabled.

When a chunk exits this distance, the chunk is deactivated and hidden in the scene. However its contents are preserved. The OnChunkExitViewDistance event triggers. Likewise, when a chunk enters view distance again, the OnChunkEnterVisibleDistance event triggers as well. Note that only previously generated chunks use these events.


Chunk reuse occurs when a new chunk need to be created and the chunks pool is empty. In this case, Voxel Play will pick and reuse an existing chunk, clearing its contents and moving it to the requested position of the world. The candidate chunk to be reused will always be far away and probably out of frustum. Before a chunk is reused, the event OnChunkReuse is called. You can return false from this event handler to force VP to choose another chunk. Also flagged chunks with modified = true are never reused.



Chunk Stats


The Voxel Play Environment inspector provides some statistics about chunk creation:



The "Total Chunks Created" number increases as chunk contents are generated. This can occur when the chunk is new or when a chunk is reused hence the total chunks created number can be greater than the chunk pool size.



Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select atleast one of the reasons

Feedback sent

We appreciate your effort and will try to fix the article