# How code stripping affects content

> Understand how your managed code stripping configuration can affect content builds and how to preserve code your content depends on.

When you build a Player in Unity, the [UnityLinker](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/unity-linker.md) process runs to reduce the size of the assemblies by removing unused types. This process can strip the following:

* Entire C# types such as classes derived from `MonoBehaviour` or `ScriptableObject`. Unity can strip these from core Unity assemblies like `UnityEngine.dll` and `Unity.dll`, but preserves them in custom assemblies once those assemblies are marked as used.
* Regular C# structures and classes.
* Portions of classes (for example, methods that aren't used).
* Entire Unity modules, such as AI or Physics, if no type from that module is referenced.

The effect that code stripping has on content appears in the Player as null reference exceptions, missing type errors, or crashes. Content that you build separately from the Player can't use types that have been stripped out of the Player build. This applies to [AssetBundle](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/assetbundles-section/asset-bundles-intro.md) content, Addressables content, and [content directories](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/content-directories/create.md).

You can use the [Build Report Inspector's](https://github.com/Unity-Technologies/BuildReportInspector) Stripping tab to inspect which modules and types have been preserved in a Player build.

You can prevent the linker from stripping code in the following circumstances:

* [Prevent code stripping of types used in content directories](#prevent-code-stripping-content-directories)
* [Prevent code stripping of types used in AssetBundles](#prevent-code-stripping-assetbundles)
* [Prevent code stripping of types used in Addressables](#prevent-code-stripping-addressables)
* [Prevent module code stripping](#prevent-code-stripping-modules)

## Prevent code stripping of types used in content directories

A [content directory](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/content-directories/create.md) that you build with [`BuildPipeline.BuildContentDirectory`](/engine/6000.6/script-reference/unityeditor/buildpipeline/buildcontentdirectory.md) can contain types that aren't in any scene or asset in the Player build. Unity might strip those types from the Player, so the content fails to load at runtime.

Each content directory build records the C# types and the Unity object types it uses in a `ScriptsOnlyCache.yaml` file in its build report directory. Because this record includes the Unity object types, it also preserves the modules those types belong to.

To preserve these types in the Player, build the content directory before the Player, then pass the content directory's build report directory to the Player build with one of the following APIs:

* Use [`BuildPlayerOptions.previousBuildReportDirectories`](/engine/6000.6/script-reference/unityeditor/buildplayeroptions/previousbuildreportdirectories.md) when you exclusively trigger Player builds from a custom build script, rather than from the **Build Profiles** window.
* [`BuildPlayerContext.AddPreviousBuildReportDirectory`](/engine/6000.6/script-reference/unityeditor/build/buildplayercontext/addpreviousbuildreportdirectory.md) works for both custom build scripts and the **Build Profiles** window, because you call it from a [`BuildPlayerProcessor`](/engine/6000.6/script-reference/unityeditor/build/buildplayerprocessor.md) [build callback](/engine/6000.6/manual/building-and-publishing/build-customize-build-pipeline/build-callbacks.md). You can build the content directory in the callback, or locate the build report directories of earlier builds another way, such as through the [`BuildHistory`](/engine/6000.6/script-reference/unityeditor/build/buildhistory.md) API or your own project configuration.

Both APIs take the build report directory, not the path to the `ScriptsOnlyCache.yaml` file inside it. If the directory isn't a valid build report directory, the Player build fails with an error.

For a complete build script that builds a content directory and preserves its types in the Player, refer to [Create a custom build script](/engine/6000.6/manual/building-and-publishing/build-customize-build-pipeline/build-script-build.md).

## Prevent code stripping of types used in AssetBundles

This section applies to AssetBundles that you build with [`BuildPipeline.BuildAssetBundles`](/engine/6000.6/script-reference/unityeditor/buildpipeline/buildassetbundles.md), which produces a `.manifest` file. For AssetBundles that you build with Addressables or the Scriptable Build Pipeline, which use a `link.xml` file instead of a manifest, refer to [Prevent code stripping of types used in Addressables](#prevent-code-stripping-addressables).

Unity might strip a Unity object type that's present in AssetBundles, but not in any scene or asset included in a Player build. This means that content from the AssetBundle might work when testing in Play mode, or on builds with minimal code stripping, but errors or crashes occur in a Player built with code stripping enabled.

To resolve this, you can create a custom build script that directly includes the AssetBundle's manifest file, as follows:

1. [Build the AssetBundle](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/assetbundles-section/creating/asset-bundles-building.md) before building the Player. The output folder includes one `.manifest` file for each AssetBundle, and a root `.manifest` file with the same name as the output folder.
2. Pass the path of the root `.manifest` file into the Player build process with the [`BuildPipeline.BuildPlayer`](/engine/6000.6/script-reference/unityeditor/buildpipeline/buildplayer.md) API.

The manifest lists the types of Unity objects that the AssetBundles use, so this approach also preserves the modules those types belong to.

For more information, refer to [AssetBundle file format reference](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/assetbundles-section/creating/file-format.md) and [`BuildPlayerOptions.assetBundleManifestPath`](/engine/6000.6/script-reference/unityeditor/buildplayeroptions/assetbundlemanifestpath.md).

You can also use the [Preserve attribute](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/preserving.md), or manually author a [`link.xml`](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/xml-formatting.md) file in your project, to further influence the code stripping behavior.

## Prevent code stripping of types used in Addressables

This section applies when Addressables builds AssetBundles. When you configure Addressables to build content directories instead, follow [Prevent code stripping of types used in content directories](#prevent-code-stripping-content-directories).

If a type of Unity object is present in content built with [Addressables](https://docs.unity3d.com/Packages/com.unity.addressables@latest), but not in any scene or asset built into the Player, then Unity might strip that type.

Addressables automatically generates a [`link.xml`](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/xml-formatting.md) file inside the `Library/com.unity.addressables` folder describing types used in the content. The Player build takes this `link.xml` file into account, provided the Addressables content has been built before, or at the same time as, the Player build.

You can also use the [Preserve attribute](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/preserving.md), or manually author a [`link.xml`](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/xml-formatting.md) file in your project, to further influence the code stripping behavior.

## Prevent module stripping

If you need to use types from a module in an Addressables or Scriptable Build Pipeline AssetBundle build, make sure the Player build includes some content that references that module. For example, to keep the Physics module, add a component such as a Rigidbody or Collider to a GameObject in a scene included in your build. This creates a dependency that the Player build process recognizes, and preserves the module.

This is required because you can't use a `link.xml` file to prevent entire Unity modules (for example AI or Physics) from being stripped.

This workaround isn't required for AssetBundles built with [`BuildPipeline.BuildAssetBundles`](/engine/6000.6/script-reference/unityeditor/buildpipeline/buildassetbundles.md) or for content directory builds, including content directories built by Addressables. Both record the Unity object types that they use, so passing the manifest or build report directory to the Player build also preserves the modules those types belong to.

## Type usage records

Both Player builds and content directory builds record the types they use in a `ScriptsOnlyCache.yaml` file, which you can look at to diagnose code stripping issues:

* A Player build writes this file to the `Library/PlayerDataCache` folder to support the [Incremental build pipeline](/engine/6000.6/manual/building-and-publishing/building-introduction.md#incremental-build-pipeline), which can reuse the content from a previous Player build. In that case the Player build passes the cached type usage from the file to the Unity linker.
* A content directory build writes this file to its build report directory. When you pass that directory to a Player build, the Player build passes the recorded type usage to the Unity linker. For more information, refer to [Build history file reference](/engine/6000.6/manual/building-and-publishing/build-analyze-builds/build-history-file-reference.md).

> **Note:**
>
> The `ScriptsOnlyCache.yaml` file uses an internal format that might change in future Unity versions. To control code stripping, use `link.xml` files in your project instead of modifying this file directly.

## Additional resources

* [Link XML formatting reference](/engine/6000.6/manual/scripting/compilation-and-code-reload/script-compilation/managed-code-stripping/xml-formatting.md)
* [Addressables package](https://docs.unity3d.com/Packages/com.unity.addressables@latest)
* [Build assets into an AssetBundle](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/assetbundles-section/creating/asset-bundles-building.md)
* [Create content directories](/engine/6000.6/manual/assets-and-media/assets-managing-runtime/content-directories/create.md)
* [Create a custom build script](/engine/6000.6/manual/building-and-publishing/build-customize-build-pipeline/build-script-build.md)
* [Build history file reference](/engine/6000.6/manual/building-and-publishing/build-analyze-builds/build-history-file-reference.md)
