Purgatory Purgers: Buggery

Warning: Spoilers Ahead!

This post discloses the locations of some of the secret rooms found within Purgatory Purgers. If you’d rather discover these surprises for yourself while playing the game, you may want to avoid reading further!

A Fresh Perspective

Players are often your best resource for identifying possible bugs, exploits, and missed opportunities (read: feature requests). The week Purgatory was released, I received a lot of feedback and, with it, fresh eyes to point out my mistakes.

I addressed what I could and tabled the rest, save for one elusive bug I could never pin down but appeared so infrequently that I couldn’t get a bead on it. Occasionally, an object or group of objects (e.g., a gem block, ethereal coins, etc.) would go missing from a room, and I couldn’t explain why nor duplicate the behavior. Unable to identify the culprit, coupled with the sporadic nature of the bug, I decided to leave well enough alone…

Recently, a new YouTube channel, “Back to the Past Gaming,” started a playthrough series for Purgatory Purgers. While watching ABitNosthaligic‘s playthrough of the fourth level of Purgatory Purgers, “Stilted Pond,” I was surprised to see that the secret room he discovered was empty:

He suggested it might have been an oversight, and while it’s certainly possible that I’d forgotten to populate the room, the problem was (unfortunately) not that simple… And so, after a 3-month hiatus, I decided to tear back into the code to under, once and for all, why this was happening!

First, Check the Obvious

Looking at the room layout in the GameMaker IDE, I could see the objects had been placed:

So why were they missing during his playthrough? I fired up the game, went straight to the offending level, and made a beeline for the secret room. Upon entering, there were the Ethereal Coins right where I expected them to be:

To try to duplicate the [unwanted] behavior, I did a normal playthrough, and lo behold, the coins were missing for me, too! Progress, at last! But why? What exactly was happening to the coins? Were they failing to render? Were they being destroyed?

So, to begin my troubleshooting, I added the following code to the “obj_oneup” object’s Draw GUI Event:

// Am I here?
draw_self();
draw_text(20,20,"I'm still here!")

Whenever you use custom draw code (e.g., draw_text), you must precede it with “draw_self(),” or the sprite won’t be drawn. The purpose of the draw_text message is to print the string “I’m still here!” in the upper left-hand corner to let me know that at least one instance of the object still exists on the map. Simply put, these two lines of code tell me that the object is both visible and present.

I saved my work, then launched the game, and upon entering the first level, I could see the message right where I expected it:

After collecting the Ethereal Coins, the message disappeared as expected. So, I continued playing until I reached the offending level (Stilted Pond), and after some experimentation, I was finally able to observe what was happening…

Next, Eliminate the Impossible

“When you have eliminated the impossible, whatever remains, however improbable, must be the truth.”
– Sherlock Holmes, The Sign of Four

Whenever I pushed one block into another block, all of the Ethereal Coins in the current room were instantly destroyed. This was true, regardless of level, but I couldn’t yet understand why…

The way I coded movement for blocks, enemies, and the player in Purgatory Purgers was a modified version of my grid movement system, explained here and here. In short, here’s what happens when you “push” a block:

  1. An instance of an invisible 16x16px target object is created 32 pixels ahead.
  2. The block moves toward the target object.
  3. Upon collision, the target object is destroyed, and the block’s movement speed is set to zero, stopping it.

Because we’re using an Instance Variable, it has to be declared in the Create Event, e.g.:

block_target=0;

This variable would later be defined in the Step Event whenever the block was moved, something to the effect of,

block_target=instance_create_layer(x-bdist,y,"Instances",obj_block_target);

In the example above, “block_target” is the variable that refers to the Instance ID of the specific instance of the obj_block_target object we’re dealing with and nothing else! So when obj_block collides with the instance of obj_block_target that it created, i.e., “block_target,” only that instance should be destroyed, but somehow, the obj_oneup was being [mis]associated with “block_target.”

Block movement was one of the first features I coded, and later implementations used the place_meeting function in the End Step Event. So, simply recording it to do that fixed the issue.

I still don’t fully understand this, and after hours of troubleshooting, I am relieved that this was resolved. I have since posted the fix to itch.io as version 1.4.

Purgatory Purgers: Post Mortem

How It Began

Back in September ’23, I announced that Eric and I were working together again after a 7-year hiatus. We’d agreed to start small, and after some initial discussion, Eric committed to taking on the roles of Game Designer and Level Designer. I would do the programming, artwork, sound effects, and music.

When we initially brainstormed game ideas, Eric fondly recalled the time he’d spent playing Chip’s Challenge on an old Windows 3.11 system and suggested we create something like that, starting with the core mechanic of pushing blocks into slots.

