A Retrospective


It’s not a postmortem, because the game is not dead. It’s the most alive it’s ever been. It’s out.

Now that Archetype and the Four Winds of Hell has been out for just over a month, I want to take a look back at the project and see what I learned. What went well, and what went poorly? What mistakes did I make that were obvious in retrospect? What have I learned that I should have already known? It’s time to get really introspective. I’m going to be brutally honest with myself. I’m going to destroy myself with facts and logic.

Just The Numbers

But first, a look at the numbers. I had 343 wishlists at release. That’s not a lot, but a lot of people overvalue wishlists. They are not sales. Different games can have very different rates of wishlist conversions based on a variety of factors. And half of my sales have actually been from people who never wishlisted it.

According to Steam’s visibility documentation:

Wishlists (Mostly) Aren't a Factor
With a few exceptions like the Popular Upcoming tab, wishlists are not a factor in your game's algorithmic visibility on Steam. However, wishlists are still important. Customers who wishlist your game will receive an email notification when your game launches or transitions out of Early Access, or when your game is discounted at 20% or greater.”

So it’s great if you make it into the popular upcoming tab before release, but it’s not exactly something to rely on. I actually just visited the popular upcoming page for the first time. There are over 1000 games on the list, and I only recognized a couple of them. I don’t know how many players actually use that page, but I certainly never have. I guess Valve wouldn’t keep it around if no one used it though.

But for visibility on most steam pages, the only things that really matter are purchases and active players. And yeah, wishlists can give you a bigger burst of purchases and active players at launch and during sales, thanks to that email notification. And that can give you a boost in visibility. But as I said before, different games have very different wishlist conversion rates, and half of my sales were people who hadn’t even wishlisted it.

I have 24 sales so far. With numbers like that, Steam isn’t going to be helping with visibility. Only 11 of those sales were wishlist conversions. That gives me a 3.2% conversion rate. And here’s a reminder: there is no such thing as a typical conversion rate. It varies a lot based on genre, art, gameplay quality, trailer and screenshot quality, release timing, and more.

Two people have refunded it. That’s 8.3%, which is a pretty high rate, but numbers are easily skewed when they’re this low. Unfortunately, there’s no exit survey when people refund a game, so I can’t know exactly why they did. But I can guess. It’s either too aggressive a difficulty curve, or that they bought it expecting a more typical metroidlike, and were put off by the permadeath structure. I do make the permadeath part clear on the steam page, but people don’t always read the whole description.

For example, I haven’t read the description on the steam page for Hollow Knight: Silk Song. I’m gonna buy it on release day without ever reading it. I don’t need to.

I have 3 reviews so far, all positive. Neither of the two people who returned it left negative reviews.

And this is not a success metric most people talk about, but there have been no bug reports. I’m sure with a larger player base, there would be a few. But not many. Because my shit’s tight. Want to prove me wrong? Buy the game and try to break it. If you can, I’d love to fix it.

I spent about $2000 paying my art and music contractors, and I was hoping to make that amount back in sales. I have made $134. So, barring some weird Among Us-like turnaround, this is far from a financial success. But financial success is not the only type of success. I had many other goals that were not financial, so let’s talk about those.

Non-Financial Motivations

One big reason I was making this game was as a portfolio piece. Most game companies won’t hire you unless you have worked on a commercial game that was released. Now, how am I supposed to work on a commercial game if no one will hire me to work on one? So, I did the Thanos meme and did it myself. Now I have made a fully released commercial game, and no one can take that away from me.

Another reason was to learn and improve my tech stack. There is a reason game companies want applicants to have worked on a fully released game. There are a lot of things you only really have to learn when you’re making a fully released game. A robust options menu with accessibility features; tutorials; showing the appropriate button icons even if the player has remapped them; all the edge cases with control remapping; supporting both keyboard/mouse and controller; save games; and much more. These are all things you don’t really worry about on smaller, non-commercial games. Then there’s conducting and responding to playtesting. I got some practice at that, and learned that I have so much more to learn. And then there’s messing with Steam’s back end to set up a store page and upload builds. That interface is a mess. I have some notes for Valve if any of them are reading this.

Another reason was just to have fun. And I did. Next goal.

Another goal was following the inspirations I wrote about in my first dev log.

Inspiration 1: the GDC talk from id Software about push forward combat in Doom. This was programmer inspiration, to recreate the core mechanics they talked about in 2D. I’d call this one a mixed success. The specific details I called out as wanting to recreate were:

  • Enemy AI is limited on how many enemies can be attacking at once, to avoid overwhelming the player. They implemented this with a token pool. I successfully implemented this basically the same way they did, including allowing “high priority” enemy attacks to steal a token from a lower priority enemy and force that lower priority enemy to cancel their attack if necessary.
  • Enemies are less accurate the faster you are moving. They defined probability distributions for enemy projectile accuracy as a function of your velocity. I did not. That would not work as well in a side scrolling game. I just made enemies aim straight for you without leading you, and prefer shooting at you from higher ground, so the end result is still that they are less accurate the faster you are moving. So I’d still call that a success, albeit with a simpler solution.
  • They had several different levels of hit reaction animations in the enemies, ranging from the most common but least impactful, to the least common but most impactful. The three in particular I remember were twitch, the most common, least impactful hit reaction, which was just an additive layer that would throw off enemy projectile aim, but not interrupt their actions; falter, the medium one, which would interrupt enemy actions for a short duration; and stun, the most impactful hit reaction, in which they are disabled and open for a glory kill. I originally planned to do all of that, but ended up cutting the twitch reactions, because I didn’t want to mess with additive animation layers. Also because my enemies were from an asset pack, and opening up their files in Blender screwed up their rigs and broke all of their existing animations. So that one’s gonna be a mixed success. Twitch was obviously the least important hit reaction for gameplay, but it still would have been nice if I had done it.

