Horseshoe Crab Rescue! 2D - Postmortem, Part 2


Building the HUD

HUDs are one of the most important aspects of most games, and yet GB Studio 3.2 doesn't have a good built-in way to create them. For Horseshoe Crab Rescue! 2D, I knew I would need to display an HUD with the player's current score and how much time they had left to finish the stage, but it was quite a challenge to find the best implementation.

There's a GB Studio Cental article on building a HUD, but it relies on pinning actors to the scene. I knew right away that I didn't want to use this approach because it would reduce the number of horseshoe crabs that I could have on screen. 

I was pretty sure that the best approach for HCR2D would be a simple dialog box at the bottom of the screen that remained active at all times and didn't interrupt gameplay.

I first tried implementing this as a GBVM script which ran once a second and also ran when the player rescued a crab, but (not surprisingly) the performance was too slow - there was a noticeable stutter every time the HUD refreshed. Then I moved the basic HUD-drawing logic into C, automatically refreshing once a second as the timer ticked down. This solved the stutter, but there were two other issues:

  • The HUD didn't update immediately when the player's score increased
  • The HUD flickered slightly for each refresh

I wasn't sure at first how to solve the first problem. Scripting events can't call custom C functions (at least not without modifying the GB Studio Editor itself, which was definitely outside of the scope of this project). I ended up using another global variable here. When the script that updates our score runs, it sets a global variable to 1. When the engine code sees that the global variable is 1, it re-draws the HUD and then sets the variable back to 0.

To alleviate the flicker, I decided to only redraw the time digits when the timer ticks down, rather than redrawing the full HUD. This is also better for performance! It was a bit tricky to get the text alignment right because I used a variable-width font, but it worked out.

Animating the waves

I designed the wave animation in Adobe Photoshop. Because all of HCR2D takes place at the beach, I made the wave animation much more elaborate than you’d typically see in a top-down gameboy game. The wave animation has five frames; each frame is 3 tiles wide and has 4 rows of unique tiles, for a total of 12 unique tiles per frame. In the gameplay scene, the first two rows of tiles are reused with an offset to create an additional row.

Waves

On the Game Boy, the background can be animated by replacing specific background tiles. GB Studio lets us do this with two different commands, though fundamentally they work in the same way - by replacing a specific tile in memory with a different tile. Every place where the original tile appeared in the tile map will now display the new tile. If we want to animate multiple tiles, we have to replace them one at a time.

I tried using the GBVM command VM_REPLACE_TILE_XY to animate the background, but unsurprisingly this was yet another area where GBVM is too slow. I had to write my background tile animation logic in C. However, the replace operation requires a reference to the tileset where the new tile is located. Since I knew I would never use GBVM to animate the background, I modified the engine code so that when I call VM_REPLACE_TILE_XY from GBVM script, the engine simply stores a reference to the wave tileset. I then only need to call VM_REPLACE_TILE_XY once at the start of the application to store that reference, and afterward do the animation in C. Of course, some of the non-gameplay scenes don't have animated waves, so I had to use another global variable here to indicate whether or not the current scene requires background tile animation.

Another headache here is that the engine requires us to specify the new tile by its index in its tile set. GB Studio 3.2 automatically removes duplicate tiles when creating tile sets, but it doesn't give us a way to view the tile sets that it's created or to find the index of a particular tile. This can be an absolute nightmare when your animation tile set has a bunch of similar looking tiles, and there are some duplicates in there somewhere but you aren't sure where the duplicates are. In retrospect, I wish I had written a tool to find the index of each unique tile, as it would have saved a few hours.

Music

The music was the most time-consuming and frustrating part of creating HCR2D, for two reasons:

  1. I don't have any formal musical training
  2. The UGE Music Editor in GB Studio 3.2 is terrible

Both of these are huge issues. #1 is, of course, my own fault. I've arranged music (usually starting from loops) for a few projects, but it's not something that I need to do often enough that I have had any reason to take music lessons. For the original HCR, I used premade music from the Unity Asset Store. For HCR2D, I wanted to create original music, but didn't want to take the time to find a chiptune composer who was interested in the project, so I resigned myself to fumbling my way through it.

As for #2... I cannot stress this enough: Do not use the Music Editor in GB Studio 3.2 to compose new music. You should compose your music in a dedicated sequencer and then transcribe it to GB Studio in the Music Editor. Obviously it won't sound exactly the same, but the Music Editor has so many bugs and UX issues that it's counter-productive to use it for composing. (Note: I've looked at the change logs for GB Studio 4.0.0 beta and I don't see any mention of most of the issues I've encountered in 3.2, so it might be just as bad). Some of the issues I've encountered:

  • You can't click on the piano keyboard to preview a note.
  • You can only use your physical keyboard to record notes while the track is playing, not to preview notes or plan out a melody while the track isn't playing.
  • Note previews when placing Noise notes are not accurate.
  • Undo/redo not working correctly for FX added to notes.
  • Sometimes an entire track will completely break if you remove the first pattern.
  • There's no "loop the current pattern" option; you tediously have to add an effect for this and remember to delete it afterward.
  • If you change the selected pattern, it doesn't move the playhead. Then, if you hit Play without manually moving the playhead, it jumps you back to the pattern where the playhead is located.
  • If you accidentally run your game without saving the track, all unsaved changes will be lost.
  • Sometimes, a track just won't play until you quit and restart GB Studio.
  • Sometimes, audio will continue to play from muted channels.

As far as actually writing the music – I started composing in Korg DSN-12 for the Nintendo 3DS. While Korg isn’t the easiest sequencer to use (due to the limited screen size and lack of Undo/Redo), it has Kaoss pads and is fairly powerful. I eventually came up with two variations of a main theme, as well as a secondary theme, and transcribed these into GB Studio.

My original tracks were each only three patterns long. Early feedback suggested that the tracks were too short and repetitive, so I extended each track to around 7 patterns and added more variety. I also ended up creating another short track (a variation on a section of one of the main theme tracks) for the "You Win!" screen at the end of the game.

I may not be a composer, but I'm happy with how the music turned out. What do you think?

----

That wraps up part 2 of my overly long postmortem for Horseshoe Crab Rescue! 2D. Stay tuned for part 3, where I'll discuss artwork, optimization and balance.

Get Horseshoe Crab Rescue! 2D

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.