Chunk Dimensions
Chunks are defined with fixed dimensions insrc/chunk/chunk.h:15-17:
Chunk Class Structure
TheChunk class (src/chunk/chunk.h:19-62) manages all data and operations for a single chunk:
Key Data Members
| Member | Type | Purpose |
|---|---|---|
blocks | uint8_t[16][128][16] | Block type IDs (0 = air, 1-84 = block types) |
lightmap | uint8_t[16][128][16] | Packed lighting data (4 bits block light + 4 bits sky light) |
neighbors | Chunk*[6] | Cached pointers to adjacent chunks for fast neighbor queries |
subchunks | map<tuple, Subchunk*> | Subdivisions for parallel meshing |
mesh / translucent_mesh | vector<uint32_t> | Combined mesh data for opaque/transparent blocks |
Lighting Storage
Lighting uses 8-bit values with packed storage (src/chunk/chunk.cpp:44-48):
- Lower 4 bits: Block light (0-15) from torches, lava, etc.
- Upper 4 bits: Sky light (0-15) from sunlight
Neighbor Caching
Chunks cache pointers to their 6 orthogonal neighbors in the order East, West, Up, Down, South, North. This enables fast boundary queries without world lookups. Theget_block_number_cached() method (src/chunk/chunk.cpp:62-78) demonstrates the caching strategy:
Chunk Lifecycle
Initialization
When a chunk is created (src/chunk/chunk.cpp:8-34):
- Allocate block/light arrays - Zeroed via
memset - Create subchunks - 1×8×1 grid of 16×16×16 subchunks
- Setup GPU resources - VAO/VBO for mesh rendering
- Configure vertex layout - 3 packed
uint32_tattributes per vertex
Update Queue System
When a block changes, the affected subchunks are queued for remeshing (src/chunk/chunk.cpp:128-160):
Mesh Building
The chunk combines all subchunk meshes into two final buffers (src/chunk/chunk.cpp:173-191):
Rendering
Chunks are rendered in two passes (src/chunk/chunk.cpp:209-239):
- Opaque pass -
draw()renders solid blocks with depth writes - Translucent pass -
draw_translucent()renders water/glass with depth writes disabled
- Bind the chunk’s VAO
- Set the
u_ChunkPositionuniform for vertex shader offset - Issue indexed draw calls using the shared world IBO
Performance Considerations
Why 16×128×16?
Why 16×128×16?
- 16×16 horizontal matches Minecraft’s chunk size for familiarity
- 128 vertical provides 64 blocks below and above sea level
- Power-of-2 dimensions enable fast bit-shift coordinate conversions
Neighbor Caching Benefits
Neighbor Caching Benefits
- Avoids map lookups during meshing (thousands of queries per chunk)
- Enables seamless face culling at chunk boundaries
- Cache invalidation handled by world when chunks load/unload
Separate Opaque/Translucent Meshes
Separate Opaque/Translucent Meshes
- Correct transparency requires depth-sorting translucent geometry
- Better performance by avoiding state changes mid-render
- Alpha testing in shaders handles partial transparency (leaves, fences)
Related Topics
Meshing & Subchunks
Learn how subchunks parallelize mesh generation
Block Types
Understand block type definitions and models