Then, of course, there was the glory kill. A big part of the appeal of the glory kill is the animations. I didn't even try to recreate that. I’m just one developer, with the core skill set of programming, not animation, and I was trying to spend under a year on it. So I just gave up that significant part of the appeal. I was more interested in glory kills as a mechanical weapon and a healing system. And I will also call that a mixed success. Here’s a passage from my first dev log about healing systems:

“Metroid went with the natural solution of just making enemies drop health pickups. That led to the degenerate gamer strategy of standing in front of a spawner and waiting for tiny bugs to fly out, shooting them one at a time and picking up a small amount of health from each one, simply because they were low risk. What would have happened if you made the health drop conditional, like in doom? The newer Metroid games have a parry and counter system, which is higher risk and higher reward than shooting a helpless little bug just as it exits the spawner. I’m not sure if that actually increases the health or ammo pickup rewards, but it would incentivize higher risk, more interesting play if it did.”

So I wanted players to have to engage in riskier combat and lean on glory kills to heal them. But I ended up with this being possible:

You can still just camp a fodder enemy's spawn point and use it to heal up. It's super easy and low risk to glory kill these guys.

Thanks to infinitely respawning weak enemies, that degenerate Metroid healing strategy is still possible, despite needing to do a glory kill to get health. So that’s a design fail. One I could have easily fixed by making most enemies not infinitely respawn.

Anyway, inspiration 2: wanting to turn the reincarnation cycle from Avatar: the Last Airbender into a game mechanic. I clearly did that, but was this the best game to do that in? I never really considered making it anything but a Metroidlike. And I should have. I should not have just uncritically made the original idea that came fully formed out of my head. I should have experimented with a few different game styles to decide which one was best for exploring this concept. Maybe a more typical roguelike or roguelite or roguelurk or rogueluke (rogueluke is how the empire refers to Luke Skywalker) would have been a better form factor for exploring the Avatar reincarnation cycle as a game mechanic. I just wanted to make a Metroidlike, and I never really considered if that was the best game to make.

I shit talked roguelites in my first dev log for not having level design, and I stand by that. But after making this game, less level design kinda sounds nice. I learned a lot about level design over the course of this project, but most of all, I learned that it’s tedious, a lot of work, and I’m not great at it.

So once again, I’m gonna give myself a mixed success on this one.

Finally, Inspiration 3: Randomizer mods. Specifically, the way a randomizer makes you experience parts of a game not only in a different order, but in different ways based on what abilities you’re bringing in. And I think Archetype does a pretty solid job of capturing that neat aspect of randomizers. One great moment in development was when a play tester used the flame burst ability to hit a switch through a wall to open a door from the wrong side instead of doing the platforming challenge to get around and then open up the door as a shortcut. It wasn’t intended for that to work, but I loved that it did. Players were able to experience this platforming sequence in the water area completely differently if they brought in a specific ability from the fire area. Similarly, there was a point in the fire area where the player is meant to get across a gap by using the flame burst to pogo off of a flying enemy in the middle of the gap. But if they come in with the dash from the air zone, they can use it to cross the gap, completely ignoring the flying enemy in the middle. You can get through many platforming sequences without the intended abilities by creating stalactites and using them as stepping stones. While testing, I did a challenge run without ever getting the wall jump ability, one without ever getting the water grapple ability, and one without the air jump. I bet I could complete a challenge run without any one of the abilities in the game. I think the challenge run community would have a good time with this game if they got into it.

But that ignores another part of the appeal of randomizer mods and challenge runs: it’s a game that people are already familiar with. You’re experiencing something you already know, and usually have a lot of nostalgia for, in a different way. There’s a reason Ocarina of Time is the most popular game for randomizer mods. Everyone knows it and has nostalgia for it. There’s a lot less appeal to a randomizer if you’re not already familiar with a game. I hoped my use of all the classic Metroidlike abilities would make it feel more familiar, but that’s at most only half the equation.

Larger item pools also help. Ocarina of Time has hundreds of items in the item pool, allowing for a ridiculous amount of variety in a randomizer. Archetype has 32. That’s much less variability. That’s a lot less searching to find the abilities that will open things up for you. And making a game with a larger item pool would have required a lot more level design, implementing more items, etc. And then the game would be longer, and that would make the permadeath a problem. Permadeath only works because the game is short enough to be completed in under an hour. The larger item pool that would normally make the item randomizer more appealing is fundamentally at odds with the game structure.

Another thing I didn’t account for is how niche the item randomizer appeal is. Making a niche game is fine, but you need to know who the target audience is and where to connect with them. You also need to set realistic expectations for how many people are in that target audience, and put in an appropriate amount of effort for the expected audience size. I did not.

