How to deploy game updates with Unity Cloud Content Delivery and Codemagic

Did you know you can set up an online bucket of data to make your Unity game updates a walk in the park?

This article was originally published on Codemagic’s blog.

While beginner projects are usually quite small, they quickly start to grow in size when reaching somewhere near production stages, as quality assets tend to weigh a lot. Does that mean that, each time you plan on updating your game to patch some bugs or add some new content, you’ll have to force your customers to re-download the entire game from the stores, wasting gigabytes of traffic?

Fortunately, it doesn’t. There are multiple ways to avoid it, and in this post, we’ll be looking at one such solution – Unity Cloud Content Delivery tool. The goal of this service is to use the power of the net to easily deliver data to everyone in a synchronised way, and still make it easy to properly re-assemble the outsourced assets with the code and 3D scenes once inside the game.

If you’re already familiar with CCD and you already have a project ready, you can skip over to the automation part! 🙂

Anyhow, in this post, I want to:

  • Give a quick overview of what Unity Cloud Content Delivery is.
  • Take a super-simple sample project as reference to show how to configure a new Unity Cloud Content Delivery setup from scratch.
  • Improve on this config and show how to use Codemagic to automate the synchronisation of assets with the game builds.

What is the Cloud Content Delivery (CCD) tool?

Unity Cloud Content Delivery is a cloud service that lets us easily store resources online, to then deliver them to all the users of our app across the world without forcing them to re-download anything. Roughly put, it’s an easy-to-use fully integrated Unity tool that helps with separating the code from the assets, so that any bug fix or live data update is a breeze to manage.

We can obviously build our own setup with custom tools, but CCD is really quick to configure and straightforward to use, and it offers 50GB of bandwidth per month for free when you first start. Then, you’ll pay as you go, which makes it possible to scale your app at your own pace and try out the tool without any financial commitments to see if it fits your workflow.

CCD mostly relies on a system of environments, buckets, entries and releases.

The environments are similar to namespaces: they allow you to publish content for a given audience, or a given production stage, and having multiple versions in parallel.

The buckets are the core element of the CCD system – they are the storage units you’ll put your files (called the “entries”) in. Usually, you create different buckets for each build target your project needs; and of course, you can set those up with Unity’s new Addressables tool to streamline content to your game and get perfectly self-contained assets.

The entries themselves are single files: they can be images, text files, XML data, Asset bundles… the tool accepts a very wide diversity of file types! This is the strength of Cloud Content Delivery: you can extract whatever chunk of your game data you want to make it more flexible for further updates 🙂

Finally, the releases allow us to take a snapshot of the current state of the bucket and mark all the recently added, updated or removed entries as ready for delivery.

Note: if you want to have full-control over which release is currently in use, then you can take advantage of the badges, too – take a look at the official docs for more details!

Setting up the Unity CCD project

For this article, I’ll work with a sample Unity Android app I prepared: the “Shape Browser”. The project in itself is pretty basic: it simply lets you pick one of the three available primitive shapes, change its colours and optionally set a texture (check out the bottom of the article for the Github repo’s link!).

This sample project doesn’t have a lot of resources, so it would probably be a bit overkill to use Cloud Content Delivery in a real production… but it will be handy to introduce the basics of the service. I will be using a CCD bucket to store all of my images, i.e. all of the files in the Assets/Images folder:

But before we are able send any files via CCD, we actually have to prepare a project on the Cloud Content Delivery platform and prepare a bucket to store our resources in. We’ll also take this opportunity to write down some useful IDs or keys that we will use in the following section to call the service via the terminal.

So, first, head over to the Unity Dashboard, and log into your Unity ID account (or create one if you don’t yet have one). You’ll be faced with a general dashboard that presents you the various Unity Gaming Services and lets you create a new project.

When you click the “Create project” button, you’ll be shown a popup to set up the basic info about your project – in my case, I just need to fill in the name:

After you’ve created the project, you’ll have access to its detailed dashboard. This is where you can add the various modules for analysing, testing and overall monitoring your game – to see all that’s available, just go to the “Explore Services” menu on the left:

In particular, you can scroll down (and optionally filter by the “LiveOps” tag) to find the Cloud Content Delivery tool. Just click on it to add it to your app project:

However, you’ll notice that, by default, CCD is not actually active: You’ll have to start your free trial first!

Even though the first 50GB are completely free, this will require you to give some credit card info just to properly set up your Unity ID account for gaming services. Simply follow the instructions until you get to the confirmation order page where you can click the “Complete onboarding” button:

From that point on, you can go back to your Unity project dashboard and start to use the CCD tool! In particular, it’s time to download the command-line tool (CLI) to call the Cloud Content Delivery APIs via a terminal:

