Category Archives: Development

std::chrono vs timer coalescing in macOS

Recently I needed to call a function in the background of a C++ program periodically. I decided to use the STL for the task.

During research, I found a nice article about periodic processing with C++11. The sample code has helped me to quickly put together a solution for my project. However, I noticed that the author was showing average wakeup errors of 20 microseconds on Windows and 96 microseconds on Linux. Running the sample code on macOS yielded errors of up to 2000 microseconds! That is a big margin. I was a little disappointed. My favorite OS is getting worse results… oh no.

But then I remembered that newer versions of macOS employ “timer coalescing“, which tries to save energy by reducing timer accuracy and “bundling” wakeups together to let the CPU sleep for longer periods of time.

Nice, but thankfuly we can turn it off for more accurate testing:

sudo sysctl -w kern.timer.coalescing_enabled=0

After that the errors went down to about 40 microseconds on average. I have yet to look up the proper way to tell the OS that my app needs this, regardless of the global setting, but my curiosity is satisfied for now.

Note: the source code from the article is only provided as a PDF from which it is hard to extract in a usable form, so I took the liberty to make a plain-text copy on Github.

Designing a C++ Property System

As I’ve been working on Devastro 2 I thought it would be great to be able to see and adjust properties of the in-game entities in the level editor.

Properties can be generic ones such as position, angle or color but there can also be ones specific only to certain types of objects – for example a “crate” object can have a (bool) property that defines if a pickup item should appear when the crate is broken. An enemy ship can have a property that defines how much damage it can take.

But how does the game know what types of objects have what properties? I guess we’ll need some kind of system for that.

A property system is a way to inspect and modify the properties of objects at runtime.

Implementing this is quite easy to do in languages such as Java or C# because reflection (aka introspection) is part of their runtimes. Also, custom annotations can be used to further describe how we want the properties to be published. But being the stubborn person I am, I’m writing this game in C++, so… how hard could it be? Maximum effort

Use cases:

  • Serialization – read/write properties to a file when saving and loading levels
  • Editing – interactively adjust properties using sliders, checkboxes etc in a GUI.
  • Debugging – inspect objects at runtime

We need to:

  • Get a list of properties for each class in the game
  • For each property, get its type, name and additional info for editing & serialization purposes
  • For a given object instance, get/set the value of each property

I defined several constraints for the system:

  • No custom preprocessing steps (looking at you, Qt)
  • No macros
  • Don’t use C++ RTTI
  • Non-invasive – objects don’t need to register or add getters/setters; this is hard to avoid completely but currently there’s only 1 line of boilerplate declaration to be added to each class
  • No runtime overhead for objects with properties (allow direct access to values when type is known)
  • Simple setup (all properties for all objects defined in single location, DRY for subclasses)

And some compromises:

  • OK to do string lookups but only when editing/loading, not in main game loop
  • Limited set of property types (int/float/bool/string/enum)
  • Limited amount of validation (can set a property to any value, object must deal with it; a value range can be defined as a hint for editor UI but is not enforced internally)

As of now the property system is up and running. Phew! I went through several iterations before settling on a design and it took a lot of effort to flesh it out for all the use cases and integrate it into the game.

Bottom line: Interesting challenge; looking forward to using Jai.

New sound mixer

The audio effects you get with OpenAL are:

  • pitch
  • pan
  • gain
  • that’s it

It’s a shame that OpenAL doesn’t provide more built-in effects or some equivalent of OpenGL’s shaders. HW accelerated or not – they could provide a lot of flexibility without having to rely on vendor-specific extensions.

With Superforce we had to make do with pitch shift where we really wanted a lowpass filter (in-game pause menu slows down the background music to 50%; this workaround actually turned out nice but lowpass or a combination of the two could have been even better). For the next game I decided to write my own audio mixer.

The actual sound mixing code turned out pretty well. Pitch shift was a bit tricky to get right. I also integrated the stb_vorbis decoder for streaming music. At first I was willing to keep using OpenAL as a backend since I already had it working. But OpenAL is a layer on top of Core Audio, so I couldn’t sleep well knowing that I could get rid of it…

So, Core Audio. With OpenAL, you play sounds. You can take your time. OpenAL will keep playing the sounds you already fired – no problem, no glitches. With Core Audio, it works the other way – you don’t call them, they call you. Like some sort of crime syndicate. And they will keep calling, whether you’re ready or not. You better be.

I got basic Core Audio output to work on the Mac pretty quickly but the setup wasn’t right. I was filling my mix buffer on the main thread and the Core Audio callback could come in to pick it up whenever it wanted. This was definitely going to cause problems when I’d start playing more sounds – sooner or later the callback was going to happen at a BAD TIME. Also, whenever the main thread got behind even a little bit during fullscreen transitions or loading, I could hear glitches – it didn’t fill the buffer quickly enough.

