Traversal

It took way too long, but we finally got our internet service activated at the new apartment, so hopefully there won’t be any noticeable interruption in my productivity as we get the last few things moved over to the new place.

Continuing from last week’s projectile lobber experiments, I’ve been prototyping another new enemy type this week. As I was in the middle of replaying Super Metroid, I thought it might be fun to try to replicate the crawling behavior of these guys.

geemer
Pictured: Not Super Metroid.

It’s a pretty simple design, and one that’s been used in countless games. The enemy traverses the surface of the world either clockwise or counterclockwise, turning corners as appropriate. But despite its apparent simplicity, this was the first time I’d implemented this particular behavior myself, and it turned out to be an interesting problem to solve.

The first step was to identify the two kinds of corners the creature may encounter: “inner” corners, those in which our path crosses a wall and we turn to crawl along that wall, and “outer” corners, those where the surface we’re crawling on ends and we turn onto the adjacent edge. Each of these cases requires a unique solution.

geemer_inner

Identifying inner corners is easy enough. My collision system can send a callback to anything that requests one whenever we collide with anything. So in the event of a collision, we check to make sure the thing we hit was a solid wall and not another entity like the player. If it was, we rotate our velocity ninety degrees in the appropriate direction, adjust our position such that we’re flush against the new surface and not intersecting the old one, and continue our traversal.

geemer_outer

To identify an outer corner, I do line traces from the center of our entity opposite the normal of the surface it’s crawling along. If this line trace collides with the world, we still have solid ground and can continue, but if it doesn’t, we’ve reached the end of our foothold and should turn. As in the other case, we rotate ninety degrees and reposition ourself flush against the adjacent edge.

GunPreq 2015-08-26 03-12-47-332

My solution accounts for entities with various collision box shapes, flat or tall. One case I haven’t solved yet is when the collision box is larger than one 16×16 tile in either dimension. This would require doing some additional checks to ensure that we can fit in the allotted space before turning.

Another edge case that arose in testing, and one that I did feel was necessary to solve upfront, is when the surface a crawler is standing on is destroyed out from underneath it. As I am supporting destructible terrain in the Gunmetal Arcadia games, I knew this was likely to come up at some point, so I should probably figure it out as soon as possible.

GunPreq 2015-08-27 13-27-31-233

When I had initially prototyped crawling movement, it was as an alternative to my usual physics path that most other entities utilize. That path handles the typical case of gravity pulling down at a constant rate, and crawlers have no need for gravity most of the time. To address this edge case, however, I chose to give crawlers physical properties so they can respect gravity, but keep this motion suppressed as long as a valid crawling surface exists.

When the crawler’s tile is destroyed, it initially reacts as though it had reached an outer corner. The line trace fails to find an expected surface, so we turn. But if after turning, still no valid surface can be found, we engage physical properties and fall until we hit another valid surface. Once we’ve landed, we suppress physics once again and begin crawling as usual.


A couple of quick notes on future things in case I forget to mention them in Wednesday’s video:

  • I’ve submitted a pitch for a GDC 2016 talk as part of the Math for Game Programmers tutorial. It’ll be some time before I hear back on whether it’s accepted, but that’ll be an exciting new experience if it is!
  • I’m thinking about putting together a (second) Super Win the Game postmortem for its one-year birthiversary at the start of October. I have a lot more data now than I did when I wrote last year’s doom-and-gloom piece. Let me know if there’s anything in particular you’d be interesting in reading!
  • That also means we’re coming up on one year of Gunmetal Arcadia devlogs soon! I’ll probably do a recap and look-ahead blog for that week, so again, let me know if I can address any specific questions you might have!
  • For local-ish folks: I’ll be demoing Super Win at two more events next month. Come say hi!

Trajectories

This weekend was mostly spent readying things up to move to another apartment over the next couple weeks — not a drastic relocation, just moving from one suburb of North Dallas to another — and my home office is a bit of a mess right now. By which I mean, I have to jump over several boxes to get to my chair. Probably a literal fire hazard. That sort of thing.

I’ve been working on enemy designs recently, mostly on paper but also prototyping in the game as I’m able. My goal is to have about 15-20 unique enemies types in Gunmetal Arcadia Zero, plus some variations on these (palettes swaps with alternate abilities), plus bosses and minibosses. It’s entirely possible that will be overscoped and I’ll have to scale it way down, but why not aim high, right? If you’re curious, I chose those numbers by looking at the bestiaries and rogues galleries of a number of NES games in the same vein, especially Castlevania.

