What's New in SDL Version 3

Following the first official version 3 release tag of the SDL_mixer library a few weeks ago, I thought I would explore what enhancements have been made from SDL version 2 to SDL version 3. I'll be focusing particularly on updates to the library suite that would have impacted the development of my own jigsaw puzzle game. But I'll also list a few items in summary form that others might find interesting.

I figure this might be helpful for other indie game developers out there who are used to SDL version 2, but have been thinking about upgrading to SDL version 3. Particularly those who are wondering what really matters... Updates that might help improve your everyday development.

Developers looking to upgrade existing projects do need to be aware that SDL Version 3 has some breaking changes to the API. The migration path is not a simple drop-in of the new library. The SDL team put together a migration guide.

The SDL team also put together their own summary of new features in SDL 3. There are quite a few new APIs, with increasing cross-platform support for modern devices, dialog boxes, the file system, and so forth.

I'll provide my own much shorter summary below, listing items that I think are particularly relevant to indie game developers.

Summary of Enhancements from SDL Version 2 to SDL Version 3

The core SDL 3 library

  • A new GPU API that offers access to a more modern cross-platform GPU pipeline, with support for Vulkan, Direct3D, and Metal. My knowledge and experience in this area is still quite limited.
  • Direct support for rendering nine-patch texture atlases. This is a great improvement if your game or application needs to render custom dialog boxes, buttons, and other UI elements.
  • Better cross-platform support and event handling for gamepads and other modern devices.

Some of the new APIs initially sounded to me like they might only be for developers still using plain C, since the more recent versions of C++ offer better cross-platform file system handling, for example. But on further inspection, they do provide value even beyond these more recent C++ improvements. If you need cross-platform save/restore of game data, native open/save dialogs, and so forth, they're worth looking into.

The SDL_ttf library

Introduces new TTF_TextEngine and TTF_Text structures and API calls that handle glyph caching and text layout internally. This allows text to be rendered efficiently, without resorting to manually building glyph texture atlases, or building your own SDL_Surface to SDL_Texture pipeline when rendering text.

For my jigsaw puzzle game, I built two classes to handle rendering of text that I likely wouldn't have needed, if I was using SDL version 3.

I had a Utf8TextureCache class that built and cached SDL_Texture objects internally, given a text string. It checked the cache to see if the same font, font size, and string had already been constructed previously. This was great for common user interface strings, for example, that would be re-used throughout the life-cycle of the game.

A separate GlyphTextureCache class built and cached texture atlases for individual sub-sets of glyphs. During construction, it accepts a font and a set of characters. I had a simple text rendering context structure that recorded information like font size, color, character spacing, and alignment. I needed this specifically for rendering my game timer, but it could be used for rendering any dynamically-generated string.

These classes, and the supporting rendering code around them, weren't a monumental undertaking. But they did represent several days of coding, testing, and debugging that SDL_ttf version 3 provide more direct support for.

The SDL_mixer library

My impression is that the new version 3 SDL_mixer library doesn't necessarily add any significant new functionality that wasn't available in version 2, but it provides a significant clean-up of the API. Audio is now played in tracks rather than a fixed set of channels. It brings it closer to how other modern audio engines operate.