Archive

DevBlog

For reasons some of you may be familiar with, September was a hell of a month. Along with many other independent game developers I was knocked significantly off-track by Unity’s antics, and it’s something of an open question exactly how big of a problem that will continue to be. I’ll dive more into that a bit later on – let’s start at the beginning.

At the end of last month I was wrapping up an extensive and annoying rework of the dialogue system. This whole process was very frustrating and tedious, but I wanted to follow through on that work and build the Notebook – an inventory item the player could use to track progress and dialogue, an entry point back into the game for players who hadn’t played for a while and a way to communicate some non-obvious details about how the game systems work. This all adds up to a not-insignificant challenge: How does all this information get displayed? Where do I store the information? How do I format it? 

One of the trickier features I had to tackle was a way to display enemy attack hitboxes and damage. This is made particularly tricky by this information changing with each enemy movement and attack. Unity’s UI elements have completely different display properties than the sprite renderers used in gameplay, adding another layer of challenge to getting this display working. I built out the UI and an enemy sandbox room with its own camera that just gets rendered out to an image for the enemy display to use. I also figured out how to copy out enemy hitbox information into a SpriteShape display so the collision data can be visible in real time.

This is a pretty solid start, but there’s a fair bit left to do. Everything so far is partially implemented and untested, and I still need to hammer out some of the specifics of how old dialogues will get displayed and how the journal will be implemented. However, all of my efforts to figure this out were interrupted when Unity, the game engine I’ve been building the project in, decided to ruin everything for everyone.

For those of you fortunate enough to be unfamiliar with these events: A couple of weeks into September, Unity announced their new pricing plan. Under this plan, after a game reached certain thresholds Unity would begin charging game developers per game installation. The exact amount charged varied based on license, but the following facts were true regardless: First, there is no plausible way to track the number of times a game has been installed by users, and suggesting otherwise raises Questions. Second, there is no way for a game developer to account for these hypothetically unbounded expenses, putting every developer at unknown levels of financial risk, particularly if these numbers can be manipulated by malicious actors. Third, they’re asking us to place our financial futures entirely in the hands of their opaque black box algorithm and abide by whatever number it spits out. Fourth, declaring that these changes can happen retroactively and affect everyone who developed in the engine in the past, who had no opportunity to disagree to the terms or account for them, establishes a, let’s say, worrying precedent.

Now: They have since amended their proposition to cap the fee at 2.5% of gross revenue and to require devs who cross a sales threshold to pay a $2000/y subscription to Unity Pro. This is unequivocally better, in that it is an expense that one can realistically plan for, that there’s now no scenario where they can simply claim a game’s entire revenue because of some behind the scenes numbers. It’s still simply not very good: While these terms only apply if you update to the newer engine versions, they have not to my knowledge added anything preventing them from trying the same retroactively applied abuses as they proposed before, or from changing these cuts to be even worse down the road. Additionally, these sorts of revenue shares are an egregious pricing model in the first place, particularly coming on top of an exorbitant subscription fee. However, this is at least enough of a compromise that I can countenance finishing the project in this engine, which I was otherwise having serious doubts about.

I mention all of this for two purposes: First because I’m still mad about it and wanted to vent a little, and second because development of the notebook feature got completely derailed by all this. The couple of weeks following this announcement were mostly occupied by shock and anxiety, then explorations into what would be needed to port the game to another engine such as Godot. The answer I arrived at, after a fair amount of exploration and experimentation, was: A Lot. Many of the game’s systems and rendering solutions are tied pretty intimately into Unity’s architecture, and these would need to be painstakingly reproduced. That being said, it wouldn’t necessarily be a completely ground-up effort: It would probably be possible to export and reimport the basic levels, though scripting and lighting might be trickier, and the sound systems could probably be rebuilt relatively quickly. Still, if there’s any way to avoid these months of additional tedious and depressing effort, I would prefer that.

All of this, of course, was terrible for morale. I still haven’t resumed work on the notebook feature – not least because this is one element that would need to be rebuilt more-or-less completely to port it into another environment – and have instead focused my efforts on level-building. This should be relatively satisfying – it is one of the most direct and active tasks I can do on the project! To some extent it is satisfying, but I am still so tired from all of the Unity issues and from various other life events that my energy and enthusiasm are at a notable low point.

Still, even if I’m tired and frustrated, the problems presented by this project are fun and interesting ones. In particular, I have been building this with more of an eye towards verisimilitude, towards building an environment that feels plausible and lived in, than most games seem to be interested in – particularly action games, and particularly 2d platformers. This results in some pretty odd circumstances! For instance, in building a parking garage, what does one expect to be there? Perhaps a staircase and elevator for people to go up and down on their way to and from parking, and perhaps a ramp for the cars to drive up or down to change levels. But: What does that mean in a 2d platfomer? Most of the stairs in the game are non-interactive background elements placed behind one-way platforms.

This creates something that serves the same purpose as stairs, and are interacted with in a similar way, but which in practice the player jumps up an entire flight at a time. What’s so remarkable is how invisible this arrangement quickly becomes: The stairs read as stairs, the platforms read as platforms, they both seem in place, and the player doesn’t even notice how odd the specifics of the interaction are. However, I’m not sure how far I can push this dynamic before it starts to get weird. Returning to the parking garage, the specific example that prompted this line of thought, let’s look at what the ramp looks like:

It’s the same theory as the stairs. Make something that looks like a ramp, make a set of platforms that can be used in the same way and fit into the art, and hope the player never thinks about the bizarre non-sequitur logic of using a ramp this way. Will it work? I don’t know! This seems to really push the boundaries of visual plausibility, but it also looks kind of fun and interesting. Whether it works or not is something that will probably require some testing and feedback to determine. If it doesn’t, well, there are always alternative solutions.

Anyway, as the project lurches unevenly along I’ll be continuing to build out these levels. There’s still much to be done even on that front alone — I’m maybe a third of the way into level-building for the next demo, and of course there is much to be done aside from that basic construction work, so I have my work cut out for me. Let’s hope there are no more announcements like this recent one any time soon.

Most of this month was taken up working on tweaks and changes to the dialogue system, which is definitely not how I had hoped to spend this time. One fix to the system required another more fundamental fix, which led to bugs, which required fixes which themselves required other fixes to the core system to enable, and so on and so forth over the course of three weeks or so. All-in-all this has been one of the more dispiriting months on the project so far and an object lesson in the dangers of relying on third-party tools. I think the real lesson I need to take from this is that at the moment where the third party tool’s capabilities and my requirements begin to diverge I need to immediately consider dropping it and rolling my own, because working around limitations like that can be An Ordeal. Now that I’ve done it, I may try to compile all these experiences into a list of recommendations for the developers of Yarn Spinner to implement internally so no one has to go through this in the future.

Giving a play-by-play of this entire struggle would probably be boring for you and stressful for me, so let’s skip that even if it comprised about 2/3rds of the month. I did achieve some notable work before and after this bleak venture that might be interesting. First, and precipitating much of the above-mentioned struggle, I built an interface for asking NPCs about keywords:

Now that I have everything I need to query the dialogue system for which lines have been played or not and which lines can be reached from every other line, I can have these keywords fade out as they’re played. Yes, that’s what all this effort was meant to achieve: The mere ability to query whether there was more dialogue available on any given dialogue branch. 

Another little flourish I added to the dialogue system is the ability for characters to play incidental dialogue lines into the game world without changing the game state to dialogue mode. This makes it a little bit easier for the player to spot NPCs, since they can say something when the player encounters them, and I think a little later on will be a great way to add a bit more flavor to boss encounters, with the boss cursing or gloating as the battle progresses.

I also added some new background tile art to flesh areas out a bit more:

Ideally I’d like to have posters and graffiti be modular tiles so I could construct something that looks relatively natural, but in practice it can be difficult to compose images in such a way as to make that possible. I may give it another shot later, but in the meanwhile just having a bunch of little pictures that I can place where posters ought to go or the like is probably going to add a lot to each area visually.

Of all the work I did this month, though, I’m most pleased with the new music composition. First, I started developing a character theme:

This is mostly background for a conversation with one of the game’s more important characters, and I’m a bit worried that it’s a little too busy for that purpose. However, I really like the overall mysterious and wistful tone, which I think will fit the scene well. I’ll probably leave it as-is until that part of the game is implemented and I can decide how it feels in place.

I also went back and revisited one of the stage themes I’ve been meaning to develop a little further. This is one of the first pieces I created for the game – actually, I originally wrote the sketch that became this piece in 2008, wasn’t sure what to do with it then, and changed it to the chiptune style when I was figuring out what this game would sound like during the first month of the project. I expanded it a bit then, but this time I revised it completely, adding new melodic lines, changing the instruments around to make it better balanced, and adding little pitch-bend details to the instrumentation (a technique I’d just started experimenting with in Burnt-Out or Oxygen-Deprived). I’m quite happy with how this all turned out, and I think this feels like one of the stronger tracks now. I always knew that that sketch I made had potential, and I’m happy that finally, 15 years later, I’ve managed to make something that lives up to that potential.

In the midst of all this, I finally invested a chunk of time and money into updating the old dilapidated laptop I was using for a mobile workstation – not least because, as I am planning on moving soon, I expect to be working on the go significantly more often. I am simultaneously excited about how nice it is to be working (and gaming) on a modern machine, and stressed about having to spend a thousand bucks to make that happen, but over time I hope the latter will become less acute.