I’m starting by decoupling the visual design of enemies from their functional abilities so I can focus entirely on gameplay for now. I just played through Symphony of the Night again last week, and I’ve been trying to identify interesting ideas that I can adapt to Gunmetal. One of these came in the form of the bone-throwing skeletons found throughout that game.

For months now, I’ve had a pending task to implement aimed shots, and I finally began prototyping that this week. The goal is for an enemy to be able to hit a moving target (typically the player) with a lobbed projectile, given some constraints on how fast the projectile can move. This is a fairly common problem in game dev and one that I’ve solved in various forms before, but in this case, the solution was a little more complicated than I anticipated. But before I get into the details, let’s step back and look at solutions to similar problems in the same vein.

aimed_1

Hitting a stationary starget with a linear projectile is trivial. We take the vector from the shooter to the target, normalize it, and multiply it by our projectile speed.

aimed_2

Hitting a moving target with a linear projectile is slightly more complicated, but still not bad. Assuming the speed of the projectile is constant, we know how far it will have traveled in any direction at time t. Assuming our target maintains its current velocity over time, we can solve for any point (or points) at which the target is this same distance from our shooter. (I like to visualize this as a line-sphere intersection test, but with the added condition that the radius of the sphere increases linearly over time.) This turns out to be a quadratic equation, so we may have up to two valid (non-imaginary) results, and we may choose any result with a positive time t value.

aimed_3

When we introduce acceleration due to gravity, things get a little trickier. If our target is stationary and we want to hit it with a projectile that follows a non-linear path affected by gravity, we can represent this path as a parabola that intersects the positions of our shooter and target and solve for the angle of elevation given our desired projectile speed.

aimed_4

So now we want to put both of these together and hit a moving target with a projectile that is affected by gravity. And this is where things get really hairy. Due to the additional complexity of modeling acceleration, however, this actually turns out to be a fourth-order, or quartic, function. This means it may have as many as four results.

aimed_5

Now, I’m not aware of any equivalent to the quadratic formula for solving quartic functions, so once I realized this was a fourth-order problem (and verified that with some internet searches), I had to decide whether it worth pursuing an exact solution. I spent an hour or two poking around at it before deciding it was not. Instead, David suggested I separate the vertical and horizontal motion of the projectile, fix one of these, and solve for the other, and that’s what I’ve ended up doing. The downside to this is that the magnitude of our velocity vector will vary depending on input conditions. The upside is it’s much more easily solved and for the sort of game I’m making, probably no one will notice the difference anyway.

GunPreq 2015-08-24 00-48-54-666
Fixing the horizontal speed of projectiles and altering the vertical to hit our moving target.

My first attempt was to fix the horizontal speed of the projectile and alter its vertical velocity to hit the target. This works, but it feels a little wonky in practice, especially when the vertical velocity is near zero, and the projectile appears to have been dropped rather than thrown or fired. I got far better results when I fixed the initial vertical velocity and altered the horizontal speed to hit the target. This guarantees that the projectile will always spawn with a good amount of speed, it will always reach a certain height, and generally it just feels more tangible and physical.

GunPreq 2015-08-24 00-46-37-782
Fixing the vertical speed of projectiles and altering the horizontal to hit our moving target.

If we disregard the player’s velocity, this becomes a problem of hitting a stationary target. This is a little easier to solve, and still a pretty good gameplay experience. If we account for the player’s velocity, then we end up with the case where the projectile will always hit the player unless they change their course after it’s been fired. I’m not yet sure how I feel about this. I feel like it’s somewhere between challenging and unfairly difficult or frustratingly artificially calculated. So what I’ve done instead is allow this to be tuned by solving for a variable amount of the player’s velocity. At zero, this becomes a stationary target solution and the player will never be hit as long as they keep moving. At one, this becomes a moving target solution and the player will always be hit unless they change course. It feels like somewhere in the middle will probably be a sweet spot, where projectiles are not totally predictable one way or the other, but can be avoided in most circumstances simply be staying aware of the playing field.

