Game Audio Instrumentation: The Paradox of Choice

Hello, world! This is a retrospective about Shuriken, a Super NES style original soundtrack for a hypothetical action platforming game released on 25 September 2017. Today we’ll talk about choosing instruments for a game soundtrack, and how this affected my experience with Shuriken. These ideas also apply to developing an album regardless of genre.

Note that today, I’m talking about traditional game audio, the kind of music that loops without variation. Modern tools allow for infinite variation in how to handle loops and stems, including adaptive and reactive music. Those are out of the scope of what Shuriken was attempting to accomplish, a classic soundtrack that would have been released alongside a Super NES game in the mid-1990’s.

Electronic Music and the Paradox of Choice

A difficulty electronic musicians face is the overwhelming amount of instrumentation available. Nothing can stop an electronic musician from making a song with guitar recordings alongside a breakbeat sample, virtual synth, and sounds from old Nintendo consoles. This can be a double-edged sword. While it’s great to have such flexibility and this combination might result in a cool sound, the number of choices makes it difficult to come to a firm decision on what instruments to use throughout a project in order to remain consistent.

Historically, music has been rigid with instrumentation. There were set kinds of orchestras with a set number of each instrument. These were all common, well-known instruments from the period and location. Mozart wouldn’t throw in a didgeridoo because it was unknown to the western world.

Even with the choices available to an electronic musician, it’s important to have an end goal in mind when choosing instrumentation. If breakbeat electronic guitar chiptune is the target genre for your album, go for it. No one can stop you.

The key here is that it’s a conscious choice. Heading into an album with a plan to make synth-rock then turning around and ending up with breakbeat electronic guitar chiptune can only result in a confused mess. The work might be salvageable, but it would require a lot of reworking, especially for earlier things which were meant to be more traditional synth-rock. At the very least, the work would need a new focus on this new genre, otherwise it will continue to shift forever.

When I started Shuriken, I made the conscious decision to produce a somewhat authentic Super NES sound. That meant focusing n the technical specs of the Super NES’s audio capabilities, using sampled instruments from the console. This limited what I could do, but still left my with a lot of choices for instruments.

Super Audio Cart, the Kontakt-driven sample bank I used for samples from the Super NES, has hundreds of options for base recorded sounds. Beyond that, it offers several options to tweak sounds and create new combinations.

Most modern ROMplers and samplers work this way. Not only do you have loads of possible sounds, you can also change the sounds to your liking, resulting in a near-infinite amount of sounds for you to choose from. So, choosing Super NES wasn’t enough. Choosing Super Audio Cart wasn’t enough. I had to keep working to find a focus.

Games and Genre

A fascinating thing about game music is that it rarely sticks to a known genre, unless it’s (again) a conscious choice like Jet Set Radio or Dance Dance Revolution. Most larger projects require a plethora of emotional experiences brought on by different genres. Final Fantasy IX includes operatic orchestral, organs, rock, a bit of classical guitar, and even some electronic undertones at times.

Because of this, I didn’t want to limit Shuriken by genre. I knew the battle themes needed to be intense rock-inspired pieces, the cutscenes would be more cinematic, and the levels somewhere between, ranging from mellow to intense. Still, I needed limitations. I couldn’t jump into a full game soundtrack with the only idea being to make it sound like a Super NES game.

The best limitation I could come up with was to select a small number of instruments. Granted, I made a huge mistake in not using motif as much as I should have, but the common instrumentation was a good step in the right direction.

I made a spreadsheet to show myself which levels had which instruments. Then, I went to consolidating that list. When there were two similar instruments (such as STRINGS Section 1A and STRINGS Section 1B) I chose one of the available options and converted everything to that choice. It didn’t make sense to have two different string sections, two different clarinets, two different electric basses, and so on. This greatly reduced the number of instruments used through the soundtrack.

 

The Google spreadsheet I used to track data about Shuriken, including instrumentation

 

