voxelforge

A voxel engine with a playable browser demo. The renderer targets WebGL2/WASM, while the simulation core builds natively and is covered by tests - tens of thousands of assertions.

voxelforge
TL;DR

A voxel engine with a playable browser demo. The trick is that the simulation core knows nothing about rendering - which lets you test the logic without a GPU, across tens of thousands of assertions.

Overview

voxelforge is a voxel engine with a playable demo running in the browser. The renderer targets WebGL2 and WASM, but the most interesting decision is not about graphics - it is about architecture: the simulation core is completely cut off from rendering. It holds the voxels, the rules and the neighbourhoods, and knows nothing about anything appearing on screen.

That single decision changed the character of the project. Instead of an engine that only works when you launch it with a graphics card, it became a logic library that runs everywhere and can be tested like ordinary code. The rest of this case study is about why that paid off.

A voxel engine has to do two hard things at the same time: render the world fast and simulate it correctly. Both are easy to break in a way that looks fine at a glance yet is wrong - a block disappears one frame too late, a neighbourhood is counted one voxel off. These bugs do not shout, they quietly break the world.

When rendering and logic are braided into one body of code, you cannot separate them, not for testing and not for debugging. You cannot tell whether a block vanished wrong because the simulation computed it wrong, or because the renderer drew it wrong. Untangling those two worlds was the most important thing in the whole project.

A core that does not know about the GPU

The solution was also the simplest: the simulation core is pure logic, and the renderer takes its state and turns it into triangles. No part of the core touches a canvas or a GPU. The interface between them is narrow and explicit, so the renderer can be anything and the core does not know.

core.ts · typescript
interface SimulationCore {
  tick(dt: number): void;
  voxelAt(x: number, y: number, z: number): Voxel;
}

interface Renderer {
  draw(core: SimulationCore): void;
}

Who does what

LayerRoleGPU dependency
Simulation corevoxels, rules, neighbourhoodsnone
Rendererturning state into trianglesWebGL2 / WASM
i
Note

Since the core does not depend on a GPU, it is built natively and tested like a normal library. The renderer targets WebGL2 and WASM, but the logic passes its tests even on a CI machine with no graphics card.

Tests instead of hope

This split is not an academic luxury. It is why the simulation has test coverage in the tens of thousands of assertions - and that is the only way to say a voxel engine is correct, not just that it "looks fine". One-voxel-off bugs surface in a test, not after an hour of play.

thousands
voxels per chunk
tens of thousands
assertions in the core tests
0
core dependencies on the GPU

The result: a demo that grows without fear

What comes out is a playable browser demo that can grow without fear of quietly breaking the world logic along the way. Because the core is tested on its own, a change in the renderer cannot silently break the simulation, and a change in the simulation surfaces at once in the assertions. The engine is not just flashy - it is checkable.

More projects

More work from the same category - see how we tackle similar challenges.

Have a similar project?

Get in touch - a quote is free and comes back within an hour.