Coding into the Void

Coding into the Void

A blog that I’ll probably forget about after making thirty-five posts.

Catching My White Whale: Bound to Happen Eventually

Every game developer has it: the game they’ve been poking away at on and off for years. For me, that was ProtoBound. Making a game inspired by Bound-type custom StarCraft maps had long been my dream. I made several Bound maps for StarCraft, of varying quality, back in the early 2000s, and it was my first real game design experience.1 I had a lot of fun hanging out with that community, and the scope of the project wasn’t too egregious.

This post is really going to be a meandering series of thoughts, so if you’re looking for some grand insights, I’d temper your expectations.

Oh, and, of course, I’d be remiss if I didn’t actually link it:

A Timeline

Because I do love my timelines. This time there are six2 of them because it’d be unreadable if it was just one eight-year long timeline.

Having the timeline laid out in front of me like that, the amount of work I’ve put into it seems underwhelming. If you’d asked me how many days I’d worked on it, I certainly would have said more than 68 (although that number seems like a lot in hindsight). I certainly wouldn’t have said that this most recent iteration was the most consecutive days I’d worked on it.

For reference, the numbers are:

2014: 12 days ( 74 commits)
2015: 10 days ( 74 commits)
2016:  0 days (  0 commits)
2017: 17 days (147 commits)
2018:  0 days (  0 commits)
2019:  0 days (  0 commits)
2020:  7 days ( 56 commits)
2021:  8 days ( 97 commits)
2022: 14 days (140 commits)

Now, of course, this isn’t a solid indicator of how much I actually worked. I could have done one line of code five days in a row and gotten a higher day count, or committed a bunch of smaller changes one year versus fewer bigger changes another. I wasn’t optimizing either way, but I imagine my commit style has drifted over the years. I’m not going to compute LOC because I don’t care enough.

Having two years in a row with 74 commits was not a mistake in computation, just an interesting3 coincidence.

Too Much History

2014

I started working on what would become ProtoBound way back in 2014, starting on February 8th. My memory is a bit hazy, but I believe it was the first project I started in Unity. I started by working off of this old stealth tutorial that Unity put out and pivoted into working on bound.

Within two days of my first commit, I had a couple obstacles up and running. They were hand-placed and rudimentary, but as you beat the two obstacles, it would start you over at a faster speed. It was rudimentary, but was playable.4 Despite its rudimentary look, the textures in it survived to be my “dev” texture theme.

By the time I had stopped development in 2014, I had switched generation over to being driven by an XML scheme.

I don’t know why I fell off of it. Maybe I’d satisfied my game dev urge. Back in those days, I wouldn’t bother releasing games. I’d get them to a playable point and then drop them. Usually they were written for iOS (this is the one exception), so there wasn’t any point in trying to release it.

2015

September 2015 was the first indication that I wanted to release Bound publicly. In addition to updating to the new hotness, Unity 5,5 I’d started work on game saves and a main menu. Menus, at that time, were still the bane of my game dev existence, so it was a haphazard thing that didn’t make it to the final product at all.

I did a good deal of work in this period, including switching from iterative difficulty to a live-based difficulty sections, adding tick tock mode, and introducing shorthands for XML generation. Additionally, I made a whole bunch of obstacles, roughly sorting them into what I gauged their difficulty to be.

I fell off development after adding basic win/lose popups,6 which I theorize made me realize the full scope of the project and scared me off.

2017

I came back to this in 2017 after having released a game on itch, BinPuzzlin. Once again, the reason that I picked this up was lost to time. Maybe having finished an actual game, I thought it was time to return to this one. I was making this because I wanted to see a game like it, after all.

I started out with a lot of refactoring of my XML/game construction code, which probably wasn’t the best foot to start on, but I also added much of the content for the “castle/dungeon” theme, most of which would survive to the game’s release. I also fixed some timing related issues, making it so the game played consistently no matter the framerate.

I ran into issues with the wall structure—since I wanted to support multiple tile sizes, I needed to have walls of different lengths, but the standard Unity shader doesn’t tile like that. I ended up putting off the issue, which ultimately was the correct choice. Later, I worked on outdoors and tech themes (which didn’t make it into the final release) and road and hedge themes (which did).

I added suction obstacles, which ended up feeling mostly vestigial in the game, and made a bunch more obstacles to be categorized later.

In what would become a trend, I once again tried refactoring my layout code. Frustration with not managing to get it to work caused me to fall off of development. This is a pattern with most of my in-development games; I generally don’t make a conscious decision to stop development. I just don’t pick them up again.

2020

I returned back to Bound in August 2020, having finished developing What a Card! and having fallen off development of Strange Traveler. I had done my refactoring code on a branch, so to get back into it I ignored the branch and went to the working state.

