Creating Mac App Store games with Unity

**** Technical stuff warning **** If you’re not a Mac developer, skip this one. It involves nasty stuff that’ll make your brain melt!

 ***** Update. Looks like we didn’t catch everything required. process edited with more correct info thanks to Apple’s DTS team ******

So, I’ve finally submitted the first beta of Fast Fishing to the Mac App Store and had to jump through a few hoops to get it right.

Most of the issues appear to have been caused by the way Unity builds its Mac apps without using Xcode and one issue which I’ll get into in a bit caused by its file system. They’re not insurmountable but as Mac Games aren’t that high on the Unity dev list and the addition of the App Sandbox in Mavericks and Yosemite, it can be a bit awkward finding reliable information on how to get it all right..

The good news is, I’ve got a build of Fast Fishing successfully uploaded to the Mac App Store (soon to be submitted), so I thought I’d share what I had to do to make it work 🙂

 

Firstly, as I mentioned, Unity has an annoying issue with its file system. Anything in your project folders gets a .meta file created for it (I’m assuming to help track it within the Unity editor). This is normally fine as long as you remember to build your target app *outside* your project folder, except for when you use any plugins..

Because your plugins are stored within the project folder, their bundle files all have .meta files in them. When it comes to signing, these meta files break the signing and as they’re data files in the root of the bundle (which is bad).

So before you do anything to sign your build, you need to right click the app build and “Show Package Contents”

Fast Fishing Show Package

You’ll find your plugins in the Contents/Plugins folder and for each bundle you’ll need to Show Package Contents too. Go through each of those folders (and any sub folders) and delete any .meta files in there.

Once you’ve done this it’s wise to make a copy of your de-metad plugins folder so for the next build you can simply replace it with your clean copy.

The other thing that Unity doesn’t quite handle is your Info.plist file which contains various bits of useful info about the bundle and things like your Copyright info. Again, I make a separate copy of this to clone into my builds each time.

Unity does create an Info.plist file, but it’s missing various items and others are rather generic “Unity Player” ones. So a bit of editing and addition is needed..

You’ll need to add the Application Category line with the specific App category/sub-category that your game is in, as well as the Copyright (human-readable) line with your copyright info.

It’s also the place to modify the Get Info String to your game’s name and copyright. Make sure the bundle identifier matches that of your game and its provisioning profiles (I’m working on the assumption that you’ve read Apple’s documentation and have development and more importantly, distribution profiles already done and downloaded for your game) as well as checking the Bundle Versions String, short is your App’s main version number and Bundle Version is the build number (this has to be different for each build you submit to iTunes Connect).

Screen Shot 2015-02-16 at 17.56.21

 

Copy this info file over the Unity generated one in your package (and make a backup) and you’re ready to start signing..

As the game’s going to work on Yosemite and Mavericks and be downloaded from the Mac App Store it *MUST* have the App Sandbox enabled. This protects users from any bugs in your code accessing and breaking things it shouldn’t. However it does mean you have to specifically add any features your app needs.

You create an entitlements file in Xcode (actually the easiest way is to create a dummy Mac application and add entitlements to create the initial file).

You’ll need the App Sandbox entitlement (set to YES) and if you’re accessing anything on the internet, you’ll need com.apple.security.network.client set to YES too

To cover Game-Center you have to manually add the following entitlements in your entitlements file (normally Xcode would handle this for you..)

 

com.apple.application-identifier   xxxxxxxx.com.mycompany.gamename  where the xxxxx is your team ID

and

com.apple.developer.team-identifier  xxxxxxxxx   where xxxxxx is again your team ID

(these are also handy for iCloud and Handoff).

I put my entitlements file in the root of my Unity project folder

Another key step is to include a copy of the provisioning profile in the app bundle before signing it. It goes in the app bundle at Contents/embedded.provisionprofile.  Again, this is something Xcode would do for you normally that you have to do manually when building with Unity.  Do this for both development and distribution builds including the correct development or distribution profile.

 

After messing around with it to get it working I actually created a short script to handle my signing. It also copies the Info.plist file into the game package just so I don’t forget 😉