After a bit of research I settled on a more sophisticated approach. It is multithreaded and it gets me gapless playback even when loading a level or switching to fullscreen mode.

  • MAIN THREAD (GAME LOOP) → PLAY SOUND 1 → PLAY SOUND 2 → VSYNC, RENDER → REPEAT
  • MIXER THREAD → GET CURRENT SOUNDS → MIX INTO A FREE BUFFER → WAIT A BIT → REPEAT
  • CORE AUDIO CALLBACK → GET A FULL BUFFER FROM MIXER → USE IT TO FILL CORE AUDIO BUFFER → RETURN

The threads communicate using lock-free queues.

  • The game thread starts and stops sounds by sending commands into a lock-free queue.
  • The mixer thread reads from that queue and updates its internal information; then it gets a new empty buffer and mixes the sounds into it. When the buffer is filled it is put on another lock-free queue.
  • The Core Audio callback is called by the OS. It gets a full buffer from the buffer queue and just copies that into the destination Core Audio buffer. The size of the buffers coming from the mixer may differ from Core Audio, so it keeps a “cursor” inside the current source buffer.

There are several variables I can adjust:

  • Buffer size (currently 512 samples, matching Core Audio)
  • Buffer count (currently 3)
  • Mixer thread update frequency (currently 100Hz)

The latency is ~30ms, which is about two frames at 60FPS. I think that’s fine. I should probably add another thread dedicated to reading audio streams from disk and decoding to avoid problems with slow disk access. Some people still have HDDs…


In general, I’m quite happy with this. Ironically, my new mixer can still do only pitch, pan and gain but I now have the option to write my own sound effects, because I control the whole thing.

Font quality

In the upcoming Superforce 1.1 update I stopped using stb_truetype and went back to pre-rendered fonts made with Glyph Designer.

Superforce fonts before & after switching away from STB Truetype

Before & after switching away from STB Truetype

Unfortunately I had some problems with stb_truetype which I wasn’t able to solve. Some characters from some fonts were cut off on the left and sometimes on top a bit, with no reasonable explanation. Also the glyph shapes in general did not have the right amount of sharpness and smoothness I wanted. Perhaps I’m too used to Mac OS X font rendering? Who knows.

I’m sure most people can use stb_truetype properly and I still have high regard for it (and anything that @nothings produces for that matter) but it seems like this one was not meant for me. I’d still like to finish my own font converter someday.

GUI editor

As a little diversion from working on Superforce, I added an interactive GUI editor to NLEngine.

Pressing a hotkey anywhere in the game switches to GUI editing mode. In this mode, I can drag any GUI element around. I no longer need to re-launch the game several times and check if I’ve set the correct coordinates. I just move it around with the mouse until it looks right, then press Save and I’m done.

All in about 200 lines of code, with full undo/redo support and SQLite persistence. Glad I took the time to do this. It’s not actually super useful in Superforce because there the layouts are finalized but I’m pretty sure I’ll use it for something later. Like, for real.


Here, buttons are made aware of the GUI editing mode and will ignore input when it is enabled.


The GUI editor just handles the dragging. The layout (x, y, w, h) is then saved to disk and that’s pretty much it.

The Construct

Here’s a little feature from Superforce that I really like. It saves me a lot of time during development.

Going through half a level just to get to the enemy that I’m working on? Boring. I really need to launch the game and see results immediately.

To do that in Superforce I have a special mode which I call The Construct.

Construct

You could also call it “The Playground” or “The Firing Range” or whatever.

It’s an empty level with just the things I need at the moment. It runs the standard game loop and renders everything just like the game itself. In addition to that, it has special functions I can use to manipulate the game objects in various ways.

For example, when working on a tank, I can move the mouse cursor around to make the tank aim at a particular spot, press a mouse button to make it fire and press SPACE to make the tank explode. Pressing SPACE again spawns a new tank. Fun!

Superforce for Mac? Not really…

I have a working build of Superforce running on Mac OS X. Am I going to release it? Nope. So what is it for?

The iOS Simulator is fast enough for running apps. It is way better than the Android emulator, but it’s not fast enough to run a game at 60FPS. And it is completely useless for running a game that is controlled by the accelerometer. There’s a way around that, but it’s too complicated for my taste. I want to iterate quickly, so I’ve invested some time to optimize my workflow.

Setting up a Mac build has paid off almost immediately.

The Mac version starts super quickly and runs smoothly at 60FPS. I can comfortably control it with keyboard and mouse. Another big advantage is that it can read and write files in the filesystem. This is required for the built-in level editor. It also helped me identify a few areas in my code which had problems on a 64-bit architecture. I was able to fix those without ever running the game on a 64-bit iOS device.

Superforce running on Mac OS X