So, with all of this dialogue reworking behind me (hopefully), what’s next? There are still some fixes and tweaks to be done to the display of keywords and dialogue choices, but after that I will have to build the journal. This inventory item will track all dialogue lines played (another reason I’ve been working so hard on this system) and make it so you can look up any conversation later on. It will also store a short summary of “the story thus far” so the player can quickly catch up after taking a break, a list of known keywords that also works to look up dialogues, a reference manual for any non-obvious gameplay tips the player may need to refresh themselves on, and an enemy bestiary with information on attack patterns and weak points. It’s entirely possible I may decide one or more of these aren’t worth the trouble and cut them later, but that’s the current plan. In the likely event that I want to take a break from dialogue stuff altogether for a while, I also have plenty more level-building to do, which would be a real relief after all this.

Around the start of July, I went on a trip for a couple of weeks. I mention this to explain why this is another two-month DevBlog: When a trip like this coincides with the start of the month, it’s easy to get distracted from posting updates while I prepare for the trip, and then once I’m traveling I don’t have the time or energy to rectify that. When I get home a couple of weeks later, it seems like there’s not much point to posting such a late update, so I combine it with the next month’s update — which is probably fine, since with trips like that I end up doing about half as much work over the month anyway.

After putting the finishing touches on the revolver special weapon I mentioned in the May update, I started addressing a fairly common bit of feedback I got from the demo: Several players felt the weapon attacks were a bit clumsy, and found themselves frustratingly committed to attacks that were slightly misplaced in one way or another. At first I had no real intention of doing much about this beyond tweaking attack timing and so forth to make the whole thing feel a bit more fluid — however, a suggestion that came up a couple of times to address this was the idea of adding some directional control to attacks, and this idea has been floating around in my mind and gestating…

At the same time, one of the ideas I’ve been thinking about for a while is that of weapons that have significantly different attack patterns and styles. A lot can be done with the sword swing animation I started with but I found myself running up against its limitations. Iif, for instance, I want to add a rapier or spear weapon (which I do) then these attack animations work quite poorly. At the same time, if a weapon like a spear were to be added, it should offer some unique advantages over other weapons — range, obviously, but the ability to attack in more directions and from more angles also made sense. These two ideas seemed to dovetail nicely together, so for the first couple weeks of June I extensively overhauled the weapon and attack system to bring them into reality. 

At this point there are three classes of weapon attack: Swing, the default type which all the old weapons in the demo belonged to, now with the added ability to aim up/down by 33 degrees; Thrust, which includes fists, spears, and rapiers and can attack in 45-and-90-degree angles; and Two-Handed, which has no directional attack and can’t be used while climbing, but has a very wide arc of attack.

The way attacks were implemented before, creating all of these weapon and directional attacks would have required me to create a full custom animation for each attack direction. Attacks were implemented as a weapon overlay placed on top of the character sprite, which contained both the visual representation of the weapon and of its attack, an arc of dissolving pixels. I extensively reconfigured the player animations, creating a set of attack animation frames that ended up being significantly more numerous than all the non-attack player frames combined. To keep things within a modicum of reason, I made the attack preparation and recovery frames the same across every direction of attack, with only the two frames of actually performing the attack changing. Additionally, I stripped the arc of the attack (the “flash”), out of the weapon overlay and made it so these effects were generated from a couple of sprites and a programmatic fade.

All of this was a lot of work, but relatively straightforward. Much more frustratingly, I found myself struggling for several days with the Unity Animator system. The logic chart I use to play animations works relatively well with a small set of animations but, as things get bigger and more complex, cracks begin to emerge. Animations started to get desynced by a frame or two, or display the wrong sprite for just a frame — little issues, but unacceptably jarring in practice. 

After a lot of frustration, I eventually found that two Animator features I had been overlooking were indispensable: Layers and Blend Trees. I had discounted these features early on, as their descriptions were all couched in terms of animating a 3d character and they were focused on use cases such as making a part of a model do one animation while the rest of the model did another. However, these also provided some crucial functionality that could still be used with 2D frames: First, layers allowed me to take all of the dense logic of weapons and attacks and completely separate them from the standard player animations, which let me prevent the rapidly developing situation of having a hundred ugly and error-prone crisscrossing lines of logic.

Second, blend trees allowed me to have a set of synced animations that I could snap between based on a parameter, which allowed me to enable the player to change positions during attack recoveries without resetting the animations.

While I was doing all of this, I also began implementing the Charge Attack upgrade. You’re probably familiar with the basic idea from other games: You hold down the attack button for a second or two, then release it to do a special super attack. I’ve been thinking a lot about how this is going to work. There are two ways I’ve seen this type of attack go wrong in other games: The first is when there’s no drawback to charging so the player just ends up constantly charging attacks, making inputs a little more complicated for everyone for no particularly interesting tactical result. The second way, conversely, is when charging restricts your movements and actions to a degree where it’s seldom ever really worth it compared to just attacking normally. 

It was very important for me that charge attacks feel useful but situational, something everyone would want to use sometimes but few people would want to use to the exception of normal attacks. It remains to be seen if I can hit that mark — a lot of testing will have to happen before I think we’ll know — but I am doing everything I can to address it now. Charge attacks do leave you completely immobile during the charge, but you can conserve momentum from a jump to minimize this vulnerability, and, while you probably will do less damage with a single charged attack than if you just spammed standard attacks, charged attacks will have the unique ability to parry enemy attacks, canceling them out and dealing additional damage, as well as deflecting all projectile attacks back towards their source. That last part isn’t implemented yet, and all of this will require a lot of fiddling and testing, but that’s what I’m aiming for. This also means that charged attacks may be required for entering certain areas blockaded off by otherwise unavoidable damage!

Doing these attack reworks took a couple of weeks, and once they were wrapped up I was pretty tired of creating art and animations, so I decided to work on something a bit more purely programming-focused. A concept which has come up in a number of different places over the project so far is various forms of special level tiles. At first, these were just breakable blocks placed to hide secrets, then more breakable blocks placed casually to make encounters more interesting, then falling breakable blocks that did damage for a boss’s special attack. For a while these different types had functionality spread across different classes and prefabs, but now they are combined into one dynamic block class, along with additional functionality allowing the player to push and stack blocks, and for the blocks to subsequently permanently remember the positions they were pushed to. With this, creating permanently unlocking shortcuts by nudging a block or two is now possible. A few tweaks and improvements still need to be made: As you can see at the end of the demo video, some weird collision situations can be created which might result in the player falling out of the world. I would also like to be able to anchor blocks to each other — so, for instance, one block might not fall until the other is destroyed, which I think will feel much better for conceptually solid pieces like logs or beams, and could lead to some interesting puzzles and effects. Additional special terrain types like elevators and conveyor belts will probably also eventually be implemented in this class.

I made another fairly minor change with potentially major ramifications: it’s now possible for the map to change dynamically based on the game state. For instance, I might have an intact and ruined version of a room which I can flip between, or a room that only exists under special circumstances, or an entire section of the world map that gets flipped out for another one. This all would have been possible to fake before by making special entrances between levels, but doing it this way ensures that any changes will be reflected on the map screen as well. I also worked on building a series of special rooms: The player will probably start to encounter these shortly after where the demo ended, and there will be one of them for each area. I have the first couple completed, for the hotel and park respectively. I am quite pleased with the results so far. The park’s room is the header image, here is the hotel’s:

This is the point where I left on the aforementioned trip. I started working on a piece of music before the trip and managed to more-or-less wrap it up over the course of my travels. This piece is the track for the confrontation with the dragon, a character who you’ve mostly been just hearing rumors and confused snippets about up until this point in the game. I’m broadly pleased with where the piece is at now: I was having a lot of trouble keeping all of the parts from sounding muddy against one another and keeping the audio from clipping, but I think it’s finally come together pretty well.

Aside from this, I’ve mostly been working on fleshing out the next major section of the game, the Undercity. Since this whole section is mostly intended to be subway tunnels and stations, it was difficult at first to keep the terrain feeling varied and interesting, but I’m really pleased with how it’s starting to come together. Each stretch of tunnel and track feels dangerous and challenging in a slightly (or significantly) different way, and each station feels like it’s got its own personality that’s somewhat related to the section of city it serves. However, so far it’s just terrain and lighting: I still don’t know what the enemy encounters are going to look like, what the specific challenges and obstacles are going to be, what the moment-to-moment experience is going to look like. I’ve got some ideas, to be sure, but more ideas will be needed to fill the gaps, and the ideas I have will change over their implementation.

I’ve long been having second thoughts about the dialogue system. I was broadly happy with it and the responses to it in the demo were generally positive, but I noticed some issues, and the more I thought about these issues the more they bothered me. Players would speak to NPCs once and move on, not realizing they had more to say, or they’d repeatedly accidentally use items from the inventory, or they’d be unsure why they were having a conversation with a character or where it was meant to go. These are the sort of issues players don’t voice — you can’t complain about the things you never notice — but it feels like it quietly undermines a lot of the narrative of the game. I’ve been thinking for the last couple weeks about how I want to rework things to address those issues. First, I think I’m going to streamline a lot of the “use/give” item functionality in the inventory, so this is only possible with key items you’re likely to want to investigate or find unorthodox uses for. Second, I’m going to be introducing the idea of keywords. A few games have used this concept, the main one I’m familiar with being Final Fantasy 2 (not 4, I know it’s confusing). With this system, if you encounter a keyword in dialogue, it unlocks the ability to ask other NPCs about the keyword and uncover new information about it, potentially unlocking new keywords to inquire about and so on. I really like the idea of how intentional this makes the process of investigation: You can choose to specifically ask about an idea you’re curious about, and the causal relationship between that investigation and your options for future investigations are made clear. It also means that, whenever I get to implementing the Journal item to track dialogue and other information, you might be able to quickly look up everything you’ve learned regarding a given keyword.

