One year ago I pushed the first build (preAlpha 1724) onto itch.io: time to recap some things I have learnt over the last year.
1004 commits with changes in 647 different files (this includes changes to assets; i.e. models). 62989 lines were added, while 10513 lines were removed during that time in text files (i.e. scripts, code, layouts, ..). This results in a net positive of 52476 new lines added during the last year.
26 devlog entries (every even week, except during Christmas holidays) +1 during an odd week right before the Christmas holidays. Only 3 of those Tuesdays included no new builds (this includes today).
Most Visible Change
Rewriting the Engine
Most of last year was spent rewriting the engine in Metal and Vulkan. And this already paid off since Apple announced (only a week ago), that with the release of macOS 10.14 OpenGL will be deprecated.
Deprecation of OpenGL and OpenCL
Apps built using OpenGL and OpenCL will continue to run in macOS 10.14, but these legacy technologies are deprecated in macOS 10.14. Games and graphics-intensive apps that use OpenGL should now adopt Metal. Similarly, apps that use OpenCL for computational tasks should now adopt Metal and Metal Performance Shaders.
About a year ago my options where to rewrite the existing OpenGL back-end to make it production ready, or adopt Metal and Vulkan. By anticipating Apple’s move the decisions was an easy one and it paid off on multiple fronts. Not only because of OpenGL’s deprecation on macOS but also the much nicer experience developing for Metal/Vulkan than for OpenGL.
Writing My Own Engine
Would do it again. 10/10
Back when I started working on Margin Magnate the Unreal engine was not free. Neither was Unity, but at least it was cheaper than Unreal. However it was nowhere close to the engine that it is today. So the landscape of existing engines was quite different to the one today. Both of those engines have many features that I do not need (adding considerable overhead during run-time) and lack features that I knew were necessary for the game. So I would have spent considerable time checking and modifying the entrails of those engines. This of course requires access to their source code which was/is not possible or cost a considerable lump of money. And fighting against the internals of an existing engine might not be so easy to start with and takes a lot of time as well. So I doubt it would have been much faster (even if access to those engines would have been the way it is today) to use and modify one of them to really suite my needs.
On the other hand, I can confidently say that developing the engine (and I am still not done) took the vast majority of my development time until now. In hindsight it feels like I spent only a few weeks/months on the actual gameplay, all the other time over the last few years was spent on the engine exclusively. Looking at the current marketplace and if your requirements align with on of the existing engines (including things like Godot Engine) then please use them!
However, I cannot add “do not be as stupid as I am”, since I would do it all over again because there are many big and small things in those engines keeping me from using them for Margin Magnate. But otherwise: save years of your life and use existing solutions if at all possible!
How To Write a Devlog
Looking back at the first entries in this devlog it is glaringly obvious that I had neither a clue what to write about nor how to write it. But over time I found my way and changed the way I approach this blog, which solved two of my major problems:
- I did not know what to write about
- It was stressful since it all came down to half a day of writing about the last two weeks of development
The one change that made things much easier for me was to see writing an entry not as something I do at the end of two weeks. A kind of afterthought; something that needs to be done before release. Instead I incorporate it into my day to day operation. It is much easier to write about something I am still hyped about because I worked the last 3 days on it, instead of writing about something that happened over a week ago. Writing about developments in a timely fashion allows me to write about my thoughts/decisions during its development, the problems &c. because I still remember them. A week later it just becomes a blur for me since it is done and I move on. Instead of a few lines about a new feature that may even contain interesting information, all I can write is “Added X” because that is basically all I remember. The other advantage is that the blog entry grows during the two weeks leading up to a new release. So on release day I just need to make sure that it somewhat resembles a cohesive whole, proof-read it and that is that. No more running around like a headless chicken, trying to figure out what to write about in the hours before a release.
Single Developer Woes
One of the most important lessons I had to learn was what I could possibly achieve in two weeks time and how being a one-man-show changes things. It took me 5 releases to get there and you can read about it here; I wont repeat what is written there, just reiterate that it took me a long time to really come to grips with that and take some pressure off of me, not feeling bad every single day because I felt like I get nothing done.
Any Given Tuesday
Publishing new releases/devlog entries every other Tuesday worked out great. Most people play games on weekends, so I would not want to push an update on Friday, just by mistake breaking the game and having an angry mob with pitchforks outside my home. So the more time there is between a release and the weekend the better, since this gives me more time to fix a catastrophic bug. Mondays would be too early however, since longer weekends may disturb the schedule and make releases seem sporadic at best.
The other aspect of a regular release schedule is that I am forced to think about what feature(s) I could possibly get into the game in less than two weeks time. This makes development more focused on specific aspects of the game. On the other hand this also constrains me to tasks that only take less than two weeks to finish. Most of them are, but not all of them. This makes things more often than not quite stressful, to be honest. Even to the point where I need to take the rest of the Tuesday and the following Wednesday off, because I need to clear my head before I can start with the next batch of work. But I think this is only a result of still being early in development where there are major changes necessary, which of course can take a bit of time.
What Went Right
Let me end this post on a positive note and list a few (technical) decisions that turned out to be the right choice.
I am glad that I stripped all C++ code out of the project and only use C99 now (with a few C11 features) and do not have use C# or any other language. Well, there is Objective-C on the Mac, but that one does not not feel so bad when approaching it from C instead of C++. However, getting rid of C++ under Windows in favor of C11 was only made possible when Microsoft started to support Clang as front-end while still using their code generator as back-end. In other words: using clang and generating .pdb files to be used when crash-dumps were generated. An important feature for me, that was, until the GDPR came along and I had to strip that functionality in favor of a simple stacktrace in the logfile. Oh well, hindsight is 20/20. Nowadays I do not even bother with Microsoft’s Clang/C2, but use the current official LLVM/Clang release for Windows.
When I started the project support for modding was not on the horizon. However this changed quite early (luckily) and so I needed a viable scripting solution. Initially I went with Squirrel since it was easier to integrate with C++ (it sounds so stupid now…) and was closer to writing C++ as a script than Lua. However performance took a considerable nose-dive when things became more complex, so I needed another solution. LuaJIT came to the rescue and I am glad it did. Lua is such a wonderful language to work with. I like the simplicity of C and the same can be said about Lua, so those two languages are the perfect fit for me.
Initially I used a homemade build system. It was a huge beast but had some nice features. However it became a burden to maintain when more and more features crept in. So I was looking for a ready-made solution and CMake seemed like a good fit. But adding my own rules or changing its behaviour was much less straight forward than it should be, so I abandoned it (after a too long time) for something much simpler, fitting my ‘no fuss’ attitude like C and Lua: a plain Makefile. Currently sitting at 1222 lines it is easy to modify, and keeps the cognitive load minimal.
Originally Margin Magnate was meant to use pre-rendered isometric graphics. And pre-rendered graphics can work for games even today (i.e. Factorio). But I quickly discovered that, for the things I wanted in the game visually, going with the pre-rendered approach makes things either incredibly hard to implement or impossible. So I made the decision to go fully 3D (not an easy one!) and to develop my own engine (another hard decision). But as I have already covered above: I think that going 3D, using my own engine, initially using OpenGL, and later rewriting it for Metal and Vulkan were the right decisions in retrospect.
Lastly, the best decision was the project itself. I have many abandoned prototypes for other games, all of them I think would be more than decent games. But each of those games are the kind of games that I would buy on $distributor when they are done and polished, enjoy them, probably adore them, but not play more than ~10 hours. The thing that became clear to me: how am I supposed to keep interested and motivated over the span of year(s) to develop a game that I would only play for the time I spend developing during a single day? The answer seems simple now but took me a very long time to figure out: Put me in front of games like Sim City, Anno, Capitalism, OpenTTD, Factorio, Railroad Tycoon, &c. and 10 hours are nothing. 100 hours may be nothing and I will keep coming back year after year. Thus Margin Magnate was born and I still want to play the finished game like on the day that I came up with the idea. No, in fact I want to play it even more than all those years ago!