2020’s development was focused primarily on refactoring, but not in the layout system (at least at the start). I integrated KHPackageCore, and migrated some of the code to use some of the more modern coding styles I’d picked up (scriptable objects, variable references).

I used what would later become my Menutee library to start off a more respectable main menu, and then got bogged down into making a level editor, which got me bogged down into refactoring the layout code again. This, once again, made me fall off Bound development.

2021

2021 is unique, as I remember why I picked up Bound development. As I mentioned in another post, I’d come in contact with a group of people who still regularly played Bound maps. Seeing that people still had a passion for bounds got me motivated to get something out. This was when I came to terms with putting out a prototype, and when I came up with the final title, ProtoBound.

I had a focused goal: cut whatever I needed to get ProtoBound out. On my trello board to track the progress of the game, I aggressively moved tasks into the “Future”7 list, and updated my libraries to the newest version. In an effort to make a more appropriate “red light green light” model, I switched the dungeon to use spikes, only to realize that it didn’t work with the mechanics of the obstacle. Whoops.

I then decided to lean into having the player be a robot, and settled on being fine with the RLGL look.

I added structure for levels, adding campaign and custom level loading, and I added navmesh support to support better pathing for mouse movement. I made some overtures at tile refactoring, but managed to break those off before losing the will to work on it more.

Game saving was added, a tutorial level was added, settings were hooked up, text boxes were added, and sound effects were integrated. The trap I fell into this time was not refactoring the level layout system, but instead a misguided attempt to switch from declaring obstacles in seconds to frames. I’m not sure why I did this,8 but I ended up bailing out as I fell off.

2022

In 2022, of course, I had the goal of finishing six games, with at least half of those being in-progress ones. This project was intimidating, but when I found myself two months ahead,9 my thoughts fell to Bound.

So, I updated all my libraries and the Unity version, and got to work. I decided to set out by trying to understand my level definition code, thinking that maybe not comprehending what past me was trying to do was where I was falling short. I did managed to poke around here and there, making small and safe improvements to code clarity.

I always came back to redesigning my layout system for two reasons:

  1. Rotating obstacles was broken in some cases. In the best case, it’d be disjoint. In the worst case, it’d break level loading.
  2. I wanted to support multiple tile sizes in the same map.

If it’s obvious to you how to cut this particular Gordian knot, don’t worry, I’ll get there eventually. Unfortunately, in a previous year, I’d restructured my code so that it was partially depending on two independent layout systems, which wasn’t readily apparent.

The tile positioning code would think it was at one point, but the level generation would actually put it in a separate spot. This discrepancy needed to be fixed.

I was, however, worried that I’d fall into the same trap that I had the last few attempts.10 Offsetting obstacles is easy logic to understand. It’s just an {x,y} offset. Rotations are more complicated, especially with how they compound. So, to keep it simple, I don’t allow rotations. If an obstacle is going to rotate, I mark it as disjoint from the previous one and force a teleportation.

With this simplification, I was able to narrow the setup down to just one layout system: one that worked. I also, of course, abandoned any thought of combining multiple tile sizes.

Once I resolved this issue, my motivation didn’t flag again. All that I needed was polish. Well, polish and the actual levels that you play.

I added support for selecting levels in the menu, polished mouse movement, and made a few QOL improvements for the XML level structure. I added support for medal times, and hooked up an end game stats screen.

I then resolved myself to the task of making the levels. I decided to target 5 levels with 10 obstacles each. I took stock of the obstacles I had already made, and quickly found that I had more than enough to meet that goal. I moved the obstacles into levels with rough difficulty ordering, and I only ended up having to make five additional obstacles to meet my target.

I then moved on to polishing the level appearance. ProtoBound does support multiple tile sizes, but it accomplished this by squishing tiles in the X and Y axes (but not the Z). Unsurprisingly, this caused texture squishing. With some simple shaders written using triplanar mapping, this issue was resolved.

The final task was to create the actual player model. This was something that I’d written off for the prototype, but it felt wrong to have the only placeholder asset be the player model.

I created a simple robot model and gave it a bit of life with procedural animations. The procedural animations lent the main menu a bit of life, as the robot will move around a bit.

And with that, I was done! And, despite my 2021 thoughts, I’d say it fits more as a full-fledged game than a prototype. While it didn’t feel like long, the 14 days I spent on ProtoBound in 2022 was the longest contiguous period of time I spent on the game.

Postmortem

After that overly verbose trek through history, I thought I should try to evaluate where I went wrong, and how I managed to overcome those hurdles. These are very specific to me as a hobbyist developer, so many of these will be irrelevant to people actually trying to make money.

Why Did It Take So Long?

I didn’t care about releasing it.