There are a lot of remaining questions, even as this design takes shape. Can you ask every character about everything, even things it’s extremely unlikely they’ll know about? Does everyone use the same word to refer to the same characters and concepts, or are some keywords aliases for one another? Should items you can ask about appear in the keyword list? Some of those ideas I’ll probably only figure out once I start grappling with the specifics of the system. In the short term, I’m glad to have figured out the generalities – even if it means I’m going to have to spend a little while rewriting character dialogue to fit the new format.

I’m starting to get a sense for what the scope is for the remaining work for this second slice of the project. It’s a lot, but it feels manageable, and it’s exciting to start to see things take shape and solidify all over again.

It’s been an exciting and frustrating month as I keep running ahead and getting pulled back. This is the first time in quite a while I’ve gotten to focus on seriously expanding the game rather than just refining and polishing a narrow slice of it, which is both exhilarating and mildly panic-inducing as I struggle to slot all of the pieces of the puzzle next to one another in a way that makes sense. 

Before any of that, though, came the final 1.3 version of the demo. This work dominated the first week of the month: Aside from a few bug fixes and balance tweaks that aren’t really worth mentioning, the main change introduced in this version was a significant tweak to the combat system, reworking most attacks to have a slight startup delay and an extra frame of animation. This provides another lever of weapon balance, in particular allowing me to change an early weapon that turned out a bit stronger than intended to be a bit more of a challenge to deploy. I also reworked some enemy animations to make their behavior a little bit more obvious and added some additional feedback as to when and how special weapons are being used. 

Once that was done and 1.3 was out the door, I settled down and focused on building out the game’s map. The content of the demo comprises, I would estimate, somewhere around 20% of the finished map, so I’ve clearly got my work cut out for me. For the most part, I’ve just been focusing on figuring out basically what rooms are needed and how they ought to be placed relative to one another — a surprisingly exhausting and time-consuming process, considering how rough these rooms currently are, mostly just solid black blocks arranged as placeholders. Every room, though, is a convergence of several design challenges: What is it meant to convey? What happened here? What is the danger or interest of the space? How is the player supposed to navigate it? And so forth. These challenges are particularly tricky in the dense urban space that this part of the game is meant to take place in: Figuring out what an obstacle should look like, be themed around, while still conveying the concept of a city full of action and history, is a challenge.

Of course, in the meanwhile I sometimes go and play other games, other Metroidvanias and such, and can’t help but notice they usually don’t worry at all about any of this shit! Platforms float free of support in space, rooms exist with no history or practical application, backgrounds are generic tone-setters with little specificity, and so forth. It’s probably worthwhile to remember that probably few players will care as much about this as I do. Still, I personally find it important — Bound City, the city itself, is part of what the game is about, and I do want to do it justice.

As part of the level-building process, I’ve also added a little bit of flexibility to the tile set. Previously, all tiles the player could interact with were either solid blocks or drop-through platforms. However, as I’ve been developing the aesthetic and layout of the world, I keep feeling like the setup now, where stairs are represented as combinations of background elements and platforms, simply doesn’t feel very good in a lot of situations. Thus, I have added the dreaded sloped tile.]

With a few collision tweaks this works well enough with the player object, but there are a number of Ramifications that will take me some time, and probably lots of testing, to really contend with. One of the more minor ones is that the player animations sometimes don’t look very good on it, so it will require some additions and tweaks to resolve that. Another more significant one is that the existing enemies were developed with the assumption of all solid or platform tiles, so they may require a significant amount of additional reworking — particularly the spider enemies, which crawl along surfaces. The potentially trickiest obstacle I foresee at the moment, though, is the interaction with the player’s wall grab and climb abilities: Now that ledges don’t map completely straightforwardly with tile boundaries, a more generalized solution is necessary than the kind of hacky one I’d previously developed. I’m not wild about creating all this extra work for myself, but I really do think it creates a more interesting and varied space

Along the way I’ve also needed to tweak and improve some of the rendering fundamentals, half in preparation for future special effects and half just to have something to play with when I didn’t feel very driven towards hard problems. One of the effects I really liked in You Have to Win the Game and Super Win the Game, a pair of retro-styled platformers with incredible post-processing effects, was the subtle reflections created on the edges of the screen to recreate the experience of viewing on a CRT television. I spent a day on the related tasks of ensuring correct aspect ratio on every display, of creating these reflections, and of creating a rendering layer that bypasses most post-processing effects. The first of these is a technical necessity for compatibility, the second is a fun diversion that makes a pretty effect, and the third is largely unused for now but will be vital for creating certain special effects later on in the project.

Finally, reaching the end of the month, I decided it was a good time to fully implement the second special weapon (or I guess the third if you include the healing ability) — The Revolver. This was a design challenge I’ve been turning over and over in my head since the beginning of the project: What makes a satisfying gun, particularly in the context of a pseudo-retro platformer? What is the correct balance between aim and mobility? What’s true to the style of the game and creates interesting gameplay situations? My original concept for a gun was a weapon that could be aimed in any direction, but the issue with that is that it creates a conflict between the player’s directional inputs: Do those inputs aim or do they move? As I was working under a 1-month deadline on the original prototype, I decided to reduce this to the simplest possible version: The extremely early prototype of the game included the gun, but it just fired straight ahead, making it nearly useless against any enemy smaller than the player. I found this very dissatisfying, both in that it felt flat as an experience and that it had a very narrow use case. This version has remained in the game over the intervening couple years, but over the last few days I’ve gradually replaced it with the gun as I’d originally envisioned it, as it was meant to be.

https://imgur.com/a/zyBjdBq

I decided to completely deprioritize movement when aiming the revolver, locking the character in place. This may seem strict in a platformer, but is fairly consistent with the other weapons and abilities, all of which restrict movement while being used. I also made very fine aim adjustments possible: Aim starts in whatever direction is pressed when the attack action is started, but higher or lower inputs swing the aim in the direction of the input rapidly with a bit of acceleration. Both quick reactions and fine adjustments are quite feasible using a D-Pad or arrow key, and using an analog stick allows direct 1:1 aiming input. This is also the first application of a mechanic I’ve been planning for a while, critical hits: Only the revolver and a few other weapons are capable of critical hits, but when using these weapons if you hit enemies in the head or other vulnerable locations you can deal critical damage, usually somewhere around 2x the weapon’s standard damage. 

This month has been a real breath of fresh air — even if each new breath also brings a touch of hyperventilation as I get overwhelmed thinking about all the work that still needs to be done. Moving into June, I’m going to be detailing the world I sketched out over the last few weeks, adding some core interactive elements such as pushable blocks and switches that affect the world — and figuring out how to implement a fast travel system, both aesthetically and logistically.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.

Well, my assumption was that after finishing the demo, I’d be mostly taking the month away from Bound City to focus on other things. That didn’t happen so much for two reasons: First, the feedback from the demo and bugs uncovered in playtesting felt like they needed to be addressed, so a significant portion of the month was spent developing new versions of the demo with various tweaks and fixes. Second, around halfway through the month I came down with a fairly nasty cold, which completely destroyed my ability to focus for about 10 days, so this was effectively 2/3rds of a work-month. For the most part, the month was taken up by listening to feedback, thinking about it for a while, and trying to address that which was in the scope of the demo.

First, a lot of people complained about spikes, both in terms of them being visually identifiable and in terms of how brutal they were. I already had a system in place to make spikes visible from a little further away than normal terrain, but given how much visual noise the lighting system has I don’t think dimly lit spikes really visually registered as dangerous. I changed the spikes-only lighting to be more flickery and red, so the peripheral glances of them might more readily register as dangerous. I also toned down the damage a little, as it was extremely brutal for this stage of the game.

Another challenge which didn’t quite work as intended was the boss battles. I quickly learned that one necessary step in testing a boss battle is to ensure that the tactic of walking up and attacking over and over is not an overly effective one! With version 1.0 of the demo, boss attack speed and aggression were low enough that the knockback of basic attacks was sufficient to mostly keep them at bay, and their attack frequency was low enough that even when they could sneak attacks through they weren’t keeping up with the player’s more steady damage output. However, once I made the obvious tactics no longer overpowered, the bosses became significantly more challenging to deal with even using normal tactics. Work balancing these boss fights, ensuring that they’re fair and readable while not being trivial, is ongoing — it’s a tricky process, but quite satisfying.

A number of complaints came in regarding specific areas in the levels. Most of these centered around either an enemy near a screen transition or an enemy being introduced for the first time in a way which was confusing. I was vaguely aware of this as an issue, but it seems clear in retrospect that the way an enemy is first encountered — particularly an enemy that requires a different method of engagement — is very important. Moreover, I realized that I need to be paying careful attention to where these encounters were pushing players. A difficult encounter in the wrong place might guide the player away from an interesting moment, or even a health upgrade or save point — making all future encounters that much more difficult! Placing enemy encounters will, naturally, be an ongoing process of level design, and I’m sure I’ll make more mistakes like this in the future. In the meanwhile, I’ve learned a few more things I’ll have to pay attention to.

