DiveCraft — Blocky Waves & Procedural Islands • WIP (Final-Year Project)

Engine: Unity 2022 LTS  •  Language: C#  •  Role: Solo Developer

Overview

DiveCraft is my final-year work-in-progress: a voxel island world with a stylised, block-based wave system and a chunked terrain pipeline. Core systems include chunk generation/meshing, a hotbar + block placement/breaking, a water volume mesh, and player movement with swim physics.

Footage

Building

Mining

Image Gallery

Generated island view Underwater terrain Terrain layers

What I built (programmer focus)

Chunked world & generation

  • A Worlds singleton spawns a grid of chunk GameObjects and keeps a lookup of loaded chunks. It batches creation over frames to avoid stalls.
  • Each Chunks instance fills a 16×128×16 voxel array, blends an island radial mask with Perlin detail, layers materials (grass/dirt/limestone/stone), and fills above terrain with water up to a defined sea level.

Meshing & materials

  • Solid block mesh is built face-by-face only where neighbors are non-solid (air/water), with UVs pulled from a block atlas; water uses a separate child “WaterMesh” with its own material/UVs, and we skip water-to-water faces for fill-rate.
  • UV helpers, face tables, atlas sizing, and shape flags live in VoxelData (e.g., 16×16 chunk width, atlas size = 7, sea level, per-face UV rotation).

Interaction & player controller

  • PlayerController does mouse-look + CharacterController movement, block breaking/placing via camera raycasts, and swim logic when feet are inside a water block (space to rise, shift to sink faster).
  • Hotbar cycles block types, with a simple TMP UI showing the current selection.

Representative code

// Worlds: spawn chunk grid (batched)
for (int i = 0; i < chunkCoords.Count; i += 8) {
  for (int j = 0; j < 8 && i + j < chunkCoords.Count; j++) {
    var coord = chunkCoords[i + j];
    // new GameObject("Chunk_x_y") + AddComponent<Chunks>() + GenerateChunk()
  }
  // yield return null; // keep frame times smooth
}
// Chunks: only emit faces against non-solid neighbors (skip water→water)
if (!IsSolid(neighbor)) {
  // choose water or solid mesh buffers
  // add 4 verts, 6 indices, and atlas UVs per visible face
}
// PlayerController: interact with voxels via camera ray
if (Input.GetMouseButtonDown(0)) TryBreakBlock();
if (Input.GetMouseButtonDown(1)) TryPlaceBlock();

Results & next steps (WIP)

  • Stable chunked rendering with separate water mesh and atlas UVs.
  • Functional placement/breaking, swimming, and hotbar.
  • Next: optimise meshing (greedy merge), expand island variety, add underwater caves & tides, and profiling passes.

Note: This page represents an active, in-progress build for my final-year university project.