This was primarily an issue with my 2014 development. I simply didn’t have the drive to release a game. This isn’t necessarily a bad thing, but it isn’t conducive to doing all the boring parts of game development.

I wanted to sell it.

Once I was past the hurdle of not wanting to release it, I wanted to sell it as a full game. To do so, I was tuning it towards what I thought would be desired: nice graphics, a story, a robust level editor. It could be that these are actually successful for financial success in the genre, but all this resulted in was forcing me to spend mental bandwidth on things that ultimately were unnecessary.

I was precious about its quality.

I wanted everything to be perfect. The biggest obstacle for me here was the character design, as animation and modeling is a major weakness of mine. I don’t think I could accomplish my earliest vision with my skill set, then or now.

I was afraid to compromise.

Similar to the previous issue, but subtly different. There were aspects, like obstacle rotations and mixing tile sizes, which I was afraid to compromise on. I wanted to make a game where you could recreate all of the bound maps in StarCraft, which had an incredibly robust level editor. The majority of people won’t notice the difference, and the minority who want to make levels can adapt. I was spending too much time on details that turned out to be inconsequential.

Refactoring bogged me down.

There were three separate times where refactoring efforts killed my motivation to continue working on the game. That’s at least two too many to have been a good decision.

Menus are a huge hassle! They’re tedious and time-consuming, and if you want to tweak colors or visual appearances on a UI element you have to change it everywhere.11

How I Did It

I freed myself from download performance expectations.

My self-worth is not based around people playing my games. Part of the reason I found myself not wanting to release the game was because marketing is required for success and I didn’t want to market. Of course, the simple solution to this is simply not to market your game, but with that comes the inevitability that your game won’t be a success. I’m fine with that. If developing games is your job, however, this clearly isn’t for you.

I cut scope.

I had initially wanted something like 5 themes with 10 levels each. I cut the number of themes down to 3, and I didn’t worry about reusing assets across themes. This helped avoid some of the more time-consuming parts of game development. Similarly, 50 levels would have been a lot of content to make. Better to ship with fewer and add more if I want to later.12

I set goals.

Throughout this year, I’ve been setting game development deadlines for myself. Deadlines will let you accomplish things faster than you would’ve thought, and can be useful for maintaining motivation.

They can go wrong, but otherwise there’s always the temptation to push a release to get more content or more polish. In the week leading up to the deadline, I broke all my goals into tasks down day by day. I ended up being ahead of schedule, but that the awareness of my target kept me on track.

I identified the parts of the code that caused me issues.

The code to support rotation obstacles in my layout system caused no end to bugs. By cutting that from my game, I was able to avoid future refactoring pitfalls.

I gained experience.

I’m much better at game development, especially using Unity, than I was back in 2014. This will be true of anyone who’s actively engaging in game development. So wait a few years, I guess?13

I developed tools over the years.

In my years of game development on Unity, I’ve made several tools that made game development easier. Most saliently for this, it was Menutee, my programmatic menu generator. Through this, I was able to quickly stand up complex menus. It did expose some weaknesses in Menutee’s capabilities (mostly around having content generation across multiple containers), but I was able to adapt my solution around those weaknesses.

Conclusions

If I had to boil down what I think got me over the finish line, it’d be:

  • Avoid refactoring unless it’s 100% necessary or it can be done iteratively while keeping a functioning game.
  • If you do do an in-depth refactor, keep it on a branch so you can abandon it when you come back.
  • Cut scope aggressively.

If you’re reading this and you have your own white whale, it’s possible to finish it! It might not end up being everything you dreamed it would be, but that’s better than it never releasing at all.


  1. Well, arguably it was a really basic Quake map I made back in the day, but that was more of a series of boxes you could jump around in. Also some very simple, very short CYOAs in Basic. ↩︎

  2. ! ↩︎

  3. Admittedly, not that interesting. ↩︎

  4. Although if you get to a high enough speed, it is no longer winnable. ↩︎

  5. This does make me feel old. ↩︎

  6. Which are more or less how they made it into the finished game. ↩︎

  7. A euphemism for “never”. ↩︎

  8. Not entirely true, as I remember people on the bounding discord talking about frame timings. Why I decided that I needed to switch my project over to it is a mystery. ↩︎

  9. And also fighting insufficient motivation for Fighter’s Guild, to which I’d been making minor changes every day in an effort to keep going. ↩︎

  10. With good reason, clearly. ↩︎

  11. If only someone made something to make this easier! Menutee. I’m talking about Menutee. ↩︎

  12. This is especially true with a free game, where you can see if anyone will actually give it a shot. I don’t know that only having 1-2 hours worth of content on release is good for a paid game. On the plus side, at least it’ll let you release it. ↩︎

  13. Don’t do this. Intentionally delaying a project in search of some mysterious experience you’ll gain is foolish. ↩︎