Chip's Challenge 🔥 Play online

After some discussion, we settled on a Purgatory theme. Eric proposed two characters, an angel and a demon, each with their own unique abilities. The ‘demon’ (Imp) could push blocks, and the ‘angel’ (cherub) could fly over obstacles (e.g., water).

Eric didn’t remember any of the specifics of Chip’s Challenge, so I watched some gameplay videos and got a very rudimentary idea of how the game worked, focusing first on orthogonal, tile-based movement and then the “Sokoban” mechanic of pushing blocks into designated places.

I didn’t have a clear vision of the art style and started out with the intent of creating 32x32px tiles and character sprites. Here’s an early rendition of Bob:

Although he looks pretty good, the bigger the sprite, the more detailed it needs to be and the more time it would take to create. In addition to the player character, there are also the enemy sprites and tile sheets to consider.

Early sprite sheet designs were 32x32px tiles and single-height, meaning that the tops of the walls were on the same plane. This was simpler but didn’t look very good.

I eventually scrapped this all in favor of simpler, 16×16 tiles with fewer animation frames, akin to something you might see on the NES, albeit a slightly larger color palette (64 colors instead of 52, and support for alpha channel, which wasn’t something the NES could do).

In an effort to work in parallel, I’d asked Eric to block out level designs with primitive tiles that we could later replace as the finalized tile sheets were created.

This worked well initially, but as the tile sheet began to take shape, we encountered two issues that set us back:

  1. Eric’s designs were more complex than what my simple tile sheet was capable of, and absent the correct tiles, Eric would ‘wing it’ with the ones he had.
  2. The levels Eric created assumed features we hadn’t previously discussed. I was still working on the core mechanics and did not even have a working prototype of the basic gameplay yet.

In order to get this under control, I knew that I needed a playable game, and by mid-September ’23, I had one. I asked Eric to build a simple test level so that we could play the game. Here’s what that looked like:

The First Prototype

Having a working prototype can teach you a lot about your game. Is it fun? Does the core gameplay loop (i.e., the thing the player does in the game) work the way you expected? Is it complete?

I watched the Extra Credits video series on Making Your First Game. I’d watched dozens of GDC videos on game design. I knew that our focus needed to be getting the game to a playable prototype so that we could see what worked and what didn’t. I knew this – Eric did not…

How could he? He’s never made a game before. To him, game design meant thinking up cool ideas. That’s only natural, as that’s how a writer might approach the problem. A game designer needs to be able to articulate, in great detail, the logical systems that make up a game, the rules, for instance, and how to resolve problems you might encounter.

Take the angel for example. In our original discussions, we wanted the angel to be able to fly over water, so I focused on getting that mechanic working without thinking about why. In order to facilitate this, I had to create a test level and realized that simply moving to areas the demon couldn’t get to on his own wasn’t all that interesting – then it hit me…what about a bridge? What if the angel could lower bridges, allowing the demon and a block to reach places he couldn’t previously access?

This would not have occurred to me without actually playing the game.

Iterative Refinements

Initially, the movement system I created moved the character one space per key press. This worked fine on small levels, but with big, expansive ones like the test level he’d created, it was very fatiguing. To address this, we opted for continuous movement.

The more I played, the more I realized that half the fun of the game was exploration and collecting the souls, and the other half was the puzzles, but you had to have both. You can read more about Purgatory Purgers’ level design philosophy here.

As we talked through new features, I tried to corral Eric’s ideas into building on existing mechanics to create more value, using the example of secret rooms and passageways. The mechanic behind this reuses the water tile in a novel way. Eric suggested “hiding” the secret room, but there wasn’t an obvious way to do this due to the ‘skybox’ background we were using at the time.

By scrapping the sky tiles in favor of a plain black background, we could use an opaque black rectangle that’s destroyed on contact with the player to reveal the secret area. This was both easy to implement and highly reusable!

Creating the UI

We knew that we were going to need a UI for the game, so we discussed what should be in it, and Eric went to work on a simple mockup. Here’s what he came up with:

We initially discussed a scoring system in which the player earned points based on souls collected, gems slotted, completing a level, and number of moves made. Our game resolution was 480px wide by 270 pixels tall (1/4 scale of a target screen resolution of 1920×1080 in a 16:9 aspect ratio).

I found that even using the smallest font I could find (~5x5px per character), it would be impossible to cram all that information into such a small area. To get a sense of proportionality, I started with a simple shape and put it on the playfield:

