Posts Categorized: Unity

Gist: Stop Playing on Recompile

Full credit goes to Takuan Daikon (of DFGUI), but we happen to share a mailing list, and this is worth spreading.

Throw this script in an Editor folder in your project, and anytime you save and switch back to Unity, it’ll automatically stop playing.

Under the Hood: Building a Build Pipeline

We’ve been slowly working towards a build pipeline. The code below expects that you have your project organized in a specific way.

With this build pipeline setup, you’ll get:

  • Per-store build options, with automatic preprocessor defines based on the store names.
  • Build versioning, with that version included in the project resources to use at runtime.
  • Post-build file copying, at a per-store, per-platform level.
  • Zipping of projects to names based on their version for easy distribution.
  • The ability to copy and archive your builds in Dropbox for distribution. (Old builds are automatically moved to an “Archive” folder when a new version for that platform is copied in.)

Note: Someone pointed out on Reddit that this is Pro-only. (I’ve always been a Pro-user, so I wasn’t keen to look out for those things. I’ll try to do that more in the future.)

Setting up the Pipeline

Import ZapdotBuildTools.unitypackage to get started.

For most of this to work, my scripts expect the folder hierarchy to mimic what is described here. (Mainly that BuildTools and Unity exist in the same folder.)

  • If you’re running in Windows, you need to unzip the command line version of 7zip so that it exists in PROJECTFOLDER/BuildTools/7zip/7za.exe.
  • In AppInfo.cs, change companyName, longName, shortName, appleAppId, appleBundleId, and steamAppId to match your information. shortName is used for bundle identifiers and filenames, so keep it alphanumeric, with no spaces.
  • In Build.cs, change scenes to match the scenes in your game. The first scene in the array is the one that Unity loads first, and these paths are relative to your Unity project directory.
  • If you want any post-build file copying to be done, simply create a BuildIncludes folder at your main project directory (Same folder depth as BuildTools) and mimic the Store/Platform folder hierarchy to whatever depth you want. The file copy operation will overwrite the destination with whatever you place in the BuildIncludes folder.
  • If you want to use the Push to Dropbox feature, it should automatically work on Windows, but for Mac users, you need to edit line 203 on FileTools.cs to include your Dropbox path. This assumes, of course, that you’ve installed and linked Dropbox to your account.
    • Tip: Grab the share link to the top-level folder for game builds in Dropbox, and create a shortlink for it, so you can then simply share something like bit.ly/MyGameBuilds.

See it in action!

Under the Hood: Versioning your Builds

If you’re going to be putting builds of a game in development into the hands of testers frequently, keeping track of what build they’re playing with can be crucial to tracking down bugs. For the most part, you might be able to tell a build by a major new feature or other visual change. As those builds become more frequent though, especially between strictly bugfix builds,  you’re going to have a much harder time determining what build the user has without explicit definition somewhere.

What you could do is simply throw a static string in some class, and update it every time you kick a new build out. You could also stick your hand on a hot oven. Neither of those options sound very fun to me, though.

Overview

I create a static class that I call AppInfo. In this class I have a bunch of strings and ints that don’t change very often, if ever:

  • Company Name Zapdot
  • Long Name Battles of Ug’Matumtum: Acid Reflux
  • Short Name, without punctuation ugmatumtum
    • This might be used for a filename or path.
  • Major version 0
  • Minor version 1
  • Apple App ID 0123456789
  • Apple Bundle ID com.zapdot.ugmatumtum
  • Steam App ID 9876543210

With this, I can easily create build scripts or UIs that use this information. The most important string that I’ve got in this class is AppInfo.fullVersion, which includes the major version, minor version, build date, and build count.

The build date is formatted YYMMDD (for sorting purposes) and the build count is simply an incremented integer to differentiate multiple builds on the same date.

Storing the Data

I want the data to be easily available to both the editor and the built project. I’d also prefer that the user cannot easily access the data of this file to edit it and potentially introduce confusion with bug submission. To accomplish this, I store the data in a comma-separated format within the Resources directory.

The Goods!

Throw AppInfo.cs in Scripts/ProjectSpecific/AppInfo.cs

Whenever you need to increment the stored build number, call the following function (editor only):

AppInfo.IncrementBuildNumber();

Whenever you want to print or display the full version, simply print or display this string:

AppInfo.fullVersion

Jam: Xeno Overpass

What do you get, when you do a game jam, in one* hour, with thirteen people?

An hell of a time, for one.