Every time I went through the soundtrack, I had fewer instruments. I’d ask myself if a sound was different enough to merit a unique instrument for that track, and for the most part the answer was no. Sure, Organ B3 had a certain darkness that sounded great for a certain cutscene out of context, but introducing the Drawbar Organ that would be prominent in later tracks made more of an impact.

Seeking Connections

The effect of a game soundtrack happens over a long period of time. The player hears several tracks repeat in a traditional game soundtrack, which breeds familiarity with the sound of that one loop. This makes it even more jarring when music comes along that doesn’t fit the mold they’ve come to expect.

Granted, there are times you want a jarring effect, when you want to say to the player, This is where things change or This is where things get serious. But overall, the best soundtracks are those where you hear a random song and instantly think back to the experience you had. Few people familiar with the games will hear Earthbound or Mega Man X and wonder what game it might be from.

The smallest callbacks can sometimes make the biggest difference. The exact combination and reverb of electric guitars prevalent in Mega Man X or the unique sound effects riddled throughout Earthbound bring them a special character. Mega Man X is especially in strong in its limited palette of instrumentation for each installment, although the soundtracks never get old because of variation in style, rhythm, and arrangement.

Shuriken, on the whole, failed a bit in this regard, as the small connections in instrumentation were the only connection running through the soundtrack. In retrospect, I should have spent more time creating a consistent palette of sound that would run throughout the game, even with extreme variations. As the project went on, the instrumentation got away from me and introduced too many different sounds, creating a disconnect throughout the overall soundtrack.


Thank you for taking the time to read this blog post. I hope you found the information useful. If you have any questions or comments, feel free to leave them below.

For more from me, please follow me on Twitter.

Happy composing!

Ludum Dare 37 Postmortem: Orb Protector

Every time I do Ludum Dare, the “competition” which gives developers 48 (or 72) hours to develop a game, I have a totally different experience. When I did the 34th and 36th editions, I decided to go the jam route, even though I was working solo. This gave me that pivotal extra 24 hours. The first time I did a top-down racing game, and the second time I did a pure text game.

For the 37th edition, I was planning long and far ahead to make a retro-styled platformer of some description using Unity, and to enter the compo (48 hours). This doesn’t mean I did much to lead up to it, though. More on that later.

I ended up with an action platformer where you protect orbs from enemies and can shoot them with a crossbow. Technically, I achieved what I set out to create, albeit in a stripped-down fashion.

You can play Orb Protector here or check out the postmortem after the break.

play

What Went Right

Design First

I started with a plan, and by golly gee I followed it. Living in the EST time zone, the jam started at 9pm, which is an awkward thing because it only gives me a couple hours at most (hey, I’m old, I need to get to bed early) to do anything on the first day (Friday). I wouldn’t let myself go to bed until I had a solid, workable idea.

Right off the bat, the theme triggered four ideas. I eliminated one of them based on scope, and the other three were awful. I racked my brains for another hour until I hit the proverbial light-bulb, whereupon this happened.

idea

This is, more or less, the idea as it was eventually implemented. Forcing myself to do this was a great idea. I even threw together a preliminary asset list based on these thoughts before heading off to bed.

Technical Implementation Second

My proudest moment of the jam was having a functional game with boxes and lines before adding any other assets. It took most of the first day and almost half of the second day (more on that in “What Went Wrong”) but there’s something about seeing the ideas in play that allows you to think more critically about the design elements. Without any distracting graphics, you can see which parts are fun and which parts aren’t.

When the “bullets” hit the wall and didn’t disappear, I was intrigued by the idea of them sticking, so I made a script to stick them to the wall. I think it ended up pretty cool. I got the movement, reloading, shooting, spawning enemies, killing enemies, and so on working, tweaking as I went, conceptualizing what everything would look like when the art came along.

On the same note of the technical implementation, I’m proud that I kept to my reusable, readable code standards in spite of the time pressure up until the very end. There are few hacks, and I added most of them in the last few hours of the jam to fix some weirdness. Most of the code I wrote will be reusable as framework for my next game jam, or any other games.