You can see that the CLI is available for the various OS – since, in the next part, we’ll test manual CCD synchronisation, you will need to download the CLI matching your local computer OS from this page:

The next step is to get our API key, which you can find in the “API Key” section in the project menu. Keep in mind that it’s specific for your account and CCD and can’t be used for any other purposes.

Finally, we have to prepare a bucket to store our contents in. Just click on the “Buckets” menu in your project menu:

There, you can create a new bucket – I simply gave it a name (“Android Content“) and left all options to default:

When the bucket is created, you’ll need to get its ID – we’ll use it in the next section to upload our resources via shell commands.

By the way, we also need to get another piece of data from the dashboard before we leave: the ID of our default environment. This will be a necessary parameter for our command-line upload but, sadly, Unity’s dashboard UI doesn’t yet make it super easy to find (they’re apparently working on it, though!).

The trick is to go the bucket we just created and click on the link in the right part, “Upload content to create your first release” (see on the picture above). There, you’ll get various techniques to upload the assets, including the terminal way, with some useful commands that contain the environment ID:

Pausing for just a second

Ok, so at this point, we have:

  • our Git repo with all the codebase and the assets on the one side
  • and the CCD bucket ready to be filled on the other side

It’s crucial to understand that these two repos have to coexist, and that you can’t simply “merge” them together – they are used for different things. Your main repo contains all the files of your project and it is the usual snapshot you want of all your codebase and resources at a given time. The CCD bucket is a specific “mirror” of your assets with a bunch of nice labels and release versions bound to it so that you can easily serve this version of your assets to your customers.

However, the assets in your CCD buckets still have to live in your main repo too (for starters, you actually need them for the build!).

Using CCD manually

With that said, let’s give the CCD a try and at first do a manual release of our assets to get more familiar with the system. All I need to do is download the CCD CLI tool (from the download page we saw before) on my local computer, and unzip it.

Note: if you want to add the ucd executable inside the archive to your PATH to make it accessible from anywhere, feel free to do so – I’m just going to move it to my current project directory to make things simpler 😉

Then, I’ll head over to my project in a terminal and login into my CCD service using the API key:

./ucd auth login <api-key>

If all goes well, we get a “Login successful.” message. We’re now connected to the CCD, and we can start interacting with the buckets, releases and so on.

In particular, we can set our default bucket to be the “Android Content” one with our bucket ID, and our environment ID:

./ucd config set bucket <bucket-id> --environment <environment-id>

When the operation is finished, the tool will log the updated config:

Successfully switched to bucket <bucket-id>.
  Currently active project: <project-id>.
  Currently active environment: <environment-id>.
  Currently active bucket: <bucket-id> (Android Content).

Finally, we just have to actually synchronise the files we want to store and deliver through CCD for our project, in our case the images inside the Assets/Images folder. The command to use is pretty straight-forward:

./ucd entries sync Assets/Images --environment <environment-id>

As usual, the CLI will log the result to help you check everything went well, here by listing the files it added to the bucket:

Calculating...
Added Entry: icon-checker.png.meta
Added Entry: icon-cylinder.png
Added Entry: icon-dots.png.meta
Added Entry: icon-cube.png.meta
...
Complete! Bytes uploaded: 200783

However! At this point, if you go to your Unity Dashboard and take a look at the buckets list, you’ll see that nothing has changed: the bucket seems to still be awaiting some content…

That’s because, for now, we synced files but we didn’t actually create any release. So, basically, our changes haven’t been published.

Once again, the CLI has a nice command for that:

./ucd releases create --environment <environment-id>
Calculating...