So that’s all my goals. Lots of mixed successes, a few outright successes, and a big financial failure. Now, I want to get into the classic retrospective thing of what went well, and what went poorly.

What Went Well

The most obvious thing that went well was the technical aspect. My shit was tight. There were few bugs throughout the development process, and virtually none on release. For the character working so well, I credit the state machine architecture I wrote about in this previous dev log. I fixed several bugs throughout development by moving additional functionality into the state machine.

The enemy AI, which I detailed in this previous dev log, brought a lot of challenges. While I did end up fixing the major bugs in it, that was more a result of doing a lot of work than having a good framework for preventing and fixing bugs. Some of the behavior tree nodes I wrote were very helpful, like Execute With Attack Token and Execute With Waypoint. I realized too late in development that there would have been an extremely helpful generalization of those two: a “try-catch-finally” behavior node. In programming, try-catch-finally is a feature in a lot of programming language that allows you to write three blocks of code: the try block is what you attempt to do first; the catch block is what you do if something in the try block fails; and the finally block is what you do at the end no matter what. The behavior node could have had a child node for each one. Execute With Attack Token would have released the attack token as the “finally”. Execute With Waypoint would have released the waypoint as the “finally”. One try-catch-finally node that would have been really useful and prevented several bugs would have been one that stops navigation as the “finally”. Instead, I did a lot of tedious work adding Stop Navigation nodes to a lot of behavior tree branches.

Another thing that went well, still technical, was my UI frameworks that I have been building up over the past several projects. I had to write relatively little new code for all of my HUD and menus in this game. I’ve complained a lot about Unity’s UI system, but this framework makes it suck a lot less. One of the major features is generating a collection of UI elements based on a prefab to represent a collection of data elements. It also adds good support for gamepad menu navigation, since Unity’s built-in support for that is really half-assed.

So this framework makes it basically no work to make things like this:

That data list to UI element collection mapping framework is used for so many things. The ability menu, the tutorial menu, the controls HUD, the switch HUD, the tabs in the menus, the control remapping menu, the controls tutorial, and more.

It’s a super useful bit of shared code that saved me a lot of work. It’s also used for this:

The map screen

This bit of shared code for collections of UI elements is used for the room images (each room is its own image, since each one is only added to the map when you enter that room), the item icons, and the fast travel point icons.

I’m happy with my architecture for the map and for saving games. I created a singleton class to track the game state. It contained several game state subfields for various aspects of the state, like map state, tutorial state, pickup state, switch state, and character state. GameObjects would read from that game state object on start, and they would update that state when relevant. For example, whenever a level loads, each switch in that level would check the switch state for whether it should be activated, and update its own state accordingly. Then, when you activate or deactivate a switch, it would update the game state with its new state.

I did that pattern for many things: whether switches are activated, whether combat arenas have been completed, whether pickups have been found, whether rooms have been entered, whether you’ve seen a tutorial, your character’s current health and mana, etc.. When you open the map screen, it checks the map state for what rooms you have entered, and displays them all with the appropriate sprite in the appropriate position. It does the same for what pickups you have found, where you died on your previous run, and what fast travel points you have activated.

When you load a save game, it instantiates the player character, then checks the game state for what pickups you have found, and applies the effect of each to the player character. This did have a little gotcha at first because I made health upgrade pickups also fully heal you when you get them, so I had to add a bit of extra logic so it wouldn’t automatically fully heal you anytime you load the game after having found one.

Since every object was updating the game state as things happened, I could at any point save the game by just serializing that game state object to a file. So I’m happy with that system. It made state management quite easy.

I’m happy with a few other of my shared libraries that I’ve been building across projects as well. I made one for options menus. I have a custom editor window in unity where I can configure what options I want there to be, then I can basically click “generate” and have an options menu in game.

Here’s where I configure all the options:

A custom Unity editor window where there are dropdowns for all of the options in the game. The "Enemy Aggression" and "Platforming Obstacle Damage" dropdown arrows are open showing the configuration fields for each. Enemy Aggression is configured as an Enum type, with the options "Low", "Medium", and "High", with the default value set as "Medium". Platforming Obstacle Damage is set as a Toggle type, with the default value set as off. Options can also be configured as Slider type, which allows me to configure their minimum value, maximum value, step size, default value, and whether I want their values represented in text as raw numbers or percentages.

And here’s where I generate the menu:

A unity inspector on a game object where I add to a list which options I want to be in a given menu, then right-click and select "Refresh Display", and the whole options menu is generated for me.

Then to implement the effect each of those options has, I can just reference them in scripts like so:

[SerializeField] private OptionSO damageOption;
public override void Process(Damage.Builder builder)
{
    int damageLevel = damageOption.enumIntValue;
    float damageMultiplier = damageMultipliersByDamageLevel[damageLevel];
    float knockbackMultiplier = knockbackMultipliersByDamageLevel[damageLevel];
    builder.WithDamage(builder.damage * damageMultiplier)
        .WithKnockback(builder.knockback * knockbackMultiplier);
}

This code also makes use of another shared library I’ve been building up over the past couple years: hitboxes. One powerful capability of this library is called Damage Interceptors. They each take a Damage Builder object (an in-process damage calculation) and can manipulate it in various ways. Several damage interceptors can be added with different priorities to either a hit box (the thing that deals damage) or a hurt box (the thing that receives damage) and they will all be processed in order.

