Rival Fortress
I do most of my game development on Linux, and I’m very happy with GDB, but when I have to do some debugging on Windows, Visual Studio is my debugger of choice. In this post I’ll lightly rant about some of the features (or lack thereof) of the Visual Studio...
Rival Fortress
In a previous post I talked about how avoiding automatic structure padding can be beneficial for performance, because of the importance of cache locality in modern CPU architectures. Today I’ll talk about why I wish C or C++ would allow us to specify a logical arrangement for struct members in...
Rival Fortress
This week, among other Windows related things, I added a constrain to allow only a single instance of Rival Fortress to be run. This comes for free for games on Steam or GOG Galaxy, but it is a consideration when you are also distributing your game through other means. The...
Rival Fortress
If you have a cross-compiling toolchain for building Windows executables read on. I use both Clang and Mingw-w64, and I’ve recently discovered a “fun” little gotcha that has to do with the __chkstk routine that is output automatically by the code generator of both compilers. What is __chkstk The __chkstk...
Rival Fortress
This week I started work on the Windows platform layer for Rival Fortress, and while I was at it, I also reduced the number of functions exposed by the API. The platform layer As is common in many modern games, Rival Fortress doesn’t interact directly with the operating system, but...
Rival Fortress
Every so often, when the compiler is slacking, I pop the hood and get my hands dirty with assembly. My modus operandi is to write the optimized function in an .asm, assemble it with NASM and add it to the build, along with other .asm functions, as a static library....
Rival Fortress
After last week’s transition from C++ to C99, I decided to dedicate this week to code cleanup. Re-enabling all warnings My compiler of choice is Clang and I like to build with the -Weverything and disabled warnings to a minimum, but whenever I do a cleanup pass (or when I...
Rival Fortress
Over the past couple of months I’ve been working as a consultant on an embedded project written in C99 and I’ve been toying with the idea of transitioning the codebase of Rival Fortress from C++ to plain C. As I hinted in a previous post I’m not a big fan...
Rival Fortress
Note: You can find the source code for the bit flag logger generator on Github. The logging system I wrote for Metric Panda Engine uses bit masks to support arbitrary composition of logging categories like so: Log(INFO, "One"); // Outputs: [INFO ][ ][ ] One Log(ERROR|CATEGORY1, "Two"); // Outputs: [ERROR][CATEGORY1][...
Rival Fortress
__COUNTER__ is a preprocessor macro available in most compilers that expands to sequential integers starting from zero. It resets at the beginning of each new translation unit (i.e. each object file), and is commonly used with the paste (##) operator to create unique identifiers within other macros. While on working...
Rival Fortress
Note: You can find the source code for Include Detective on Github. This weekend I wrote a little Bash script to investigate include chains of some system headers, and it turned out to be pretty useful, so that’s what I’ll talk about in this post. This is what Include Detective...
Rival Fortress
I share Metric Panda’s Engine code with multiple projects, and since I’m actively adding features to it I often tend to make changes or fix bugs while working on the parent project. I use Git for source control and it is important for me to be able to make commits...
Rival Fortress
Note: You can find the source code for the optimized version of poly2tri on Github. I needed a fast and robust mesh triangulation solution for Metric Panda Engine and after some research I found the excellent Poly2Tri library, an implementation in C++ of the Sweep-line algorithm for constrained Delaunay triangulation....
In this post I’ll share my favorite tips for getting the most out of GDB. Tip #1: Try GDB Dashboard This may or may not be your cup of tea, but if, like me, you like having access to more program information at every break stop you may want to...
Rival Fortress
The video demonstrates the crash resurrection functionality in Metric Panda Engine. Crash resurrection of Metric Panda EngineRead More A simple feature that, by using the engine’s hot reloading functionality, reloads a previous version of the game .dll/.so when a crash occurs. This is development only feature, that gives you a...
Rival Fortress
Note: This post is x86 centric. On other architectures your mileage may vary. Compiling with the -Wpadded flag on GCC/Clang or -we4820 -we4121 on MSVC, warns you when the compiler inserts padding in your structs. These warnings are off by default, because in most circumstances automatic padding is quite convenient,...
Rival Fortress
Back in December I implemented naive hot swappable game modules by simply checking for file updated_at timestamp each time through the game loop. This method has worked fine for hot reloading of the game DLL, but this week I wanted to extend the system to game assets, in order to...
Rival Fortress
I modified the asset subsystem for Rival Fortress to support unpacking of compressed assets at runtime. Things like PNG images and TTF fonts will be converted to “game digestible” formats at runtime instead of having them preprocessed offline and shipped with the game. The reason for this is that I...
Rival Fortress
This week I started working on the audio subsystem for Rival Fortress. I’m not using FMOD, OpenAL, or any other middleware to output game sound. As with the rest of the engine, I’m trying to build most things from the ground up. The sound APIs I’m using are: DirectSound on...
Rival Fortress
This week I extended Rival Fortress’s Meta reflection system to generate ‘rich’ overridable #define preprocessor directives as well as INI configuration parsing/writing. As I explained when I first introduced the Meta reflection system, being able to generate automatically repetitive code is a huge time saver and cuts down on copy-paste...