Created release (#1) in bucket (<bucket-id>).
  Id: fb5842ae-1f0d-4a85-80d9-2afecbc1a3dc
  Created: 2022-06-04 23:42:02
  Badges: latest
  Content Size: 200783
  Content Hash: ace92ec0aea865553f93c02fc8f49657
  Notes: 
  Metadata: 
  Entries:
  - icon-checker.png  (version: b657e118-2dff-493d-b9c7-2e5bf705a179)
  - icon-checker.png.meta  (version: 8fe42658-028b-481f-babd-3f5bbb6bc655)
  ...

This time, when you refresh your CCD buckets list in the Unity Dashboard, you’ll notice that your “Android Content” bucket contains a new release (auto-numbered “Release 1”, obviously):

You can click on it to get more info, and in particular, check the various files that were tracked by this release:

That’s great! We’ve successfully synced our assets with the CCD bucket, and so our CCD tool can now track, version and deliver the various resources in our games!

The really cool thing is that, at this point, if we change assets and want to “redistribute” them to our customers without asking them to re-download stuff, we can re-sync the data and the CCD tool will help us auto-deliver the goods properly 🙂

Auto-syncing the CCD assets in a Codemagic workflow

But, wait: what if we change the code and create a fully new build of the app? We should insure the customers get all the new updates at once, images included, right? Except we said previously that our Git repo and the CCD buckets are co-dependent but separated…?

Also, given that CCD has you (generally) use different buckets for each platform, and that you typically set it up when you plan on your updating your content often (for example for a live game), running all of the commands we saw before manually every time for every bucket can get tedious and error prone. That’s why lots of developers prefer to use automation tools that have a predefined set of steps to run and therefore avoid inconsistencies during releases 😉

For example, Codemagic can help you make a more robust pipeline by always executing the CCD synchronisation and Unity project build together. Also, because it temporarily lends you a machine to run your workflow, you can actually request a different OS than the one(s) you have and thus build for even more platforms! For more info about Codemagic, check out this article.

Note: to use Codemagic, you need to version your Unity project with Git, and then publish it on a common Git provider like GitHub, GitLab or Bitbucket.

Basically, for my sample project, I’ll just need to insure that:

  • my Unity project is properly configured for building Android Unity apps, as explained here
  • I have all the required API keys and IDs about my Unity CCD project, its buckets and its environments
  • my project repository contains a script to build my project via the command-line (it’s the equivalent of opening the “Build settings…” panel and clicking on the “Build” button, but it can be called from a terminal)
  • finally, my project repo also contains a configuration file, the codemagic.yaml, to specify which steps to run in which order whenever I start a new build process

Setting up the Codemagic app with CCD

If you’re not familiar with Codemagic and want to see how to setup an app step by step, take a loot at their docs.

The only thing to keep in mind here is that we have to define several environment variables for the workflow to work properly. These are essential to properly securing passwords and other sensitive data – in short, you use a variable in the (publicly versioned) command lines, and then you give them actual (private) values in your Codemagic app’s settings.

Here, we want to create several variables and split them in three groups: “unity“, “keystore_credentials” and “ccd“:

The various values for the “unity” and “keystore_credentials” variables are discussed here. As for the “ccd” variables, they are pretty self-explanatory:

  • CCD_API_KEY: This is the global API key we found in the dashboard, and it allows us to login to our Unity CCD service from the terminal to run the synchronisation
  • CCD_BUCKET_ID: This is the ID of the bucket you want to synchronise
  • CCD_ENVIRONMENT_ID: This is the ID of the environment you want to use for the storage

Preparing our automation files

Now that the app is ready, time to add the automation-related files and try it out!

The build script simply calls various Unity APIs to build the project for Android – you can see what this file looks like here.

The codemagic.yaml allows us to specify the basic environment config we want on the machine, and then run shell commands to do our tasks. For example, here we can use the following set up:

The first lines are general info or constraints on the workflow, and the environment block lets us import and/or define environment variables for our pipeline. You see that we just recall the name of the environment variable groups we prepared to directly re-inject all the variables they contain.

Then, the script part is true meat of the file: in this workflow config, I use the pre-installed Unity CCD command-line tools to access the bucket I prepared and synchronise the assets inside. Finally, I activate my Unity license, prepare my Android keystore credentials, build the game and deactivate the license.

You’ll notice that the command that actually uses the CCD CLI to synchronise the files integrates all the environment variables we took from the Unity dashboard and added as environment variables.

Trying out the pipeline and checking our uploaded resources

Every time this pipeline is run, we’ll therefore re-update our CCD resources to their latest version and build the associated game version (that we can then download from the Codemagic build page as a .zip “artifact”).

The really cool thing is that, as you can see, synchronising assets with the Unity CCD tool is actually very fast – of course, it depends on the amount and size of your resources, but here it just takes three seconds!

Now that I have run my automated workflow, I have an up-to-date version of my game and, if I go back to my Unity CCD project bucket dashboard, I see that my “Android Content” bucket has another release, “Release 2”:

Again, we can see more details, and in particular check out the list of releases and see their badges!

Conclusion

Finding the right architecture for a Unity game and its contents can be hard, and usually, the more complex the project, the larger the number of assets. But nowadays, tools like the Unity Cloud Content Delivery help us better organise our projects and decouple resources from code. Adding a little varnish of automation on top with extra services like Codemagic is also a nice way of avoiding any unwanted inconsistencies when you build a new version.

I hope you enjoyed this tutorial — and of course, don’t hesitate to share your ideas for other DevOps topics you’d like me to make Unity tutorials on! You can find me on Codemagic’s Slack, on Medium, or on Twitter.

You can checkout the sample project for the entire “Shape Browser” project on Github over here 🚀

Leave a Reply

Your email address will not be published.