Amazing Tools and Pre-Jam Experimentation

Unity was great as always. The 2D Platformer Controller by Markus Staib was an absolute godsend of a Unity package. I modified the code a lot, but it gave me a really good basis for excellent maneuverability and player control.

Aseprite has never steered me wrong, even with my lacking pixel slinger skills. Exporting from there to Tiled then into the project with Tiled2Unity is smooth and, although it has some kinks, does a lot of the heavy lifting quickly.

I used all of these tools to make a little thing before the jam started, which helped me rediscover a lot of things. I should have spent more time with this (see bits about animation and audio in Unity below) but I would have been completely lost if I’d jumped into the jam cold.

What Went Wrong

Freaking Out About the Idea

I couldn’t sleep much Friday night because I kept thinking the idea wouldn’t work, that it would have to be tweaked to be top-down or 3D, otherwise the game would never be any fun. I shouldn’t have come to these conclusions so quickly without going forward with the idea. Be confident in your idea. Not your first idea, mind you, but the one that strikes you as “hey, this is the one!”

Changing course should happen early, but know that game jams aren’t meant to create gems every time. It’s a sandbox where failure is not only possible but encouraged. If the game isn’t fun, if it’s completely unsalvageable, well hey – it’s a game. It’s done. Now you can eliminate a possibility that doesn’t work, and learn from why it doesn’t work.

Too Long to Technical Implementation, or No Such Thing as Small Scope

This issue was a combination of two things: having too grand a plan and not having enough of a framework from the start. Next Ludum Dare (assuming I do Unity again), I’ll have a lot more basic framework stuff to work with.

Without assets to implement, I didn’t have any framework for animation or audio, and I wasn’t handling all the mechanics correctly. This was a mistake because I ran into snags with all of these things in the final six hours of the jam. I should have modeled the final requirements (sloped surfaces, ladders) more accurately with boxes and lines before calling the technical development “finished,” and I should have put in temporary bits for audio and animation to make sure those technical areas were covered.

As the jam progressed, I had to drop features. Luckily, I was smart enough to develop the core before anything else, so I didn’t have to remove anything that I’d already implemented, but there were things I would have liked to have that I couldn’t:

  • Ammo limitations and static ammo box for refilling
  • Enemies with actual weapons (the swords are fake *gasp*)
  • Multiple enemy types
  • Melee weapons
  • More ranged weapon types
  • Player health
  • Other droppables by enemies etc.

Of course, that doesn’t mean I can’t add these in a future version. 🙂

On a related note…

Not Enough Time for Assets

I literally threw together the wave complete, game over, reload, and pickup sounds plus the enemy and player death animations in the last hour. There wasn’t any animation at all until three hours before the jam ended. There wasn’t any player/enemy art until six hours before it ended (except the crossbow).

If I’d finished the technical stuff earlier and didn’t have to go back to it in such a large degree, there would have been more time for the assets. But when I started constructing the levels from tiles and experienced issues with slopes and ladders, I had to put the art on hold. And when I needed to implement audio and animation, I had to remember all the quirks of Unity that I’d long forgotten, which I should have experimented with before the jam so I didn’t have to run around in circles during the crammed hours of Ludum Dare.

Also, I made the music early on in one pass per track, and I should have spent more time on those, maybe even chosen NES or Sega Genesis as the basis and had them fit more nicely together.

Conclusion

At the end of it all, I felt like the 48 hours hadn’t happened at all, that I was going to sleep on Friday night and the whole thing had been a vivid hallucination. Since the game exists, I guess that isn’t true.

Now that I know what the 48 hour limit feels like, I can prepare for Ludum Dare 38’s compo. The framework code I’ve put together from this jam should be a huge boost.

