D2 log 003 – PAK files

Game assets are packed into a single “PAK” data file, with optional compression. The game’s virtual filesystem can access files in the PAK file and has a fallback to the native filesystem. For compression I used the LZ4 library – it’s fast and easy to integrate.

The format of the PAK file is quite simple. It contains data of all the files and at the end there’s a table of contents, with filenames, offsets and lengths.

I have a simple utility app that creates the data file. There’s an option to turn off compression for faster rebuilds during development; it also gets automatically disabled for  files smaller than 1KB and for all OGG audio tracks.

D2 log 002 – Entity system ready

Phew, new entity system is up and running.

First I wrote standalone code for basic entity management and a few unit tests to make sure it worked properly.

Next step was to integrate it into the existing codebase. Quite a transplant!

There were raw Entity pointers throughout the codebase and lifetime, ownership & validity checks were not exactly a solved problem – at least not systematically.

I also had to make sure the serialization still worked and preserve the same entity IDs across load/save cycles. Perhaps not 100% necessary but I want the diffs to look tidy.

Last major issue was the level editor, which needs to hold on to entities for a little longer than the rest of the game for undo/redo support. I added custom methods to remove them from the entity list without deallocating and to add them back with the same EntityID.

The level editor.

On to the next one. Time to clean up the filesystem layer.

D2 log 001 – Entity system

Getting back to D2 development after a year of focusing mostly on Tiny Player and Tiny Player for Mac.

Some of the C++ code is not so great. It’s been a while…

The property system is “awesome” but it seems like I was trying to be very clever and now it all looks pretty complicated for what it does. But at least it works, so let’s keep it for now.

First, I’m going to rework the entity system and make it simple and solid.

We won’t store entity pointers directly anywhere in the game. Instead, let’s store an index into the entity array and use a getter to retrieve the pointer when we need it. To make sure the array slot actually contains the object we expect, we’ll add a “generation” index, which gets increased each time a new entity is added. That way, we can query the entity list using a handle and get a valid pointer or NULL if it’s gone.

EntityID {

EntityID AddEntity( Entity* e );
Entity *GetEntity( EntityID id );
void RemoveEntity( EntityID id );


Tiny Player for Mac 1.2.4

Tiny Player for Mac version 1.2.4 is out now. This update brings the following improvements:

  • Playback → Always enqueue new files (don’t clear playlist)
  • Playback → Go to current track
  • Fix zero padding of track number for current track
  • Fix ⌘L shortcut for changing playback mode
  • Remember playback mode after restart

UPDATE: 1.2.5 is out now to fix a problem with saving the Playback mode.

Alternative music players for Mac

Tiny Player for Mac

  • First and obvious choice
  • Free


  • Subscription based, from $4.99 / month
  • Cloud storage service


  • $19.95


  • Hub for online sources

Audio Playr

  • $8.99


  • Open source


  • Primarily a video player, but has a playlist and handles audio as well


  • Open source


  • Open source, media manager




  • Electron based
  • Open source
  • Drag & drop breaks it

foobar2000 for Mac