As I began to play with designs, I arrived at something closer to the final one but found that placing it over the playable map didn’t look (or feel) good:

Moving it 16px to the right and adding a black background seemed to do the trick, but I also modified the camera (which was set to follow the player) to include a buffer equal to half the width of the level to keep the player centered on the screen – this would prevent the player from getting behind the black border (128px or approximately 8 tiles):

With the general layout done, I had to figure out how to populate the information it contained… More tweaking! I scraped the score (we didn’t have a solid design, and it felt a bit arbitrary), making more room for other elements. I also decided to stretch the UI a bit vertically to make more room for label text:

Finally, I added the animated ‘judged soul’ graphics, which brought it all together:

I noticed there wasn’t much room for the soul counters, so I incorporated some additional code to change the font once it reached the triple digits, but that came much later…

Mid-Development Hell

By October ’23, the core of the game was finished, save for creating a menu system, secret levels (and a system for accessing them),  and additional levels to flesh everything out. Eric and I argued frequently.

We could not agree on a shared vision for the game, what a level should look like, or even the definition of Game Design!

For example, Eric spent what might have been several hours creating a very faithful rendition of the Pacman maze. While very well done (for what it is), it did not fit the theme of our game (not to mention possible copyright infringement).

pacman
Purgatory Purgers II: Copyright Infringement!

Then there were the logistical obstacles… I had Eric create the levels in Tiled, and then I’d recreate them by hand in GMS2. This meticulous process took hours because each level comprised several tile layers (e.g., Walls and floors, decorations, water, object instances, etc.).

As the month came to a close, I was nearing my deadline for completing a very difficult certification Exam for work, so I put my development efforts on hold for the next 2 months to focus on that.

The Last Mile

At the end of December, I passed my Exam and was ready to resume work on Purgatory Purgers. Over the next few weeks, I started investigating ways we could improve our workflow and allow Eric to create levels directly in GameMaker.

My first thought was to try to implement source control, but not knowing what I was doing almost ended in disaster. I kept at it and was eventually able to work out how to import room resource files.

Although we’d overcome the technical hurdles, Eric wasn’t used to using GameMaker as all of his previous work was mocked up in Tiled,  and then (re)created by me. Naturally, Eric did not create levels as quickly as he could in Tiled, nor were they of sufficient detail to meet the current standard. This isn’t to say that my levels were perfect either, and in fact, after playing through the game over and over again, I ended up redoing my first level and making significant cuts to other levels I felt were too bloated.

“…[sometimes], You must kill your darlings.” – William Faulkner

I came to the grim realization that Eric and I had fundamental disagreements that wouldn’t get resolved in this project. Eric had lots of ideas, but the concept of testing them and killing off the ones that didn’t make the cut was abhorrent to him. He placed a lot of value on his individual ideas as well as his ability to generate them. Still, he did not understand that the idea itself represented a tiny fraction of the overall effort required to execute it. Our imaginations are limitless; my time and abilities are finite. Sometimes, you must kill your darlings!

The only way forward was to create the remaining levels myself, along with the endings, menu system, and artwork, which I spent the next few weeks working on. By the middle of February ’24, I was done!

I took a few days to recover, then went back again to finalize it for release.

Publishing Purgatory

I originally intended to publish on GameJolt and Itch.io and advertise in the official GameMaker forums.

Unfortunately, I couldn’t edit the content on my GameJolt Developer page without encountering an “ERR_TOO_MANY_REDIRECTS” browser error. The platform is covered in ads, which suggests it’s either dead (or dying), so I decided to abandon it and move on to Itch.io.

Itch.io turned out to be a good choice. It is simple, easy to use, and straightforward. I captured a few screenshots and then spent about an hour creating a YouTube video to promote it. I spent a couple of days creating an old-school-style instruction manual and packaged it with the game.

Posts in the “Made with GameMaker” thread on the official forums require moderator approval. What confused me was that my post was initially visible to me and then disappeared later, leading me to believe it had been deleted. Thankfully, after reaching out to the moderators, I was assured that hadn’t happened, and a short while later, my post went live.

Reception and Payout

The only people who played and/or bought the game were a handful of personal friends, acquaintances, and a couple of kind folks from the Official GMS Forums. Jason D., John J., and others pointed out bugs and potential exploits, and I fixed what I could.

Overall, I spent about 480 hours on this project over 8 months. The proceeds were around ~4.2¢/hour (gross, 3¢/hour net).

Lessons Learned

Communication was a constant problem for Eric and me. Because we had different schedules, we could only speak in real time once per week. Between our weekly calls, I’d try to share my thoughts on progress with Eric through Discord messages. My DMs to him were too verbose, and his responses were too succinct.

