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.
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.
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.
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:
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
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:
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).
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:
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
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.