How to sync Addressables when you have a server authority backend?

Has anyone developed a game using Addressables that involves a backend with server authority, such as a CCG? I am facing a challenge of syncing my backend with my game client when using Addressables. For instance, let’s say I have a card graphic along with metadata for the card, such as “mana cost” and “hit points”. I have already developed a backend for all the server logic, which needs full authority and understanding of the catalog of cards to use for example the “mana cost” values for calculating things in the backend. On the other hand, the game client requires both the metadata and the graphical assets, including “hard” assets like 3D meshes. If I use Addressables to deliver the content like the graphics, I am not sure where to store the metadata.

Should I include it in the asset bundle/addressable as well? If I did, this would create duplicate data in the server and client. The only solution I can think of is to have my backend API offer a method like GetCatalog(), which gives the metadata to the client. However, this approach seems to defeat the purpose of using Addressables, as my GetCatalog() endpoint would have to account for versioning and such if things got updated, so why not just include a link to a CDN with an asset bundle on it at the same time?

Am I missing something? Can anyone suggest an efficient way to sync metadata and graphical assets in a card game using Addressables and a backend with server authority?

We do. All game logic data is stored on the server. The data is downloaded by the client at logon time and cached. It references the addresses in the addressables bundles. Our game data tooling ensures that any address in any of the data actually exists in the latest bundle build. This allows our designers to change anything they need to change on the data side on the live game at will.

This approach isn’t without its challenges.

Thanks for the reply. So the game client makes some call to some server API to get all the data available, which I’m guessing is a JSON file that gives all the info including the addressable address? And then it downloads it with the URL at that address?

If that’s the case, why even bother using addressables? Couldn’t you just put the URL to the asset bundle in that JSON file instead? This is what I can’t wrap my head around. It seems like youd basically have to recreate the asset bundle logic anyway of versioning and caching your servers data. That’s fine if that’s the case, I just cant figure our what I’m missing, why I would even bother using addressables.

Yes.

No, just Addressables.LoadAsset() with that address, addressables handles the rest.

No. We have bundles with very complex dependency relationships and Addressables handles that for us, bearing in mind that we have customised the addressables build process with custom packing modes etc. to fit our needs.

Not really, we don’t have to recreate anything to do with the bundles at all. Addressables handles all dependency management, building, loading, and unloading of bundles. All we need to keep track of on our data side is the address of the leaf assets we load.

In order to make our designers’ lives easier, we did built extra tooling, bearing in mind that our tooling is not running inside Unity. We have some custom scripting so that when bundles are built a separate asset catalogue of addresses and their types is built that is only used by the tooling and our automated data testing, to allow stuff like asset pickers and to ensure that data cannot be published that does not match the bundles currently online.

Long story short, Addressables is only part of the story when it comes to our game data. It handles the Unity asset side of things and nothing else. We could have written that ourselves but not doing so saved us a hell of a lot of time, even considering the custom work we had to do.

Our game is live for iOS and Android, and has in excess of 15k downloadable asset bundles, so the process has scaled beyond anything Unity themselves had tested, which did not come without problems.

Whether it is the right solution for you is a different story.

Hey, thanks so much for taking the time to respond with these details.
I have spent a lot of time researching and digging and talking to others and have not found anyone who could help me untangle this problem in this way.

So from what I understand, you have to sort of duplicate your catalogs. You have a “metadata” catalog (in my example it is a JSON snippet that has information like the mana cost is 5 and the addressable address is XYZ) and then you have your addressable content catalog.

Your tooling must have some kind of “publish” button that not only publishes the addressable content but also goes up to your backend server to tell it that there was an update, here’s the addressable address, an here’s the metadata updates (e.g. “mana cost is 5”) so that the server knows the critical metadata information. It’s probably using Mongo or some other DB to persist this information.

Then your server can give the client the full metadata, including the addressable address, and the game client can download the content using addressables.

Does that sound about right?

What about when you update something, does this JSON snippet contain a version number so that the game client knows it happened so it can get the latest metadata + latest addressable asset as well?

So the JSON for the card game example would look like this:

{
   CardCatalog[
       {
          id:"some-guid-here",
          name: "goblin",
         manaCost: 6,
          (other metadata goes here...)
          assetBundleAddress:"XYZ",
          version: 1
       }] (more cards here)
}

So the Game client calls some endpoint on an API somewhere called GetCatalog() which returns this list.
The game client checks its local cache to see if it has everything, if it does, it checks the version number
Anything missing or out of data due to lower version number, it retreives the asset using the address?

Does this sound about right?

Yes. Technically speaking you could just make your tooling deserialize and use the actual addressables catalogue, but we found it far easier to just have a simpler catalogue for that express use only.

More or less. The way it works in our case is that we have a CI process that publishes bundles to our development servers, and runs the data tests using the catalogue for those bundles. If the tests pass, there is another CI process that allows publishing that data to our development servers. Once our game data has passed all QA, it can then be published to the production server.

At a high level, yes, that is right. In all fact it’s actually done by SHA hash, the server returns the hashes of all data files to the client at logon time, but that’s an implementation detail more than anything.