I've been working on KingCraft, a voxel-based 3D game inspired by Minecraft, built entirely with Three.js and vanilla JavaScript. Here's what I learned building a chunk-based world renderer from scratch.
Architecture Overview
The game is structured around a few core systems that run in a loop:
Game Loop
├── Chunk Manager (world generation, mesh updates)
├── Physics Engine (collision detection, gravity)
├── Player Controller (input handling, camera)
├── Inventory System (block placement/break)
└── UI Layer (hotbar, crosshair, debug info)
Chunk-Based World Generation
Instead of loading the entire world at once, KingCraft uses a 16×16×64 chunk system. Only chunks near the player are loaded and rendered. When the player moves, old chunks are unloaded and new ones are generated.
Each chunk is built from block data and merged into a single geometry using BufferGeometryUtils.mergeBufferGeometries — this drastically reduces draw calls from thousands to ~50 per frame.
Block Types & Data Structure
Blocks are stored in a flat Uint16Array for memory efficiency. Each block ID maps to a type:
0— Air1— Grass2— Dirt3— Stone
Player Physics
Physics runs at a fixed timestep with simple Euler integration. The player has:
- Gravity (world-space down)
- Collision boxes (AABB vs block grid)
- Smooth camera with pointer lock
- Jump with variable height
Block Interaction (Raycasting)
To place or break blocks, I cast a ray from the camera center using Three.js Raycaster. The ray hits against a simplified block grid instead of mesh triangles for performance.
Performance Tips
- Use InstancedMesh for repeated block types (like stone)
- Disable shadows for distant chunks
- Limit chunk updates to 1 per frame (spread across frames)
- Use requestAnimationFrame with delta-time capping
Debug Tools (F3)
Pressing F3 toggles a debug overlay showing:
- FPS / frame time
- Player position (x, y, z)
- Chunk coordinates
- Loaded chunk count
- Block at crosshair
Next Steps
KingCraft is still in active development. Future plans include:
- Multiplayer via WebSockets
- More block types (wood, leaves, water)
- World saving/loading with IndexedDB
- Terrain generation with Perlin noise
Try the game here: KingCraft Demo