In the next two weeks I have deadlines for two different contests coming up, so things are getting pretty hectic. Lots of things changed in the ~100 or so commits since the last blog post, so I’ll pick a few to describe.


Combo System & Attack Chains

Previously, combat basically consisted of hitting the punch button over and over to kill monsters. This sucked.

I took a few major steps to address this:

First, I added a second attack type bound to the button I was previously going to use for the grappling hook. This attack is slower and hits heavier, with a wider attack arc, and gives you a nice alternative to the fast, lighter-hitting punch attack.

After the addition of the second attack type, I built on that to add ‘combo’ variations of each attack (punch combo, slash combo). The player can combo these attacks onto a previous attack by properly timing another button press near the end of the previous attack animation. Missing the timing (either by pressing too early or too late) ‘botches’ the combo and causes the delay before they can perform another attack to be longer than it would be otherwise. The size of the time window in which you can successfully combo an attack decreases every time you combo, so over time it gets harder. This means that simply attacking once will be slow and inefficient, but you are also prevented from comboing attacks indefinitely, which strikes a good balance. The fact that a failed combo has a longer delay than a normal attack means that a player won’t be punished for choosing to simply combo once or twice and then attack again, since the effectiveness ends up being nearly the same.

Finally, I added a ‘attack chain’ system that tracks the number of hits you land on a foe in rapid succession. This allows me to delay the ‘flinching’ animation normally played when a creature recieves damage, so that the creature stays within reach of your attacks, allowing you to combo. Each successive hit extends the chain for a short period of time, allowing you to continue landing blows, and when the chain ‘breaks’, all the hits you landed deal their damage to the creature at once, knocking it back and possibly killing it. Chains can span across multiple creatures as well, allowing you to keep multiple enemies ‘locked’ by your chain at once. Right now it’s a bit overpowered, but I think some careful tuning will maintain most of the positive aspects without making the game too easy.


Instance Limiting Overhaul

Recently, while working on audio improvements, Troupe ran across a bug in XACT. PC builds of the game ran perfectly without any significant CPU usage problems, and the audio sounded great – but on the 360, as soon as enough channels of audio started playing, the game’s framerate tanked to around 15FPS and stayed there indefinitely. This was despite the fact that the game already issues most of its audio calls on a background thread to work around the prohibitively high cost of XACT’s API calls.

The problem turned out to be that despite the fact I was using XACT’s built in instance limiting support to control the number of instances playing at once, XACT was struggling to handle the number of cues I was asking it to start at once. Essentially, I was starting all the ambient loop cues for my level at once – around 30 – and expecting it to pick the 8 loudest ones to play at any given time based on the instance limit. On PC this worked perfectly without any performance issues, but for whatever reason, not so on the 360.

As a result I basically tore out all the existing code that relied on XACT instance limiting, and reimplemented limiting inside my engine. Luckily this only required changes to about 500 lines of code, but it was still rather frustrating to have to reimplement it when it worked perfectly on PC. On the bright side, now I have more control over how instance limiting behaves, so I at least got something out of it.


Active Controller Detection

While doing some testing on my 360 I realized that my approach to handling the 360 controller was incorrect. While I assumed that the player might want to play with any of their four connected controllers, I neglected to notice that most of the XNA Guide APIs (storage device selection, etc) are designed to only respond to input from a single controller. This meant that I needed to detect which controller the player was currently using and make sure to only show XNA dialog boxes using that controller, and that I also needed to detect if that controller became unplugged so that I wouldn’t attempt to show a dialog box the player was unable to close.

I ended up spending a while changing my input framework so that it would automatically detect disconnected controllers, and inform the game code when a controller had been reconnected. I also did some work to automatically track the active controller, while still handling keyboard input correctly on the PC.