Thursday, August 28, 2014

Using Jenkins with Unity

Going off my last post where I used a batch script to automate Unity builds, I decided to take it a step further and integrate Jenkins, the popular CI sofware, into the process. 

With Jenkins, I can have it poll the Demons with Shotguns git repository, and have it detect when changes are made, in which it'll perform a Unity build (building the Windows target) and archive the build artifacts.

What's great about this is that I can clearly see which committed changes relate to which build, helping me identify when, and more importantly where, a new bug was introduced. 


I currently have it set to keep a backlog of 30 builds, but you can potentially keep an infinite number of builds (limited to your hard drive space, of course). 

So how do you configure this? Assuming you have Jenkins (and the required source control plugin) installed already, create a new job as a free-style software project. In the job configuration page, set the max # of builds to keep (leave blank if you don't want to limit this). In the source code management section, set it up accordingly to whichever source control software you use (I'm using git). This section, and how you set it up, is going to vary greatly depending on which source control software you use.

Under build triggers, do Poll SCM and set the appropriate cron job syntax based on how frequently you want to poll the source repository for changes. 

Under the build section, add a Execute Windows batch command build step. You then script up which targets you want to build (you can use the script in my previous post as a template). 

Under post-build actions, add Archive the artifacts. In the files to archive text box, setup the fileset masks you want. For a standalone build it would look like "game.exe,game_Data/**". 

That's it! I do know that there is a Unity plugin for Jenkins that'll help run the BuildPipeline without having to write a batch script but I never had success in getting it running so I just went this route. 

Automating Unity Builds

I wanted a way to automate building Unity projects from a command line, but to also commit each build to a git repo so I can keep track of the builds I make (in case something breaks, I can go back to previous builds and see where it might of broken). This is my poor man's CI process.

Here's the script in all its glory.

As you can see, it's nothing special. Simply plug in the path to your project and where you want to the exe to spit out. Adding other build targets is trivial as well. Best part of this, it doesn't require the Pro version of Unity at all!

This solution is temporary. I'm going to wrap this in Jenkins so that it'll detect git commits then build and archive the game's .exe. More on that soon!

Monday, July 7, 2014

How to program independent games by Jonathan Blow - A TL;DR

On April 1, 2011, Jonathan Blow gave a presentation at UC Berkeley's Computer Science Undergraduate Association entitled How to program independent games. Thankfully, it's available on YouTube. This talk is insightful not just for the indie game dev, but for any software developer in general. Please take the time to view it.

This is a talk about productivity, about getting things done, more than anything. Programmers that get their computer science degree are often taught how to optimize code, but this generally comes at a great expense to productivity. Indie game devs have to wear several hats (if not all of the hats), so time is too precious to be wasted.

