> go back

Critters Doing Combat devlog

Banner for Critters Doing Combat

A pokemon-inspired critter battler themed after NYC. Scoped out before work began and completed within 2 weeks (kind of).

Warning! There will be plenty of spoilers for the game here.

Twitter Itch

Background

Art of Pizzaling

I was working on cloning Pokemon Red from the ground up, as a sort of "Master Study", a concept that interests me a lot. This is a commonly done thing in other art forms, where beginners will look at works by a master of the form and try to mimic one of their pieces as closely as possible. I don't think people do this for video games very much!

I also expected (and it did play out this way) that I would get bored doing this, and it would lead me towards thoughts about what I would change or things I could incorporate into my own games. About the time I finished up the combat system, I was in fact bored and started thinking about the base, most composite parts of Pokemon. I ended up focusing in on combat, and thought about if I could make a game that's just the simplest form of Pokemon combat with all extra cruft removed. That left me with hitting each other, type effectiveness, using items, and running away.

I'd also recently read a couple of pieces on gamedev that resonated with me, encouraging the creation of small games. I'm an idiot, and don't have either of these saved, hopefully I can find them later. One of them was about appreciation of small art in general, and the other was a realistic piece on how you are going to make multiple bad pieces of art, so why do amateur game devs in particular insist on making a huge, multi-year project for their first game? Assuming 10 bad games before you make a good one, may as well spend 2 weeks making a bad game instead of 5 years.

So that's where I was. I can't remember why I landed on two weeks. The article probably suggested it. I brainstormed bullet points in a notepad doc, and then fit as much of that as I could in a 2 week, day by day plan. I have the benefit of knowing about how much I can realistically accomplish in an evening. Here was the plan I ended up with:

Art of Roachmeiser

Week 1

  1. Monday: Basic game in place, 2 dudes smacking each other, increasing spawn rate, recharging heal, recharging "heat decrease"
  2. Tuesday: Multiple game areas, replace "heat decrease"
  3. Wednesday: Leveling up
  4. Thursday: Special moves
  5. Friday: Shop for buying things (level ups, items, special moves)
  6. Saturday: Area bosses
  7. Sunday: Different starting critters

Week 2

In addition to the work this week, I wanted to work on my publishing presence starting here.

  1. Monday: Type effectiveness
  2. Tuesday: Final boss
  3. Wednesday: SFX
  4. Thursday: Music
  5. Friday: Start menu
  6. Saturday: Save/load?
  7. Sunday: Victory/loss

Additional notes

Day 1: Base game

This was night 1 - go from nothing to some sort of "game". Fee was already asleep, I had some late night caffeine, and was just going full gamer mode on this until it was done.

So, the most basic version of the game turned out to be "how long can I survive?". You have a guy who's doing attacks. You have enemies who are doing attacks against you. You have a recharging HEAL button to restore your health. On the side of the screen is the "heat" meter. The idea here is two different colored bars moving towards each other from the top or bottom - when they meet, an enemy spawns. The top bar resets, but the bottom bar keeps climbing. This increases the spawn rate as you survive longer, which makes the waves more overwhelming. There's also a recharing button you can press to lower the heat a little.

I knew even as I worked here that a ton of stuff would change. It wouldn't be an endless game eventually. Heals would be limited. The heat would be reduced via different methods (that we'll see later).

It was important to me to not use placeholder assets as I went, so that I actually felt good about the game and could stand looking at it. I was open to revising assets later, which I did, but I took enough time to start to find the real voice/feel of this game from the get go.

Day 2: Different areas

Right away, we're replacing elements from Day 1. Instead of a recharging button that lowers heat, you instead charge up to run away from the encounter when it gets to be too much. While you're building up heat in one area, it lowers in the others you're not in.

The goal from the beginning was to have 3 different main areas. I never added explicit "make more critters" days because I figured nearly everything I did would necessitate adding a critter or two, and I was right.

Great example from the get-go on how I would underestimate every small feature. Add a couple areas looks small on paper, but includes replacing a button, finding the art for new areas, creating new critters, and making a whole map system and imagining how you would travel between them.

This was my first time working with Godot's Path nodes, which I used for tracing out the path along the subway lines the critter would travel. Very easy to use!

Day 3: Leveling up

In comparison, this actually was a pretty quick day. When you killed ever-increasing numbers of critters, you leveled up. It would rotate between increasing your health, increasing your damage, and increasing your attack speed.

