In the last months I have been working on a video game. In the early development days I made some choices regarding the technologies to use. Here I want to talk specifically about my choice to go with low-level languages and low-level components, rather than a high-level game-engine such as Unity.
A polished design
The market for video games is huge, but pretty saturated. So, how does one stand out among the crowd? Well, you can debate endlessly on that subject, but I want to focus on one particular topic: I believe that nowadays your game should be polished in order for people to take it seriously. And by polished I am not referring to super-4k-graphics or complex game mechanics. Rather, I mean that a polished game feels natural to the gamer. In a polished game the game play, mechanics, style and interface all blend into each other as one natural, coherent and obvious whole.
This design-trait is not at all specific for games. Rather, it is an almost universal design truth. Humans are pleased by natural aesthetics and elegant design. Whether it is in cars, tablet-computers or coffee-machines: we enjoy it if design is coherent and elegant and just feels natural, simple and obvious. If we can agree that this is an important design trait, then the next question is: how can we achieve this? And, in particular, how can we do this in game-development?
For my game I want to create a digital world that really comes alive and in which the gamer submerges. I figured that this meant I needed to have full control over every experience: from graphics and sounds to interactions and performance.
I started exploring various game-engines, frameworks and libraries that could enable me to develop the game as fast as possible whilst at the same time offering this ultimate control. I spent some weeks working with Unity and Ogre. I made some prototypes and was able to deliver fast, but still I foresaw that both engines could not deliver me that full control that would allow me to really create that envisioned, polished game. For Unity it quickly felt that I spend too much time fighting the engine in order to fit everything together. Another engine, Ogre, was too authoritative in it’s architectural influence which made it harder to integrate other components.
Obviously, the main advantage of using these game-engines and libraries is that there are many plug-ins that you can use to quickly leverage your functionality and decrease development time. For example an outdoor scene manager, an efficient A* pathfinder or a SkyBox renderer. However, I found that it was quite difficult to merge these together into a whole. As each of these components had different expectations regarding data layouts and architecture it quickly became a process of transforming your data in various high-level data structures all the time to enable these components. This actually increased the development and debug-time significantly. This reminded me of the fact that most programming is about integration rather than about devising new algorithms.
I soon realized that if I really wanted to make my game polished, I needed to have more control and go one abstraction level lower. I opted to go with C++, SDL, OpenGL and various low-level C libraries such as freetype, libpng, etc. The big advantage of these libraries is that they mostly work on low-level data structures. That is, simple arrays of bytes or some small structs. They do not force you upon a certain architecture or high-level class design. This makes interoperability much easier, and there is less boilerplate-code to integrate everything into a coherent whole.
I could make this choice as I have a fair amount of programming experience and and I feel confident in wiring up these low-level components. For somebody with less experience it might be more rational to go with the higher-level game engines. I’m not saying this will make me finish the game earlier, I expect quite the opposite to be honest. However, I feel that this is the way to go to actually create the game I envision. Now, As I have yet to finish my game, time will tell if this approach is pure wisdom or a fine example the Not-Invented-Here (NIH) syndrome! ;)