Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove assets from Renderer's build #175

Open
AjimenezDCL opened this issue Jan 16, 2023 · 12 comments
Open

Remove assets from Renderer's build #175

AjimenezDCL opened this issue Jan 16, 2023 · 12 comments
Assignees

Comments

@AjimenezDCL
Copy link
Contributor

AjimenezDCL commented Jan 16, 2023


layout: adr
adr: 175
title: Remove assets from Renderer's build
date: 2023-01-16
status: Idea
type: ADR
spdx-license: CC0-1.0
authors:

  • ajimenezDCL

Abstract

This document describes an approach on how to make the reference's client lightweight by streaming the currently embedded assets.

Glossary

  • Asset Bundle : Unity's proprietary system to pack assets that can be consumed in runtime (without going through importing).
  • Addressables : Unity's new abstraction layer to deal with remote assets.

Problem

Every nice UI, sound effect, particle or material we add to the renderer increases its size. This directly impact loading times or caching since the client's size will go above the max allowed for it. The idea is to pack textures and audio files and stream them in runtime.

Solution

Pack the Assets

Similar to what we are doing with scene assets, we can pack everything into one or multiple (to always be under the cache size limit) asset packs to be consumed by the client. This solution should be part of a different system than the one used for scene assets; therefore we can evaluate using an alternative like Addressables for consuming the assets.

  • Asset bundle: We have lot of built in tools to deal with ABs, we can make use of them to get all the packages when loading the experience.
  • Addressable: Unity's new API to consume streamed resources theoretically provides a seamless layer of abstraction that would allow the client to work with assets and textures as if they were local.

Regardless of the bundling approach, a CI job (within the same pipeline) can be developed as a part of the building process. It would take the assets, pack them and upload them to the server.

Retrocompatibility and Versioning

Currently the renderer is a self-contained experience; to run any renderer you just need a compatible kernel and catalyst; it should be the same for the assets packs.

Getting your compatible Asset Pack

A handful of solutions can be implemented to ensure that a version of the Renderer consumes its asset packs counterpart. All of them would require versioning the packs so the client can distinguish them by name/endpoint/path. At building time a manifest with this information can be placed in StreamingAssets to be consulted in runtime.

Open Questions:

  • Addressables or Asset Bundles?
  • CI's tasks breakdown to deliver the feature?
  • How to make the renderer aware of what version to consume.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

@AjimenezDCL AjimenezDCL self-assigned this Jan 16, 2023
@menduz
Copy link
Member

menduz commented Jan 16, 2023

Awesome!

Regardless of the bundling approach, a CI job can be developed as a part of the building process. It would take the assets, pack them and upload them to the server.

I'd like to suggest having only one pipeline. The associated operative costs of:

  • QA-ing the new pipeline
  • Selecting matching versions i.e. StreamableAssets_v3 and Renderer_v2
  • Maintaining two or more pipelines, and their derived desktop implicancies

May be mitigated by assuming the cost of building the assets and deploying them on every build. The only downside is that during many versions, the assets may be exactly the same, not being able to cache them. For that purpose, we can later on create rules for the CDN like:

Redirect 301 https://cdn.decentraland.org/unity-renderer/<version>/StreamableAssets/hello.assetbundle
To https://cdn.decentraland.org/StreamableAssets/3b3a1258-95aa-11ed-a1eb-0242ac120002

Optimizing bandwidth and cache-hit at the cost of one hop/redirect

@AjimenezDCL
Copy link
Contributor Author

My idea behind having a parallel job (within the same pipeline) is based on the assumption that we will reduce building time, since the assets can be packed in parallel.

In any case this decision is all yours, my knowledge of opeative costs of CI is super shallow and current build times are acceptable.

@mikhail-dcl
Copy link
Contributor

mikhail-dcl commented Jan 16, 2023

We should evaluate the risks and costs of sticking with good ol' Asset Bundle or introduce Addressables.
Currently, we have a runtime for AssetBundles but nothing for Addressables.
Also if we want to start benefiting from it ASAP AssetBundles are our choice. It will not block us from Addressables in the future at the same time.

@menduz
Copy link
Member

menduz commented Jan 16, 2023

My idea behind having a parallel job (within the same pipeline) is based on the assumption that we will reduce building time, since the assets can be packed in parallel.

In any case this decision is all yours, my knowledge of opeative costs of CI is super shallow and current build times are acceptable.

