[Devlog] – FastChunks to Infinity – 27/06/2018

So… I was working on the new Course, the « Fast Chunks – 8 – Infinite Chunks » and after testing a few things, i quickly noticed that it was absolutely not ready for infinite generation.

So i tried to start from scratch. I made a new version of the FastChunks project and tried to optimize a lot more. I took a few notes, trying new methods to get blocks in the world :

First i needed a better way to find a block in the world. I kept the old « GetChunk » method and used a few new things :

  • Getting a local block :

Block world position – Chunk world Position (In this order)

  • Getting a world block :

Block world position + Chunk world Position (In any order)

Then i put this into a new Method :

public static Block GetBlockInWorld(Vector3 _pos)
{
//The chunk containing the block
Chunk chunk = GetChunkAtPos(_pos);

if (chunk == null) //If chunk doesn’t exist
return null;

//Get the position of the chunk
Vector3 chunkPos = chunk.chunkObject.transform.position;

//Convert block world to chunk local (Block pos – chunk pos)
Vector3 blockPosInChunk = _pos – chunkPos;

//Get the block in the chunk (From the chunk map)
Block block = chunk.GetBlockAtPos((int)blockPosInChunk.x, (int)blockPosInChunk.y, (int)blockPosInChunk.z);

//Give back the block
return block;
}

With this method i was able to simplify so much things! I don’t have to get a neighbour chunk and check if there is a block at a certain local position. Now i can just get the next block in the world. All i had to do was checking if it is null (If it exists) after searching for a block.

From this point i created a lot if useful methods, every one of them simplifies the scripts control :

public static Chunk GetChunkAtPos(Vector3 _pos) //Returns the chunk at the position 

public static Vector3 GetChunkPos(Vector3 _pos) //We convert a position into a chunk position

public static Block GetBlockInWorld(Vector3 _pos) //We get any block in the world if it exists

public static bool BlockExistInWorld(Vector3 _pos) //Checks if a block exists at a position

public static void ResetChunk(Chunk _chunk) //We clear the chunk values, chunk object, and redraw

public static Vector3 GetMapLocationInChunk(Vector3 _blockPos, Chunk _chunk) //We get the position of a block inside the chunk map

public static Vector3 CenterPositionInBlock(Vector3 _pos) //When we click on a block, the position we are checking is centered inside the block

public static void RemoveBlockAtPos(Vector3 _pos) //Removes a block at the given position (If chunk exists)

public static void PlaceBlockAtPos(Block _block, Vector3 _pos) //Places a block at the given position (If chunk exists)

public static void CheckForNeighbours(Chunk _actualChunk, Vector3 _pos) //Checks if chunks around the position exists and resets them

public static Vector3 ConvertBlockPosToWorld(Chunk _chunk, Vector3 _blockPos) //Convert a block local position (Inside the chunk given chunk) into a world position 

public static Vector3 ConvertBlockPosToChunkLocal(Chunk _chunk, Vector3 _blockPos) //Converts the block world position into a local position inside the given chunk

Then i tried to call the RemoveBlockAtPos method to create a new one, just for fun, it was called « BombAtPos ». Here are the results :

ezgif.com-video-to-gif (1).gif

It loops around a position, at -1,-1,-1 to 1,1,1 and removes the block at each position if there is a block here.

public static void BombAtPos(Vector3 _pos)
{
//Loop all around the block
for (int x = -1; x <= 1; x++)
for (int y = -1; y <= 1; y++)
for (int z = -1; z <= 1; z++)
{
if (BlockExistInWorld(new Vector3(_pos.x + x, _pos.y + y, _pos.z + z))) //If block exists
RemoveBlockAtPos(new Vector3(_pos.x + x, _pos.y + y, _pos.z + z)); //Remove block at pos
}
}

It was really bad in big world because it checks neighbours around it. And there were a lot of chunks to check. So i had to remove some of them, that’s where Infinite generation comes in!

First, i had to generate chunks around the player. It was not that hard to do, it was just « If player last chunk is different than the actual player chunk position, we generate chunks around ». It looked good and worked fine :

Infinite.PNG

So the next part was adding noise to test the chunk generation with it. I added Penny’s noise, the one i used in « Fast Chunks – 4 »

I also added the Concurrent dictionaries system. It avoids the out of sync dictionary when we read, draw and remove at the same time.

I also added chunks all around the player, using her « BuildRecursiveWorld » method. It generates a chunk, and chunk around it, and chunks around the new ones until we are out of the radius. These two additions gave me these results :

FastChunks_2

It started becoming slow but it was time to remove old chunks. And that’s where it stops working. Removing chunks means accessing the chunks list again and all i was doing was looking in the Dictionary, all the time.

So it was even more slow, and i knew i had to find a new solution.

It tried to generate chunks columns, it was also slow.

The last solution i have for now, that i still have to try, is to virtualize a lot more. Don’t draw the sides of chunks, don’t draw anything that is not visible, and add occlusion to hide chunks behind the player. I have to minimize the drawn chunks and blocks, minimize the chunks in the list with bigger but optimized chunks.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.