Skip to content

Data flow of a chunk

larspensjo edited this page Dec 3, 2012 · 6 revisions

This page describes the steps taken to make a chunk visible to the player. The content of a chunk can (roughly) have a couple of different states:

  1. Empty place holder.
  2. Compressed data in a byte vector.
  3. Unpacked data in a 32x32x32 array.
  4. List of triangles that represents visible faces of the blocks in the chunk.
  5. The same list of triangles, but transferred to the graphics card.

Every chunk has an address, constisting of three integers, making a 3D coordinate. Chunk 0,0,0 is this the middle of the world. The data flow process below describes how the chunk go through these states.

render.cpp: DrawLandspace()

This function is called every frame. Depending on the view distance, a number of chunks are going to be needed. This list (sListOfNearChunks) is created and sorted on distances to the player. The list consists of chunk pointers (chunk *).

chunk.cpp: ChunkFind()

As the world is unlimited in size, it is not possible to organize chunks in a 3D array. They are managed in a std::map<ChunkCoord, chunk*> sWorldCache. If the chunk is unknown, it will not yet be listed in the map. If the chunk is found on the local file cache, the compressed data is loaded immediately.

Otherwise, an empty chunk is created, which will be added to the map. A request for the chunk will also be sent to the server. This empty chunk will be used for drawing initially.

chunkcache.cpp: LoadChunkFromCache()

The compressed data is simply loaded. Nothing else is done here. To save communication bandwidth, the chunks are permanently stored into the file system of the client. One file for each chunk. These files will not be updated unless the server sends a new checksum, or the server sends a command to update one of the blocks in a chunk. If a chunk is found in the cache, it is not requested from the server. Only the checksum is verified.

parse.cpp: ParseChunk()

This function is called when a compressed chunk is received from the server. It will only initiate basic facts about the chunk and initiate the compressed data. A job will be sent to the thread pool to request unpacking of the chunk.

chunkprocess.cpp: Task()

The chunk will be uncompressed and saved to the cache. A "dirty" flag is set, to indicate that the list of visible triangles need to be recomputed.

chunk.cpp: Draw()

If the chunk is marked as dirty, a new job will be sent to the thread pool that requests a "RecomputeChunk".

chunkprocess.cpp: Task()

So now the chunk is in the ChunkProcess queue for the second time. This time, the list of visible triangles will be computed from the 32x32x32 blocks in the chunk.

chunk.cpp: Draw()

It will be found that there are defined triangles, but no VBOs defined in OpenGL. These will be created "on-the-fly".

Finally, the OpenGL draw() function can be called.