Behold as I pretend that I am a game developer.
Having gotten the very basics of the game--the input system, chiefly--squared away last week, I decided to spend a bit of time on the gameplay itself. Going into the week, I was expecting to make a lot of tweaks to the various projectile mechanics but things ended up taking a different turn.
On Tuesday, I was struck with a little bit of inspiration for what the hero of Ensue should be. I had originally envisioned the hero being a sex- and race-randomized version of a batkid but, in thinking about how the prototype looked, what with all of its rectangles, I thought it'd be funny to use an anthropomorphized strike zone instead. It's somewhat of a programmer's way out of a problem ("just use a rectangle-shaped thing to make the artwork easier!") but I've fallen in love with it. The idea that a strike zone has somehow become disconnected from its umpire and is on a nine-inning quest to find its way home just manages to hit exactly the correct amount of absurdity for my brain. I quickly jotted down some concepts for what the hero could look like and then opened up Piskel and started playing around. I landed on a design that I thought looked solid and fit in with the feel of the mechanics.
With the new sprite, I decided to prioritize improving the animation system. I wanted to see this strike zone's feet move! Animating its shoes was my first time doing such a thing and I was looking a lot at various reference images, for instance Mega Man's classic four-frame running animation and these excellent running sprites by Jason Mercado. I ended up with a six-frame running animation that I'm pretty happy with, especially after tweaking the timing to better fit the real speed of the game.
Once I'd opened the can of animation worms, I found myself wanting an idle animation, i.e. something that would happen whenever the player left the hero in an idle state for a little while. All I did was play with the orientation of the grid lines, to sort of simulate the strike zone's eyes peeking behind him to make sure that no enemies were still coming at him. It was a great proof of concept that added expression to this otherwise quite sterile-looking character. I'm excited to see where we can go from here.
Now that the player controls a character who has feet that you can clearly see, I quickly noticed a bit of an issue: I was still assuming a solid rectangular shape when deciding whether the hero was standing on a ledge or falling off of it, meaning you could very easily make it look like the hero was floating. I'm already using the concept of a "feetbox" to help determine whether the player has bounced off an enemy or has gotten hit by it, so it was a pretty natural thing to just go in and tweak its size and then redo the "standing or falling" detection to be based on the feetbox instead of the overall size of the sprite. I'm not actually sure how games tend to implement all of this stuff, though this thorough deconstruction of hitboxes and hurtboxes in Street Fighter II certainly suggest that a sprite can be rendered at just about any size independent of where its vulnerable and attacking areas are. That makes sense and is something that I'm very interested in refactoring pretty soon; right now, sprite size and hitbox are pretty equivalent concepts in a lot of places of my code.
There were concrete implications to adding new artwork to the project. The fundamental size of the hero changed, specifically widening him from 24 pixels to 36, which meant I needed to regression test all of the basic mechanics. They all still worked as expected but I introduced a bug where, if the hero jumps in just the right way, he would clip through a block that he was supposed to bang his head on.
This was happening because 36 pixels (the hero's width) was now wider than 32 pixels (the base width of a tile in Ensue) and I was only checking for collisions at the hero's extremities (i.e. pixels
(0, 0) and
(35, 0)). Once I started also checking for a collision at the hero's head's midpoint (i.e.
(18, 0)), things were much better.
Having actually dug into all of the pixel-pushing movement code, I was motivated to fix an old fringe bug where the hero erroneously bangs his head on nothing when he jumps just the right way into a wall. I won't go too heavily into specifics here but I needed the game to be willing to cancel out of a situation where it was planning on nullifying the hero's y-movement, specifically in the case that it's already going to nullify his x-movement and there's nothing above his head. This required a good several hours in the debugger to actually understand what was going on and craft a solution. I'm still not convinced the solution is sound but it does seem to work.
Before I added the new artwork, I had implemented a change that turned the hero blue whenever he was up against a wall that he could wall jump off of. The sprites, unfortunately, have rendered this change pretty moot, so I'll need to figure out something else going forward. Adding stickiness to the wall so the hero slides down it slower--thus, hopefully, tipping the player off to his wall jump eligibility--seemed like it was a more complicated thing to do than I wanted to tackle this week, especially considering that I'm not super-sold on this change in the first place.
I changed the triple jump timing window to ten frames instead of five because that seemed to be what people at the Seattle Indies Support Group preferred--in concrete terms, it gives the player 1/6 of a second to earn a triple jump instead of 1/12 of a second--but I've ended up totally unconvinced that its better. In thinking through the feedback process a little more, the triple jump is the third thing my players were being asked to execute and they've spent probably five seconds on the game up to that point. A final product would certainly not require the player to do something with a tight timing window this early on; they'd have spent a significant amount of time playing with the game's mechanics and getting used to how it all feels, maybe even accidentally discovering that a triple jump is possible. When you're still parsing all of that in your first few minutes with Ensue, though, the five-frame window probably does feel unfair. Indeed, I think I'm going to roll this back to five frames this week.
This is where I kind of failed this week. Though I did play around a little bit with the glove and bat, I still can't figure out how to craft a situation that requires the bat over the glove. In thinking about it, it seems like I just haven't yet implemented the environmental types of things that would justify the bat as more than a fun toy. Specifically, things like "hit this wall with your bat to break it" and "hit something into this switch to turn something on, allowing you to progress". When I added these things into the sprint, I was thinking I'd do stuff like goof around with different control schemes for the two devices but I'll just have to settle for having given a good amount of thought to why these things exist in the first place. I plan to implement a bunch of those environmental changes in the near future.
Finally, I tracked a very rough cut of a bass line that could set the tone for some boss music but I'm only medium-happy with it. What I am really happy about, though, is the speed at which I was able to do that in MilkyTracker, along with how much more comfortable I'm getting with Piskel. Good tools are great but knowing how to use them is better.
So, like I said, in a backwards way, this sprint actually did end up being about mechanics, just justified by artwork. I was about to think thoughtfully about why the player might want to use the bat versus the glove, which, even though I initially envisioned more progress with the mechanics than that, is something I've been needing to do for a while. I also wrote down a bunch of thoughts for how automated testing looks in the video game world and I'm very interested in exploring it next week.
For Sprint #3, I'm going to focus on infrastructure. From implementing a basic bug database for myself to getting a flow set for recording GIFs that I can post to an r/gamedev Feedback Friday thread, I'm going to work as much as possible on things that exist behind the scenes and make the actual game development better. It's going to be a shorter week as I'll be traveling on Thursday but I still hope to get a lot done.