Bound City DevBlog, June/July 2023 – Swings and Arcs

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.

Leave a Reply

Your email address will not be published. Required fields are marked *