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....
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...
Rival Fortress
In the past months working on Rival Fortress I found myself having to spend an unreasonable amount of time fussing with CMake build scripts. Don’t get me wrong, I like CMake. I think it’s an excellent tool if you have to manage complex build systems that have to work on...
Rival Fortress
Engine work for Rival Fortress is coming coming to a close. This weekend I decided to give it a test run with a simple prototype in order to get a feel how the API was shaping out. While I was at it I also extracted the engine into a separate...
Rival Fortress
This week I upgraded my main development PC and after a fresh reinstall of the OS I decided to do some spring cleaning. Codebase cleanup Since I recently upgraded Clang from 3.7 to 3.8, I tried compiling Rival Fortress with -Weverything enabled to see if they introduced new useful warnings....
Rival Fortress
Clang is my compiler of choice as I found it to be the fastest for development and it works on all desktop platforms. In this post I’ll talk about how you can setup Clang on Windows without having to cross-compile from Mingw or Cygwin. Flavors of Clang on Windows There...
Rival Fortress
Last week I talked about the new binary asset file format used by Rival Fortress. This week I’ll talk more about PAK files in general, as in the previous post I didn’t explain why I chose the “PAK” approach for game assets. The naive approach A common approach to game...
Rival Fortress
This week I updated the storage file format used in Rival Fortress. The previous file format was a quick implementation I came up with while still figuring out what was needed for the engine. Now that most of the engine functionality is fleshed out, I decided to revise the file...
Rival Fortress
Perfect hash functions are the holy grail of hashing functions. They guarantee no key collisions and work really well when dealing with data that is either static, where all keys are known in advance, or rarely changing. Minimal perfect hash functions (MPHF) are even better. They guarantee 100% load factor,...
Rival Fortress
There’s an excellent chapter in Game Engine Architecture about custom tools that are often developed to aid in the making and debugging of a game engine. Today I’ll talk about the ones I developed for Metric Panda Engine, the game engine that powers Rival Fortress. The Shell Swiss Army Knife...
Rival Fortress
Sometimes it is useful to split code into shared libraries that get loaded by the main executable depending on runtime requirements. For example, the current development version of Rival Fortress is structured like so: The Launcher is the main executable that contains shared data types, interacts with the OS and...
Rival Fortress
Not much coding went into Rival Fortress this week as I decided to give the website a facelift. It has been a while since I dabbled in web dev stuff, so it was fun to get up to speed with how the cool kids are “left-padding”. Get ready for some...
Rival Fortress
I like to keep an eye on new developments of the C++ spec and the direction the language is moving, but in the code for Rival Fortress I don’t use most of the features that C++ has to offer. The features I don’t like I don’t use object-oriented programming. Most...
Rival Fortress
This week has been dedicated to more multiplayer development for Rival Fortress. I’ve fleshed out a networking model based on the one described in the original Tribes paper with a few twists of my own. The model is built on top of the User Datagram Protocol(UDP), a very flexible and...
Rival Fortress
I’ve started working on the multiplayer code for Rival Fortress. It’s an exploratory process, as low level networking is very much new to me. I’m trying to get the simplest and dumbest possible implementation running without adding too much complexity. I’ll probably have to double-back on most of my decisions,...
Rival Fortress
This past week I did some more work on the rendering engine for Rival Fortress by adding a deferred shading path. Deferred rendering is particularly useful when working with many dynamic lights, and since I really want to have light/dark mechanics in the game, a combination of forward and deferred...
Rival Fortress
This week I’ll briefly talk about the custom memory allocators used in the 3D engine that I’m developing for Rival Fortress. Minimizing system allocator usage C and C++ don’t have built in garbage collection, so it’s up to the developer to decide how and when to allocate and free memory....
Rival Fortress
Having a way to capture game video footage is essential for any Indie game developer. It can allow you to: Store videos for visual comparisions of different builds (useful when testing) Capture gameplay demos to share online Have a video of the last few seconds before a crash There are...
Rival Fortress
Most game programmers like to have quick access to graphical performance charts in order to keep an eye on potential performance bottlenecks while developing or testing the game. Every off-the-shelf game engine offers some kind of profiling HUD that you can enable while developing and, if you are rolling your...
Rival Fortress
A while ago I talked about the font rendering used by Rival Fortress. This past week I added more functionality to the text rendering subsystem in the form of better text formatting and Complex Text Layout. Rival Fortress won’t need a complex text rendering engine, but it will require the...
Rival Fortress
This week I started working on the game editor for Rival Fortress. In a way similar to how Unreal Engine does it, I chose to implement the game editor as DLL module that gets loaded by the game executable on demand, instead of writing a separate application that edits game...
Rival Fortress
I’ve moved permanently to Linux as my development platform. I’m in love! Linux is giving me even more freedom from clutter and OS annoyances than what OSX was giving me. How did I ever get by without a tiling window manager! Fanboyism aside, this week I finally finished the cross...
Rival Fortress
This week I started working on collision detection for Rival Fortress. Since I’ll be rolling my custom collision detection/physics solution I had to do a lot of groundwork that you don’t have to do if you pick up an off-the-shelf middleware like Nvidia Physx or Havok. The upside is that...
Rival Fortress
Vulkan was announced this week. It’s looks promising and I can’t wait to start hacking on it to see what’s under the hood. Unfortunately Apple has no intention of supporting Vulkan on OSX, as Metal is the API they are pushing, so I’ll have to choose either Windows or Linux....
Rival Fortress
The engine for Rival Fortress is coming along nicely, and in a few weeks I’ll probably start working on game code. This past week I integrated LuaJIT in the engine. LuaJIT is a just in time interpreter for the Lua language that is lightweight and very fast. Integrating LuaJIT I’m...
Rival Fortress
This past week I’ve been working on a useful engine feature for Rival Fortress: the Reflection Preprocessor. Reflection is usually defined as the ability of a program to examine itself at runtime. Many programming languages, such as C# and Java, offer built in semantics that make reflection easy. C++ offers...
Rival Fortress
If you’ve ever worked with OpenGL you know that extension loading is always a bit of a pain. You can either do it manually, by loading the correct library for your platform and getting function pointers for the OpenGL functions you need, or you can use one of the many...
Rival Fortress
This week has been cross platform week for Rival Fortress. I’ve been trying to set up a toolchain that can allow me to easily compile the game on Windows, Linux and Mac, from a single build machine. Since my main development platform is OSX, the first thing I tried was...
Rival Fortress
This week I finally tackled font rendering for Rival Fortress’s game engine. After a few iterations I decided to use pre-cooked bitmap fonts for the debug overlays and True-Type runtime rasterization for the game proper. For both paths I’m using Sean Barret’s excellent stb_truetype library, along with stb_rect_pack to pack...
Rival Fortress
Last week I talked about the asset preprocessing pipeline that I’m working on for Rival Fortress: essentially all game and engine assets are preprocessed and packed into a single giant file that is optimized for faster loading during runtime. This week, while tackling font rendering, I’ve refined the asset packer...
Rival Fortress
Taking a page from the awesome Handmade Hero I decided to pre-process game assets in a format more suitable for game consumption. You can take a look at how Casey approaches it starting from Day 150 of his series. Rival Fortress is a 3D game, so it uses a variety...
Rival Fortress
Rival Fortress will use a custom 3D game engine that I’m building from scratch in C++ and a bit of Assembly. Currently the only dependencies for the game are SDL, and the truetype library from Sean Berret. The engine is still in active development, but so far the most fun...