This could use some additional work to make it easier to keep straight what order all of the interceptors are processed in. Right now, they all just define their own numeric priority, and there’s no view to see all of them in relation to each other.

The damage interceptor in this code snippet references the difficulty option for increasing or decreasing your damage, looks up a multiplier based on the value selected for that option, and multiplies the damage and knockback values of the damage accordingly. And here’s what an instance of this Damage Interceptor looks like in editor:

A Unity inspector for a ScriptableObject where I specify an integer priority, two lists of three multipliers representing the damage and knockback multipliers for each rank in the "Enemy Damage" option (Low, Medium, and High), and most importantly, a popup menu where I can select which option I want to use as the damageOption in the above code snippet.

It’s a scriptable object. Scriptable objects are great. The options object has a custom property drawer that just creates a dropdown menu where I can select the option I want from all those I’ve configured. Then I can add these to a hitbox or hurtbox like so:

A Unity inspector for a HurtBox component on a GameObject where I have added three damage interceptor scriptable objects simply by clicking and dragging.

I can just click and drag the damage interceptor scriptable objects into the Attack Effects (for hitboxes) or Armor Effects (for hurtboxes) list.

The block ability also uses a Damage Interceptor to cancel damage.

The hit box library can also add Attack Effects, additional code that is executed after the damage dealt. This can be used to add screen shake, hit pause, particle effects, or more functional stuff like adding a status effect. The hit box library also includes a framework for status effects. I used it for the burn you can inflict on enemies using the heat beam, the self-immolation that immolator enemies do, and the shields that the defensive earth enemies grant other enemies. Those shields add a Damage Interceptor to their hurt box to zero out the damage they receive.

The options library can also be used to do this:

[SerializeField] private OptionSO vSyncOption;
private void OnEnable()
{
    vSyncOption.AddValueChangedCallback(UpdateVSync);
    UpdateVSync(vSyncOption);
}
private void OnDisable()
{
    vSyncOption.RemoveValueChangedCallback(UpdateVSync);
}
private void UpdateVSync(OptionSO option)
{
    // Code for setting the VSync settings here
}

That AddValueChangedCallback function is very helpful for things like this V-Sync setter script.

The options object can also be used for things that are not actually options. When you get down to it, it’s really just a variable wrapped in a scriptable object that has an on change event. I used an option for whether the player was using a controller, so that I could have all of my UI listen for the value to change and update the button prompt sprites when it does.

One other thing that worked out really well was some of the automated tooling I made. After making several level design changes, with the click of a single button, I could update all of the map sprites for each room, generate room registry data for any new rooms, update location data for all of the pickups, generate arena IDs for any new arenas, generate switch IDs for any new switches, generate checkpoint IDs for any new checkpoints (anything that’s part of the save file needs an ID, so those all need to be generated), update the starting point for each elemental area, and update the default location to pickup ID mapping. That eliminated a lot of what would have been tedious work in starting and iterating on level design.

The location to pickup ID mapping was part of the save file, which made implementing the item randomizer quite easy. For a non-randomizer file, it just uses the default mapping. Otherwise, it algorithmically generates a new possible mapping, and every pickup object in the game will look up what pickup it should be in the mapping.

So I think those were my biggest wins in this development process. Good automation, technical architecture, and use of shared code libraries that I’ve been building up across my past few projects. And that brings us to…

What Went Poorly

There were two obvious ways the results were bad: timeline and sales. So what went poorly to produce those results?

I’ll start with the most obvious: I’m a software engineer, not a producer or a manager. I’ll get better at those skills with practice, but my first commercial attempt was pretty bad. I waited way too long to recruit collaborators for art and sound, which I already talked about in my dev log on timelines. If I had started that effort early on in development, I wouldn’t have been waiting for them to finish their work at the end, so the whole thing would have been finished several months sooner. It also would have given more time for iteration on their work, which would have been nice for sound effects in particular. Miles did great work on the sound effects, but it’s an iterative process that requires a lot of feedback between it, animation, and game design to get everything feeling right. More time for feedback and iteration would have definitely helped.

Another knock-on effect of working with an artist so late in the process: I couldn’t get any good-looking screenshots or capsule art for a steam page until only a couple months before release. You want to get a good-looking steam page as early as possible. It gives you more time to gather wishlists before release, and while wishlists are not as important as many people think, they do still matter. You also basically can’t do any promotion until you have a steam page. A promotion needs a call to action. And “wishlist my game” is the simplest call to action you can make. There are essentially four points in time when Steam gives you a boost in visibility:

  1. When you publish your steam page
  2. When you publish a demo
  3. During Next Fest
  4. When you release

So it helps to be able to spread those out a bit. I published my steam page the first week of October, published the demo the second week of October, participated in Next Fest the third week, and released at the end of November. So it was all very clumped together and I didn’t get the most out of each visibility boost. I also just didn’t have nearly as much time to promote my game, gather wishlists, and, most importantly, gather more public feedback to improve the game.

For art, I came up with a modular tiling background scheme to cover a lot of background with relatively few assets. With more time, we could have done more bespoke, one-off background screens. Of course, that would have also cost more, and this was, as one Reddit reviewer said, a “Budgetvania”. That would have also required me to give more art direction and have more world building to inform that direction. And I wasn’t really interested in that.

