Build Automation with Unity

Why automate?

We’re developing Grand Cru’s first game The Supernauts in three individual teams. Changes are coming from many directions, multiple times per hour. To make sure our game stays constantly in good shape we’re using Continuous Integration with automated builds and testing.

Often running CI for the server code is enough as all of us are working with a local Unity Editor. Still, the fastest way to detect that the whole build is in good shape is to build, deploy and, in the future, test the client automatically as well.

It’s quite easy to forget to commit new files or get frequent updates from version control, making the local version work perfectly while everyone else’s environments break. If the server build itself fails the old server version keeps running and all our developers get a build failure notification into our Flowdock Team Inbox. With our CI, when things break badly, they tend to break badly for everyone and that makes sure the problems are always also fixed very promptly.

Jenkins & Amazon

Our build grid is set up with Jenkins on Amazon EC2 servers. We have a master instance running on Linux and one Windows slave to execute the Unity client builds, as there’s no Linux build support for Unity at least yet. Setting up a Jenkins slave was easier than we could’ve imagined, in fact it was so easy I’m not going to cover it here in more detail.

The build flow works so that on every commit to version control a server build is triggered. This covers also all of the C# code we’re sharing between the client and the server. Once this build succeeds, the Unity build script kicks in and after succeeding, pushes the Web Player binaries to Amazon S3 to be used with our in-house “alpha” game site together with the newly built and deployed server.

Build Scripts

Jenkins takes care of a lot of the groundwork, including version control updates, cleaning up the workspace when necessary etc. To build the Web Player binaries on a Windows Server machine, we need to execute Unity in batch mode. The tricky part was to detect any errors in the build as even if the build fails, the Unity executable returns successfully. Here’s a rough outline of the Windows build script:

set UNITY_BUILD_TARGET=..\supernauts 
Unity.exe -quit -batchmode -nographics -executeMethod BuildScript.BuildWebPlayer -projectPath [full project path] 
:: Print out logs so Jenkins can directly show what has happened in the build 
type C:\Users\Administrator\AppData\Local\Unity\Editor\Editor.log 
:: "Fool-proof" error detection, if the binary is missing the build has failed 
IF NOT EXIST ..\supernauts\supernauts.unity3d GOTO FAIL 
s3 put sww-content/UnityBuild/ supernauts.unity3d /nogui 
GOTO END 
:FAIL 
echo Build failed 
exit /B 1
:END

Another thing you’ll need to be able to execute builds on command line is a Unity build script. Ours looks like this:

using UnityEditor;
using System;
class BuildScript
{
    static void BuildWebPlayer ()
    {
        string buildTarget = System.Environment.GetEnvironmentVariable("UNITY_BUILD_TARGET");
        if (buildTarget == null || buildTarget.Length == 0) {
            throw new Exception("UNITY_BUILD_TARGET -system property not defined, aborting.");
        }
        string[] scenes = { "Assets/Level0.unity", "Assets/Level1.unity", "Assets/Level2.unity", "Assets/Level3.unity" };
        string error = BuildPipeline.BuildPlayer(scenes, buildTarget, BuildTarget.WebPlayerStreamed, BuildOptions.None);
        if (error != null && error.Length > 0) {
            throw new Exception("Build failed: " + error);
        }
    }
}

Future improvements

In the future, we’ll cover on this blog our automated testing systems. It would also be interesting to see how we can produce automated builds for mobile platforms and possibly even push them all the way to the beta users with TestFlight or similar.

Mikko WilkmanMikko is our CTO and takes care of all things, well, technical. Mikko knows his metrics and is enthusiastic about technical challenges, online services and games with scalable business model. In his free time he disc golfs and snowboards.