This week, I finally started working on two related systems that have been lingering in the “stuff I really need to do” pile for way too long. The first is combat; although I started prototyping a melee weapon and testing its collision against the environment and other game entities last month, I hadn’t yet completed the loop by funneling these collision results to a health component and reacting to damage correctly. The second is AI; in order to start testing damage against the player, I needed a simple placeholder enemy who could move around and inflict damage on touch.
When I was working on an untitled, unreleased dungeon crawler prior to Super Win the Game, I had written a few components releated to the concepts of health, damage, knockback, etc. Most of these had been sitting unused for over a year and had never really reached a shippable state, so rather than revisit each of them, I chose to rewrite all of them into a single new component that would manage all of these elements at once. Ever since moving to an entity-component system (and perhaps the origins of that system will be my next blog), I’ve been trying to find the right scope for each component. I find that when I break things down into the smallest, most granular level, I end up with a lot of dependencies and communication between components, and that feels bad to me. I like it when components are able to function autonomously. There will always necessarily be some interaction among components, but in this case, nearly every piece of functionality in each of these components was dependent on another one, and it made more sense to unify them into a single component.
So now I have one component (still called a “health component”) which manages the entity’s current and maximum health values, receives damage from external sources, sets stunned and invulnerable states in response to damage, and tests whether incoming damage is valid based on entity allegiance, invulnerability, and so on.
The second feature I worked on this week for AI. I’ve been dragging my feet on this one for a while; along with UI and collision, AI is one of those systems that I’ve historically had difficulties implementing. When I was working on the Win the Game titles, I was able to avoid implementing AI by treating the enemies as “hazards” that would simply bounce back and forth between two walls forever, but for Gunmetal, I’m going to want a variety of enemy behaviors, and I will benefit from making it as easy as possible to author and maintain those behaviors.
For now, I’ve chosen to script AIs with markup in largely the same way I did in Super Win, but with some additional rules for choosing a random action from a weighted set.
This is a first pass. It’s highly unlikely this is the implementation that will ship in Gunmetal Arcadia, but it’s a start. Looking back at my previous post on animation tools, it’s easy to imagine how I could produce this markup from a visual interface. In fact, I’ve been debating whether to extend the editor’s entity construction tool to encompass all components such that I never have to author any markup by hand. That might be a little too ambitious for this project, but if I continue reusing these systems and this editor for future games, it could be worth the time investment.