As for any advice for those wishing to enter Ludum Dare:

  1. Finish all technical stuff early: game flow, core mechanics, additional mechanics, and temporary animations, sound effects, and music. Make a complete and playable (maybe even releasable) boxes and lines prototype with zero assets. If you have an audience, release that version to them and get feedback on pure gameplay.
  2. Focus. Do design, code, art, sound, music, animation, or testing, but do not jump back and forth. Set aside multi-hour chunks where you only do one thing. You get 48 (or 72) hours. Allocate them.
  3. Leave at least six hours for polish. This includes technical testing, refining assets, and adjusting game values to ensure maximum balance and fun.
  4. Spend time getting good default controls. Don’t put too much effort into a readme. People won’t read – they’ll download, launch, and play your game. Even though Unity has a nice launcher where they can see and customize the controls, they won’t. (Apologies if this sounds cynical but it’s true. >_>)
  5. Package your game in a zipped folder containing a folder containing all your game stuff. The extra top-level folder makes it easier for people to drop it into a folder where they’ve extracted other stuff. Include a shortcut or link to your Ludum Dare page so they can rate your game even if they closed out of the page, and don’t forget all your social media links!
  6. Do the 72-hour version. The compo is for lunatics. xD

Ludum Dare 36 Postmortem: Conor & Harley

This is the postmortem for my game Connor & Harley made in 72 hours for the Ludum Dare 36 game jam.

Yes, you’re reading that right–there’s no Ludum Dare 35 postmortem. Although I was involved in making music and audio for that particular jam, I felt separate from it, and my work was sporadic rather than constant. For that reason, I never got around to doing a postmortem because it felt wrong doing it for a disjointed event rather than a specific project.

For the 36th edition of Ludum Dare, which was my third and the second one in which I attempted the compo (working alone), I decided to make a text adventure. I know the modern parlance is to call it interactive fiction, and in fact the game did veer in that direction, but I can’t bring myself to call it anything except a text adventure, because to me these games owe their legacy to Crowther’s Adventure and Infocom’s Dungeon (Zork series).

No, I don’t think the thing I cobbled together in 72 hours come anywhere near comparable to these. Actually, I won’t even call it a finished game (story) until I’ve had at least three or four more releases in the distant future. However, these games are a deep part of my childhood, even though they were around for decades before I was born.

I won’t bore you with a historical account of my experience in interactive fiction, except to say that I owe a lot to Campbell Wild’s ADRIFT system. Not only did this system get me making my first games, it also taught me many things about programming, including the revelation of the mysterious things known as “variables.”

And now we move on to the fabled Two Sections of a Game Postmortem.

What Went Right

The decision to switch to the jam (72 hours instead of 48) in the middle of the competition.

I also mentioned this in my Ludum Dare 34 postmortem, and it was exactly the same situation. I figured because I wouldn’t be spending time creating assets, I wouldn’t have this problem again. I was very wrong, for all the reasons outlined in “What Went Wrong,” below.

But it was a good idea. I came to a point in the middle of the second day where I realized my game had potential. This left me with two options: cut corners now to get the game into a finishable state, or continue on to the third day. There weren’t really any cons to adding on the extra day, other than being out of the competition. Since this Ludum Dare doesn’t have rankings it didn’t make a huge difference.

The jam option allows additional benefits, such as working in teams and not sharing your source, but I decided to stick to the compo rules and tack on the extra day as a sort of hybrid challenge to myself. The end result is much better than it would have been otherwise, especially because:

Someone who wasn’t me play-tested the game.

Watching this play-test, taking notes, and seeing the resulting transcript led to a huge number of changes in the last four hours of the jam. These ranged from simple typos like “your hair rubs against your ceiling” to huge, game-breaking situations like the player being able to magically hop into the ending without solving the second-to-last puzzle.

Even though this meant finishing the game before the deadline and taking time out to watch the play-test on-fold, the benefits were huge. I had always heard it’s a good idea to finish at least half a day early for play-testing even in a severely limited event like a game jam, but now I’ve experience it first hand, and I truly believe it. I only wish I had left more time for testing, or had more testers to try the game.

Eating, sleeping, and generally looking out for myself.