There's surely a better way to do this, but boy did I go to fucky lengths for the yellow glow from the critter. Instead of just making a yellow copy of every art asset (since I knew I'd be making a lot of critters), upon loading a critter of any kind I walk its sprite pixel by pixel, and if there's a color there, I make it yellow. Then I saved that as a separate sprite behind the first one. I would also do this with blue later. I think I could have done something much easier with the modulate property in Godot, but I didn't.

This day is also notable for being when I abandoned balancing everything (anything). I just figured I'd do it all at the end.

Day 4: Special moves

To be honest, I wasn't quite sure what I wanted as far as moves yet. Would I want status affecting moves? Typed moves? What would the interface be for them? For the time being, I decided to keep it as simple as possible and add a button that when activated would double your attack, and trusted design of later elements would lead me towards something more satisfying. This actually played out for me, I think.

Day 5: The shop

This is when the game started to feel real to me! A lot of mechanics that were just automatic were moved to the bodega for purchase. I was really happy with the feel of this area.

Most importantly, this added a lot of player agency. You got a dollar or whatever for every critter you defeated, and now could choose how to use that to best keep yourself alive, whether that was more heals, more health, more damage, etc.

This was a lot of individual pieces of work to get all hooked up, but honestly not that bad. I found, largely, having a plan for the end state of the game made everything pretty approachable, and I found implementing each little piece was simpler than I was expecting.

I really went goofy with getting the critter's stats shuffled around the game. I basically had a GameShell node that was always loaded and acted as a global singleton. It contained player stats (actually, it contained how many times the player had leveled up each thing... every time a battle is loaded, the critter is put in at level 0 and leveled up a bunch of times accordingly) and also managed loading and unloading the battles, map, and shop as appropriate. When it loaded the shop for example, it would pass the player's level up stats down into it. When the shop was done being used, it would reach in to grab the player's new stats, and update itself.

This was so messy and bad. I learned much later that Godot actually has a global singleton system that I should have been using. Sidenote: don't be afraid of using global singletons in game dev! It's not the anti-pattern it is elsewhere.

Notably, and probably personal preference, I did not go back and refactor code once I learned about the global singleton. I always derail myself trying to make my code nice, I knew I had a limited time to work on this and concrete plan, and I had already given myself permission for this game to not be perfect. I'm happy with this choice to charge ahead.

The shop screen of the game

Day 6: Bosses

Another one that really made the game start to feel more like a game! Progress is cool for players and for devs.

Instead of the heat just rising forever until you're spawning enemies every millisecond and guaranteed to lose, once it gets to 90% of the screen size it spawns a boss. Yes, the YOU DEFEATED text is a Dark Souls reference, as is required by indie games in 2023.

I had considered leaving all the enemies, or letting them continue to spawn during the boss fight. The idea would have been to allow explict targeting, in that the player could click on which enemy he wanted to target. This would have given the player a bit more agency, as they decide whether it makes more sense to rush the boss or take out adds, and down the road, to target different critters if I'd had areas spawn multiple types (kind of happened). I went back and forth on that idea for a long time, but it never made it in. Perhaps for the best - I love the effect off the boss entering and blowing away all the other critters.

As an aside since I mentioned screen size - I just used Godot's default for this project, 1152x648. I ended up thinking it worked great for my capabilities and the MSPaint esque, handdrawn art style.

Day 7: Different starters

Worth mentioning that so far I had been sticking strictly to the plan, with full intent to only work on this for 2 calendar weeks. I might have missed a day or two, but would cram to get two days of work in at the cost of some sleep. I actually loved doing this - it brought me back to college projects and invigorated me. Certainly not sustainable though. If I work on a month long project in the future, I'll probably give myself weekends off instead of 2 weeks of marathon.

More wackiness with passing variables around with my GameShell node to set this up. But I had a lot of fun making it! The whole game abuses tweening properties a TON. Thanks to every game juice talk or article on the planet, I leaned into eases & transitions. EASE_OUT and TRANS_QUAD baybeee.

A lot of names and even some designs suck, but I hope their charm carries things. The aforementioned timelimit and permission to make something that sucks means I didn't get stuck in the weeds much here. A lot of designs are "first thing that came to mind", though plenty also came from friend suggestions or things I just really wanted to force in.

Marketing intermission

@crittersxcombat twitter account

I figured by the end of my first week, the look & feel of the game would be solid enough that I could start working on marketing materials and get a store page up.

Originally, I had fully intended to put this on Steam to see what its audience looked like. One of my early goals was get surprised by a stranger playing the game, found organically! I ended up backing off of this for a few reasons. A Steam launch required a lot more effort and polish than an Itch launch. It also cost money, which I was aware of beforehand and willing to do, but played a role in the decision to back off never the less.

