Act II - Weekly Dev Log #1

Death Must Die

Descend the nether in search of Death himself! Choose from God-given powers to slay his hordes of minions. Unlock new heroes, collect powerful items and create game-breaking synergies in this roguelite hack and slash survivors game.

Hello everyone. We are still about a month off from releasing the Act II update, but we want to start sharing some of what we’ve been doing behind the curtains. Some of you are asking why the update is taking so long and that’s a fair question to ask. We wanted to scale the game to become more than it currently is, and so we didn’t want to just reskin the old act or simply add more content of the same type. Our process since the November release has been to collect all the player feedback and identify the common issues people were having. Things like the attack movement penalty, item binding, build and wave variety, etc. We then spent a lot of time thinking about the issues and how to best solve them, trying out various approaches until finding ones that work. We chose some of the more costly solutions, in terms of development time, as they involved adding in a lot more animations, rebalancing large parts of the game from scratch and refactoring the existing codebase. Because these reworks were interconnected, we couldn’t break them down into weekly or monthly updates. However, moving forward this will allow us to add in more interesting features that we hope will serve to make the game better at large. A good example of this is the new monster AI system, which we want to share with you today. We intend to make these dev logs a weekly thing, to keep you guys updated on the development. — Back to the new AI system - we wanted to create more complicated behaviors for our elite and boss enemies. Things like special moves, condition-based abilities, sequences of actions and stages. We had some of that in Act I, but all of it was hard coded and thus hard to extend. We knew we needed a more flexible system. This is where behavior trees come in - a powerful pattern that allows us to modify, combine and tweak behaviors to create interesting interactions. Here is how our implementation works using the first Act II Boss, The Mummy, as an example: [img]{STEAM_CLAN_IMAGE}/43752680/c5b2f689390470cf26fe8a664810ca5bf9dcf3dd.png[/img] It all starts with a "toml" definition file: [img]{STEAM_CLAN_IMAGE}/43752680/9fead33c191c830885a9432f153133410f946d42.png[/img] It contains several building blocks - or nodes - that we combine to create the desired behavior. We’ve defined three main types of blocks - Composites, Conditions and Actions. [list][*]Composites allow us to combine other blocks. "c_sequence” for example will try to execute all contained blocks in the given order, while "c_random” will pick something using a weight-based random algorithm. [*]Condition blocks allow us to branch the monster decisions based on a given trigger. For example, the Mummy will only execute the powerful ”flies” ability once its hp drops below 40%. [*]Actions are the actual monster abilities. They can be attacks, jumps, spells or anything else. They have a timeout parameter and a code_slot field, which tells the parser which ability from our table of monster abilities to execute. [/list] And this is a part of our monsters ability table: [img]{STEAM_CLAN_IMAGE}/43752680/c7b4f79092f599f757a91c1fe2b38af8110e19ae.png[/img] Here we can fine-tune parameters to nail the behaviors we want. As a side note, we are reworking this table and other monster tables as well (but that should probably require another post to really delve into). In short, this rework will speed up the development around defining enemies and balancing them. It will also set us up for randomly generating interesting enemy combinations for the waves in the future, instead of the static system we are currently using. The last two parts of the AI are the parser and AI controller. The parser is the code that interprets the toml definitions and creates in-game decision trees. Then each enemy is initialized with a “_brain” - controller that takes a decision tree and executes its logic in the context of the game level. [img]{STEAM_CLAN_IMAGE}/43752680/d709307f59c333139eaf98cc8fdbd5318cd1b47a.gif[/img] So this is a brief overview of how we’re improving the system for defining enemies and how they behave. Would you like us to go more in depth on these technical aspects or should we make some art-heavy posts instead? We would also like to talk about some of our game design plans and get your opinions on them. Let us know what you think.