This one is a given which I learned was a good idea in my first jam. Although Conquistaquest ended up being rather impressive since I was learning the tech as I went and didn’t have any prior completed-game experience, I basically blew off the last 12 hours in a blind daze and couldn’t solve some of the more killer bugs late in the jam. This led to us dropping a couple features which could have been fun, and which I could have implemented quickly after some proper sleep and nourishment.

Using good tech designed specifically for what I wanted to accomplish.

You’ll see my decision to use Inform 7 as a pro and a con. It’s a pro because the system is hugely intuitive. Inform 7 uses a “natural programming language” which means most of the code reads like a book. Some of it can be a bit weird–which I’ll get into in the “What Went Wrong” section–but generally it’s as smooth as writing a novel.

Here’s an excerpt of actual code from the game which reads like normal English:

The crystals are part of the chandelier. They are scenery. Understand “crystal” and “pearls” and “glass” as the crystals. “Glittery balls of glass held together by nearly invisible string or chains. Some are more globular than others, and a bit cloudy. You wonder if they’re pearls or simply meant to look like them.”

Although some of it is a bit stilted and technical, you can get a good idea of what’s going on here. You can see more by browsing the game source and learn more about the language on the Inform 7 website.

Going out of my storytelling comfort zone.

I have a long history of jumping on fantastic worlds, magic, the traditional (cliché) medieval setting, and the like. I used a bit of this as a crux in this adventure, but the idea of setting it in a modern, real-world (ish) place would normally terrify me.

The leap out of my comfort zone was intentional: by doing so, I created a brand new universe to explore. Although the game isn’t set in a specific, real place, it involves college students in a renaissance-era palace and I did a significant amount of research in the short 72-hour development period. I think this led to a more believable and interesting experience, but it may have also led to some holes and inconsistencies. We’ll get to that soon.

What Went Wrong

Very minimal outline before starting development, which led to all sorts of problems.

Here’s a shortlist of the problems this cause:

  • I was way too blabbery in the beginning, and as I started to run out of time, the game text grew terser.
  • I didn’t leave any time in the beginning for research because there wasn’t any idea specific enough to research. This was especially a problem in a modern setting.
  • The work went from start to finish. As I suggested to myself in the LD34 postmortem, it’s always best in a tight deadline to get the thing done from start to finish as quickly as possible, then fill in the complexity and details of the middle. Didn’t do that.
  • A lack of focus as to what the game was going to be. I started making an event-based story but had it in my head that I wanted a traditional text adventure, so the game became this weird collection of both and sometimes a hybrid.

Limited prior experience with Inform 7.

Although I worked through the entire tutorial book several years ago, Inform 7 has changed drastically since then. I’ve also only made a single, very small game with the system, so I wasn’t familiar with all that it took to build a larger project from start to finish. Sometimes I tripped on the more obscure pieces of the compiler.

For instance, you can’t use “if, otherwise if, otherwise” unless you’re using the “big if statement” format. This means that the following won’t work.

If the player is tall, say “You hit your head on the ceiling”;

otherwise if the player is short, say “You pass through with ease.”;

otherwise say “You pass through, but your hair brushes the ceiling.”

Instead, you have to phrase it like this.

If the player is tall:

say “You hit your head on the ceiling”;

otherwise if the player is short:

say “You pass through with ease.”;

otherwise:

say “You pass through, but your hair brushes the ceiling.”

Notice the semicolons, colons, and indentation here. Those are all super-finicky, including the periods, so it took a long time to get used to these rules. No matter how natural Inform 7 appears, it’s still a programming language. That means it abides by very strict, very technical rules.

On this same note, finding a specific phrasing of something can be very difficult. The functionality to search through the documentation searches broadly and has no advanced features. So if I’m trying to find what the word “called” does, I get every single instance of the word “called” in the documentation, including the ones in the main text (not in code examples).

These problems largely went away later in the jam as I grew more familiar with the system’s quirks. I also started to find answers more quickly as my vocabulary began to match that which the system expects. It’s kind of ironic how using Inform 7 can be like playing a frustrating text adventure sometimes, where you’re stuck trying to guess the verb, like when the action is “using it with” instead of “using it” or “using with it”.