I also made a twitter account at the beginning of this and tried to post gifs every day with a bunch of hashtags. This didn't work. I'm not sure if my game is unappealing to look at, I was doing this wrong, or a week just isn't enough time. I would have liked a follower!

Eventually I gave up on the twitter account and settled on an itch release. I'm satisfied with this, but leaves room to grow for my next releases.

Day 8: Type effectiveness

This was another "line item really undersold the amount of work" day, but it was largely me paying off decision debt from earlier days.

It was pretty easy to implement the most basic version of types - I made a fire>grass>water triangle out of rodent>trash>bird. I also thought it would be funny to add Holy and Devil types outside of the triangle, as an SMT reference. They're super effective against each other.

First round of work, critters when super charging their attack just added their primary type to it, which would potentially make it stronger or weaker.

I didn't think that was quite satisfying enough, so I went and added buying special moves from the shop. I was already keeping track of how many enemies of each type the player had defeated, and gated a special move of each type behind certain requirements, usually bosses. This also gave the player more reason to progress. Required a lot of new menu interactions!

Remember; still no balancing.

Day 9: Final boss(es)

The fun part about working on something by yourself is you get to add in a bunch of 1-off features and expand your scope (reasonably) because you're only hurting yourself.

For me that looked like adding a final boss rush. This required adding a new area with a few unique mechanics, including locking out escapes, dialog, no critter spawns, and transitions between multiple bosses.

I had a ton of fun doing this. In true jrpg fashion, the final boss is God himself. I thought it was the funny kind of edgy to make him holy/devil type, and it also made him mechanically interesting as he was weak to moves of either of those types (potentially tricky to get) and double resistant to the basic critter types.

Day X: Sound

I fell off the wagon! I both went on vacation and got sick, AND was totally overwhelmed with the amount of sound I needed to add to the game. So wrapping up the game actually took longer than the 2 weeks, because I just didn't do anything for chunks of time about this point. Make manageable chunks of work! You wouldn't believe how many little things need sound effects.

I had played around with the idea of doing all the sounds for the game, including music, with my mouth. I kind of loved this idea, and still do. It fits the aesthetic. Here's a demo I played with covering One Winged Angel with my mouth:

Here was my conundrum: I couldn't figure out how to successfully mix normal quality mouth sounds. I made a bunch of bitcrushed sound effects that sounded great, but didn't fit the game itself because the art style wasn't 8-bit at all.

I finally gave in and turned to freesound.org and Kevin MacLeod for my sound and music. I think this turned out alright. I loved that freesound let you bookmark sounds into folders, which made copypasting into my credits much easier. Kevin's music is great; it's all CC and lets you search by vibe, speed, instruments.

I'll revisit the bitcrushed mouth sounds one day. It was too fun of an idea.

Day Y: Balance

This took me a long ass time to get to just because it sounded miserable. All the numbers in my game were an absolute mess. I tried to find guides on how to do this holistically, but at the end of the day the answer was just make spreadsheets and playtest things.

I'm not going to lie - this was a chore. But it wasn't as bad of a chore as I intended. How I ended up thinking about this was taking Ratler and giving him some arbitrary numbers to start with. The rest of the game started from that bottom up approach.

I set up my spreadsheet to adjust his stats appropriately with different amounts of level ups (spread evenly). I decided things kind of randomly like how long I wanted a level to last. I wrote python scripts to see how many enemies would spawn before the boss.

Where we kind of ended up was a level would take 2 minutes and spawn about 30 enemies. I figured it would take at least a few goes before you could get all the way to the boss, so maybe around 30 kills total. I saw what Ratler's health and DPS were at at level 30, assuming even spread of stats, and made the first round of bosses have stats like, say, HP that would last 20 seconds with a level 30 ratler, DPS that would match his HP for that time assuming a few health items. You get the idea.

This was a good starting place, and then I played it. If it didn't feel good, I'd half or double whatever value felt off to get it feeling radically different, and then work in that space until it felt good enough.

I didn't overbalance on purpose. Partly because I'm lazy, and partly because I wanted to be surprised by how players would break the game or encounter difficulty.

I was really pleased after playing through the whole game that it took just about 30 minutes, including failures, to beat. I've said before that I was unsure if I could make a 30 minute video game, and to do so by accident felt cool.

Lessons learned

Picture of Ratler

That's all I really have. Thanks for reading! Reach out if you have any questions at all.