We spent a Frunch at the Collective pulling together a game. Everyone had something to do — art, audio, PR, programming, design… and we not only ended up with a game for you to enjoy, we ended up with a documentary too.

Give it a shot with a friend, or read the press kit.

* I was the only one in Unity, so I actually spent about 2.5-3 hours on the game, integrating the assets, and getting gameplay in. Next time we need a tech artist. :)

Jam: Molydeu…l

This past July, I was one of the organizers for the Boston-area MolyJam. This year, the prompt was from a selection of quotes from Peter Molyneux himself.

I was worried I might be pulled off due to duties that organizing the event might entail, so I decided to whip something up on my own.

PROMPT

I’m not punishing you for button mashing; I’m rewarding you for not button mashing, and that is a really big distinction.

 

I took some heavy inspiration from the humor that QWOP evokes from making movement difficult. Multiplayer games like WrestleJump are very easy to pick up, and a blast to play. What if there was a Western-style duel game, where you had really floppy arms?

After a short amount of time, I had some joint constraints working:

Thanks to the magic of the Unity Asset Store, I quickly whipped together a scene:
SceneAfter a little bit of work on the joints, it was simply too easy to get the player to manipulate the shoulder/elbow joints. I decided to switch gameplay to be a bit more based on timing.

After a weekend of work, I ended up with a finished game. I don’t think I’ll pursue the idea much further — through this little experiment it became pretty obvious that much of the challenge and enjoyment of QWOP and Wrestle Jump come from balancing against gravity.

Under the Hood: Project Organization

I spent a few hours this weekend fixing up a build script to drop into some prototypes that I’m working on. Much of the work originates from the lessons I’ve learned shipping multiple Unity titles to various storefronts. I started writing a post to describe it all, but it had so many various dependencies that it made a bit more sense to break it up and go a bit more in-depth when needed.

Over the next few weeks, we’ll look at how I’ve crafted this build script. If it goes well, I may continue the series with more “Best Practices” that I’ve picked up over the past few years.

Project Organization

Cooking is a pretty big hobby of mine. In the same ways that drive my infatuation with games — I’ve had some incredible experiences with some incredible meals, and I couldn’t simply leave them to hand-wavy magic. There was talent and knowledge behind the preparation of the food I was eating, so I set out to learn what it took to make a good meal or three.

One of the first cooking lessons that you should learn is a simple concept called “mise en place”. It’s French for “put in place”, and it refers to the constant organization of your kitchen. Time is incredibly valuable, especially in a professional kitchen, so efficiency must be at it’s highest point wherever possible. Keep your knives, measuring utensils, spices, and cookware in the exact same location, and preparation becomes quicker, allowing the chef to put their time and effort into the creation of their dish, not the assembly.

This applies to game development too. Spend the majority of your time on your craft. Don’t waste your time looking for the damned cinnamon.

Here’s how I currently set up my projects. Certain things get moved around and changed as I find slightly better ways to consider the organization, but after a few projects, I’ve arrived at this.

  • ProjectName
    • Builds
      • Steam
        • Linux
        • Mac
        • Windows
    • BuildIncludes
      • Steam
        • Linux
        • Mac
        • Windows
    • BuildTools
      • 7zip
    • Unity
      • Assets
        • Art
        • Audio
          • Music
          • SFX
        • Editor
        • External
        • Fonts
        • Plugins
        • Resources
        • Scenes
          • _Test
        • Scripts
          • ProjectSpecific
          • SceneGame
        • Shaders
        • StreamingAssets
      • ProjectSettings

From here, I add everything except the “Builds” folder to version control, and I’m on my way. Since the BuildTools will be included, and I can find all the included tools via relative paths, *any* computer that syncs to version control will be able to run the build on their machine.

My “Scripts” folder gets broken up a bit more, but that’s a bit dependent on the project . For instance, with Ugly Baby, level generation and PCG were very important, so there was a “Level” folder with a dozen or so scripts related to that.

The “External” folder is generally where I put all the plugins and assets I grab from the Asset Store, GitHub, and the ilk. If there is some unmanaged code that I’m compiling on my own to include as a plugin, I’ll put the source in a folder of its own at the same depth of the Unity and Build_____ folders.

“Builds” and “BuildIncludes” follow the exact same folder structure. (StoreName/BuildTarget) This is important, but I’ll get to it in a later post.

I still haven’t found a perfect solution for my “Art” folder. I’ve previously separated things into Models, Prefabs, and Textures, but that doesn’t work well when you have many assets for a 2D game. With the new 2D system from Unity in beta right now, I imagine that might change how I deal with sprites going forward.