Purgatory Purgers: Level Design

What Should a Level Look Like?

In my last post, I solved a major collaboration issue by figuring out how to export/import individual rooms in GameMaker Studio 2.

Since then, Eric and I have been creating levels to round out the game, and with a little over an hour’s worth of content, I’ve been looking at some of the larger levels to see which parts I can cull so that the game doesn’t get dull/outstay it’s welcome.

Level design is difficult to do well. Purgatory Purgers’ level elements can be broken down into a few different components:

Features

At its heart, Purgatory Purgers is a puzzle-exploration game. Each level is a series of interconnected rooms of varying shapes and sizes and could include:

  • Gambits: Rooms with one or more dangerous enemies
  • Treasure Rooms: Filled with lost souls (the primary objective of the game/scoring system) and free lives
  • Puzzles: Moveable blocks, bridges, etc.
  • Secrets: Hidden rooms and passages marked by a small crack in the floor or an odd-looking bush.

These aren’t mutually exclusive and could be combined to form interesting and progressively more challenging areas.

Flow

A good level shouldn’t railroad the player down a specific route; instead, there should be 2-3 branching paths and reward players for exploration with additional lives and/or hidden shortcuts through the level.

Embellishments

To bring the Purgatory Purgers levels to life, I created lots of additional tiles to add flavor and mystery to each set of levels. Locked doors, sewer grates, pools of water, grass, grates, blood spatters, arcane symbols, and even emptiness in the later levels.

Putting It All Together

A good level combines all of the above to form a cohesive package; the level is:

  1. Good looking (i.e., makes good use of the available tileset and avoids excessive repetition)
  2. Intuitive to navigate (it doesn’t require a lot of backtracking)
  3. Sufficiently diverse in enemies, puzzles, and mechanics
  4. Above all, fun to play (read: sufficiently challenging, but not too difficult)

Stepping Stones and a Clear Path Forward

Building on an Unstable Foundation

As we draw closer to a working prototype, it’s become increasingly more apparent that there are some fundamentally flawed issues with the way we’re going about implementation.

Eric is new to both programming in general (save for some college level coursework a few years ago), and GML. All in all, he’s got about 4 or 5 weeks worth of experience in total, but no formal training. As such, he doesn’t have a solid foundation of knowledge to build on, forcing him to seek out tutorials (usually YouTube videos) which give him ideas as to how a thing can be done.

The most popular videos are more akin to “Let’s Plays” with little (if any) structure, and even fewer explanations as to why the developer elected to go about doing things a certain way.

This forced Eric to look at what the other developer did, attempt reproduce it, then reverse engineer it without understanding what each piece’s purpose – trying different arrangements and configurations until it worked (or at least appeared to).

What troubled me was that sometimes I’d ask for a seemingly trivial feature only to find that he was unable to work out how to program it, and compromised with an implementation that wasn’t up to spec.

For example, instead of using keys 1-6 to toggle a different weapon type, and Ctrl to fire,  he mapped weapon type 1 to key 1 because from a logic standpoint, he had no idea how that would work, let alone how to frame the problem so that he could look it up.

Another example was the breakable wall from my prototype specifications in the last post. What I asked for was for wall, when placed, to take damage when it collided with the enemy, and update it’s animation frames to show progressively more damage before being destroyed.

Because he didn’t understand how variables worked, the wall was killing the enemy rather than the other way around – my suspicion was that he didn’t use the “with other” construct to indicate that it was the wall taking damage, not the enemy as they both had an instance variable called “hp” (i.e. hitpoints).

After a few more hours of working on it, he came back and this time the walls were taking damage, but being destroyed after only a second or two. This was because he was using the image_index property to advance the frames of damage to the wall sprite, destroying the object when it reached the end of the animation, foregoing hitpoints altogether.

Since the room speed was set to 30 (i.e. 30 cycles/second), the enemy was colliding with the wall 30 times a second, causing the wall to cycle through each frame of its sprite sheet within a fraction of a second. While this “appeared” to work, it in fact did not follow my design specifications (no hitpoint system) and was therefore not fit for purpose.

I suggested how this could be solved in pseudo code, but he insisted he tried that and it didn’t work – again, probably because of which object he was calling the variables from, but I didn’t know that either at the time.

So where could we go from here?

You Don’t Know What You Don’t Know…

The root of the issue was that while I understood the basic logic I wanted to use, I didn’t have the syntax for it, and neither did Eric. We needed to take a step back and learn the basics before trying to implement big, hairy, complicated features.

So again, I took to YouTube – we’d watched several of the Let’s Learn GameMaker: Studio channel’s videos, lots good information covering what was available and what options there were for each feature, but there was no practical application of those lessons; at at the end of the lesson, there was no example of a typical use case for that feature in your game

A Clear Path Forward

Just when I was about to give up, I managed to stumble upon another channel aptly named, Gamemaker Game Programming Course.  The channel is a bit confusing (the playlists in particular) until you work out that it’s actually just a video repository for his website:

www.gameprogrammingcourse.com

Start there, download the resource packs and project files, then start with the playlist labeled: Level 02 [ GameMaker Basics Sprites Objects Events ].

The site and videos were created by computer programming teacher named John Janetka for his high school’s computer science program. The quality of the content and structure of the lessons are the best I’ve come across on YouTube thus far.

By the end of Level 02, I was able to solve both of the programming issues Eric was struggling with above, and created two games in the process. Simple as they were, the experience was valuable.

I’d asked Eric to place his programming efforts on hold to go through this course with me. I asked him to try not to think of this as a step backward, but rather rather a stepping stone forward toward better, more stable code. He agreed, and will continue to check in every day or so to share what we’ve learned.

###

Image Credit: “Martyn B

Disclaimer: I have no affiliation with any of the websites, applications or YouTube channels referenced above.