Oh ok, I didn't understood that correctly. As long as it is part of the same build pipeline we are ok, I was trying to prevent an independent pipeline that does not produce a single publishable artifact

@AjimenezDCL
Copy link
Contributor Author

Oh ok, I didn't understood that correctly. As long as it is part of the same build pipeline we are ok, I was trying to prevent an independent pipeline that does not produce a single publishable artifact

Let me rephrase it, so it's more clear!

We should evaluate the risks and costs of sticking with good ol' Asset Bundle or introduce Addressables.
Currently, we have a runtime for AssetBundles but nothing for Addressables.
Also if we want to start benefiting from it ASAP AssetBundles are our choice. It will not block us from Addressables in the future at the same time.

@mikhail-dcl I have no experience with Addressables, we could do a quick spike to evaluate the costs. How would it work with ABs? prefabs with references to textures or scripts referencing audios will get them automatically once the bundle is loaded or do we need some integration stuff there? For what I've heard from Addressable they automagically solve this.

@menduz
Copy link
Member

menduz commented Jan 16, 2023

@AjimenezDCL I have no further comments, I think this is OK to be converted into a PR

@AjimenezDCL
Copy link
Contributor Author

As soon as we agree on addressables vs ABs Ill do it, thanks!

@mikhail-dcl
Copy link
Contributor

Oh ok, I didn't understood that correctly. As long as it is part of the same build pipeline we are ok, I was trying to prevent an independent pipeline that does not produce a single publishable artifact

Let me rephrase it, so it's more clear!

We should evaluate the risks and costs of sticking with good ol' Asset Bundle or introduce Addressables.
Currently, we have a runtime for AssetBundles but nothing for Addressables.
Also if we want to start benefiting from it ASAP AssetBundles are our choice. It will not block us from Addressables in the future at the same time.

@mikhail-dcl I have no experience with Addressables, we could do a quick spike to evaluate the costs. How would it work with ABs? prefabs with references to textures or scripts referencing audios will get them automatically once the bundle is loaded or do we need some integration stuff there? For what I've heard from Addressable they automagically solve this.

I have never used Addressables on prod as well, so we need to perform a spike

@aixaCode
Copy link
Contributor

I would suggest going with Addressables, they have a bit of learning curve, that is true, but it also solves a lot of problems dealing with underlying ABs.
In the end, Addressables, are just higher abstractions API built on top of asset bundles, allowing for much more convenient fetching of assets. And it's much easier to maintain also the bundles in the project.

Addressable would also quickly solve the problem of moving assets away from Resources folder.
You can actually reference addressable in inspector without having direct reference to asset.

Our setup would be quite straightforward, so I don't think we would need to expand a lot on Addressables code for custom providers, which is the most time-consuming effort, because of the lack of documentation.

@mikhail-dcl
Copy link
Contributor

Also according to Unity, Building Addressables can be a part of the build pipeline out of box:

Build Addressables on Player Build (Unity 2021.2+)

Determines whether Unity builds Addressables content as part of your Player build.

Building Addressables content together with the Player can be convenient, but does increase build time, especially on large projects, since this rebuilds the Addressables content even when you haven't modified any assets. If you don't change your Addressables content between most builds, consider disabling this option.

The options include:

Build Addressables content on Player Build: Always build Addressables content when building the Player.
Do not Build Addressables content on Player Build: Never build Addressables content when building the Player. (If you modify Addressables content, you must rebuild it manually before building the Player.)
Use global Settings (stored in preferences): Use the value specified in the Unity Editor Preferences (under Addressables). This option allows every project contributor to set the option as they choose.

@AjimenezDCL
Copy link
Contributor Author

I would go with Addressables, worst case scenario we fallback to ABs if we encounter issues

@Kinerius
Copy link

We can have both systems running in Harmony.

What adressables were made to fix are the complex systems that you had to build around AssetBundles (what we have right now) to load certain assets, now you need less code and systems to achieve that.

So we will end up with:

  • Using addressables to separate the build in cacheable chunks, this can be done using Adressable catalogs. Catalogs have versioning so we have to be careful about how we load them in case we have breaking changes in the assets and we decide to roll back one version.
  • Using AssetBundles to optimize the scene assets to load them in WebGL. In theory we could migrate to adressables too, we will gain nothing from that but we will be using a more modern pipeline.

I completely agree with this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants