September 2025
This month has been a bit of everything just to keep the ball rolling. I have mostly focused on small annoyances, some where maybe lower hanging than others.
Lighting
As I left the lighting half-finished it was time to pay the piper. Previous implementation traded performance for quality by just having a high number of lighting samples. This means there was naturally less noise but the cost was very high. So I set out to improve the performance by reducing the sampling and implement better denoising.
Above his how it looks with the noise. This is with 2 samples for the ambient occlusion, 1 sample for the sun light, and with lighting applied at half the resolution.
And after the denoising applied. Here I just compute the lighting of a pixel by averaging over a neighborhood, taking the surface normal and depth into account to not blur edges (bilateral filtering). Samples are also accumulated over time to make it even smoother (temporal filtering).
This made everything run smoothly on my macbook. It also made the job easier for the temporal anti-aliasing and now the world is more pleasant to walk around in. There are some subtle issues left though, like low frequency noise and small artifacts in corners due to the raycasting.
Grass
To put some life into the picture I set out to add some simple animation to the grass.
This is how it started. As always, ordering when applying transforms is important!
And this is how it ended.
Hot-reloading textures
As I did some work on the grass, including using my limited artistic talent to shape and color it, my frustration with having to restart the game over and over grew. So why not just do the same as with shaders, lets hot-reload!
I used the Zig build system and the handy --watch
feature to create a build step for assets that automatically builds assets as they are changed. Then the game listens for changes in the built assets and reloads if needed. Now the actual build step is very simple, but I wrote a simple parser for the OpenRaster format (basically just unzipping a .png) as a proof of concept.
Misc
Here are just a collection of smaller things I worked on.
For the actual game part I have implemented tools as a way for the player to interact with the world. I took some time to reimplement this system to make them easier to implement. For now they don’t provide much in terms of gameplay but I have the basics for modifiying the voxels and I made myself a marker/ruler tool for some debugging purposes.
Implementing the tools above I identified some problems with the raycasting and to debug those I quickly put together rough grid view to visualize the voxel data structure (chunks and bricks). Lines are frickin’ hard to deal with.
What’s next
I have two goals in mind for the near term:
- Procedurally adding objects like trees to the world.
- Setup a file format for the voxel world. Mostly motivated by me wanting to play around some more with writergate, but there is also a point to being less dependent on the procedural generation when testing stuff.
First I need to deal with some annoyances when working with the voxel structure. I got the ball rolling with the tools system but there are still some loose ends.