No codebase to work from.

Related to my lack of experience with Inform 7, I didn’t have any code for it lying around. Before the jam, I pulled together as many extensions as I could so I could make my starting point super-flexible. However, I found that many of these extensions use obscure language just like the core language, so trying to figure out all their technicalities on top of the language itself only made things worse.

Now that I have some more code under my belt, I can start creating my own personal extensions. The next time I write an adventure I’ll have a lot of the technical bits from this specific game already implemented in a way that makes sense to me. That’s a huge boon over starting from scratch.

The adventure blew way out of scope.

This is something I need to continue to work on, and I think it’ll get better as I do more of these jams. You can’t do a lot in 48 hours, or even in 72. There’s no getting around that. So instead of trying to do more, you should find a way to accomplish more in less actual content. Hence the popularity of procedural generation at Ludum Dare.

The scope getting out of hand was largely a product of not having a complete outline. I didn’t know the ending, I didn’t see the bigger picture, and I kept changing course as I went along. I started with large swathes of text, spending the entire first day on what I thought was going to be nothing more than the introduction to the game. Possibly I should have cut my losses at that point and made the introduction the full game. In that case, I might have finished in 48 hours.

In the end, the game has a lot of empty space and things which don’t exist because it was too big for me to handle in this short period of time. Next Ludum Dare I’m going to think so small it hurts, and then build from there. Much easier to do that than to think big and cut down.

Conclusion

My initial thought was to do procedural generation, but when I went down the text route, I had to familiarize myself with the language. Now that I’m more clear on how Inform functions, maybe I could pull off something a little more procedural. The problem with text is that it can’t be abstract enough to really be generated without insanely advanced natural language processing.

Maybe at the next Ludum Dare I’ll do something procedurally generated, more abstract, more programmery. Or maybe I’ll try another crack at a text adventure. My next big project is going to be NaNoWriMo, so it could go either way: I might be burned out from writing my novel, or I might be so into writing that I want to keep going with it.

In any case, I feel like I succeeded again at this Ludum Dare. I made a game that is playable–and winnable–in a period of 72 hours, on my own. Got to give myself credit for that.

Ludum Dare 34 Postmortem: Tech Rider

I made a game in three days for the 34th iteration of a popular game jam called Ludum Dare. My entry is a two-button futuristic racing game called Tech Rider. Well, I say racing–really it’s a time attack game.

You can play the game here.

My involvement in this game jam kind of came out of nowhere. Less than a week to the event, I realized two things:

  1. It was happening next weekend.
  2. Nothing was stopping me from entering.

With these things in mind, I decided to enter. It was a bit late to find anyone to work with, so I decided to enter solo. Because of this, I was on the fence about whether to enter the Compo (48 hours) or Jam (72 hours). In the end I went with the latter, but I was sure to follow the rules so I could make that decision near the end of the Compo.

Fly Killer

(the game, not the racer – a brief prejam postmortem)

On the Thursday before the event began–23 hours to its start–I decided it would be a good idea to do a warmup game. So I set myself a time limit of three hours, spent about 15 hours doing preliminary setup stuff, and made Fly Killer.

flykiller.png

This turned out to be a very good idea, because it helped me work on the kinks in my workflow. I rediscovered quirks in Unity (except the new scene management, but that’ll come up later), relearned a bit of what works with git, and revisited the flow from Aseprite to Tiled to Tiled2Unity to Unity.

I managed to hit my playable target within the three allotted hours, which was a huge boost to morale right before the jam. During development, I switched from a more traditional design of “move swatter over fly and click to swat” to the simpler “move swatter into fly to swat.” Personally, I found the latter more engaging–and it was easier to implement without bugs.

That out of the way, it was on to the main event!

Three Days to Tech Rider

screenshot_title.png

What Went Wrong

Circuitous Route to Design

I spent a large part of the jam’s first 24 hours implementing a mechanic where pressing left and right together would cause your ship to charge, then pressing left or right after charged would cause your ship to “smash” in that direction. This was meant to be an attack mechanic.

