Detail Generators

Modified on Tue, 23 Jan 2024 at 09:37 AM

A detail generator is a ScriptableObject that contains code that adds or remove details on the world. Voxel Play provides two references for Detail Generators: Cave and Village Generators.

Both components run in a similar fashion but while the cave generator adds "holes", the village generator stamps complete building models (previously created in the Constructor).


You can add any number of detail generators to a World definition, like in the image below (see Detail section at bottom):



To create a new detail generator based on the provided templates (Caves or Village Generator), right click in the Project Panel and select Create -> Voxel Play -> Detail Generator -> ...



Please note that both components are provided as functional examples. Feel free to create your own detail generator class or modify the existing components. They are located here:




How does a Detail Generator work?


A detail generator is executed by Voxel Play in the same loop than the terrain or rest of the world is generated and rendered. The difference here is the working range - usually a detail generator will add new voxels to chunks that are not within view distance yet.


The Cave Generator

This component works following the principles of Perlin Worms but it uses pregenerated random values to optimize the execution. It works this way: for every chunk in a distance of "visible_distance" + 1, it picks a random value and decides if a "worm hole" will start there. If it's positive, a new worm is created with its head positioned on this chunk. Note that this chunk is not within visible distance yet.

During the game loop, Voxel Play calls iteratively the Cave Generator which loops in turns for each worm and moves the head throughout the terrain for a random number of steps. On each step the Cave Generator adds a special kind of voxels to the chunk: a hole. A hole is any voxel which hasContent field equals to 2.


The Village Generator

The village generator works very similar to the cave generator but instead of adding a new worm, it just stamps a random building on the surface of the terrain. The current village generator only exposes a list of potential building models which can be designed in the Constructor:




How to create a custom Detail Generator?


Creating a new detail generator is very easy. Create a new class that derives from VoxelPlayDetailGenerator class. For example, the Cave Generator has this class declaration:


[CreateAssetMenu(menuName = "Voxel Play/Detail Generators/Cave Generator", fileName = "CaveGenerator", order = 102)]
public class CaveDefaultGenerator : VoxelPlayDetailGenerator {
...


Note: the CreateAssetMenu class attribute just adds a menu entry to Unity Editor so an instance of this scriptableObject can be created using right-click, Create ->...


Then, your class can implement the following 4 methods (all of them are optional methods).


1. Init() method:


public override void Init() { ... }


The Init method is called once when the world is initialized. You can place any initialization code you need here, like reading your own noise textures or initializing some arrays and variables.



2.- ExploreArea method:


public override void ExploreArea(Vector3 position, bool checkOnlyBorders) { ... }


This method is called when the player moves around the world and receives the player position. If the player moves smoothly from one position to another (ie. it moves to the neighbour chunk) then checkOnlyBorders will be false. But if the player position changes a lot, this argument will be true. You can use checkOnlyBorders value to perform additional tasks and ensure lot of detail is added to the scene before the game starts. 


This method is used by the Cave Generator to determine if a new worm is created the surrounding chunks.



3.- DoWork method:


public override bool DoWork(long endTime) { ... }


You can use this method to add your heavy processing logic. Cave Generator uses this method to fill the terrain with holes. However the VillageGenerator since it only stamps a model at a given position, it does not use this method (it adds the building directly in the AddDetail method).


This method returns a boolean indicating if there's more work to do or not at this moment. This way you can spread your work across several frames.

The endTime argument gives you the frame duration you're allowed to spend in this method. For example, if you have a heavy loop inside this method, you can check if the current env.stopwatch.getMilliseconds value exceeds endTime and exit immediately. You should design your loops so they can resume work on the next DoWork() call (ie. using an index defined at the class level).



4.- AddDetail method:


public override void AddDetail(VoxelTerrainChunk chunk) { ... }


This method receives the actual chunk and here you can modify or add any new voxels at will. Usually you will use the work done by "DoWork" method if its intensive to write the corresponding voxels to the provided chunk.



Timing considerations between DoWork and AddDetail


Since both DoWork and AddDetail are called in the main gameloop it's important that you keep that code very optimized and light. Whenever possible design your code in DoWork so it can be executed on several frames. Return True to signal that you have more work to do.


DoWork method does not receive any parameter so you're free to include any logic here to fetch and populate any chunk in the world. Use the GetChunkUnpopulated method to retrieve the chunk on a given position before the terrain generator adds terrain voxels to it (the cave generator uses this method to add "holes" to the empty chunk, before the terrain generator is executed - the terrain generator simply skips any voxel that is marked as a hole).


The AddDetail method is called just after the terrain generator has filled the chunk with terrain voxels. So you can modify the terrain contents (the Village Generator adds the voxels from the building models and also fills below the houses so there's no gap between the floor and the irregular terrain).







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