Skip to content

Blog Catch Up: March 2020 – December 2020

Blog Catch Up: March 2020 – December 2020 published on

Reading the previous catch up before writing this was pretty rough. In that it felt like most of what I got done this year had actually been done the previous year? Let’s sort through this mess and see if I actually got anything done.

March – May 2020

The battles for Sealers, Insomnia, and Ruins were designed, implemented, and tested throughout these months. These were the final main scenarios. Along the way a few new classes got added, healers were rebalanced relative to tanks again, I took week off for a break game, etc.

I also managed to write and implement the entirety of the tutorial/prologue scenario by the end of May. While I had dabbled with sketches of it over the years, most of the final form come together here. I took an approach of just throwing extremely narrow options at the players with low-stake monsters in hopes of getting players to bumble into the solutions rather than spelling out the mechanics directly. Might be good (is certainly in line with how the game expects you to learn), might be a disaster. Haven’t put it in front of a new player yet, so we’ll find out.

You might be thinking, “well that’s most of the game done. Time to coast to content complete well before the end of the year!”. You’d be wrong.

June 2020

This month was spent populating the game’s lobby- the player’s boat. This required actually defining who our protagonists are (originally intended to be silent for sake of dialog brevity, I relented and gave them a minor voice), writing dialog between them and the Ferryman character, populating it with characters/items from other scenarios, etc. The biggest piece of work here was adding support for persistent cross-scenario flags in order to carry over progress to the lobby (including saving it to disk, sharing it over the network, and unlocking classes based on it). Considering I spent half the month on another side project, looking back I’m surprised I got all of this done in the other half of the month. Taking breaks can really work, I guess.

July-August 2020

Designed/implemented the final batch of new classes (difficult with most the battles done), designed/implemented Challenges (optional battles) 6-9, added pixel perfect collisions, and the biggest thing is that I overhauled our data system. This involved switching from storing data in SQLite to just dumping them to JSON (partially to make it more palatable for git, partially to allow loading data from multiple files to be more multi-user friendly, and partially to pave the way for better mod support). I also discovered Dear ImGui which allowed me to rewrite the UI for editing data instead of our old clunky wxpython version, which will make modding much easier but also allowed me to add a lot of features for data editing I’ve wanted for a long time. Additionally, using Dear ImGui has let me churn out a lot more small tools for working with the game so I kind of highly recommend it if you find yourself wanting to make tool UI for your game but don’t want to deal with the weight of your full UI system (though it certainly does not scale up past a certain size of tool).

This month also saw the sole improvement to our interface in this batch of updates: indicating RPS distribution with pie charts, and having the characters use rods to create battle lanes (they also indicate role, agility, and are story-relevant):

It’s a reasonable UI clutter reduction.

September – November 2020

So it was finally time to make the final boss scenario. This is also where everything came to a crash, for a multitude of reasons.

  • While I did most of the previous scenarios in batches (designed/wrote all, then map scripted all, then designed/implemented battles for each) I only did a rough writing pass on the final boss. So I had to do most of all 3 phases of the final boss back-to-back.
  • It also required more new features than the other scenarios: I had to add mid-battle class changes, one big treasure container based on previous scenario choices, disabling lanes for a battle, and generally just coping with the extra variability involved. None of these are that big, but the weight of my previous code sins were starting to crush me harder than I expected while designing it.
  • Just deciding the gimmick for the final boss took awhile (endings are stressful in general), and also ended up being an idea that took more work to design/build. I’m probably happy with the direction it took, though?
  • I was just kind of miserable during these months in general. Maybe because the art side of production ceased (earlier months were actually quite productive), maybe because it took so much longer than I expected, maybe I should have taken another break project. Who knows.

December 2020

While it was entirely possible to wrap up the remaining content this month (only 1 challenge- though an impossibly large list of backlogged tweaks probably not), I decided I needed a break from design and dived head first into optimization. I had a really good time, and finally bothered to hook up a proper per-frame profiler for the C++ side, and overhauled the Python side to make it easy to see what happened on the same frame for both.

Digging unfortunately also turned up more problems. The first is just learning that Python doesn’t really support threading, which made it impossible to allow the game to smoothly load (I used a junky workaround of checking every so often during, but it isn’t perfect and kind of bothered me with its existence).

That alone wasn’t really a deal breaker, since there isn’t that much loading in the game and load screens don’t need to be smooth anyway. The next hit to my confidence was just learning that the cost of switching from Python2 to 3 was maybe higher than anticipated? Or possibly just that Python in general is slower than I thought. Creating new map entities was just slower than expected. Partially from my own janky C++ loading functions (likely plenty optimizable), but it also seemed like even removing them wouldn’t be enough- I was just using too many bulky objects together to make them up? This also wasn’t an impossible roadblock- just space out loading them more when switching maps, maybe delay parts of creating them when doing it on the current map, etc. I may have even been misreading the profiler. But it was starting to be quite a bit more drastic work for optimization.

The larger hit was just starting to see that SFML was taking surprisingly long to draw certain unremarkable sprites at random a very small part of the time. These slowdowns weren’t necessarily visually obvious, but the fact that tracking them down would probably be impossible bothered me a lot: was it something entirely in SFML, was my janky C++ code doing something wrong, or is this totally normal and not actually a problem? Honestly, I don’t know and I don’t want to spend the time to find out.

At this point I finally started considering something terrible: rewriting the game in another engine. This would be a stupid amount of work that I really don’t want to do, the case for it was starting to build up:

  • SFML has gone largely unmaintained in the time it took to build the game. While it isn’t causing any problems right now, it makes me kind of uncomfortable to still be using it (porting to SDL2 would also be an excessive amount of work)
  • Python is such that I have no confidence in ever porting this game outside of PC. Entirely by accident the game is quite well designed for tablets, so it would be beneficial to have more platforms available (console ports are also a benefit, but I have no illusion of being successful enough to do so).
  • This was my first big C++ project, and while only a small part of the game actually uses it, I really don’t trust my own C++ code for not being awful (learning it was still worthwhile, though).
  • I have lost confidence in being able to optimize this mess properly without quite a few significant changes. It’s still probably less work than rewriting it, but if I’m messing with the guts anyway…?
  • Years of hard genre shifts means the code in general is in a terrible state. There’s also poor test coverage due to me not appreciating tests until the project reached a certain size/age. A total rewrite would probably do wonders for stability. (Of course, every programmer thinks this. I try to avoid the siren song of redoing everything for the sake of getting things done, but…)
  • The game was heavily built around the idea of separating its data (including making a light scripting system with said data), which means it’s fairly easy to just export that data to a new engine and just build the game around using it. This makes the cost of a rewrite… slightly less intimidating.
  • The main remaining task is polishing the game up. Rewriting it would allow adding that polish as I go. The new engine I have in mind would also probably make polishing easier for everyone involved.

That’s a pretty long list, but I still don’t really trust my own logic here given the amount of work involved. There isn’t actually an impossible problem that requires doing this, but all these issues have been weighing on me for so many years that I’m finally starting to give in. I’ve rewritten things before and while it takes a lot of raw work, it’s generally much faster and mostly just a matter of pouring hours into it. I’ve started preliminary work on the rewrite already, but whether we go through with it or not remains to be seen. Here’s hoping this ends well?