Of course, we don’t want enemies to be able to bullseye the player from halfway across the map, so it’s important to include some constraints on what valid solutions may be. In this case, I’m clamping the horizontal speed to some maximum value. If the player is too far away and can’t be reached without exceeding this value, then we just lob the projectile as far as we can and don’t worry about it.

In the future, I may tie some of these aspects into other AI systems, like whether the enemy is aware of the player, whether they’re facing the player, and so on, but for a quick prototype, I feel like this is off to a pretty good start.

Patreon

Just a quick note: my Patreon campaign is now live!

patreon_header_2

If you’re enjoying the behind-the-scenes look at the making of Gunmetal Arcadia on this devlog and my “Let’s Make Gunmetal Arcadia” video series, you can help me sustain and grow this side of the development process! You’ll find a number of reward tiers on the Patreon page, from receiving access to exclusive preview builds and getting your name in the credits to getting a free copy of both games when they’re finished. Check it out!

Mix ‘n’ Match

I’ve written a bit about my entity-component system in the past, and about how I define entities and their components in my editor using XML markup. My editor defines a hierarchy of entities where the markup of each parent is prepended to one’s own. XML tags typically correspond 1:1 to components, and in the event that an entity and one of its ancestors both provide the same tag, the decision to append vs. overwrite can usually be inferred from context. (In some cases, when either option may be desirable, attributes can be used to make this explicit instead.)

hier_1
Sample entity hierarchy from Super Win

This served me well enough on Super Win the Game, but as I’ve started thinking seriously about content production for the Gunmetal Arcadia prequel (title to be revealed in Wednesday’s video; stay tuned), I’ve run into a few cases where a strict single-parent hierarchy just doesn’t make a whole lot of sense and has led to some redundant markup bloat.

Consider the case of things that may drop items. Enemies drop items when they die, but environmental things like torches and sconces do too. In order to avoid copying and pasting markup between these, and to ensure we keep them in sync if we decide to change how item drops work, it makes sense to parent each of these abstract entity definitions (enemies and environmental objects) to a base “item dropper” abstract entity definition.

hier_2
Proposed consolidation of item drop markup to a parent entity

But this introduces its own problems. What happens, for instance, when we want to generalize the concept of things that have AI between enemies and NPCs? Environmental objects like torches and sconces certainly don’t need AI, so it doesn’t make sense to derive the “item dropper” entity from this “AI driven” entity. But likewise, NPCs can’t die and will never drop items, so it doesn’t make sense to derive the “AI driven” entity from our “item dropper.”

hier_3
Not a good solution. Why is an item dropper necessarily AI-driven? Environmental objects require no AI.

 

hier_4
Also not a good solution. Why is an AI-driven thing also necessarily an item dropper? NPCs will never drop items.

What we really want is to be able to pick and choose from an arbitrary number of parent entities. In this way, we can treat these parents not as a strict hierarchy, but as more of a system of composable interfaces.

hier_5
A proposal for a better hierarchy. Note that our enemy entity now has two parents.

When I started implementing this, I was thinking about it in terms of multiple inheritance, but that term carries some baggage that doesn’t really apply here. In truth, neither “inheritance” nor “composition” is really an appropriate expression here, as these aren’t classes and don’t provide functions. This is simply a way of prepending associated data to a sheet of XML markup, and for the sake of familiarity, I’m thinking about it in terms of programming concepts.

My implementation is fairly simple: instead of a single parent entity definition, an entity may specify an arbitrary number of parents. The editor interface prevents loops by disallowing an entity’s own descendents from being selected as ancestors, but otherwise, anything is fair game. Conflicts or redundancies are avoided by explicitly specifying the order in which parents are evaluated. In the event that an entity is derived from A and B, each of which is derived from C, the resulting output could be either the concatenation of C-A-B or C-B-A. By requiring the order to be specified within the editor, these sorts of ambiguities are avoided.

hier_6
The editor tool for selecting parent entities.

This implementation gives me the freedom and flexibility to choose how I want to structure my data. My expectation is that as I start migrating existing content over to this new format and building new content on top of that, I’ll start to get a feel for best practices, and maybe that can be another blog somewhere down the road.

Gunmetal Gaiden

This isn’t an overly long post, but it is an important one, so I feel a tl;dr is in order. And here it is:

Two games. I’m making two games. I’m making one game, and then I’m making another game at the same time. Two games. Okay.

