B Is For Bonus


I got a little bit ahead of myself in the last blog post and missed talking about a key area of technical discussion: what we did with a third dimension in An Altered Course. In this post, I would like to talk a little bit about some very specific ways we used the third dimension in An Altered Course and how we achieved those features from a technical perspective.

Part 1B: Where We Came From

As discussed in the last post, AAC was developed with RPGToolkit and its layer-based 2D game engine. With this system, all components of the game are subdivided into discrete layers for independent handling of physics and rendering.

Rendering Objects Across Layers

Although I described RPGToolkit as splitting the game into layers for rendering, I didn't particularly note that on each layer the engine will render first the background image and then the "item" and "player" sprites in y-axis order (as discussed in some length in an older post about layering). This is one of the features that using an engine like RPGToolkit buys developers so that they don't have to implement the feature themselves. As you will see in some of the screenshot examples, this engine also adds a fancy feature of re-rendering important sprites like the player again at less-than-100% opacity so that it still shows when it is behind something else. However, RPGToolkit does not know how to render sprites across multiple layers; so we had to do some extra work in level design to make tall object render properly.

In this first shot, you can see an example of these tall trees that were present all over the place in AAC. The player renders properly in front of the tree, and one tree renders properly in front of another tree. So far, this capability could be accomplished simply by making the trees "items" on the same layer as the player.

But in order to generalize this concept to work when there are more layers involved, our solution was to split the tree sprites across multiple layers. Generally, we would split these large trees into three different layers so that the trunk was put on layer 1, the middle section on layer 2, and the top part on layer 3.

In the example of this red region, the boardwalk is on a higher layer than the ground. (SPOILER: You can walk under it in this section.) Therefore, the trunk of the tree is on the ground layer, and the middle and top on a layer above the boardwalk. Although we don't have a screenshot for the particular case, this setup would allow the player to walk in front of the tree on the ground layer and the sprites still be rendered in the appropriate order.

OK. You probably could have figured out that part yourself, but what makes this scheme really work out alright in AAC is that everything in the game is tile-based. The blue player in the shot cannot go any closer to the fence either downward or rightward because the fence tiles completely block his movement there. Because of this artificial and somewhat unnatural division of the world into distinct square tiles, it is relatively easy to ensure that there are no impossible rendering situations when it comes to tall objects overlapping each other on different layers.

Stairs

Multiple layers are good for nothing more than fancy graphics if you can't move the player between layers. So early on in development of AAC we had to start tackling the problem of "stairs" to navigate between layers. Inspired by some default stair graphics, our early attempts turned out like this:

In this method of stairs, the tile with the stairs graphic is triggered to take the player to the layer above when they step onto it from the ground layer and to take the player to the layer below when they step onto it from the boardwalk layer. The code for this setup was trivial, and the level layout easy to set up. Part of what made this method so tantalizing was that, in RPGToolkit, y coordinates are exactly the same on every layer.


Let me digress for a minute and explain what I mean about the coordinate system, since this will be important for some future discussions:

In a 2D game, coordinates are most naturally represented with the following system:
  • (0, 0) is the top left of the level
  • positive x is right and positive y is down
  • the unit of measurement is the pixel, which corresponds to the actual pixels of the images being drawn

So when I say that y coordinates are exactly the same on every layer in RPGToolkit, I am saying that any given x and y coordinates on layer 1 represent the same location on the screen as the same coordinates on layer 2


(Back to the stairs...) There are two obvious problems with the simple method of creating stairs:
  1. the player doesn't graphically follow the contour of the stairs
  2. the player has to completely move off the of the stairs tile before using the stairs again (i.e. If the player steps onto the stairs going up, he cannot step down off the stairs. The player can only go back down the stairs after getting off of them onto the upper layer.)
I realized later that there is an easy answer to the two problems with the simple stairs method:
  1. Don't use diagonal stairs in a game that doesn't have diagonal movement.
  2. Split the stairs event boxes into two (separate tiles)
With this solution, the player experiences a smooth transition between layers without graphical oddities or awkward functionality. Under the hood, though, these type of stairs are a lie: neither gradually adjusting the elevation of the player nor instantaneously transporting them to a different layer. We may revisit later why this is potentially a bad thing.

Falling Off Cliffs

As mentioned in the last post, falling off of cliffs was a gameplay mechanic AAC stole from some inspiration games. There were essentially two variants of this mechanic in AAC:

Simple Drops
Falling Through Holes

For the simple drops, we just allowed the player to walk onto the tile of empty air in certain spots on upper layers. When the player would enter this tile, a short program would drop the player to the layer below and do a fancy animation to offset the player's y coordinate (+32 pixels) to account for the change in elevation graphically.

For falling through holes, each hole tile would trigger a program when the player stepped onto the tile. If the hole was large enough, the program would transport the player to the alternate level for the lower part of the cave. When the player entered the lower part of the cave, some other code would check to see whether the coordinates were valid for an upper layer or lower layer position and put the player on the appropriate layer.

Unfortunately, this one-to-one mapping of upper to lower cave tile coordinates had a flaw: What if the player fell onto one of the wall tiles?

In this event, the program had a special case to push the player downward (positive y axis) one tile (32 pixels).

Stepping Stones

Yet another 3D element used in AAC is that of stepping stones for upper layers. We had two dominant manifestations of this mechanic in AAC:

Literal Stepping Stones in Water
Pushable Pillars

These mechanics in the game really started to show how limitations of a particular game engine start becoming difficult to work around when trying to accomplish something outside the scope of its intended types of games. In RPGToolkit, since everything exists in flat layers, every location is either blocked or traversable, and every object (like the rock) is just solid. RPGToolkit has a concept of "vectors" which represent collidable polygons set on some layer in a level that are either non-traversable or that trigger specified code to run. There is no notion of traversable space with no ground under it. Since the two mechanics are related, I'll focus on the pillars because of their higher difficulty and stronger relationship to 3D.

So how did we solve this problem? Well, the answer is complicated, but I'll try to explain it in short.

First of all, we covered every tile that we wanted sometimes to be traversable with a blocked/solid vector that was the exact shape of that tile: 32x32. This meant that every tile of water that could have a rock dropped into it got its own square vector, and every tile of open space above where there were pillars got its own square vector. Starting to see the hackaround methodology yet?

Second of all, we actually split each logical layer of the game into multiple layers in the engine, such that every logical layer had one engine layer for background graphics and one engine layer for invisible info tiles. We needed this extra layer of invisible tiles because it was a lot easier in this engine to check what tile was rendered at a certain position than to check what vectors were present there.

Finally, every time the player ran up against a pillar, the code would

Conclusion

2.5D games can achieve certain effects of 3D in a 2D game engine based on layers, but implementing the features is often a significant ordeal because of the workarounds required. This post should have illustrated some approaches to solving some common problems for desirable game features in 2.5D games, and I personally think that even the developers of the inspiration games (e.g. A Link to the Past and Golden Sun) would have used techniques similar to these to execute that extra .5D in those games. I also hope that this post begins to show some of the reasons why having a more robust 3D game engine is desirable over a more purely 2D engine, but a further analysis of those reasons will have to wait for the next blog post.

Shout out to ezgif.com for enabling me to prepare the awesome GIFs in this post. I would highly recommend 10/10 based on first experience.