It was difficult to discuss complex design topics this way. Often, a conversation would begin with, “Would it be possible to do [insert_feature_here]?”

I read somewhere about ‘Mu,’ the third answer to a Yes or No question, and it can be interpreted as “Your question cannot be answered because it depends on incorrect assumptions.”

A lot of what Eric was asking about sounded simple and straightforward, but it usually lacked sufficient elaboration to explain exactly how it would fit into the game. When I asked Eric if the juice was worth the squeeze, I was trying to convey to him whether he wanted me to pause work on implementing core game features for the one-off feature he was asking about.

From my perspective, Eric’s question was lazy and uninformed, and from Eric’s perspective, I was dismissive and impersonal. While we eventually talked it out, it took a lot of heated arguments to get to that point.

For me, Purgatory Purgers was never intended to be my magnum opus; instead, it was one more step towards learning how to be a game developer. Eric had more faith in the project than I did, but as far as I can see, that faith was more wishful thinking than anything else. Would I be upset if Purgatory Purgers was a runaway success? Absolutely not, but I also understand that some games, charming though they are, don’t have mass appeal and never will.

I guess the biggest takeaway is that my next game ought to be more memeable :).

GameMaker Studio 2: Exporting/Importing Rooms

Background

I’ve been looking for a way to allow another user to create rooms for my existing project using templates I’d created with consistent instance, tile, and background layers.

After my experiment with source control ended in disaster, I decided to shelf that for the time being and try a simpler approach:

Procedure

  1. On PC1, I Exported the as-is project as a .yyz file (File > Export Project > YYZ) and then saved the file to a network share.
  2. On PC2, I downloaded the [MyProjectName].yyz file and Imported it (File > Import Project > Path\To\.yyz file).
  3. I updated the project on PC2 by creating a new room, and then I saved the project.
  4. I opened File Explorer on PC2 and browsed to the project’s rooms subfolder (i.e., C:\>Users\[MyUsername]\Documents\GameMakerStudio2\[MyProjectName]\rooms).
  5. I located the corresponding folder to the new room I’d created, then copied the room2.yy file back to the network share.
  6. Back on PC1, I created a subfolder in my project with an identical folder name and then copied the room2.yy file to that location.
  7. I opened GameMaker Studio 2, right-clicked in the Asset Browser, and selected “Add Existing“. After navigating to the room subfolder from the previous step, I selected the .yy file and clicked “Open.” Nothing happened!

At this point, the rooms list didn’t update with the new asset, nor did I receive an error.

The Missing Step

After opening the game’s project file (.yyp) in a text editor, I could see a list of resources, including rooms, along with their relative paths:

"resources": [
{"id":{"name":"room1","path":"rooms/room1/room1.yy",},},
],

What I did not see was an entry for the new room I created, so I simply appended the list with the new room:

"resources": [
{"id":{"name":"room1","path":"rooms/room1/room1.yy",},},
{"id":{"name":"room2","path":"rooms/room2/room2.yy",},},
],