Oh and also go vote on this survey.


“Hey Kyle,” I said to myself, “You know how you’ve been feeling like you don’t have enough time to work on Gunmetal Arcadia? I have just the thing for that. Why don’t you try making two games at once?”

Okay, so maybe that’s not exactly how it went, and it’s a bit of a stretch to say I’ll actually be working on two games in unison, but in all seriousness, I’ve found a potential solution to my Gunmetal Arcadia production problems, and it involves working on another game that isn’t Gunmetal Arcadia. No, really.

As various non-Gunmetal responsibilities have piled up and stolen away more and more of my time, I’ve been pushing back some of the critical problems that need to be solved, things like random level generation and persistent changes to the world. It’s not that I don’t have any time at all, but rather that my development time has been segmented, and I haven’t felt like I’m in a good position to address any of these tasks due to their scope. Any one of them is just too large to deal with in fits and starts. My time would be better spent working on known, quantifiable tasks, namely content creation. But content creation in the absence of some of these critical features can only get me so far. That is, assuming my goals are the same as they’ve always been.

But suppose instead of Gunmetal Arcadia, I were working on a different game, one that were set in the same universe and used the same assets and shared the same core mechanics of movement and combat, but which had a linear level structure in the style of most NES action platformers. That game would be nearly feature-complete already. With the addition of more content, it could be close to shipping before too long.

That’s the motivation behind what I’ve been calling “Gunmetal Gaiden” (actual name to be determined, see the survey near the end of this post). This would be a separate, standalone prequel game, the Ground Zeroes to Gunmetal Arcadia‘s Phantom Pain.

Probably not final artwork. :V
Probably not final artwork. :V

From a production standpoint, this is an obvious win. This content has to get made at some point anyway, and I’m in a situation where building this content now fits my schedule better than other tasks, so if I fast-track it to meet the goals of this prequel game, I can conceivably make progress on that one without significantly impacting the schedule of the roguelike game. I don’t have specific release dates for either yet, but Gunmetal Arcadia has felt like it’s trending towards a Summer 2016 launch window, and I see no reason for that to change on account of this revised process.

This “Gaiden” game will be smaller in scope than Gunmetal Arcadia. I’ve been thinking about it in terms of the original NES Castlevania or Contra; I’ll probably aim for about half a dozen handcrafted levels, and it will be priced accordingly. I’ve been wanting an opportunity to gather data on releasing a game at a lower price point, and this is a perfect low-risk scenario. This game will launch somewhere under five dollars, likely as low as two or three. I don’t yet have a release date in mind; it feels reasonable that I could finish it by the end of the year, but I’m wary of shipping a game during the holiday rush, for obvious reasons. So we’ll see.

To be clear, this isn’t an early access version of Gunmetal Arcadia, nor is it a demo. These are separate, standalone products. They are companion pieces, complementary in nature but each a complete experience in its own right.

As I mentioned above, I don’t have a name for this thing yet, but I’ve been tossing around a few ideas. If you’d like to help me pick a name, I’ve put together a short survey (one multiple-choice question) where you can vote on a title. I’ve provided a few suggestions of my own, but you’re free to write in any others.

This blog post is verging on 100% overlap with Wednesday’s upcoming video, so I guess I might as well mention a couple more things. Next Thursday, August 20, I’m going to be making a small support update to You Have to Win the Game to finally add support for 32-bit Linux (and not at the expense of 64-bit distros this time) and to add an upsell blurb for Super Win to the title screen. This will coincide with a weeklong sale on Super Win and also with the launch of my Patreon campaign, which I feel like I’ve been talking about endlessly and never actually doing.

Finally, a few words on in-dev builds. I’m not really happy with the way these have turned out, so I’m changing things up a bit. I’m going to be scaling back the frequency of in-dev builds from once a week to probably either biweekly or monthly, depending on how often I have substantial new material to show. I don’t feel like these have been serving their purpose well, as recent week-on-week deltas have been superficial at best. By publishing these on a less frequent basis, I’m hoping to make them more meaningful. Each one should represent a significant change from the previous. I’m also going to be turning these into a Patreon reward. I haven’t decided yet whether they’ll become freely available after a period of time or whether they will remain patron-only content indefinitely, but in any case, patrons will have first access to this content.

So there. Two games. Huh.