A surface scan of planet Axel

About

Hi, I'm Axel! I'm a programmer from Helsinki and a current student at Hive Helsinki. I'm excited about games, graphics, audio, and low-level programming. I also enjoy riding and wrenching on bikes. Below is a sampling of projects I've worked on, either for Hive or for my own amusement.

Software ray tracer

My second group project at Hive Helsinki, a software ray tracer written in C. Developed together with Maksym Oliinyk. Supports scenes with multiple different geometric objects, reflections, soft shadows, antialiasing, depth of field, texturing, normal mapping, and a physically based lighting model.

The renderer is multithreaded and renders at a progressively finer resolution over time, allowing the camera to be moved at interactive speeds, refining the image by accumulating samples gradually. The project also gave me an excuse to read up on quaternions, learning how to use them for spatial rotations.

GitHub link

Block building game

For this project, I wanted to explore the idea of a Minecraft-like block building game, where the pixel art on the block faces is interactively editable without leaving the game.

The project also served as a test bed for experimenting with ambient occlusion and shadow mapping techniques, and for testing different ways of packing block data for efficient updates and raycasts.

The game itself is written in C++, using SDL for windowing and input and OpenGL for rendering.

GitHub link

Hive 48-hour game jam

My entry, together with my teammate Jasmine, for the Hive 48-hour game jam in October 2025. By audience vote, our game won the awards for Best Game and Best Gameplay — we even got some sweet 3D-printed trophies to prove it!

The game is a cute little platformer, written in C using Raylib and the Tiled map editor tool (both of which were unfamiliar to us at the start of the game jam). The jam was a fun exercise in rapid iteration, and in doing the kind of prioritization and triage necessary to churn out lots of work in a short timespan.

GitHub link

Itch.io link

Platform abstraction experiment

At first blush, this project looks like a basic terrain renderer; it's actually an effort to create my own platform abstraction layer that has everything I want, and nothing I don't. The goal is to be able to build freestanding executables that run on Linux, Windows, and the Web.

Right now there is support for keyboard and mouse input, OpenGL context creation, and audio output via a callback function. To achieve this, I call available system APIs directly, instead of relying on third-party libraries.

On Windows I use only core Windows APIs and WASAPI for audio. On Linux, libX11 is used for windowing and input, and PulseAudio is used for sound. For the Web version, the application is compiled to WebAssembly, and uses WebGL and an AudioWorklet for graphics and sound.

GitHub link

IRC server

My third group project at Hive Helsinki, built in 13 days with Eve Keinan and Hien Nguyen. Written in C++20, it's a server implementing the IRC chat protocol, tested against the irssi IRC client. The server is single-threaded, employing an event-driven architecture, using the epoll system call API to respond to I/O events.

The project involved combing through RFCs and technical documents to discover and replicate the minutiae of an application-layer protocol. It also provided an excellent opportunity to get intimate with the Berkeley sockets API.

GitHub link

Game Boy music tracker

I taught myself the D programming language by building a tracker (a kind of music sequencer) that emulates the Nintendo Game Boy sound chip. I built a custom user interface, complete with buttons and scrollable viewports, tool tips, full copy/paste and undo/redo history, and with some nice oscilloscopes for each sound channel, for good measure.

Internally, a full emulator of the Game Boy sound chip synthesizes all sounds; any songs produced in the tracker could theoretically be played on real hardware. To write the sound chip emulator, I studied publicly available documentation for the Game Boy, and also trawled through the source code for the Gambatte and SameBoy emulator projects for ideas.

GitHub link

Minimal GIF encoder/decoder

Another weekend project: a minimal GIF image encoder and decoder written in Python. The decoder fits in 50 lines of code, with an even smaller encoder. The decoder takes any file-like object and returns a tuple with the dimensions of the image, the palette (as an array of RGB triples), and an array containing palette indices for each pixel (in row-major order).

The code is structured as a kind of pipeline of generator functions, converting from size-prefixed "blocks" to variable-width LZW codes, to actual palette indices. It was a fun exercise in reading and implementing a technical spec, and in understanding the intricacies of the LZW compression algorithm used by the GIF format.

GitHub link

Mesh compression experiment

As an experimental side project, I implemented the Edgebreaker mesh compression algorithm (notably used by the Google Draco mesh compression software).

The Edgebreaker algorithm encodes the connectivity of the mesh, and is then combined with a simple predictor, followed by quantization and delta encoding of vertex coordinates, to reduce the size of the vertex data.

The encoder is a Python script that converts a GLB file to a custom file format that, when gzipped, reduces the size of the mesh to about 10% of the source GLB asset. The decoder is a small, portable C library that converts the custom file format to raw vertex and index arrays, ready for use by a low-level graphics API.

GitHub link

ProTracker MOD file renderer

A header-only C library for rendering ProTracker MOD music files to raw PCM audio data. The code is written in portable C89, with no external dependencies (save for a couple C standard library functions), and performs no memory allocation at any point, sourcing pattern and sample data directly out of an in-memory MOD file.

For the project, I spent a great deal of time closely reading any documentation I could find on the MOD file format. I tested with different songs and trackers to find bugs and discrepancies. I also dug into the source code for OpenMPT and MilkyTracker to discover how they handled various edge cases.

Here are some example songs rendered with the library (and then converted to MP3):

a_king_is_born.mod (original on ModArchive)
space_debris.mod (original on ModArchive)
radix_-_supernova.mod (original on ModArchive)

GitHub link (note: this is my old account)

TrueType font file parser

A header-only C library for parsing TrueType font files. Allows the user to extract glyph shapes, metrics, and kerning data. A test suite is included that ensures point-for-point matching output with the FreeType library for a range of different fonts.

The library has no external dependencies, save for the C standard library. It also allocates no memory, but instead reads glyph and metrics data directly out of an in-memory TTF file. All output is written to memory allocated by the user.

A simple rasterizer is included as a demo, which uses the library to extract glyph shapes and then render them directly to standard output as ASCII art.

GitHub link

WebAssembly module visualizer

A Python script that parses DWARF debug info embedded in a WebAssembly module and outputs an HTML file containing the disassembly for each function.

Where one function is inlined within the body of another, it is presented as a nested box. Functions are color-coded to aid readability.

For the project, I spent some time reading the WebAssembly specification and the DWARF debug info standard, in an effort to figure out how to extract the information I needed, and how to present it in a legible way.

GitHub link

Blue noise texture generator

A weekend project: a very simple library that generates textures containing a 2D blue noise pattern. Blue noise can generally refer to any noise pattern that has little low-frequency content, and has a number of uses, including sampling and dithering of images.

I used the method of generating pure white noise and then repeatedly applying a high-pass filter, and renormalizing the image to restore the distribution of pixel values to a flat histogram.

There are more sophisticated ways of generating blue noise textures, but I wanted to see how little code it would take to make a basic generator. (Turns out, it takes less than 100 lines of C.)

GitHub link