Towards the bottom of the list is the room order, which I also appended:

 "RoomOrderNodes": [
{"roomId":{"name":"room1","path":"rooms/room1/room1.yy",},},
{"roomId":{"name":"room2","path":"rooms/room2/room2.yy",},},

After saving and closing the text editor, I fired GMS2 back up, opened the project, and after an agonizing minute or so of loading, the project opened without error!

To my delight, there sat the imported room in the asset browser. I double-clicked it, and there it was:

Alternatives Considered

Someone on the official forums had suggested having Eric submit asset packs – I have no idea what that means exactly, but he seemed to suggest this was less than ideal.

Eric’s original levels were created in Tiled, and then I’d manually recreate them in GMS2, which was inefficient and very time-consuming; however, I’d heard that there were tools that could convert a Tiled map to a GMS2 .yy room resource file but couldn’t get it to work properly with my project. This is because our maps utilize multiple tile layers sandwiched between an instance layer (where the objects live) and the background layer. Most of these tools assume you are working for a single tile layer to another single tile layer, and none of the address how to get the room.yy file back into your project.

Caveats and Disclaimers

  • In order for this to work, all of the resources used in the room (i.e., objects, sprites, tilesets, etc.) must be present and unchanged in both the source and destination projects
  • GMS2 is known to not play nice with Cloud-synced project folders, so make neither system

Purgatory Purgers: Git Thee to a Repository!

Doing Things the “Right” Way

I’ve worked alongside development teams for most of my professional career, and they all used source control. So, if I wanted to do things the “right” way, I also needed to use source control [with GameMaker Studio 2]. But alas, the map is not the territory, and you really screw things up if you don’t know what you’re doing. I didn’t know what I was doing.

Initial Setup

Although GMS2 offers [limited] native support for source control, it seemed simpler (and easier) to install GitHub Desktop and point it to the project folder.

Using this method, I was able to upload an entire project to GitHub, then install GitHub Desktop on another PC and clone (download a local copy of) the entire repository (i.e., the project folder) onto the second PC.

Once I got it working to my satisfaction on my end, I went ahead and walked Eric through it over Discord/screen share.

Where It All Went Wrong

Eric volunteered to clean up the tile layers of several maps – little mistakes where the incorrect tile was used for a given room that needed to be updated. Eric and I both thought that he’d pushed these changes to the repository, but the mistakes were still present.

Initially, I’d assumed these were regression problems that Eric introduced, but after looking at the same levels on my second PC, I realized these problems were present in older versions of the project, meaning Eric’s updates didn’t get pushed.

By then, I’d already fixed these problems on my end and pushed the updates to the repository. When Eric introduced his changes on top of mine, the levels were suddenly missing.

Recovery

After quite a lot of troubleshooting, I eventually decided to make a backup copy of the broken project, export the backup I had on my second PC, and then manually redo the changes I’d made over the last 24-48 hours.

This worked, and I was able to get back on track despite losing a day of productivity.

Lessons Learned

In troubleshooting, I discovered:

  1. Eric’s project folder was being synced with OneDrive, which I later learned could cause problems with GMS2 Projects.
  2. We were using different versions of the GMS2 IDE, which is also a bad thing.
  3. You have to be very careful when merging changes, as this can cause problems for individual resource (.yy) and project (.yyp) files.

At this point, I’m going to abandon source control for the time being in favor of something I know (traditional backup), but I may revisit it later…

Revisiting the Triple Threat

About ten years ago, I distilled video game development into three core skillsets (i.e., the triple threat):

  1. Art
  2. Music (and sound effects)
  3. Programming

I’ve always been interested in art (drawing, sculpting, and to a lesser extent, painting). I taught myself how to play simple melodies on a cheap Casio keyboard in my teens. I learned to use, repair and maintain personal computers in the early 90s out of necessity (I didn’t have much money, so my choices were to fix it or do without).

Eventually, I started entertaining the idea of combining my love of art, music, and computers to try my hand at making video games instead of just playing them. Thus began my journey of self-discovery.

Art

I’d always been able to draw relatively well by hand. I lightly scribbled rough shapes, then fleshed them out with strong lines. As technology became more accessible, I’d digitize my art using a flatbed scanner.

I even purchased a digital camera and some clay in the early 2000s to sculpt models and photograph them from different angles in much the same fashion as Adrian Carmack did for DOOM. I could never get the hang of 3D modeling or translate these analog skills into digital media. In time, I abandoned that track in favor of pixel art.

At first, I was terrible at it. But by studying examples, watching tutorials, and practicing, I developed proficiency using Pyxel Edit. I started with a 16-color EGA palette, then later expanded this to the 52-color NES palette.

This has become my niche and primary medium for artwork creation. Tile sheets are relatively quick to make, which is important when you’re a one-man operation. There are 40 years of examples to draw upon for inspiration.

Music

I’ve been writing music for almost 30 years on the Amega Module format, beginning with tunes written on Fast Tracker II using samples ripped from other people’s files. Later, I sampled some high-quality instruments – these were used in the publication of my first album.

Unfortunately, the songs and samples used were lost to time, but I still have a 20-year backlog of my previous work,  dating as far back as 1997, all written for games that existed only in my imagination.

These days, I use a Windows port called “Skale Tracker.” It’s based on FT2, can export to .WAV and .OGG formats, and supports up to 64 tracks (although I rarely need more than eight these days and write chip tunes with half that). I’ve mixed and mastered my exported works in Audacity and have been very satisfied with the results.

Programming

Programming has always been my biggest weakness. I’ve never been the kind of person who can read a book on a subject and put that knowledge into practice. At best, I can look at examples, then adapt those to my needs once I understand how.

Someone once told me that DOOM was programmed in C++ and that I could do likewise. I remember seeing a boxed copy of Borland Turbo C++ at the local Best Buy, retailing for $300. I remember thinking then that if only I had the money to buy it, I’d have everything I needed to program my own version of DOOM. I was woefully ignorant back then…

Many times over the years, I’d hoped to get around my limitations by using a game creation engine,  my first exposure to this was around 1995. I’d gotten ahold of the Pie in the Sky Software’s 3D Game Creation System for MSDOS.

It was a 2.5D game engine capable of creating games slightly beyond Wolfenstein 3D (floor and ceiling textures, angled walls) but fell short of DOOM (no height variable). While I had limited success designing very simple levels, I didn’t understand its limitations or advanced features and gave it up in frustration.

In my late teens to early 20s, I experimented with 3D Game Studio.

I could create primitive shapes, texture them, and use those objects as building blocks to create a castle out of modular pieces. I could render the map and fly through it, but I had no idea how to use its scripting language. I continued to toy with it for a couple of years, but again, I got discouraged as my imagination outpaced my ability.

In 2014, I picked up GameSalad, and created this website. I had no idea what I wanted to create, so I groped around aimlessly in the dark, bumping into bugs and lacking support.

At the time, GameSalad was primarily marketed to Mac users, and the Windows version lacked many core functions. By the time it caught up to the Mac version, they had stopped offering the Standard Edition for free and switched to a subscription model. I didn’t feel comfortable paying for something I wasn’t entirely sure I could learn to use, so I abandoned it and moved on.

I discovered Game Maker Studio in the spring of 2016. I teamed up with my old friend Eric, and we set out to learn the engine. Eric volunteered to do the programming, I would do everything else (artwork, music, design, documentation, project management).

In the early days, YouTube tutorials were our primary source of GMS programming information. Later, I would compare these to “let’s play” videos rather than proper lessons. Thankfully, I eventually discovered John Janetka’s Game Programming Course (GPC). This was a game changer for us (well, me anyway). While the second half of the lessons became disjointed, it was enough to see me through the creation and publishing of my first game.

Unfortunately, I’d run out of time (and money) and had to start working again. Work became all-consuming, and after spending 10-12 hours of skull sweat a day on technical matters, I didn’t have the energy or drive to devote to game programming when I got home. On the weekends, all I wanted to do was sleep.

I tried to pick it back up several times but couldn’t get back into the habit…

When Stars Align

That all changed this year. I have…

  • Started a new job with a pension, so now I have a future and retirement to look forward to.
  • Rid myself of $117,000 of student debt.
  • Nearly paid off my mortgage (8 months to go).
  • Lost 43 lbs. of excess weight through diet and exercise, and I am on track to be back to my ideal weight by the end of the year.

I’ve finally reached a point in my life where I can resume my pursuit of game development now that I have the time, energy, and resources to do so.

More to come…

The Whimsical Whibsy

Ignorantia Neminem Excusa

Years ago, an acquaintance I’d met on a Discord server expressed interest in working with me [in game development]. He went on to tell me about a negative experience he had when trying to recruit a team to work on his ‘game idea’ for him…

That should have been a red flag, but I kept quiet and let him continue… His approach was to create an account on a (now defunct) forum and showcase his ‘ideas’ in the form of a bulleted list of features/characteristics from other games he wanted to incorporate into his own. He posted a single storyboarded scene and spent about a paragraph explaining it, followed by screenshots posted from other games, comics, and pictures of scribblings from pages of his notebook.

At the end of the post was another list labeled ‘MAIN GOALS,’ which was just a list of vague, arbitrary tasks (e.g., form a small team with enough members, sign a contract between members, develop enough concepts needed with the overall project).

Predictably, the responses ranged from practical advice (e.g., here are some books on beginner programming) to outright hostility (i.e., you expect me to work for free?). He was obliged to dismiss the practical advice given to him, arguing that he didn’t have the time to learn how to use development tools nor the money to pay for them.

One of the forum members pointed out that his Steam profile showed 100 hours of playtime over the last two weeks since his initial post, challenging his assertion that he didn’t have time to learn new skills. After some feeble excuses and rebuttals, he relented and asked which tools to look at (remember, these had already been suggested to him). After the previously made suggestions were quoted back to him, he persisted in asking for additional information (i.e., what are the differences between the X tool and Y tool? etc.).

By now, those who responded to the thread had written him off as a lazy troll, and whatever questions he had were dismissed as further evidence of his unwillingness to work for the answers he sought for himself.

###

I’ve come to refer to this young man as a “Wouldn’t It Be Cool If… Guy” or Whibsy for short. Derek Yu refers to them as “…a dreaded Idea Person, stalking the internet for unwitting artists and programmers to make their dreams come true.”

Wibsy didn’t understand that there is no shortage of ideas (or Idea People, for that matter). There is always a shortage of time, money, and talent.

Armchair Game Developers

Recently, I’ve encountered Wibsy under a different guise, the armchair game developer. You know, the one who hangs out on forums, calling for nerfs and radical redesigns of game mechanics while explaining to the rest of us how easy these would be to implement and that any “competent” programmer would be able to do it in an afternoon. All this tells me about this person is that they’re neither a programmer nor competent.

Those who can’t, criticize…

“Those who can, do. Those who can’t, teach. Those who can’t do or teach, criticize.” – Marsha Hinds

Conclusions?

It didn’t take long for Whibsy and me to grow tired of each other. Although it was his decision to break off the acquaintance by putting me on ignore, I obliged him by reciprocating. Although he attempted to re-establish contact a couple of times since then, I decided it was best just not to engage.

How can I help anyone who can’t help themselves?

Porker Let’s Play Campaign – Post Mortem

In the wake a half dozen or so key requests on WeaselZone.com which yielded no Let’s Play videos, I decided to do a post-mortem on my advertising campaign to evaluate what went right and what went wrong.

###

It’d been a little over a year since I programmed Porker: The Quest for Tastiness. That little game was never intended to be a serious endeavor, but rather a means to get some experience creating and publishing a game.

All of that changed on on February 12, when I’d noticed a couple of kids had:

  1. Found that obscure little game on GameJolt
  2. Installed it
  3. Played it
  4. Posted it on YouTube

They did this all on their own, without any prompting, incentive or instruction.
I was so inspired and encouraged by their Let’s Play that I decided go ahead and expand the game significantly into a fully-featured game.

It took about 2 months to finish the game, and I was very proud of the result. We started looking at ways to advertise and I’d settled on engaging the YouTube Let’s Players community. After all, that’s where it all began, right? What follows is how I went about it and what I learned from the experience in hopes that this may help another fledgling game developer…

###

The Popularity Paradox

Although I did not coin the term, “Popularity Paradox,” as far as I am aware (as evidenced by the entire 2 minutes of Google Fu I spent looking) I’m the only person who has applied to the term to this context:

…many indie games become popular because they receive a lot of YouTube coverage from Let’s Players, but Let’s Players tend to only review games that are already popular…

Therein lies the rub! While I sent keys to the usual 1M+ subscriber Let’s Players, I doubted any of them would ever see, let alone play my game. My research seemed to indicate that their backlog of Let’s Play games was dictated by their audiences, usually by popular request via Reddit or some other medium.

So instead, I focused on smaller to medium sized channels, who I hoped would be willing to do a fellow small-fry a solid. Here are the numbers…

I started with the [now defunct] YouTuber Gaming Megalist, a spreadsheet of over 5,000 YouTubers and their demographic information. As I went through the list, I was able to prequalify about 100 or so potential YouTubers, spending about 5 minutes each on their channels to answer the following questions:

  • Do they post frequently (at least once a week)?
  • Do they cover small indie games, or just the ones everyone else is playing?
  • Does their ‘about’ page encourage developers to contact them, or state that they play indie/random/rage games?
  • Do they have an email address?

If I could answer, “Yes!” to all of these questions, they received a..

  1. Personalized message, tailored specifically to them (no mass-mailing)
  2. Game key for Porker to use for a Let’s Play video
  3. Let’s Player’s guide (PDF)

Of those original 100 or so emails sent out, 25 clicked the link to view their key, and of those, 14 claimed their key. Of those, only 3 went on to make Let’s Play videos.

So how do those figures stack up? Well according to Mail Chimp’s Email Marketing Benchmarks*, the Games industry average was a 19.71% open rate, and a 3.19% click through rate.

Since I emailed my recipients by hand, one message at a time, I can’t really say how many of the 100 odd that I emailed a key to actually opened the message, so instead I’m going to consider “key views” to be my open rate and “key claims” to be my click through rate.

Using those metrics, my open rate is 21% higher than the industry average, and my click through rate is nearly 4.5x greater than what I should reasonably expect.

I suppose that a 21% conversion rate (i.e. ~ 1 out of every 5 people who claimed a key made a video). That’s not terrible, but that was result of about 80 hours of work on my part…

I don’t have a full-time PR person, and have no way of distinguishing between people who are serious about exchanging services by helping each other grow versus dishonest scammers who just want something for nothing.

Going forward, if I do hand out keys, I will use a service like distribute() to do it.

Changes

“Time may change me, but I can’t trace time.” – David Bowie

About 8 weeks ago, I celebrated my 1 year anniversary in my new role. A week after that, my manager resigned and I was tapped to take his place. Since then, it’s been a whirlwind of changes and new responsibilities.

By all accounts, this is old hat for me, but the demands on my time have increased significantly, becoming greater and greater as I unravel years of mismanagement and willful neglect.

While I’m very happy in my new position, I am busier than ever, and even less inclined to do anything productive when I get home after 10-12+ hours of skull sweat…

Pressure requires a release valve, and lately, my pressures had been relieved by playing games rather than making them. What’s worse is, these games introduced a whole-new set of pressures and demands on my time – so much so that it felt like a second job, albeit one which I wasn’t being paid to do.

###

While playing games can be fun and interesting, that part fades quickly. What keeps me interested is the social interaction; meeting and spending time with new “friends”. What I found was that for the people I was spending a great deal of time with, the opposite was true – they had no interest in camaraderie, just a person to occupy a seat at the table so they could carry on their game.

Maybe it’s the age gap speaking here, and relationships have given way to instant gratification – maybe I found myself surrounded by the “single serving friends” of Chuck Palahniuk’s Fight Club…

So what did I do? I withdrew…

 

Credits: featured image, “Butterflies” by M.C. Escher

Dreams and Doldrums

“…there is no way that writers can be tamed and rendered civilized. Or even cured. In a household with more than one person, of which one is a writer, the only solution known to science is to provide the patient with an isolation room, where he can endure the acute stages in private, and where food can be poked in to him with a stick. Because, if you disturb the patient at such times, he may break into tears or become violent. Or he may not hear you at all… and, if you shake him at this stage, he bites…” – Robert Heinlein

These days, I find myself short on energy. It’s hard to concentrate on programming when my office is in shambles and there is no shortage of housework to be done: Painting, decorating, yard work, hauling off lots of junk left – some of it mine, but the majority belonging to my former house sitters and their extended family – all of it needs to go!

Despite so much to do I find I have little time or energy to do much of anything after a long day of work… Mostly I just lay about and watch videos until I fall sleep.

When I sleep, I dream. My unsatiated creativity gives way to restless nights of dreams, urging me to return to my unfinished work. Somehow, distractions always seem to overtake me, and before I know it, a whole day is wasted with nothing to show for it but writers block.

In other news, my code-signing certificate has been renewed despite having a few new hoops to have to jump through.

I need to find inspiration, and I need to organize my office into something conducive for productive work.

Transition

“Use a superior development system than your target to develop your game.” – John Romero, Early Id Software Programming Principles

One of the nice things about being employed again was the ability to afford a new computer, something I’ve put off as long as I could.

About 5 years ago, I’d purchased a very high-end mobile workstation to take with me overseas so I’d have something to keep myself entertained on the 26+ hour flights to and from the US:

  • Intel Core i7 3630QM @3.2GHz
  • 32GB of DDR3 RAM @ 1600MHz
  • Nvidia GTX 675MX 4GB of VRAM
  • 120GB SSD Primary Drive
  • 1TB Storage Drive

When I came back home, I found it more convenient to develop on my aging desktop machine with ideas of upgrading it when possible:

  • Intel Core i7 2600K @ 3.4GHz
  • 8GB DDR3 @ 1600MHz
  • AMD HD 5770s 2GB VRAM (x2 in Crossfire)
  • 120 GB SSD Primary Drive
  • 80GB SSD Auxiliary Drive
  • 320GB Storage Drive
  • 1 TB Secondary Storage Drive

A couple of months ago, I built myself a new PC that should last me a good 3-4+ years with minor upgrades:

  • Intel Core i7 7700K @ 4.2 GHz
  • 16GB DDR4 @ 3000MHz
  • Nvidia GTX 1080 8GB of VRAM
  • 240GB SSD Primary Drive
  • 2TB Storage Drive

I’ve been very pleased with it so far, and have been slowly reinstalling my development tools. The next step was to copy down my data so that I could pick up where I left off. To facility this, I purchased an inexpensive but well-made USB 3.0 SATA Hard Drive Docking Station.


What was intended to be a simple task, however, turned out to be anything but…The data I needed was spread across 4 different drives, one of which was BitLocker encrypted. The machine itself belonged to me originally, was lent a friend who in-turn savaged it, replacing several of the drives and the OS. On the actual computer, I’d solved this using Windows Libraries, but didn’t have that luxury when reading the raw drives.

So what did I do? I incorporated a handy application called SpaceSniffer to help me work out [visually] where the files I was looking for were.

This application is very similar to WinDirStat, but performs significantly faster. I still have a few more applications to [re]install, but I can get that done tomorrow at some point as it is now 4:13am, and I should think about getting to bed as I have to be up in 3 hours.