We’ve reached a bit of a milestone this week with Project Skyring – we actually squashed our last known bug.
Although this state won’t last for long, it touched off a little celebrating because we are about to dive into a completely new, and potentially challenging stage of the game’s project development: changing the hand-placed maps with giant objects into a seed-generated grid.
The reason we’re happy to be bug free is that bugs in any development tend to have a snowball effect, and, even when they don’t, they become more and more difficult to fix as the project gains in complexity. Not to mention, the project itself becomes more and more difficult to keep in human memory the longer it progresses.
Every object is a brick, and every function is mortar in a development project, and as time goes on you continue to stack them long enough to build whatever house or cathedral you were attempting. Bugs are like cracks. The more other pieces of the project depend on something that’s not quite working right, the more likely things are to fall apart. And when bugs begin to spawn new bugs, the whole project could easily fall apart.
With Project Skyring, we had two very difficult bugs we had to squash. The first, was making sure that the circles the player created only destroyed enemies within the circle. This was difficult because the player could trace any arbitrary polygon they wanted and close it whenever they wanted. We had to make sure the space we tested for enemies was only the space within the closed polygon, and, though the concept is simple, getting GameMaker’s ds_lists and ds_maps to cooperate wasn’t. We eventually had to unstack a lot of our bricks and redo them to get to the heart of the problem: trimming the list of coordinates in the polygon.
The second bug – the one we solved this week – was the randomly disappearing anchor points problem. As the player circles around, if they go far enough out, they drop an anchor point (one of the points in the polygon used in circling). These points are critical because they’re what allow the player to destroy the enemies they surround (the core mechanic). Unfortunately, they seemed to disappear en masse at random intervals. So long as this problem existed, the core mechanic was left unreliable, which means it wouldn’t be any fun for the player. After all, how would you like playing Super Mario Brothers if every once in a while Mario didn’t jump when you pushed the button? We eventually gained an insight into the timing of the seemingly random bug: the anchor points disappeared when enemies were destroyed. The effect wasn’t so noticeable when enemies were being circled and destroyed, but it was noticeable when the enemies hit sunlight or the player and self-destructed.
With this hint, we started digging into the enemy class. Unfortunately, there were no places where we were calling a destruction event, or anything for that matter, for the anchor points. They were completely unrelated.
There were no obvious solutions, so we started to look for less obvious ones, starting with anything calling a destroy event. We used the oldest programmer’s friend of pasting debug messages everywhere and eventually discovered that, within the section that was destroying the list of enemy connections (the lines between enemies), anchors were getting into the connection list.
Our next step was to try to find a place where we were adding anchors by mistake, but we had no luck with that, so we moved on to the second oldest programmer’s friend: commenting out lines. We found that there was nothing in the enemy object itself that was causing problems, but when we moved to the enemy line object, we noticed that commenting out a few lines in the destroy event didn’t change anything.
Ah, the destroy event. Although there doesn’t appear to be anything warning of problems with it, we discovered that once we moved the exact same code out of the destroy event and into something called before it, everything worked fine.
After we did, memories of problems caused by Destroy in Project Spaghetti wafted back into our minds. Whether it’s a bug with the way Destroy works (doubtful), or whether it works as intended, but those intentions aren’t well conveyed to us, we’re not sure, but we will be very careful of relying on this event in the future because it seems a little unreliable, and, until we know the rules for what works and what doesn’t, we need to be careful.
But, with those two bugs out of the way, we are free and clear to begin on the map generation next episode.
We’ll likely start with creating a variety of basic hex tiles (open land, mountain, forest) and then lay them down on the map.
Once that’s done, we should be able to transfer the properties of the existing objects (“land”, “mountain”, “tree”) to the hex tiles so that the game goes back to behaving as it did before the change.
From there, we’ll need to move on to generating the tiles, which requires setting the rules for which tiles get placed where, next to what, and in what rotation.
Then, we’ll have to save all of this information to data as players explore the world and try to optimize the tiles so that the bare minimum needed for the game are active at any one time. The last thing we want is a giant world with millions of objects just sitting there not doing anything.
To get us started on thinking about laying out a hex grid, we came across this excellent blog post by Red Blob Games.