This is around where I got sick. I was working on the standalone version of SoundMakr kind of half-heartedly, and as I recovered and my energy came back my mind was on fire with possibilities for things to do with Bound City, improvements to make to the demo, additions to make to the main game, what to do next, what to build, where I was going. Inevitably I shifted my focus away from the relatively tedious work of making a UI for SoundMakr and towards a final version of the demo that addressed as much feedback as possible.

Another thing I’d heard from a number of people was that the map wasn’t as useful as it could be. I wracked my brain thinking of ways to make it more useful — perhaps the fact that map tiles had such different dimensions from room tiles (1:1 vs 8:5) made the map less legible? Maybe there needed to be more terrain information to make the rooms immediately identifiable? Maybe… Oh! It turns out that one of the core map features, the display of connections between rooms as dotted lines, was simply not working! Each room was displaying as a solid block, so discerning the relationships between them was nearly impossible. This turned out to be because the code to find exits (to later display them on the map) only worked if the room’s GameObject was enabled — because all rooms start disabled, that meant it was seldom-to-never actually working when the map was generated and displayed. As it turns out, fixing this problem was surprisingly tricky. Neither 2D colliders nor Unity’s Tilemap system can be used well when disabled, so I had to prod around to figure out where the systems did and didn’t work before I could finally build something that worked regardless of the GameObject’s current status. Now… it may be that if these rooms change based on game progression whole new problems could emerge, but that’s a problem I can hopefully address later.

I also made several improvements to the map system in addition to the bug fixes. Map tiles were changed to be 18×12 to more accurately match the size of rooms — it’s still a bit off, 4:3 instead of 8:5, but having one side even and the other odd made adjoining rooms look kind of bad since the dotted exit lines didn’t line up well. However, as the tiles were no longer square, they could no longer be rotated in 90 degree increments (only 180), so I had to make a bunch more tiles to compensate and rewrite the tile selection code to account for the new restrictions. I added a display for save points on the inactive room layer so the player had more information about where they all were, and I added a tile display for room tiles which were known to exist due to connected explored tiles but which hadn’t been explored themselves. The final result is a little bit cramped, but very informative and, I think, pretty nice looking.

A complaint from several testers, which was very revealing of my own blind spots, was that the inputs from analog sticks felt a little finicky and inconsistent. Now, I’ll strenuously avoid using an analog stick in a 2D platformer where possible, so I simply never thought to test these controls very much! I’m still not sure quite how I’ll be handling these issues — what I’m experimenting with so far is making the dead zone much larger specifically for up and down inputs, so it is more difficult to accidentally input these directions, but frankly all 2D platformer analog inputs will feel pretty bad to me so I don’t know exactly what will be satisfying to others.

There are other things which didn’t receive much active feedback but which seemed to be confusing to testers. The behavior of breakable terrain tiles seemed to cause a fair bit of confusion: There’s nothing explicitly introducing the concept, so without knowing it’s a possibility many players don’t bother looking for it. Additionally, the differentiation between breakable and non-breakable visually similar tiles caused confusion, as well as tiles which required specific damage types to break. There’s a lot going on here and I suspect this is going to be something I’m tweaking for a long time: Part of it comes down to the specific visual look of breakable tiles, part of it comes down to conveying the idea of secretly breakable tiles, and part of it comes down to conveying the idea that there are certain damage types necessary to break certain kinds of tile. I keep thinking of Super Metroid’s solution of just showing you a little picture of the particular item you need to break a tile, and while I find it extremely inelegant I can see why that’s the way they went with it.

There is also some feedback which I’m not going to be addressing in any demo updates. Some of it requires sophisticated solutions which are going to take a lot of time and testing before I’m satisfied with them, so they probably won’t find their way back into the demo at that point — an example of this might be the issues people have had with the interactions between attack animations and movement. Some of it I need to think about for a while and figure out if there’s a way to address it while staying true to what I want the game to be, such as issues with the lighting system and rendering style. Some of it I have a pretty good idea how to address but is going to be a longer-term approach which will shape how I develop the game out from here and perhaps move around content so it’s encountered differently, such as issues regarding early-game dialogue density and relevance.

Anyway, within a few more days of work I’ll be wrapping up version 1.3 of the demo, which I intend to be the final version — I intended that for version 1.2 as well, but I’m intending even harder now. With that I will of course be building the game out more, expanding the world map, adding/implementing planned upgrades, new enemies, and so forth — all the exciting work I’ve been putting off to focus on getting this first part of the game finished. However, at the same time I need to be seriously considering what the future of this project is and how I want to approach it. My default inclination is to just keep my head down, keep working on it for year after year until it’s done and I can be proud of it — but whether it’s now or then, I need to figure out how I’m going to share this, how I’m going to sell this, how I’m going to make it something people experience instead of just a hobby. 

If this kind of approach came easily to me, I probably wouldn’t be the sort of guy who spends years developing solo game projects! What do I want promotion of this project to look like? What do I feel I can consistently offer in terms of promotional effort? Should I be looking into crowdfunding? Should I be looking into a publisher? I’m not sure, and each question digs into the insecurities I have over ever sharing work ever, insecurities which only cut more deeply as I put more and more time into a project. Inevitably, these discomforts just lead me to wanting to put my head down and work more, avoid them by just making something bigger and stronger and more beautiful — nevertheless, someday I’ll need to decide on an answer.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.

Well, first off, apologies on having to make another two-month devblog, and on having not really kept up on other weekly posts. Hopefully, though, what I’m about to say will make up for it: The demo/vertical slice that I’ve been talking about finishing for the last six months or so is finally done. Over the last few days I’ve been sending it out to a few test players, and early responses are encouraging! While there has been some feedback about structural issues I may need to address, so far it seems that the fundamentals of the game are sound and people enjoy playing it, which is a big relief to hear. The demo is a more-or-less complete (albeit subject to change) chapter 1 of the game, comprised of the first three zones of the map. It seems to take about 2-3 hours for testers to get through, which is a little meatier than I had expected, and represents probably somewhere from 10-20% of the complete project. Since I’ve been very focused on getting this out there, I’m taking this opportunity to briefly step back from the project, assess feedback, and take care of some other stuff I’ve been putting off – more on that at the end of this post. For the time being and foreseeable future the demo is private – if you’re a Patreon backer and are interested in access (I’ve already reached out to most of you) then send me a message and I can get you a key. Otherwise, I’ll probably open it up for some folks to stream at some point, so you can see what it’s all about when that happens – I’ll try to announce any such streams on Twitter and link videos when available.

Okay, so that’s the big news. What follows is the nitty gritty of what I worked on over the last couple of months, some of which was finishing up the demo and some of which was just miscellaneous other parts of the game I was interested in. 

First off, I realized that the control scheme I’d been working on was not very controller-friendly: I had tried to restrict everything to the face buttons, but this was increasingly obviously impractical since there were three menu screens (map, inventory, and options) and only two usable center option buttons. Well, fortunately there were all these unused shoulder buttons, but implementing them meant I had to reconsider the whole control scheme. As there are (currently) only 4 special weapons, I initially decided to bind each one to a different shoulder button and move the inventory screen onto the top button of the main cross of face buttons (Y on XBox, Triangle on PS). However, on playtesting I quickly determined that I didn’t like this scheme at all, since it forced the player to memorize all of the special’s positions even when they only had one available, and selecting with this then using with another button felt very awkward. Instead I simply ignored the back shoulder buttons and set L1/R1 to cycle through specials, with the ability to hold either down to instantly select the heal ability. This will let the player quickly orient themselves in the line-up and cycle to the tool they want without looking right at the icon, while also opening up the possibility of adding more special tools later on if I’m so inclined.

Speaking of improvements to controller play, I also added controller rumble effects. The question of when it’s appropriate for a controller to rumble and when it isn’t is an interesting one: I personally feel like a lot of games tend to overdo it, adding significant shaking when there’s nothing very interesting happening, which can be overwhelming and confusing. Because of this, I tried to restrict controller rumble to mostly conveying important information: An enemy performing a powerful attack, one of your attacks connecting, or a pulse that gains intensity as the player loses health (a favorite element of mine from Silent Hill) and is timed to the music (a favorite element of mine from Axiom Verge). The interface I’ve created for rumble effects is dead simple – similar to how I handle transitioning post-processing and screen-shake effects – so adding future effects as they occur to me should be a breeze. It does feel a bit odd sometimes adding features that only some players will be able to engage with at all – as far as I know, there’s no such thing as a rumble-enabled keyboard – but I think enough people prefer using a controller for games like this to make it a worthwhile use of time and effort.