Which brings me to the next thing that didn’t go well: why did I make a Metroidlike if I wasn’t interested in world building, varied environment art, atmosphere, etc.? Those are big parts of what make Metroidlikes great. I can’t be bothered to care about the lore of Metroid, but the atmosphere is still important. And when I think back on why I love Hollow Knight so much, yeah, the mechanics are great, but it’s really the atmosphere, the big lore moments, the feeling of meaningful secrets in every nook and cranny that make it stand out. Archetype has none of those. It’s great from a purely mechanical standpoint, but that’s not enough for a Metroidlike. Metroidlikes are not a genre for low-budget, purely mechanical experiences. That would be roguelikes. Or roguelites. Or roguelukes.

And that brings me to the next thing that didn’t go well: playtesting. This was my first project where I held regular playtests of my game. That undoubtedly made the game better. But not as much as it should have.

I should have done more broad experimentation early on and playtested wildly different prototypes rather than just making the idea that sprang fully formed from my head, which resulted from mashing two barely related ideas together. Thinking of game design as a search problem, trying to find the best possible game, as the pretty successful indie developer and youtuber Jonas Tyroller does in this video, this doomed me to no better than a local maximum in the field of all the games I could have made.

I also did not put work into finding my target audience and playtesting with them. I playtested with the willing participants who were readily available, regardless of whether they were really the target audience. I playtested mainly at the Seattle Indies coworking session I go to every Saturday, which meant my playtesters were mostly other game developers. And game developers don’t play games like normal players do. They poke at the seams. They try to reverse engineer it and break it, rather than just playing it like a game. So that often didn’t give me the information I needed on whether something made sense and was fun for a normal player.

And another problem with playtesting: I should have had higher standards. From now on, I should conduct playtesting with the mindset that if it’s not a “hell yeah!”, it’s a no. Players can’t just get through an area and say “yeah, that was cool”. They need to be ecstatic. Playtesting as I did helped a lot to get my game from bad to okay early on, but it wasn’t enough to get it from okay to great. I didn’t quite reach that local maximum even.

Part of the reason for that was that I stopped wanting to iterate more as the project went on. I wanted to finish the game and move on. But part of the reason I didn’t want to iterate as much was that my tools weren’t built well for it. The automated map data baking and stuff was great, but I needed a better workflow for a lot of other parts of level design.

Take this moving block, for example:

Left: An in-engine screenshot of a moving block with spikes on one side. Right: A view of the Unity hierarchy of that object, revealing that it is made up of a root object, 8 additional sprite objects, and four spike objects.

This is made up of several subobjects: the center sprite, the four corner sprites, a tiling sprite on each side, and each individual spike. To update the size of one of these blocks in a level, I had to update the dimensions on the center sprite renderer and the box collider, move each of the corner sprites, move and resize each of the tiling side sprites, and move and possibly have to delete or duplicate the spikes. It would have been a lot easier with tooling to just update the desired dimensions in one place and have that all update automatically. I could have just given myself checkboxes for which sides I wanted spikes on, and have the computer automatically place them. There are a lot of things like this that I could have built more tooling for, but didn’t, because I didn’t plan on doing much iteration. So there’s a lesson: you’ll need iteration. Just build the tooling up front.

One more thing that could have helped with playtesting: data collection. Most successful games nowadays have some telemetry built in. That’s how FromSoft knew everyone was using Rivers of Blood and decided to nerf it. It’s how they knew most players were dying 50+ times to the final boss of Shadow of the Erdtree and then giving up, and decided to rebalance it. That’s how Nintendo knew during playtesting of Breath of the Wild that players were all just following the main roads straight to each tower, and they solved that by adding breadcrumb trails of shrines, enemy camps, and other attractive nuisances off the well-trodden paths. Some good data points to collect in Archetype would have been:

  • Sequence of rooms visited
  • Time spent in each room
  • Locations of deaths
  • Locations of platforming failures
  • Locations where players quit the game

I did not collect any data in this game. So I am left not knowing if there is a particularly frustrating difficulty wall that is making players get frustrated and quit, or a room where players spend a lot of time confused, or if a lot of players are following the same critical path too closely rather than branching out like I want, or if players are stumbling into too difficult areas too early, or any number of other of things that could be going wrong that I would be able to deduce if I collected that data.

Lack of data collection wasn’t just limited to inside the game itself. I also didn’t collect any data on where people were reaching my steam page from. There is a capability in steam to generate different links to  your steam page so you can use a different link in each social post or ad you make, and then you can see data on which posts and ads are getting you the most visits, the most wishlists, and the most purchases. I did none of that. And I should have. I didn’t want to mess with that, because it felt like business. But thinking of it as a science experiment makes it feel more interesting and worthwhile to me. So there’s my lesson: tracking the success of a promotion isn’t just business; it’s science. And science is good. Science allows me to spend overall less effort on business by allowing me to identify and drop the things that aren’t working well.