Note we have to sign the libmono.0.dylib and libMonoPosixHelper.dylib bundles that Unity adds in Frameworks too. Essentially *ALL* code has to be signed so the App Store knows it’s you that created it and it’s not been bolted on later by anyone with naughty intentions.

here’s the script…

cp “/Projects/Fast Fishing Mac Info/Info.plist” “/Projects/Fast Fishing.app/Contents/Info.plist”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” “/Projects/Fast Fishing.app/Contents/Frameworks/MonoEmbedRuntime/osx/libmono.0.dylib”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” “/Projects/Fast Fishing.app/Contents/Frameworks/MonoEmbedRuntime/osx/libMonoPosixHelper.dylib”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” –entitlements “/Projects/FastFishing_Unity/Fast Fishing.entitlements” –force  “/Projects/Fast Fishing.app/Contents/Plugins/BigDamnMacPlugin.bundle”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” –entitlements “/Projects/FastFishing_Unity/Fast Fishing.entitlements” –force  “/Projects/Fast Fishing.app/Contents/Plugins/P31MonoBridgeMac.bundle”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” –entitlements “/Projects/FastFishing_Unity/Fast Fishing.entitlements” –force  “/Projects/Fast Fishing.app/Contents/Plugins/SocialNetworkingPlugin.bundle”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” –entitlements “/Projects/FastFishing_Unity/Fast Fishing.entitlements” –force  “/Projects/Fast Fishing.app/Contents/Plugins/StoreKitPlugin.bundle”

codesign -f -v -s “3rd Party Mac Developer Application: Strange Flavour Limited” –entitlements “/Projects/FastFishing_Unity/Fast Fishing.entitlements” “/Projects/Fast Fishing.app” –deep

echo “Fast Fishing Mac Signed”

Here I’m signing my own BigDamnMacPlugin (which is a bunch of bits Unity doesn’t do that I need for my games) as well as the various Prime31 plugins I’ve used. (great plugins btw. awful IKEA level of documentation on the Mac versions 😉 ).

It’s worth reading up on codesign in the developer documentation. Very handy tool.

Next we need to build the App installation package. This is the file that gets uploaded to the Mac App Store and can be used to install the game for testing purposes..

I’ve done myself another script here, even though it’s just a single line. It’s a long line 😉

productbuild –component “/Projects/Fast Fishing.app” “/Applications” –sign “3rd Party Mac Developer Installer: Strange Flavour Limited” “/Projects/FastFishing.pkg”

Both codesign and productbuild use your distribution certificate to sign and then package the build.

Please note that your distribution build can’t be tested locally. For local testing, use the same script but without the entitlements (and your developer provisioning profile in the bundle instead of the distribution one). When installed via the app package your sandbox ID will be needed to activate the game.

When you launch the game, you should see a dialog pop up that tells you that the game was purchased by a different account, so you need to sign in with one of your Mac App Store Sandbox test IDs here for the game to launch. Don’t use your normal login, it must be a Sandbox ID.

If this works, your game should launch and elements such as Game Center etc. should work. If you’ve got a feature that’s not working, that normally works when the game’s not signed for the sandbox, check the console logs to see if the sandbox is denying anything. You may need to add more entitlements.

*Note*. If like me, your sandbox test ID isn’t for the US store, your first login will be prompted by “This account uses the UK store” or otherwise and the App Store will try and change countries to whichever one you set it up for. It will fail of course because your App doesn’t exist yet 🙂 Don’t worry about this. Once it gets over it, just launch it again and it’ll be fine 🙂

Now you should be able to use Application Loader (launched from Open Developer Tool in Xcode’s menus or direct from the Xcode package folder) to select the .pkg file you’ve created and upload it to iTunes Connect. The app name *must* match the App name you’ve got in iTunes Connect for it.

 

Hopefully this will help someone avoid the issues I had trying to get this working and there’ll be more games on the Mac App Store.

Thanks to Apple’s DTS crew for their help with this. Fast Fishing for Mac has now been approved and ready for sale on 1st April (our 11th birthday!).

Reddit
Twitter
Pinterest
Facebook
Email