Generating Game Configuration
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 type bugs.
Replacing #defines
I tend to use a lot of #define
preprocessor directive, especially for default values and engine settings. Another usage pattern that I often use is to define minimum and maximum values along with defaults, like so:
#define MPE_WINDOW_WIDTH 1600
#define MPE_WINDOW_WIDTH_MIN 640
#define MPE_WINDOW_HEIGHT 900
#define MPE_WINDOW_HEIGHT_MIN 480
No suffix is the default, _MIN
and _MAX
suffixes are for minimum and maximum.
In order to clean up and make defines overridable, I replaced #defines
with the following:
MDEFINE(MPE_WINDOW_WIDTH, 1600, Min: 640);
MDEFINE(MPE_WINDOW_HEIGHT, 900, Min: 480);
MDEFINE(MPE_RESOLUTION_SCALE, 1.0f, Min: 0.1f, Max: 2.0f);
This generates the equivalent #define
directives, each guarded by an #ifndef
, so default engine values can be easily overrided by gamecode by defining the preprocessor directives before the .h
is included.
Generating the Config struct
I also went ahead and offloaded the generation of the config object to the meta reflection system. So, from the following snippet:
MCONFIG(WindowWidth, MPE_WINDOW_WIDTH,
Type: i32, Section:"Engine",
Min: MPE_WINDOW_WIDTH_MIN,
Comment: "Viewport width in pixels. This value excludes OS window chrome")
MCONFIG(WindowHeight, MPE_WINDOW_HEIGHT,
Type: i32, Section:"Engine",
Min: MPE_WINDOW_HEIGHT_MIN,
Comment: "Viewport height in pixels. This value excludes OS window chrome")
The following code is generated:
struct MPEConfig
{
i32 Engine_WindowWidth = MPE_WINDOW_WIDTH;
i32 Engine_WindowHeight = MPE_WINDOW_HEIGHT;
//...
};
This takes advantage of C++11’s brace-or-equals initializer, and generates the code for loading and writing from an INI file from the configuration object, by enforcing specified minimum and maximums.