There was also one big design contradiction that I was aware of near the beginning, but didn’t solve. I wanted to make combat similar to Doom 2016. In Doom 2016, you heal primarily by performing glory kills in combat. You replenish your ammo primarily by killing enemies with the chainsaw. And your ability to kill enemies with the chainsaw is limited by chainsaw gas, which you can only replenish with a finite number of pickups. You get the chainsaw pretty early on in the game. It’s linear, so the designers know you have the chainsaw for most of the game, and they can tune combat with the assumption that you can kill enemies with it to replenish your ammo. I recreated those mechanics in Archetype. You get healing by performing melee finishers, and you get mana drops by killing enemies immediately after a rock parry, or while they are on fire from the heat beam. But the problem is: this is an extremely nonlinear game, unlike Doom. You can go through most of the game without the rock parry or heat beam abilities. Because of that, I couldn’t tune combat in most of the game assuming you could replenish mana that way, which means I need to be generous enough with mana replenishment and mana costs for abilities that the parry and heat beam aren’t really even necessary. And because there’s also the healing ability in the water zone that you could go through most of the game without, I needed to be that generous with health replenishment as well. That made it very difficult to tune the game to actually make those abilities useful. Most players probably won’t run into mana being a concern at all. And many players may never need to use the water heal ability. It is a real tightrope to walk, making the game possible but very challenging without those abilities. I did not strike that balance well. Infinitely respawning fodder enemies make the tuning even more generous.

The last big thing that didn’t go well was my work scheduling. I started with the intention of working on this game full time, but that wasn’t really what happened. I spent most of my time for two months supporting an occupation protest instead of working on the game. I had an inconsistent but busy schedule with my dog walking side gig, and didn’t effectively manage my schedule to make the most of my time outside of it. I also just procrastinated a lot toward the end. Yeah, I was waiting for contractors to finish their work. But there was still valuable work I could have been doing. At the end of the day, I didn’t manage my contractors effectively, and I also didn’t manage myself effectively.

How Next Fest Went

I did promise a report on Next Fest in my previous dev log, so here it is, even though there’s not too much to report. I started with just over 40 wishlists. I ended with just over 280 wishlists. It was the vast majority of my game’s wishlists, but still not very much. I got feedback from one person. He gave me some bad, unactionable feedback, and then the good, actionable feedback that I should add support for mouse and keyboard controls instead of just controllers. I took that and implemented it, and the game was better for it.

I wish I could have gotten more feedback. For that, I would have needed more attention on the game going in (meaning, it would have really helped to have had the steam page up for more than two weeks prior), and I would have needed a more appealing page. More on that in a bit.

I was lucky to even get into Next Fest. I missed the application deadline. It was back in August 2024, and I didn’t have a public page until October, just two weeks before the fest started. But I messaged Valve asking if I could still get in, and they let me in, no questions asked. Super easy to work with. Next time, I do want to have my shit more together and be able to apply on time.

Lessons Learned

So many lessons, most of which I should have already known. But a big theme here is going to be: there are a lot of things I avoided because I thought of them as Business, but they actually result in better art too.

  • Define your target audience early on. That’s not even business, that’s just art. Develop and promote the game to them. Connecting with your target audience isn’t just good business, it’s better for your art too. Who was my target audience? It was people who are hardcore into Metroidlikes, to the extent that they play with randomizer mods. But I didn’t really have them in mind with every decision I made, because I didn't identify that until too late in the process.
  • Playtest with your target audience, not game developers. I already touched on this, but game developers are more interested in trying to reverse engineer or break the game than just playing it. Also, most of them are not hardcore Metroidlike players. Playtesting with my target audience would have also made me think earlier on about where to find said target audience, which also would help me to target my promotions at them.
  • Market research isn’t just business, it actually results in better art. I will never make a heartless survival crafting game just because they sell well on Steam, but it is worth knowing how well a certain type of game generally sells, so you know how much it makes sense to spend on development. It’s also important to know what expectations players have, what’s important to players in a certain type of game, and what’s already been done, so you can differentiate yourself in an interesting way.
  • Be more self-critical with playtests. The player reactions need to be a hell yeah, not just an okay. Just because someone is able to get through a challenge doesn’t mean it was sufficiently clear. Just because someone finishes a challenge doesn’t mean they really enjoyed it. In some playtests, I had the mindset that “I can’t help if they’re just not paying attention”. That’s not a helpful mindset for a game designer. You need to ask why they’re not paying attention. Maybe it’s just because they’re not your target audience, and your target audience would notice what you need them to. But that’s why you need to playtest with your target audience. If your target audience isn’t noticing the things you need them to, you need to rework things so they do.
  • Theming is actually really important, especially for a metroidlike. Hollow Knight would have been just as fun in the hands without the lore and atmosphere, but it would not have been so memorable, and it would not have stood out so much from the crowd. And does Avatar: The Last Airbender meets Doom sound like an interesting theming that you’ve just gotta play?

The scene from The Wolf of Wall Street where he looks straight into the camera and says, "Absolutely fucking not."

My favorite scene from The Wolf of Wall Street