I also added a number of features to the dialogue system while I reworked, expanded, and polished NPC dialogue, including some changes on how character vox sounds get played. Normally, the dialogue interface plays the character vocal sound whenever a certain category of character is played for the first time in sequence – so if it’s set to vocalize vowels, when reading the word “sequence” it will vocalize the ‘e’, ‘u’, and ‘e’ as those letters are displayed, whereas if it vocalizes consonants it voices on ‘s’, ‘q’, and ‘n’. For most casual character conversations, a setting like this works well – however, for certain pseudo-words, such as “ssshhhh” and “ahhhh” this works very poorly, and sometimes I need a character to use something besides their default vocalization for when they’re yelling or whispering, or need to temporarily disable vocalization for a longer vox effect to have room to breathe. For all of these reasons I added a [v] tag to my dialogue system, which can either override the sound file used or override the vocalization rules so all or none of the characters are voiced. This effect is used sparingly, but is quite important when it appears.

I also discovered that the game was hitting some huge slowdown issues, which was odd and frustrating for a project with such minimalistic style. After a while learning how to use the Unity profiler (which I was aware of but hadn’t really had the opportunity to learn deeply until now), I discovered the slowdown had two main sources: First, the way that I had player profiles set up to store information was very inefficient, a huge list of game flags which had to be iterated through every time a game flag was changed, which I was able to replace with a much more efficient Dictionary object. Second, the sprite settings script that was a component of my sprite shader set was updating the rendering properties for every sprite on every frame, regardless of what changes had occurred, so I rewrote it to only write new changes as necessary – hopefully, and as far as I can see, without introducing any bugs, but only time will tell.

I was dissatisfied with how destructable blocks felt, so I added a little feedback in the form of controller vibration and slightly pushing the player back whenever they hit a potentially destructable block, whether it was damaged or not (as some blocks have special requirements for being damaged). This was one of those little tweaks that quickly ended up having huge ramifications: To make this tweak feel consistent, I also changed it so that you get the same feedback for hitting an enemy, so it functions as an all-purpose “you are hitting something” feedback, and this ended up slightly but significantly changing the feel of combat. Even more significantly, once I added this as a gameplay element certain things became obvious – such as that, for the exploding maggot enemy that sent you flying if you got hit, it felt ridiculous for it to just push you back slightly. Thus, I expanded the maggot’s code slightly to make it so it had the same knockback effect when popped with a sword as when stepped on, which immediately made it a much more interesting enemy. Now, rather than just being a small and slightly mobile alternative form of spike trap, it forced the player to consider whether attacking it to get it out of the way was a good idea or if trying that would just fling them into an even more dangerous situation. Immediately one of the least interesting enemies in the game became one of the most interesting, all because I didn’t like how destructable blocks felt!

In order for the demo to be complete, of course, I had to have some sort of an ending. I had mostly wrapped up the boss battle many months ago, but a few of the underlying systems had been changed and broken things. Even after fixing those, though, I wasn’t satisfied with the battle – the boss had too few moves, too few ways to transition between them, and often became stagnant and predictable. I spent a week or so just testing the fight out over and over, tweaking the state transitions and making the fight more dynamic. Of course, all this was only half an ending – the other half was in the scripted sequences, which became rather more complex in this section and which took me another week or so just to make sure flags got set correctly, effects animated correctly, that no contradictions broke anything, and so forth.

That all pretty much covers the work leading up to the demo. However, over the last couple of months I also wrote some new music. This is a pair of pieces for different sections of the same area, a dark place which gets weirder and more dangerous the deeper you go. This is a section intended to be revisited several times over the course of the game as you get additional capabilities, and is probably going to be where a lot of the deepest, darkest, strangest secrets get hidden. These tracks represent the first two sections: All to Waste, an NES-styled action version, and I, Refuse, a much darker, more melancholy version styled after SNES music. Who knows what the third version will sound like? I don’t… yet.

Okay, that covers the last couple of months! I may actually just make these posts bi-monthly, since it does help smooth things out so I don’t feel embarrassed by slow months and don’t feel like I’m spending too much of my monthly time/energy budget just describing work I’ve already done. If so, though, I’ll probably do it after next month’s update just so I can keep it lined up with the start/end of the year and won’t have awkward December/January updates again.

Now! What’s next? This month is going to be a bit of an odd one: While I collect feedback on the demo and consider my next steps on Bound City, I also would like to catch up on the mountain of adjacent work I’ve been putting off for the last, uh, 1-2 years. 

First: I need to finish building a personal website: This is a project I started at the end of December and then got quickly sidetracked from, though I did manage significant progress in the meanwhile. This website will serve several important roles: First, as a place to centralize my writing into an ad-free space I can control, second as a place to host promotion and info about Bound City (and other past and future projects), and third to host documentation about any assets I release on the Unity store or elsewhere. Which brings me to…

Second: Soundmakr. You may recall that a few months ago I developed a tool for dynamically generating sound effects in Unity, and that I talked about selling it as an asset – and then, shortly after, as is my habit, I got distracted. In the meanwhile, I’ve had the opportunity to test it in my project, get a sense of how it performs in an actual game in development – and it is good. I think so, anyway! Because of its relative completion and straightforwardness, this is going to be my first target as a Unity asset to sell in the store. In order to make this happen, though, I need to quickly develop a free-standing demo version of the tool and to create documentation, tutorial videos, and a store page for it – which I think will take about a week, maybe a bit more.

Third: Palette effect. I haven’t thought of a snappy name for this yet, but it’s a pretty neat post-processing effect I developed for Bound City which I think I could fairly quickly build out into a publicly usable tool and which I think other folks might find useful. Right now a lot of it is pretty tangled up in Bound City-specific code, so it would take a few days to pull it out and build an interface, write documentation, tutorials, page, etc.

Fourth: Sprite Shaders. This was my main focus for several months prior to starting on Bound City, an extremely powerful and flexible set of sprite shaders for Unity. Because this is the most complex of the mentioned assets, I got burned out on documenting, fixing, and preparing these for release as an asset and put it off indefinitely, but a few small but vital fixes and improvements (such as the performance improvement mentioned above) means that they’ll be even better now than if I’d released them back then. Most of the documentation is already done, but it will take a few days to make sure I haven’t broken any of the functionality not used in Bound City, to make sure everything is documented and consistent, and to make, yes, tutorial videos and a store page.

Obviously I have my work cut out for me, and all-in-all this may be more than I can realistically accomplish over this month, but I’d like to at least get the ball rolling on all of this so that it isn’t all piled up when I get back to work on the game. I’ll be picking Bound City back up in bits and pieces as the end of the month approaches, integrating any feedback that seems applicable and starting to build out the next sections of the game. For now, though, it’s an opportunity to gain a little… perspective. And, maybe, make a little money while I’m at it.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.

Well, clearly I’ve fallen behind. I ended up combining two months of DevBlogging here partially because I fell so far behind on putting up a DevBlog and partially because January ended up being a very low-progress month, with about half of it taken up by a moderate cold and a longish vacation and much of the other half taken up by anxiety and indecision. Looking back I’m not too displeased with my overall progress over this time, but the delays have been frustrating to say the least.

After spending all of November working on the new sound system, I had a tough time returning to the core project. This has been an ongoing issue over the last few months, as I near completion of this demo portion of the game. The closer I get, the fewer easy and fun tasks remain, leaving a number of hard/tedious tasks I have to tackle in succession. I could presumably sidestep this by working on more general long-term tasks, but I’m so close to completing this demo now that the idea of putting work into anything that doesn’t take me closer to that goal is frustrating. To mediate this frustration I find myself putting plenty of time into things that don’t technically need to be done but can be considered part of the initial slice of game that the demo is comprised of – stuff like this new sound system, like the intro illustrations, like writing that I can feel unashamed of, and so forth. Some of those side-tasks over the past couple of months have included:

One: Reworking the palette-izing post-processing effect to make it more flexible and adding an ability to dither-blend colors that don’t match the assigned palette. This, too, may become a Unity Asset Store asset in the near future… but doing so will require a day or two of rewriting the interface to split it from Bound City’s systems, so it must be added to the ever-growing stack of non-Bound City professional development tasks.

An illustration from my previous project rendered as (from the left), raw, double-dither, single-dither, no-dither

Two: Writing a new piece of music for use much much later in the game. This track, the theme for a climactic confrontation with reality, incorporates several previous track motifs and plays a lot with the thematic concept of reflection, with certain phrases and sounds being inversions of one another. Also, unlike previous pieces for the game, this one has several phases, intended to be stepped through one by one as a story moment escalates; in that regard it’s almost like several tracks in one.  I am quite pleased with how this piece turned out, but it’s probably another year or two of development away from actually being included in the game. Still, that just gives me a little extra motivation to push towards that moment…

Three: Small fixes and expansions to the dialogue interface to allow for more complex conversations and for canceling out of repeated dialogues. These changes were largely made because I found myself frustrated by their absence during play-testing — and, though this demo is not meant to convey the complete experience of the game, I still want it to feel as satisfying as possible in every moment.

Four: Minor fixes to enemy behavior to make them feel a little more robust and interesting. These were also just things that bothered me in testing that I took it upon myself to fix immediately instead of leaving for the time being. Would anyone playing the game notice if dogs got stuck on terrain rather than jumping over it? Well, I would, so I fixed it.

Five: The intro sequence is technically unnecessary for the demo, since it’s more about setting tone and giving an overall sense of the world than in giving information that is required to play the game, but I’ve decided I want it in for… some reason. To that end, I need to make two more illustrations for it. The first one is more-or-less complete and is the header image for this post — while I will likely want to tweak some of the fine details later, it has all necessary elements and makes a striking first impression. The second and third illustrations are half-done, but are coming along well now that I’ve figured out their basic compositions.