There are several examples Blow goes through to illustrate this, some of which I think are very weak arguments given modern APIs (I'm referring to his hash table vs. arrays argument), but the majority of them are spot on. One that stood out in particular is the urge to make everything generic, when it may not be necessary. More often than not, a method you're writing will be a one off, only used to perform some type of action on one type of object, so time is absolutely wasted trying to make that method work on an entire hierarchy of objects.

The biggest take away is simply this: the simplest solution to implement is almost always the correct one. Get it done. Move on. Fix it/optimize it only when you absolutely need to.

Monday, April 21, 2014

Creating a flexible audio system in Unity

Unity's audio system isn't without its disadvantages. One of it's major issues is that a single AudioSource can only play one audio clip at a time. You may say "well, that kind of makes sense" but why not fire a background thread for each play request?

Playing only one audio clip at a time can be a problem in scenarios where you have an AudioSource attached to a prefab, your Player for example, and you have multiple audio clips you'd like to be played in succession. Your player jumps, so you want to play a jumping sound effect, but within the time that jumping sound effect is playing, they get hit by something, so you swap out the audio clip and play a player hit sound effect, but if you're trying to use a single AudioSource, that'll cut off the currently playing jumping sound effect. It'll sound bad, jarring and confusing to the player. Most obvious solution is to simply attach a new audio source for every audio clip you'd like to play. That may get nightmarish if you end up having a lot of possible audio clips to play.

My solution has been to create a central controller that'll listen for game events to spawn and pool AudioSource game objects in the scene at a specified location (in case the audio clip is a 3D sound), load it with a specified AudioClip, and play it, and return the instance back to the object pool for later use. This allows you to play multiple audio clips at a single location, at a single time, without cutting each other off. You also get the benefit of keeping your game prefabs clean and tidy.

I'm always reluctant to share my code because I use StrangeIoC, which not everyone is using (though you probably should!) and the code structure may seem alien, but a keen developer should be able to adapt the solution to their needs. Let's go through a working example.

I've attempted to comment this Gist well enough so that people who aren't familiar with StrangeIoC can still follow along. The basic execution is

  1. Player is hit, dispatch a request to play the "player is hit" sound effect
  2. This is a fatality event, dispatch a request to also play the "player fatality" sound effect
  3. PlaySoundFxCommand receives both events
  4. For each separate event, attempt to obtain an audio source prefab from the object pool. If one is not available, it will be instantiated
  5. If the _soundFxs Dictionary doesn't already have a reference to the requested AudioClip, load it via Resources.Load and store reference for future calls
  6. Setup the AudioSource (assign AudioClip to play, position, etc)
  7. Play the AudioSource
  8. Start a Coroutine to iterate every frame while the AudioClip is still playing
  9. Once the AudioClip is done, deactivate the AudioSource and return it back to the object pool

With this system, you never have to worry about audio clips cutting each other off, everything is centralized, and you don't have to manually manage the different possible AudioSources. However, you do need to keep an eye on memory usage as we are pooling and saving reference to a lot of resources, which may hinder how well this system can scale. A possible improvement is to limit the number of AudioClips we save reference to in the _soundFxs Dictionary, and when that limit is reached, remove an entry. You could go as far as to figure out which sound effect are least used, and remove those first. 

Thursday, March 27, 2014

Reducing Your Game's Scale: Save It For The Sequel!

It seemingly happens to almost every designer, novice or veteran, AAA and indie. You have that grand game idea. When you close your eyes, you can see it being played before you. The expansive levels, the fancy weapons, the beautiful graphics and audio, all of the little polished details. Then you snap back to reality and (hopefully) quickly realize the scale of your dream game is simply too large.

Time to start cutting!

This may seem terrible and disappointing, but just because you're cutting features and making compromises doesn't mean the initial vision is completely lost. Firstly, you're helping to ensure that you actually get to release your game. This is the ultimate goal, and everything should be done to ensure this (oh, but do make sure you provide a great experience!). Take the ideas you're cutting, write them down somewhere, as they are not lost forever.

Save them for the sequel!

Obviously, Overtime had a much grander scale when I first started designing compared to what it's been boiled down to now. Even after I write this, I'm sure more things will be cut. Being a solo developer working on his first actual commercial release, the scale needs to be small to ensure I actually release something. However, everything that I am cutting I do want to see come to fruition, so it's being saved for a sequel game, which I hope I get to work on given that the first title is received well enough to warrant it. 

So don't fret, don't fear! Cut, cut cut. You'll see an amazing thing happen, something that you probably couldn't imagine be happening. Your game becomes better for it, and you actually increase your chances of releasing. Not a bad trade off at all. 

Friday, March 21, 2014

The Importance of Player Feedback & Subgoals: Playtest Results - 03/14/2014

I had a quick playtest session with some close friends the other day. I've been making good progress on the game (which is yet to be titled, but lets refer to it by its working name, Overtime). I'd just added vertical axis shooting which I wanted to playtest and I also needed to get some real world QA done as testing a local multiplayer only game is proving difficult.

Here is a clip from one of the recordings I took.

Importance of Feedback

My biggest initial take away is the importance of player feedback for even the smallest actions. From jumping to obtaining a frag, there needs to be feedback provided. The player not only needs to be given feedback to assure his actions are executed, but to be rewarded for the things he does and make them worth doing again. Feedback can be provided in numerous ways, from elegant sprite animations, to subtle or acute particle effects. A small, brief dramatic sequence to a frag can make the frag all the more rewarding, thrilling and special as so awesomely done in Samurai Gunn.
A player swats back another players bullet for a kill in Samurai Gunn.
I quickly added some rudimentary blood splatter particles the day before the playtest to help provide feedback, but I feel it wasn't enough and lost its novelty very quickly. I've since tweaked the blood splatter to project based on the direction of the fatal projectile, tiles around the player corpse become bloody, added  flying gibs and even created dramatic John Woo like slow motion effect when the player is killed. All of these small layers of feedback will hopefully make obtaining player frags more rewarding beyond just increasing a frag score. Simply firing projectiles at other players may be fun at first, but if the overall presentation of the actions is bland and boring, player won't be interested in playing for long.

Fragging a demon with a shotgun in Overtime

Importance of Subgoals

Currently, Overtime has only one goal, kill all other players. There is very little else the player needs to focus on or worry about. This is a problem, as the game gets boring quickly. Once you've killed the other players a handful of times, you've experienced all that there is to offer and lose interest in playing any further.

It could be argued that platforming (successfully negotiating jumps to make your desired mark) and ammo management (collecting ammo packs to ensure you always have ammo) are also subgoals, but I feel they are too subtle. This just may be the nature of simple deathmatch mode in general; I do plan to add other game modes which will add more exciting subgoals for the player I'm sure.

Samurai Gunn has environmental hazards and destructibles. This give players more subgoals, avoid accidental deaths and shape your environment to your advantage (you can destroy certain tiles to the point where they become hazards). Players in Samurai Gunn can also engage in defensive actions, engaging in mini sword fights to parry player attacks and swatting back player bullets. This not only gives players a grander sense of control over their ultimate fate, but an entirely different set of actions and required skills.

This was a great round of playtesting and really highlighted serious gaps in Overtime's design, which I'll need to address. The above GIF of Samurai Gunn does such an incredible job of summing up the entire game, its mechanics, the level of polish and feedback, goals and dimensions in just under a second of gameplay. If you need longer than a second to capture the total essence of your game, you should step back and start rethinking your design.