The world of Patch Quest is made out of “Patches”. These Patches can slide around independently, entering and leaving the screen as needed. They help break up the map into self-contained chunks and they also provide an intuitive kind of “fog of war”. I think they’re pretty cool!The player can only see a 3×3 grid of patches at any point in time. As they move, some patches will slide out and new ones will slide in. This part of the world is full of Sumo Toads and Spearanha.
But programming all of this turned out to be pretty challenging. In most games you only need 3 numbers to represent an object’s position (the X, Y and Z coordinates). But in Patch Quest things aren’t so simple. The Patches pose 2 major issues:
1) The terrain is repositionable. Since Patches can be moved around independently, the world is essentially a collection of moving platforms. This makes it tricky to have absolute reference points.
2) Space is non-uniform. The Patches have borders, meaning the distance between two adjacent tiles is different depending on whether you cross a border. This makes it tricky to find paths between tiles.
In this article I’ll be breaking down how I solved both of these challenges. Let’s get started!
To describe the world of Patch Quest I use an analogy to boardgames. Patches are arranged in “boards”, and these boards are placed on a “table”. Boards are just a handy way of grouping patches together. For example, a floor of a dungeon is one single board. The overworld, on the other hand, is made out of a grid of 3×3-sized boards.
Here are 2 overworld boards (red and green) placed next to each other on the table.
Most games use a single, absolute coordinate space to describe where things are. But in Patch Quest there are 3 coordinate spaces: Patch space, board space and table space.
Patch coordinates are relative to a particular Patch. The center points of that Patch’s tiles are at 0, 1 and 2 (meaning the edges of the tiles run from -0.5 to 2.5).
Above this we have board coordinates, which are relative to a board rather than a Patch. And above this, we have the absolute table coordinates (they are not relative to anything).
We can convert between these spaces quite easily. As an example, here’s the code for converting Patch space to board space:
By converting between these coordinate spaces we can get an absolute position for every object in the game – even when the Patches or boards are being moved.
Suppose a creature is on the right-hand side of an overworld board, and we want to move it 2 tiles further to the right. This will move it onto another Patch (and onto another board). Here’s how we can figure out the new location:
Every creature knows its current patch coordinates (they’re just its location relative to the patch it’s currently standing on). We convert these coordinates all the way up into table coordinates, giving us an absolute position. We then move these table coordinates 2 tiles to the right by adding the vector (2, 0, 0). Now we can convert these table coordinates back down into Patch coordinates, giving us the final position. We can then reparent the creature to this new Patch and position it over the correct tile.
If the Patches were moved around on the board, this would be taken into account during the conversion from Patch space to board space. The same thing holds for moving boards around on the table. By converting between the different coordinate spaces we can correctly move creatures from one tile to another – even while the world is being rearranged!
There’s still an issue with table space. Two tiles might be right next to each other in table space, but different distances apart in our unity scene. This is because patches have borders, meaning the distance to travel from one tile to another depends on how many borders you cross.
Both red lines represent 1 unit in table space (because you are moving from a tile to an adjacent tile). But Patches have borders, meaning the real distance between two tiles isn’t always the same. The lower line is nearly twice as long in real space despite being the same length in table space.
Solving this is a little bit technical. Let’s all put our programming hats on for this next section!
In the image below, imagine our patch space coordinates are the blue dot (0, 2.5f) and we want to convert it to real space (the blue cross).
We find out how much this value “overlaps” the edge of the Patch (the distance of the coordinate from the tile range 0-2) which in this case is (0, 0.5f). We then scale this overlap value by the width of the border and add it to the patch coordinates. We also need to find the origin of this patch in real space and add that. Here’s the code for all this:
Note: My sensible mod function is a variant of modulo with more helpful behaviour for negative values. Instead of calculating “a%b”, it calculates “((a%b)+b)%b”
There’s one more thing to consider here. Creatures are parented to the nearest tile, meaning their position needs to be relative to that tile. To do this, we calculate their exact real space coordinates (the blue cross) and subtract the real space coordinates of their parented tile center (the red cross). Now a creature can be parented to any tile, with any tablespace coordinates, and be placed in the correct real location.
Phew! That’s the most technical part of this whole operation. Don’t worry if you didn’t follow all that.
We have the correct X and Z positions now, but we haven’t yet found the Y position (the height of the creature above the table). This is fairly simple to work out.
In the image below, we have 2 types of tile: ground and water. These types have different heights (ground is higher than water).
Suppose we want to find the ground height at the point marked with a cross. To do this, we first find the 4 closest tile centers to that cross. We find the height at each tile center (every tile type has a known, fixed height) and then interpolate between these. If one of these tile centers doesn’t exist (because we’re too close to the edge of the Patch) we just use the height of the Patch’s border instead.
The code for this isn’t too tricky. You can see it below:
Okay! Now we take any Patch coordinate and convert it into an (X,Y,Z) vector representing a position in the unity scene.
All this might sound pretty complicated, but the end result is a simple interface for handling location in a repositionable, non-uniform world. Each game entity only needs to know its current Patch coordinates. These coordinates can have vectors added to them, and they will return another Patch coordinate (all the fancy conversions happen behind the scenes). In addition, these Patch coordinates can be quickly converted into a real position in our unity scene – taking into account the non-uniform distances between tiles.
If your game is repositionable or non-uniform (or both!), these tricks may well help you out. But either way, I hope you enjoyed this look under Patch Quest’s hood.
This article is a bit different to the things I normally write. If you’d like to see more articles on how I’ve solved technical challenges in Patch Quest, please do let me know in the Reddit comments.
A major update for Patch Quest released last week. You’re given a scanner that lets you learn about the local wildlife. It also added several new habitats to explore with new plants and creatures to scan. The game can be downloaded for free here, and this video will run you through the full changes.