This stuff was all optional, but it was at least on the way. So much of how I manage to get things done, I find, is by leaving them conveniently along the way — or inconveniently in the way — of doing the things I would be doing anyway. There were other tasks a bit more pressing — arguably I could have at any point reworked the demo to make these redundant as well, either removing/rewriting characters or disabling sequences until I had a chance to create the systems to fully realize them, but I just don’t really like avoiding challenges. That’s not to say I never do, but I always feel bad afterwards because I know that I’m just going to have to confront them sooner or later and I’m putting myself in effort debt for the future.

One such system is a simple character controller for cutscenes. Once in a while I need to be able to make the player move, jump, attack, whatever, in order to create a story moment. There are a lot of ways to approach this: In this case I created something very similar to the behavior system I built for enemies, a queue of actions that directly took hold of the character and played them via the same set of buttons the player uses. This mostly works but could potentially make some future interactions, such as attacking with specific weapons, a bit tricky.

Another narrative problem I’ve been concerned about recently is that there are some very important characters which, as conceived, only showed up fairly late in the game. These character’s worldviews, and how they change or are perceived differently over time, are core parts of the narrative concept of the game, so it’s vital the player meets them relatively early — but it makes no sense for them to inhabit the early sections of the game. The solution I landed upon was to add a series of “vision” sequences, floating rooms that the player is warped to arbitrarily whenever they meet the requirements and are in a transitional state (such as after dying or restarting the game). 

Aside from these notable developments, there’s also been a lot of running the game, testing it, seeing how it goes, noting down things that are bugged or that bother me, tweaking, running again, and so forth. I’m having a hard enough time with this process that I have no idea how I’m ever going to do it for the full version of the game. That’s getting ahead of myself, though: I’ll worry about that later. The most notable of the issues I’ve addressed is a bug that’s plagued the game since the start. There’s a low-percentage chance, each time the player exits a room, of entering the wrong room — most often re-entering the room you just left, most often due to issues with detecting the exiting collision on the wrong side of the character, particularly while moving quickly diagonally. This should, one would think, be an extremely simple problem to solve, but it just keeps recurring, even when I completely rework how the exit collisions are detected. I have high hopes for this most recent solution — I haven’t noticed the error recurring yet — but only time will tell.

It’s tough to maintain enthusiasm at times like this, when the process is more about reinforcing and testing and maintaining than it is about expressing and building. At the same time, I’m having a tough time figuring out how to allocate my focus between this and other tasks — I now have three potential salable Unity Assets I will have to polish and write documentation and pages for, all of the writing I need to do that I’ve fallen dramatically behind on, and a new website I’m shifting over to to showcase this writing along with the mentioned assets, my development work, and miscellaneous portfolio works. I already struggle so much with knowing what to work on, what to turn my attention towards, and having all of these secondary targets just makes it tougher, particularly when I’m already feeling guilty for not working on things I’m “supposed to be.” I’m still not sure how to approach this, whether I’ll have to set aside a day specifically for this type of secondary work or attempt to do it in bits and pieces in the last hour or two of each work-day. As it is, I simply tend to forget about all of this stuff at the beginning of each day, and only remember it at moments like this where I try to take a wider view of what needs doing.

So Bound City continues on, at the precipice of a complete demo, as it has for several months now. When will I be satisfied enough to let go? Will it be soon enough that I can continue to work on the parts of the game I actually care about without resenting the project? I hope so. It’s almost as much a matter of what I’m willing to accept, now, as it is of what needs to be done — which, for the purposes of this demo, is rapidly but asymptotically approaching zero.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.

(Note: This post is going up quite late into the month, but I actually wrote most of it up at the start of December. The necessity of capturing images and movies to accompany these posts has become a significant bottleneck, not because it’s so very much work but simply because I’m either working on the game and want to be focusing on making progress or not working on the game in which case I don’t want to open the project when I’m meant to be taking a break. I probably just need to get in the habit of taking more screenshots and recordings as I go.)

This month was quite a divergence. I mentioned in the last DevBlog that I’d started working on replacing the sound effect generation system used in the project; I linked to a little cohost post going into some detail on the challenges as I think perceived them, but I didn’t go into much detail in the post itself. However, as the last month has been spent almost entirely on working on this sub-project, I’m going to go into detail here. Before I do, though, here’s a little video of the whole thing in action:

First, some background: Back in 2007 a little sound-generation tool called sfxr was released. This was shared with the indie game-dev community as a tool for quickly and easily generating sounds particularly for use in game jam projects, where impressive quality was a lower priority than speed and convenience. It quickly became a standard tool; it’s very likely that something you’ve played uses sounds generated by sfxr, particularly if it’s a retro-style indie game. In the 15 intervening years, various ports and variations have been developed, with two in particular of interest: First, bfxr, a version which adds several new parameters and which can save the sound parameters to files for later modification; and, second, the lesser-known ufxr, a Unity port of sfxr with most of bfxr’s features.

This latter was what I found when, a year and a half ago, I started this project. I was curious whether someone had made a version of sfxr that ran natively in Unity, which simulated the sounds in real-time, and wondered what-all one might accomplish with such a tool. ufxr did not turn out, in the end, to be such a tool: While it did have ways to play sounds directly, the way it achieved this was by creating an object, completely rendering the sound, loading it into the object, and then deleting the object once the sound playback was complete. This works fine if you’re just playing occasional sounds with little concern for latency, but caused significant performance issues when new sounds needed to be played every frame – and, of course, I wanted every sound played to be a bit different, because otherwise what’s the point of simulating them, rather than just rendering out a sound and playing it normally?

As a sort of stop-gap, I built a system that cached a set number of mutations for each sound and played them back randomly. This still wasn’t great! The game lagged significantly on start-up as it rushed to render and cache every sound, and the sounds only started playing once the caching operation had finished so the game was mute for a while after starting. Furthermore, because the way mutations worked was just a random percentage deviation for each parameter, it was very common for sounds to end up being a bit off – becoming way too loud or too long as some parameter drifted outside of the expected zone and completely changed the feel of the sound. This outcome was invisible beforehand and difficult to address once it came up.

This obviously wasn’t going to work. I needed to do something: I could strip out the whole apparatus, render the sounds to wave files, and play them back. This would be the easy and smart thing to do, being pretty much how most games handle sound playback. It was, of course, unacceptable to me, because I am a maniac. No, rather than this completely reasonable solution, I decided to create my own sound effect synthesizer in Unity – not just a port of sfxr, though I was certainly inspired by it and shamelessly stole all of the ideas I could get my hands on, but something built from the ground up in the way that made the most sense to me.

This sub-project, which I now call Soundmakr, is basically done now. Developing this system took the whole month, which is honestly fine – while I was hoping it would take less, I was also concerned it might take more, and I am quite pleased with the result. I’m going to go into some detail onto what went into this now, and the steps it took to bring this to fruition.

First things first, I had to generate a sound. A sound, from a programmer’s perspective, is just a big array of numbers between -1 and 1 representing the waveform. Normally one would play such a sound by loading it into a Unity Audio Source and letting it play, but that means you have to do the whole thing at once which just leads back to the unacceptably slow methods I was trying to avoid. Fortunately, Unity provides another way: A function called “OnAudioFilterRead” which is automatically called on any script that shares an object with an audio source. Though, as the name suggests, this is meant to process audio, it also makes it possible to write your own data into the audio buffer – which is exactly what I did. I copied all of the basic waveforms used by ufxr, most of which were pretty straightforward, and was able to play them using this function. A good start!

In addition, I created equivalents to the other basic waveform parameters: The duty cycle value, previously only used by square waves, was replaced with a generalized “cycle bias” value that could be used to modify other waveforms in the same way, such as by shaping the triangle wave into a saw wave. I don’t know if this is a common synthesizer ability or if there’s a more established name for it that I’m ignorant of. I recreated the phase-shift effect, which combines the waveform with a slightly shifted copy, and the harmonic overtone effect which combines the waveform with copies at various multiples of the frequency. The “bit crush” effect was replaced with simply having a variable sample rate – though the true output sample rate was locked at whatever Unity’s audio settings had set, the actual synthesizer only simulates at the set sample rate. This makes the synthesizer significantly more efficient, but I’m still not sure how many troublesome side-effects it may be creating…

Regardless, once I had a basic waveform, I had to control how loud it was. Sfxr uses a simple sound attack-hold-release envelope system, where the sound fades in over the attack period, is held for a period, then fades out over the release period. These are the standard terms used in musical synthesis, though in sfxr itself it uses the terms sustain and decay for hold and release, and adds a sustain punch value which is added to the volume during the hold phase. I replaced this envelope with the much more standard attack-decay-sustain-hold-release envelope: This fades in during attack, decays down to the sustain level (equivalent to “sustain punch” + 1), is held for the duration of the hold value, then fades out for the duration of the release. This may seem like a pretty minor change, but one of the things I would like to do someday is adapt this towards musical use – in which case little changes like this could be pretty important.

Okay, I have a sound that fades in and out! It’s a synthesizer! However, to have something equivalent in functionality to what I was replacing, I needed to add filters. This was a task I severely underestimated: While I knew enough about waveforms and envelopes to bang out serviceable ones in a couple of days, I quickly found out I didn’t know shit about filters. For those who haven’t done audio work, a filter is usually a tool for boosting or attenuating certain frequencies of a sound – but what is a frequency? When you’re working at the level of individual audio samples, values between -1 and 1, nothing you can see in a sample indicates what the frequency of the sound is. Looking at the source code to the predecessor tools I was working from didn’t seem to help: The filter functions remained bafflingly opaque. What I learned, in the many days subsequently spent trying to understand filters, is that filters are very complicated.