Initially, the game was supposed to be a purely vertical racer with some turns thrown in. The focus was combat: destroy other racers as you catch up to them. This seemed a bit silly on further inspection, that each racer would either die by your hand or never be seen.

The charge and attack stayed throughout further development, even as I changed the strafe movement to turn movement and made the tracks less vertical. Late in the jam, some time on Monday, I realized that the strafe attack was still going left or right, even if your ship was facing a different direction. This meant keeping it in would allow you to continuously charge for a speed boost on horizontal tracks.

This might have been fine, but when I came to the extremely late decision to remove AI racers altogether, it seemed totally out of place. I liked the idea of a charge boost but I ran out of time to make it work in the new context of the game. So, like AI racers, I ended up disabling it altogether for the jam release.

This meant the controls were woefully simply–left or right, nothing special–but after removing AI racers, it didn’t make sense to keep the attack in. This is definitely an area I can flesh out on further releases, where AI racers are a top priority for additional features, since they already kind of work.

Late Game Flow

One thing I did right in my first Global Game Jam and the GBJam earlier this year was to start with the beginning and the ending of the game, then flesh out the middle. I’d heard this was a good idea from a lot of people I trust, both at GDC and in books.  Unfortunately, I forgot this piece of wisdom for LD34.

I stared with the middle: the racer moving up the track. I later added the countdown, then the finish. Finally, I made the racer select, title, and flow between races, in that order. This led to many problems, including the Crusher Bug which I wasn’t able to fix by deadline.

screenshot_crusher-bug

This basically halted the title screen camera from getting destroyed, resulting in all sorts of awkwardness including an immobile camera.

On top of doing this in the wrong order, I didn’t realize that Unity had deprecated the Application.LoadLevel() method. I could have used this method, but early on I’d made a pact with myself to do things right with the code, since doing otherwise had almost crippled my GBJam game.

Unfortunately, a Google search for “unity scenemanager” gives hits for an extension package, and not the official SceneManager documentation. Eventually, I was able to find the documentation, but it was kind of a headache learning the one little bit I needed to know to get it to work–that scene management is in its own namespace, Unity.SceneManagement.

Targeting Windows

Although it’s convenient to target Windows, this means the porting to other systems has to come later, and is often rife with issues of its own. I should have started with a web target in mind to reach the broadest possible audience, rather than saving this for after the jam. Next time around this should be an early priority.

Track Art

The art for tracks reflected the original vertical design, in which there are only left and right walls. That was until I discovered that Tiled (in its super awesome awesomeness) allows you to rotate tiles. So, for one, I didn’t need to manually add the flipped right side tile, and for another, I could easily make walls on the top or bottom.

track-tiles.png

That said, I didn’t have time to make curved, slanting, or corner wall tiles. I was also kind of lazy and baked the walls into the road tiles. Really, the walls should be separate so I can layer them on top of the roads as I see fit. I’ll probably do that in a future version.

Minimal Testing Time / No Controls for Testing

I had very little time at the end to test the completed product, which was a huge mistake. I still don’t know if unlocking the Tech Rider really works, and i wasn’t sure the kinks were worked out of the second or third tracks. I made the third track really late in development–started the assets Sunday night, finished the track Monday morning–so I only played through the whole thing once or twice.

I added the path nodes for tracks 2 and 3 in the last hour of the jam time, so these were rushed and really spaced apart. As a result, respawning in these tracks sometimes results in jumping half the course.

Screenshot 2015-12-15 20.19.10.png

As you can see from the image, there are a lot, but really not enough–especially on the upper part of the split in the middle.

I had no way to skip to a specific race quickly, which is another lesson: include controls to test the game. These are great, because they can later be refactored into cheat codes or unlockables.

What Went Right

Unity

What is there to say about this engine/editor that hasn’t been said before? Sure, it’s rough around the edges for huge, highfalutin AAA games, but for indies it’s a bloody godsend.