It sounds like complete nonsense.

  • Think about appeal, not just fun. Honestly, I wouldn’t buy my game if I just saw it among the sea of other Metroidlikes on Steam. It’s not immediately obvious what sets it apart or why that’s cool. You can’t just see a screenshot or short video clip that conveys the structure of rotating through the four elements each run, or immediately and intuitively understand what’s cool about that. That structure is also actively unappealing for a lot of people. Majora’s Mask is my favorite Zelda game, in part because of the weird time loop business, but that’s what puts off a lot of people who like the other Zelda games. This was not a very marketable game. It had simple graphics without a lot of flash, but more than that, it was difficult to communicate the appeal. I never did really come up with a good one or two sentence pitch for it. It was always a long rambly talk that included “So, you know how in Avatar: The Last Airbender…”. If I had thought more about appeal, I would have put much more thought into theming and ease of communicating the appeal.
  • Make a demo that is representative of what makes the full game cool. My demo didn’t sufficiently do that. It was just the water zone. It didn’t involve rotation through the elements, because there was only one element in it. I still don’t have a good idea of how I could have shown the rotation through the elements without making basically the whole game the demo. It also showcased the least interesting combat area in the game. Water zone combat is too simple. There are basically only two enemy types: imps and healers. Those two are not sufficient to create interesting encounters. The chargers, defenders, and stalactite creators in the earth zone make some interesting encounters; and the chargers, imps, immolators, and insects in the fire zone make some interesting encounters. But the small enemy variety in the water zone does not make interesting encounters. It’s also the case that the water zone has less interesting abilities for combat utility. The stalactite, ground slam, and rock guard in the earth zone make interesting combat utility. The flame burst, blaze of glory, and heat beam in the fire zone make interesting combat utility. The wall jump and grapple in the water zone are much more for platforming, and less useful in combat. And thanks to how generous I was with enemies dropping health, the heal in the water zone is basically useless. This is obviously not just a problem with the demo; it was a problem with the water zone in the full game. It’s a whole area where the combat is boring, and it’s the first area players will see, so the game puts its worst foot forward in terms of combat. I needed to make the water abilities more interesting to use in combat, and make more interesting enemy variety in the water zone.
  • Bring on collaborators much earlier on in the process. I’ve talked about this one enough already, so I won’t belabor it anymore. Hopefully, in future games, I will have full creative partners and not just contractors.
  • Have a higher standard for good enough in level design. I was trying very hard to resist scope creep in this project, but it’s not scope creep to say “this level needs some reworking”. The Earth zone needed some reworking. I didn’t do it.
  • Build great tooling for content design and iteration early on. It will pay off.
  • Build some telemetry into the game. More data will help you improve the game more than any one-off playtest can.
  • Don’t plan to release when you’ll be on vacation. Archetype released the day after Thanksgiving, and I was on vacation at that time. You want to have time to post release announcements to socials and discords and all that when the game releases. I did not. Other important things to consider when choosing your release date:
    • When is the last Next Fest before release? Will you have your best steam page and demo ready for it?
    • What other games are coming out around the same time? Will you be in competition with them? It helps your visibility on Steam to have a lot of active players right around launch. If a lot of players are playing something else that just came out, that means they’re not playing your game.
  • Come up with a better title. Seriously, what was that title? Archetype and the Four Winds of Hell? That’s such a mouth full. Someone just jokingly called the character “The Archetype” as a “legally distinct from the Avatar” joke, and I just rolled with it. The title is too long, sounds generic, and also just doesn’t really make sense. Do better, me.
  • Have boundaries and maintain a steady work schedule. I was all over the place throughout the development of this, and I’ve already made some progress. For my next game, I’m going to maintain a steady work schedule, and I’m going to state it publicly so the three people who read this can hold me accountable. I have a dog walk every weekday at noon. I have one longer dog sitting engagement afterwards on Tuesdays. I do mutual aid work all day on Mondays.
    • Monday and Tuesday will be my weekend from game development work. I will work Wednesday-Sunday.
    • On those weekdays, I will work from 9am until my dog walks at noon, then from 2pm until dinnertime at 7pm.
    • On Saturdays, I will work at home from 9am until noon, then go to the Seattle Indies coworking session, and work from 1pm until it ends at 6:30pm.
    • On Sundays, I will work the same hours, just all at home.
    • I will not accept non-regularly scheduled pet sitting requests.
    • If a protest movement comes up, I will participate in it with boundaries in place to fit it into the day I am already dedicating to mutual aid.
  • Think more about what types of games are a good fit for me as a solo developer who is in favor of short-term, small-scope projects. Metroidlikes really benefit from a slightly larger scope. Very few of them are made by solo developers; the only exception I can think of is Axiom Verge, and that was in development for 5 years. I don’t think it’s reasonable to risk having wasted 5 years of your life. It worked out for Thomas Happ, but it doesn’t work out for 99% of developers. That’s why I’m in favor of development cycles no longer than 1 year. Make more, smaller bets, and it’s more likely one will pay off. But that does limit what types of games you can make. You’re probably not going to make a Metroidlike or a complex RPG that way. But maybe you can make a streamlined narrative game like Citizen Sleeper, or a streamlined roguelite like Balatro, SNKRX, Vampire Survivors, or Dream Quest.
  • A lot of developers make excuses for why their games didn’t sell well. “I just didn’t do enough marketing.” “It’s just the Indiepocalypse™.” “Steam just screws over indie developers.” None of those are true for most developers who make those excuses, and they’re not true for me. Some of my reddit posts about Archetype got tens of thousands of views. The fact that I only got 343 wishlists from that many views on socials is an indicator that I just didn’t make an appealing game. Or an appealing Steam page, or an appealing trailer. I will own that. I hate editing videos, so I didn’t want to put more effort into the trailer than I did. Maybe next time, I’ll pay someone else to put together a trailer for me. But more importantly, I will put much more thought into the appeal while making my next game.