I’d need to take at least one class to really understand filters, but I managed to scrape together enough to have enough functional knowledge to move forward. To sum up: We can infer the frequency of a sound based on the rate it’s changing over time, and we can calculate that based on the differences between the current sample and N previous samples. We can also attenuate the sound by mixing in the same sound offset a given number of samples – since a sound added to an inverse version of itself is silence, and a sound phase-shifted by its cycle length is more-or-less inverted. This is, as I understand it, the principle noise-canceling-headphones work on. This was all nowhere near enough to allow me to devise a suitable filter, or even really to understand the filter code I was working at, but it was enough to allow me to look through a number of pre-built filter solutions online until I found one that mostly worked and then bang on the relevant parameters until it was what I needed. I actually thought I finished getting filters working several times before finally getting something functional – I at least hope that it’s finished now.

Okay! But… the sfxr synths don’t just play a sound that fades in and fades out, do they? They have all these other parameters: Vibrato, frequency sweep, change amount, and so forth! Here’s the part of the project I’m proudest of, my unique contribution to the lineage: Rather than having all these individual sliders and oscillators, I created a system of Low Frequency Controllers. There are four of these: Sweep, Oscillators 1 and 2, and Step. Sweep changes the controlled value proportional to time, with an additional acceleration parameter; the oscillators control the value according to a waveform and frequency, with the waveform having all the same available shapes as the main tone-generating oscillator; and the step controller changes the value at set intervals, with an option to periodically repeat.

While in the *fxr synthesizers only a few parameters have controls like these, in my synth nearly any value can be controlled. One of the reasons this is possible, from a purely performance-related perspective, is most of these only need to be simulated at most a hundred times a second to sound smooth, as opposed to the thousands of updates per-second needed to generate a tonal waveform, so adding new effects should cost almost nothing in terms of performance. The challenge, however, was how to create an interface for having and modifying all of these available controls without becoming a complete overwhelming mess: I am quite happy with the solution I developed.

New controls can be quickly added (or removed) by clicking the icons to the left of the value to be controlled. Controls are color-coded for quick visual reading, and this with the connecting lines makes it quickly obvious which control type maps to which icon. Universal control values, such as the oscillator waveforms and sweep speed multiplier, are all in their own color-coded sections at the bottom.

Though I’m quite happy with where this interface ended up, working with Unity’s Editor was A Struggle as always. You may have noticed the knob controls on the right and that some sliders have a range of values instead of a single value: This controls the sound mutations, changes that happen every time the sound is played. This particular knob control interface is a largely undocumented and unused Unity feature, and it took a lot of trial and error to get it working – that I bothered at all is mostly a testament to how perfectly this control type met my needs for controlling this particular parameter. Nearly every value can be mutated, and once it is the slider is converted to a double-slider so you can easily set the acceptable bounds for the sound. Another subtle challenge was that of playing the sound when the game was not running – as it turns out, OnAudioFilterRead doesn’t work in the editor, at least as far as I was able to tell. To handle this, I simply created a hidden background object to play the sounds. This required rendering the sound completely before playback, something I largely wanted to avoid, but since it’s just for one sound at a time while running the editor it’s not a big deal (this technique was necessary anyway in order to export sounds as wave files).

Now I had the sound editor and the synthesizer working almost perfectly, as far as I could tell. I began the work of porting it into the Bound City project… and quickly noticed Some Issues. Most immediately, every sound in the old system was addressed by string identifiers, names which were not present at all in the new sound type. It would be easy enough to add a name to each sound, but this felt pretty sloppy – why should a sound need a name? Instead, I gave each Sound Player a library, a little list of known sound files which could be assigned string aliases for quick and easy playback. I also did a little interface work to make building sound libraries quick and painless.

The biggest stumbling block here, near the end of the sub-project, turned out to be the difficulty of porting sounds from old system to the new one. I hadn’t set out to do it this way, but the whole structure of my synthesizer was almost completely different to that used by sfxr – rather than building out each sample one value at a time, modifying each parameter as it went, my synth merely took in whatever the currently elapsed time since the beginning of simulation was and returned whatever sample was appropriate at this point in time. Doing this made it very difficult to convert from *fxr parameters to the sorts of parameters I was using. Additionally, my filters worked in a completely different way than the *fxr filters, so I have no idea how one could meaningfully convert those values. For the most part, I just ended up experimenting via trial and error to figure it all out – and, for the most part, this was enough to import sounds vaguely similar to the ones I had before, but each and every one of them required lots of tweaks and modifications. I got all of the sounds ported from the old system to the new one, but it took several days.

Okay! It’s done! Is it? Well, mostly, for now. I have a number of ideas for improvements I would like to make, and I’m still finding little bugs and issues and fixing them as I get to them. Most improvements can be deferred for a while yet, since they’re more in the realm of expanded and advanced functionality. A few tweaks, making some behaviors more consistent and intuitive and getting a couple of minor features working, might happen much sooner. I’ve also been considering how I might want to go about publishing and/or selling this work: Though this required significant labor on my part, at the start of it all it was based on a freeware tool so I feel slightly scummy just selling it outright. On the other hand, I am very proud of it and would like to both share it and to make money from it! Most likely in the near future I will build a Unity UI for it – that is, the Unity player, not the editor – and release that as a freeware version of the tool, one capable of building and playing and saving all of the same sounds. Meanwhile, the version I’m using, the one that simulates sounds in real-time during gameplay, will be available for purchase on the Unity Asset store… that is, once I build the demo version, once I write up the documentation, once I make the store page, etc. I may try to focus on that more around the dead area that always pops up near the end of the year. I will certainly post about it here once I do.

So, with that all mostly behind me, I’m working on the game again. Much as I left it, there’s not much left to do for this demo version… the demo version I originally planned on reworking the sound after releasing. Will it be done by the end of the year? Maybe! I’ve mostly been fidgeting with this and that, making slight improvements, making everything a little nicer and fixing minor bugs. As I settle into it more, I hope to finish banging out the largely-minor changes that need to be done to wrap up, testing everything, ensuring everything’s in place, adding stuff that I only belatedly notice is missing, and so forth. It feels good to get something done, at any rate.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.

This has been, to my chagrin, the least productive month of the project so far. I’ve already talked about most of the things pushing back against my progress, and all of those continue to do so. The arc of progress seems, to me, to be an asymptotic approach towards completion: The further away the goal is, the more rapidly I can approach it. One reason for this seems to be that, when there are many tasks standing between me and completion, I can pick them up as I think of solutions or feel particularly motivated to tackle them and use that momentum to advance rapidly. Conversely, when there’s only a few tasks left, I have to sit and think about solutions and pick at them bit by bit to make painstaking progress. It’s like eating a big bowl of popcorn: When you start it’s easy and fun and light, but when you get to the bottom it’s full of little hard kernels that never properly popped, and if you want to finish the job you have to slowly chew them up, one by one, each buttery desiccated kernel. Nevertheless, they must be eaten – in this metaphor, anyway, I don’t usually eat the actual kernels.

So okay. I went around working on this and that, as I could see ways to advance towards a goal. I made a number of tweaks and fixes to the dialogue system, I polished up a bunch of the character portraits, I added new single-frame animations to the main character for turning and for pushing against walls. Nothing big, but little fixes to things that had been bothering me.

I decided, though, that what’s really blocking my progress here is simply that I don’t have confidence in the story and writing of the game. I’m so fucking excited about so many of the ideas that I’m playing with in this project that I’m terrified of messing them up, forgetting bits and pieces, expressing a powerful idea ineffectively, concealing or revealing too much too late. I’m in idea debt to myself, hypnotized by possibility and humbled by impossibility. This state of affairs is probably going to continue until I have a Plan, a structure, something that makes it feel like I can tackle each problem individually without completely losing my place.

Easier said than done. I have a long list of donts, which turns out to be much harder to work off of than a short list of do’s. I don’t want to have what so many games have, characters who give quests which you do to get stuff– I really dislike how many games boil down to the idea that you should help people because they might give you their old enchanted hat. I don’t want to have characters that just sit around and say the same few things over and over, I don’t want to have characters with broken lives left around for the player to fix, I don’t want the character stories to just be static events that always happen exactly the same way… so many things to avoid, it seems sometimes to chart a very narrow path indeed. To simplify and reduce some of this pressure, I’ve started trying to note down little bits of character arc – essentially just try to figure out, on a case by case basis, what I think each character’s story is about and where I see it potentially ending up

What sucks is that while I’ve just written several paragraphs about why this is necessary work, I still feel like I haven’t done anything all month. The writing is a little better now, there’s a little more of it, it has a little more direction, but I still have no real confidence in it and don’t exactly know how to address that. It starts to feel like this entire aspect of the project is an albatross around the neck, is just slowing everything down – but perhaps that which adds weight also adds momentum, and as an artist I do want to maximize impact.