I’ve been trying to learn Unreal off and on for a while now, but it’s just so targeted toward huge games that it’s difficult to get into it as a solo developer. Unity is the complete opposite: I’ve always felt it was approachable. It’s easy to pick up new things, and all of it just works. And C# provides a whole slew of friendly stuff I can include.

One thing I hadn’t used before that was critical to getting the game done on time was PlayerPrefs. I came to the conclusion that the game needed some kind of “best times” tracking. Although I was still going to have AI racers at the time, this eventually became critical to making the game competitive at all, since this is the only way to judge your performance.

screenshot_best-times.png

(You can see here that I should have made the track a little bit wider to hide the clear color on the left…)

PlayerPrefs is a wonderful class that automagically stores integer, floating-point, and/or Boolean data to the operating system for you. It’s trivial to retrieve this data. No messing about with files or OS-specific nonsense. Implementing a “best times” table was super quick because of this, as was implementing the unlockable Tech Rider ship.

Music & Sound

As early as possible, once I’d settled on a concept and developed a bit of functionality, I created as many sound effects as I could imagine. This was a great idea because hearing the sound effects over and over made me realize how grating and terrible they were. This left me plenty of time to rework the sound effects.

I made the music for the first track early, as well. Although I didn’t get around to fixing its issues, I was able to take useful notes on the music at different points in development which will help refine it. I didn’t get to the rest of the music until Sunday morning (around the 36 hour mark) so I didn’t have as many notes for those, and like I said earlier, I didn’t get to test the other two tracks nearly as much.

My early decision to have everything in the key of C or Cmin seems to have paid off. I don’t really know about this because I don’t have any feedback on the sound at the time of writing, but all of the sound effects (engine sound, crashing sound, countdown sound, etc.) are on the note of C, and all of the music starts with a C chord. In the case of the last track, it’s C minor. I’m still up in the air whether this was good, or it should have been A minor.

I’m also proud of the decision to create the ship select / high score theme first, then remix it for the title theme. The title animation isn’t nearly long enough for you to appreciate the full track, unfortunately, but you can have a listen here if you wish.

[soundcloud url=”https://api.soundcloud.com/tracks/237618978″ params=”auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&visual=true” width=”100%” height=”150″ iframe=”true” /]

Simplified Stats

Past the 36 hour mark, I put together a spreadsheet and saw how ridiculous my formulas for ship movement had become. I stripped this down to three stats: max speed, acceleration, and weight. This was still too complex for my tastes, as I kept balancing things up and down, back and forth, so I dropped the weight factor altogether.

Time Warper has better acceleration, Sky Crusher has better max speed, and Fly Killer is between them. Since Tech Rider is unlockable, it’s a bit higher in both stats. This gave me a direction to go not only with the stats, but with the machine design: Sky Crusher would look rounder and heavier, while Time Warper would be sharper and more streamlined.

screenshot_select.png

This made a whole lot more sense with all the numbers. Even though some miscalculations and/or typos set the hidden values a bit wrong, it helped refine the design to something workable.

Conclusion

All right, so I basically made a bastardized version of F-Zero with Super NES Micro Machines graphics. But it sure was fun–and educational. I’m still working on the Mac OSX port, and considering a future Web port. I could do Android but that might be a while down the road.

I plan to enter the Compo for Ludum Dare 35, and these are the things I need to take away from the LD34 experience to make that one shine:

  1. Create sound, music, and graphics early so you can see the flaws in-game.
  2. Make the beginning and end first, then flesh out the middle.
  3. Ensure game flows from beginning to end periodically during development.
  4. Target web first.
  5. Use tile rotation in Tiled as much as possible.
  6. Separate logical tile layers (like walls) for ease of reuse.
  7. Test the whole thing as early as possible. Leave at least 3-4 hours for full game testing and fixes. Include “cheat” commands to make testing easier.

Check out Tech Rider here, and let me know what you think in the comments. I’d also love to hear your Ludum Dare experience or about any other LD34 games I should play.