WASM Raycaster in C with Clang no stdlib


I’ve been building software for profit for 25 years now - for fun since I was about 12. For the past year and a bit, I was focused on helping build out and fix some infrastructure. While there was some coding involved, I wasn’t doing much new software development.

I had an urge to shake off a bit of cruft, and do a little “code 5k”. I felt like digging back into some lower level code to stretch my legs - and, of course, throw in some games programming.

I found a neat little YouTube series that walks you through building a really simple Raycasting engine - that seemed like a simple fun thing to do. (side note: it’s a great tutorial, and the presenter is very smart, but I have many issues with his code. Please don’t write code like that.)

About a year ago I made a little teaching project that provides an API for primitive drawing in C which renders the output to the browser. The project’s target compilation is WASM using Clang directly. It doesn’t use emscripten (or any libraries at all (including the stdlib)). It has simple functions like draw line, draw point, etc. It has custom implementations of cosine, sine, rand, and a few other bits - it’s called Wefx if you’re curious or interested.

I dusted off that project, and followed along with the gist of his tutorial while porting it to wefx, and here is the silly mostly pointless result: Raycaster in C/WASM/Clang

With -0s it came in at about 223kb. That isn’t massive, but not quite as small as I had hoped. An old 5 1/4 inch floppy was 360kb - not much room for content. I imagine I could get it smaller if I wanted to spend more time on it.

So why bother with this post? I want to call out a few things for myself, and also, maybe, for others to think about.

🕶️ Sometimes doing things for no reason is just what you need.

There are some really weird bugs when using WASM and shared memory with requestAnimationFrame and trying to have input events sent from the document. Trying to figure out why that was having issues was mind bending (it’s why there is a delay when you first push a key). And trying to debug with no tools - just sitting there reading raw WASM trying to reason out “what the what…” It was a lovely reminder of how things used to be.

🕶️ You never know if the “no reason” will come in handy.

Not too long ago, I spent years building a little VR based web engine. I learned about shader programming, how GPUs work, using raw buffers, perspective projection, using matrix kernels (probably the wrong term, read Gaussian blur kind of stuff), quaternions, vector manipulation, linear algebra, quad and oct trees, and many other things I am forgetting.

The engine went nowhere; no one cared. The only good that came out of it was the WebXR Typescript Types. Fingers crossed that the new Apple Headset (if real) supports web based VR content and those types help some project somewhere make something cool.

I am smart enough to know my limitations. I realised I am nowhere near good enough to use any of that knowledge at, say, Valve or Epic Games, or really anywhere where that knowledge would be even slightly useful. The years I spent learning that were, basically, a waste of time.

However, over the past 5 years or so, I’ve found that all that video game engine nonsense has come in incredibly handy when building and playing with machine learning models.

Cosine similarity, tensors, matrix multiplication, dot and cross product, kernels, heck even how GPUs work in general has all come in quite handy because of that wasted time game engine time.

A few final thoughts:

Life is short. Make art.