After a certain point, anxiously pacing the same ground over and over loses its appeal. One of the things I was planning on doing after finishing the demo/vertical slice was completely overhauling the sound system, and in order to avoid needing to figure this shit out I just went ahead and started working on that. I went into some detail on where I’m at on that task in this Cohost post – suffice it to say that at this point I anticipate it being another week or so of work to finish it up.

Okay. What now? This month, I finish and implement the overhauled sound system, go through the writing again and send it out to some test-readers so I can exorcise my anxiety around it, put together the intro illustrations, and playtest/finalize all the in-game scripting. That sentence covers effectively everything that needs to be done to wrap up the demo version of the project. It sounds so easy! The hard part is just… accepting that whatever I do is going to have flaws, and that there will never be a perfect realization of these ideas, and just resolving to do what I can here and now.

This struggle will be ongoing, but I think I’m winning. Slowly.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.

This was another weird month, in part due to a sort of mental backlash against the whole deadline thing from last month. While I didn’t quite reach said deadline, the whole perspective of this as a thing that could be some version of finished in the near future kind of freaked me out. I have a complicated relationship with actually finishing things – most of the work which I call finished is small enough in scope that I can feel reasonably comfortable that I’ve examined it from enough angles to have confidence in its quality, as well as knowing that even if something turns out to be unsatisfactory about it I probably won’t be too upset because it’s a relatively little investment of self. This gets much more difficult with a huge project like this, and the closer I get to some sort of completion the more I have to face that. In that regard, this vertical slice completion is quite useful as a sort of practice run: Perhaps by dealing with this anxiety now I can be more prepared to handle the bigger, meaner, final boss version of it that’s going to happen when it’s time to actually release the game.

Perhaps.

Anyway. For this reason, and reasons of general fatigue and malaise, the beginning half of this month was spent almost entirely on music composition – a task I frequently gravitate towards when I’m feeling stressed or confused about more immediate and concrete tasks with more stringent requirements. These two tracks ended up being some of the more complex composition work I’ve done on the project so far, in terms of number of instruments and chord structure, and in both cases I had to spend approximately a whole week listening to them over and over and over, seeking out tiny discords and fixing little mistakes and stripping out sections that weren’t working, before I was finally some version of satisfied with them. Well, none of this is written in stone, and I may yet decide that these tracks need more work, but I at least was able to get to where I was able to call them finished without immediately crumbling into anxiety and self-doubt.

This is the track for the cathedral area, a place at the base of the tower where masses of people have merged together to become one great conflated entity, hurt and confused, always wanting more and less. I kept a motif I liked from Do No Harm – that originated when I thought that that was going to be the music for the cathedral zone – and I expanded on it, creating a dense counterpoint that kept threatening to spin out of control. I think one of my flaws as a composer is that I tend towards complexity, often unsatisfied with one or two simple tones playing against each other, and this track really fed into that tendency. The result is, I believe, a track that is rewarding to listen to attentively and repeatedly, but may feel confusing or off-putting on a first hearing. I suppose I’m fine with this in general – game music has to be able to handle being listened to over and over on a loop, naturally – but I can’t completely silence the specter in my mind of someone hearing a few notes they don’t like and then simply muting the sound in the game. Oh well!

Afterwards I was still not feeling up to returning to the rigors of programming, game design, and art, so I started working on the music for the University area. As one of the later sections, I wanted to start breaking the aesthetic of NES music a little more intently, so I started bringing in more SNES instruments – something I’ve been doing here and there, such as in the last section of The Agony of Touch, but in this case omnipresent throughout the whole piece. This is also the first piece written so far for this project that has stereo sound – which, while it has the same symbolic reasoning as adding SNES instruments, was also simply because I was having a hard time not oversaturating the mix. I put a lot of time into this track and I think I’m quite pleased with where it ended up – I can hear a lot of inspiration from Final Fantasy, Chrono Trigger, and perhaps even Secret of Mana, without feeling like it ever pulls too directly from any of those inspirations. I wanted to create a feeling of hauntedness, like this was a place that was hopeful once and empty now – I don’t know if I hit that target directly, but I think some of that comes through.

Though in my memory this was all a two-week block of solid music composition, I can see looking back over my daily dev journal that I actually worked on a number of other noteworthy tasks during this period. First, I added a set of tutorial messages at the start of the game: These are very simple and minimalistic, just a text bubble that appears and teaches a basic control, then disappears permanently once you do the thing it teaches you.

I also wrote and placed a significant number of newspapers and books in the world to serve for both storytelling and flavor.

Around the time I wrapped up the second piece of music, I also started implementing this mid-game scripted sequence I keep alluding to in vague terms. To work on this, I had to create a character design that I’ve been butting up against for a while.

An earlier version of this design popped up a few months ago, and it’s changed in several ways since. The biggest change is I felt that the giant skull was simply too goofy, and I tried to pull the elements that were interesting from that into a mask-like visage to fit onto a more humanoid design. So I had this design, a couple of other necessary character designs, I had the room for the scene to happen in – but something was gnawing at me. I was feeling the sense that I needed to start testing and scripting events, get in and make sure everything was functioning properly – I have, in fact, barely run the project at all over the last month. Testing is vitally important, and I know that – but I wasn’t doing it! How was I ever going to implement these complex scripted sequences if I wasn’t willing to go in and test? What did it mean that I kept avoiding doing so?

Sometimes I catch myself avoiding things. Sometimes I find that the mere thought of doing something that should be fun and rewarding fills me with dread, that I’ll do anything aside from that, making infinite excuses, focus indefinitely on preparatory side-tasks. It’s one of the traps I’ve learned to be very cautious of. At such times, I try to do my best to identify the problem and address it head-on: What’s causing me such dread? How can I work around it or alleviate it? One reason, I determined, was a fear of things going invisibly wrong – of something incorrect in the system going undetected and lying in wait like a landmine. This becomes particularly insidious at the intersection of the dialogue and gameplay systems: Both systems are able to get and set global variables to communicate with one another, but the actual communication is very difficult for me as the designer to perceive. A character dialogue might set a flag that places an object in the world, the object might set a flag to tell the character that you have found the object, but neither of these interactions are clear without looking at both the object and the dialogue file. A typo in either might mean the wrong flag is being written or read, and errors like that could cascade to some indefinite unknowable depth. That sense, of not being sure until testing whether any sequence will work properly, makes the prospect of testing far more stressful – since each test might reveal not just one issue but a huge set of cascading issues which make my life hellish for weeks on end.

This was a helpful realization, but it didn’t immediately suggest an action. It took me some time to decide upon a solution – and significantly more afterwards to figure out how to implement it. What I ended up creating was a Unity editor extension that draws all the information I need to understand approximately how these entities are interacting to the scene view.

This looks pretty simple, and for the most part it is, but getting this all working was a week or so of work – not least because Yarn Spinner, the dialogue system I’m using for the project, does not make most of this variable getting/setting information readily available. Because of this I had to create my own helper class which parses the dialogue files and pulls out all of the information. This was, frankly, a very frustrating thing to have to do: If I’m putting this much work into parsing dialogue files, the benefits of using a pre-made dialogue system really start to diminish. Would it have taken so much more effort to simply roll my own at this point? Perhaps not, but here we are, and the benefits of Yarn Spinner (most notably the easy localization options) probably will outweigh the drawbacks for the foreseeable future. Perhaps I will submit this helper extension as a suggestion for how they might improve the versatility of their tool in the future. Aside from those challenges, it took a bit of work learning the ins and outs of scene view GUI to actually get this to nicely visualize. Clicking a button selects the object which is controlling the flag, lines represent other objects setting the flag this object gets or getting the flag this object sets, and clicking the connection to a line moves to look at the object the line connects to.

Finally, I added an extension to the NPC dialogue inspector that displays what dialogues can be activated by speaking to the NPC, then marks up those dialogues by highlighting where it reads or writes variables, where it jumps to another node, and most importantly where it detects a given line might be too long to fit into the in-game UI.

All of this took a couple of weeks, and for the whole time I was fighting the paranoia that this was just another instance of finding something to work on so I could avoid tackling the hard stuff, just digging up another way to dodge the dread. Looking at this work now, though, I feel so much less stress that I have to believe this was the right choice. There are still probably a few issues left to iron out: Some of this information could probably be displayed more nicely, and there may be things I haven’t thought of yet that need to be added, and right now all these buttons make it a bit tougher to use the standard Unity editor gizmos – but this feels like a huge step in the right direction.

Meanwhile, I’ve been putting together a task list of everything left to do for this vertical slice. It’s not much – just as it wasn’t much at the beginning of the month – and now I’m in a much better position in terms of mental and material preparation to tackle it. I’ll be burning through this list as quickly as I can – but, at the same time, I’m feeling so restless, so impatient to start building the game out and adding all of the cool stuff that’s been waiting just behind the barrier of finishing this first segment! I keep hitting ideas for little bits of polish and improvement, tweaks to make things nicer and smoother, narrative points I want to touch upon… Perhaps, between checking things off this list, I will start putting together a second list, a list of when and how to proceed to build out the game, a step by step to figuring out how to capture the game which eludes me.

It is a strange compromise I find myself making between getting excited about finishing this early vertical slice and moving towards where I eventually want the project to go, and I keep getting lost straddled between these two guiding lights. Still, it’s not as though they’re leading in such different directions – as long as I keep making my way forward, I will be making some kind of progress towards some kind of completion.

If you’d like to help support this project or my writing, please consider supporting me on Patreon.