Who is it for?

I was at a panel of successful indie developers recently, and the topic came up of having to decide whether you’re a hobbyist or you’re running a business. But I think a better question to ask is: who are you making games for? Is it for a specific audience? Is it for your family or friends? Is it for people who need to hear a certain message?

I think I made this game just for myself. I made it just because I like Metroidlikes, and I wanted to make one, to be able to say I had. It was not for the audience. It was for me.

The gif from the end of Breaking Bad where Walt finally admits "I did it for me."

Man, how good was that Breaking Bad finale? They don't make 'em like that anymore.

No more of that. From now on, I’m making games for the audience, not just for myself. I’ll still make games I’m excited to work on; the players will feel it if I don’t like my own game. Heck, the players probably felt that in Archetype. I wasn’t really having fun by the end. I was just trying to get it out the door so I could move on to something more meaningful.

And I will make games with social messages, not games that are only for fun. Hopefully they will also be fun. Another Crab’s Treasure, which should have won the Best Narrative award at the Game Awards (I assume; I don’t actually know anything about Metaphor: ReFantazio, other than I’m not gonna play a game called Metaphor: ReFantazio.), did a good job of doing both. There are already plenty of games that are just for fun, and have nothing to say. Like Archetype. I can feel better about spending time on game development rather than more social movement and mutual aid work if the game is actually saying something.

My next game will be a solarpunk base builder that leans into the “punk” aspect. I will do more experimentation early on to figure out the exact interaction model best suited for that, but that’s the goal I’m aiming for. It will be for people who like strategy, and also care about real world political strategy for building a better world and averting the coming mass extinction caused by climate change. It will not be for cozy gamers, because overthrowing the current colonial order that’s causing climate change is tough work; it’s not going to be cozy.

But it will be worth it.

The question of whether you’re making games for the audience or just for yourself is a better way of framing the question of whether you’re a hobbyist or running a business to me, because I still think business sucks, but art is good when it’s actually for a purpose. If you make good art that is targeted at a certain audience, and you share it with that audience, they will buy it, and you will make money. How much money depends on how good that art is and how big that audience is, so you still need to do market research to figure that out and decide how much it makes sense to spend on development. In a post-capitalist world, we wouldn’t need to worry about the funding, but everything else would still stand. And even in a post-capitalist world, you’d still limit the time you spend on a given game based on the fact that you only have a limited time on earth, and so many more games you want to make in that limited time. And you’d still need to decide whether you’re developing for your audience or just for yourself. You’d still need to identify your target audience. You’d still need to test with them to make the game as good for them as you can make it. You’d still need to promote the game to them if you want your art to find its audience. As a filthy anarcho-socialist, I have a knee jerk reaction against seeking revenue. But in our current capitalist world, finding your audience is aligned with earning revenue.

And finding your audience is what every artist wants.

This decision that the games I make are for the audience and not myself means I need to accept that I don’t need to, and shouldn’t, make every silly game idea that comes through my head. So I’m just going to throw out a few stupid ideas I’ve had that I won’t make now. You have my blessing to take any of these and run with them:

  • Katamari of the Colossus: A game where you fight colossal enemies by rolling up small objects in a ball, until your ball eventually gets big enough to roll up the colossus.
  • Sisyphus: A roguelite about pushing a boulder up a mountain, only for it to roll back down the mountain at the end of every run. It’s a shitpost about why I don’t like roguelikes, roguelites, or roguelukes. Okay, I did the rule of threes, so I can stop with that joke now.
  • Afung-us: A social deduction game where you are all campers out in the woods, and you each have to forage and eat a mushroom each round to survive. One of the campers secretly is a mushroom.
  • The Pawshank Redemption: A game about being a cat breaking out of your human’s house by slowly carving your way through a wall, covering the hole with a poster, and depositing the debris in your litter box a little at a time.
  • Cat of Duty: Meowdern Warfare: I was talking to some friends about doing a cat game jam at one point, so a lot of these ideas came up. I think the idea here was a shooter where your two guns are a laser pointer to attract cats to a point, and a water gun to repel them from a point.
  • Train Soccer: Everything is better on a train, including soccer. When you score a goal on one train car, the game moves up to the next car. If you make it to the front of the train, you win. If your opponent makes it to the caboose, they win.
  • Avian Prism: A survival horror game that turns the movie Bird Box into game mechanics. You have to put on a blindfold when you’re outside and avoid looking at the bad things.

So that’s it. A long look back, and a quick look forward. Thanks for reading to the end of this incredibly long retrospective. Here’s to working with new collaborators earlier on, maintaining a steady work schedule, and focusing on the players and the message in 2025 and beyond!

Files

Archetype Demo.zip 76 MB
69 days ago
Archetype_Windows.zip 87 MB
59 days ago

Get Archetype and the Four Winds of Hell

Buy Now$5.00 USD or more

Comments

Log in with itch.io to leave a comment.

I really wish itch.io image captions worked properly. They look right in the editor, but they just appear as regular text in the actual published page. Another thing I'll definitely change going forward is find a better site for my dev logs.