Testing font code

 from Red Blob Games’s Blog
Blog post: 13 Apr 2024

Earlier this year I was trying to improve font rendering in some of my C++ projects, and that led me down a rabbit hole of learning signed distance field (SDF) font rendering. I wanted to try out the SDF fonts in a real project. I occasionally help with Galactic Assault Squad[1] (GAS), especially “engine” code, so for Week 6 I decided to try SDF fonts there.

Fonts rendered in the game world

The first day or two I was navigating the code to see how it was structured. Then I could figure out where I could add the SDF font renderer. I tested first by writing new C++ code and reusing the same shader from my JS experiments. It was a lot of hackery, including global variables scattered throughout, but I got some text on the screen:

Font atlas

The next step was to read the font atlas, which says where in the image each letter is. I started heading down a rabbit hole thinking about how best optimize that file format and code, but remembered that this is just an hacky proof of concept right now. I stopped trying to optimize and focused on getting something working.

One glyph extracted from the font atlas

Along the way I ran into some differences in coordinate systems between my JS code and the C++ code:

Buggy font rendering

But that’s fixed by flipping things upside down a few times. The next goal was to draw text in the game world. I decided to draw labels on roads:

Text above objects

But it might also be interesting for text to be on the ground, underneath other objects (note that this was tested with a different font):

Text below objects

I also made a demo of text trailing behind a player:

Fake sponsorship message

One thing I learned was that the text shadow scaling I put in place for my standalone experiments were not suitable when there’s a busy game in the background. Compared to my previous experiments, I needed the small text to have a larger shadow and the large text to have a smaller shadow. That’s exactly the reason I want to test things in a real project. Sometimes it’s not obvious from a standalone experiment.

I compared the new renderer to the existing one:

Text comparison

I think the SDF renderer is really nice at large sizes but not necessarily better at small sizes. The main value of a new font renderer would not be in making the rendering better, but in allowing new ways to render fonts (shadows, glows, distortions, and other effects).

My goal for Week 6 was to try the SDF fonts in a real game project. I think that went well. In Week 7 I looked at what it would take to properly integrate the code into the game. Right now the development priority is combat and progression systems, not font rendering. Until we have some text to render in new ways, replacing the font renderer has low value. If it were easy to integrate, I could justify cleaning up the hacky proof of concept. However I concluded that it would take some restructuring of other rendering code. That makes it a high cost and low value. It’s probably best to wait until we’re refactoring for other reasons (lowering the cost) or until we want to render text with effects (raising the value).

In a real project, I think it’s wise to evaluate the cost/benefit to the players, not adopt new things just because the tech is cool. So maybe Galactic Assault Squad[2] will get a new font renderer in the future, but not today.

With that, I am finished with my font rendering experiments. I have a different project to work on next.

Email me , or tweet @redblobgames, or comment: