# How to Set Up HybridCLR Hot Update with TEngine from Scratch

> Set up HybridCLR hot update with TEngine easily in Unity. Enable full C# hot reloading with just four menu commands and a configuration asset. Get started today.

- Repository: [ALEX/tengine](https://github.com/alex-rachel/tengine)
- Tags: getting-started
- Published: 2026-02-24

---

**TEngine provides a complete HybridCLR hot-update pipeline that requires only four menu commands and a configuration asset to enable full C# hot-reloading in Unity.**

Setting up HybridCLR hot update with TEngine involves a streamlined workflow that bridges the HybridCLR compiler toolchain with TEngine's runtime loading system. This guide walks through the exact steps implemented in the `alex-rachel/tengine` repository, referencing specific file paths and menu commands to ensure reproducibility.

## Installing HybridCLR and Enabling Symbols

### Installing via the TEngine Menu

Before generating any hot-update assemblies, you must install the HybridCLR core libraries into your Unity project. TEngine exposes this through the standard HybridCLR editor integration:

1. Open the Unity Editor and navigate to `HybridCLR/Install...`
2. This copies the HybridCLR source into `HybridCLRData/` at your project root and creates the `HybridCLRSettings.asset` configuration file in `ProjectSettings/`

The installation state is managed by `HybridCLR.Editor.Installer.InstallerController`, which TEngine's editor scripts reference when verifying environment readiness.

### Enabling the ENABLE_HYBRIDCLR Scripting Define

Once installed, you must activate the scripting define symbol that gates all HybridCLR-related compilation. In [`Assets/TEngine/Editor/HybridCLR/BuildDLLCommand.cs`](https://github.com/alex-rachel/tengine/blob/main/Assets/TEngine/Editor/HybridCLR/BuildDLLCommand.cs), the `EnableHybridCLR()` method programmatically adds `ENABLE_HYBRIDCLR` to Unity's define symbols and refreshes the asset database.

You can trigger this manually via the menu: `HybridCLR/Define Symbols/Enable HybridCLR`. Disabling follows the same pattern via `BuildDLLCommand.DisableHybridCLR()`.

## Configuring the Hot-Update Pipeline

### Generating AOT Metadata and Generic References

HybridCLR requires AOT (Ahead-of-Time) metadata to resolve generic types that IL2CPP strips during the build process. TEngine automates this generation:

Navigate to `HybridCLR/Generate/All`. This executes the code-generation pipeline defined in `HybridCLRSettings.asset`, producing:

- [`HybridCLRGenerate/AOTGenericReferences.cs`](https://github.com/alex-rachel/tengine/blob/main/HybridCLRGenerate/AOTGenericReferences.cs) – Contains bridge code for AOT generics
- Stripped AOT assemblies placed under `HybridCLRData/AssembliesPostIl2CppStrip/`

The output paths are configured in `HybridCLRSettings.asset` via the `outputLinkFile` and `outputAOTGenericReferenceFile` properties.

### Configuring UpdateSetting Asset

TEngine uses a ScriptableObject to declare which assemblies participate in hot-updating. Locate or create the `UpdateSetting` asset at [`Assets/TEngine/Runtime/Core/UpdateSetting.cs`](https://github.com/alex-rachel/tengine/blob/main/Assets/TEngine/Runtime/Core/UpdateSetting.cs).

In the Inspector (customized by [`UpdateSettingEditor.cs`](https://github.com/alex-rachel/tengine/blob/main/UpdateSettingEditor.cs) in `Assets/TEngine/Editor/Utility/`), configure:

- **Hot Update Assemblies**: List of DLL names (e.g., `GameLogic.dll`) that will be compiled as hot-update modules
- **AOT Meta Assemblies**: List of AOT assembly names required for metadata loading
- **Assembly Text Asset Path**: Target directory for compiled DLLs, defaulting to `Assets/TEngine/Runtime/Resources/Assembly`

[`UpdateSettingEditor.cs`](https://github.com/alex-rachel/tengine/blob/main/UpdateSettingEditor.cs) automatically synchronizes these values with `HybridCLRSettings.Instance`, ensuring the compiler and runtime agree on assembly lists.

## Building and Deploying Hot-Update Assemblies

### Compiling DLLs and Copying to Assembly Path

With configuration complete, build the hot-update assemblies using `HybridCLR/Build/BuildAssets And CopyTo AssemblyPath`. This menu item triggers `BuildDLLCommand.BuildAndCopyDlls(BuildTarget target)`, which performs:

1. **Compilation**: Invokes `HybridCLR.Editor.Commands.CompileDllCommand.CompileDll` to build hot-update assemblies for the active build target
2. **Asset Copying**: 
   - `BuildDLLCommand.CopyAOTAssembliesToAssetPath()` copies stripped AOT DLLs from `HybridCLRData/AssembliesPostIl2CppStrip/` to the configured assembly path
   - `BuildDLLCommand.CopyHotUpdateAssembliesToAssetPath()` copies compiled hot-update DLLs to the same destination
3. **Database Refresh**: Calls `AssetDatabase.Refresh()` to import the new `.bytes` assets into Unity

The default destination is `Assets/TEngine/Runtime/Resources/Assembly`, though this is configurable via `UpdateSetting.AssemblyTextAssetPath`.

## Runtime Loading Architecture

### How ProcedureLoadAssembly Boots the System

During game startup, TEngine's procedure system invokes `ProcedureLoadAssembly` (located at [`Assets/GameScripts/Procedure/ProcedureLoadAssembly.cs`](https://github.com/alex-rachel/tengine/blob/main/Assets/GameScripts/Procedure/ProcedureLoadAssembly.cs)) to initialize the hot-update environment. This procedure executes:

1. **AOT Metadata Loading**: Iterates through `UpdateSetting.Instance.AOTMetaAssemblies` and calls `HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(byte[] dllBytes, LoadImageErrorCode errorCode)` for each stripped AOT assembly. This restores generic type information that IL2CPP removed.

2. **Hot-Update Assembly Loading**: Iterates through `UpdateSetting.Instance.HotUpdateAssemblies`, loads the corresponding `.bytes` files from `Application.streamingAssetsPath` (or Resources), and invokes `System.Reflection.Assembly.Load(byte[] rawAssembly)` to inject the new code into the running AppDomain.

Once complete, the procedure transitions to the next game state, with all hot-update types available for instantiation via reflection or standard dependency injection.

## Automating the Workflow

For teams requiring CI/CD integration or automated setup, TEngine's editor architecture supports programmatic execution of the setup steps:

```csharp
using UnityEditor;
using TEngine.Editor;

public static class HybridClrAutomation
{
    [MenuItem("TEngine/Automated HybridCLR Setup")]
    public static void Setup()
    {
        // Install if not present
        var installer = new HybridCLR.Editor.Installer.InstallerController();
        if (!installer.HasInstalledHybridCLR())
            installer.InstallDefaultHybridCLR();

        // Enable define symbol and refresh settings
        BuildDLLCommand.EnableHybridCLR();
        Debug.Log("HybridCLR installed and enabled.");
    }
}

```

To automate pre-build compilation, implement `IPreprocessBuildWithReport`:

```csharp
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using TEngine.Editor;

public class HotUpdateBuildPreprocessor : IPreprocessBuildWithReport
{
    public int callbackOrder => 0;

    public void OnPreprocessBuild(BuildReport report)
    {
        // Ensure hot‑update DLLs are compiled and copied before building player
        BuildDLLCommand.BuildAndCopyDlls(report.summary.platform);
        Debug.Log($"Hot‑update DLLs prepared for {report.summary.platform}");
    }
}

```

## Summary

- **Installation**: Use `HybridCLR/Install...` to copy source files to `HybridCLRData/`, then enable `ENABLE_HYBRIDCLR` via `HybridCLR/Define Symbols/Enable HybridCLR` (implemented in [`BuildDLLCommand.cs`](https://github.com/alex-rachel/tengine/blob/main/BuildDLLCommand.cs)).
- **Configuration**: Run `HybridCLR/Generate/All` to create AOT metadata bridges, then configure assembly lists in the `UpdateSetting` asset (synced via [`UpdateSettingEditor.cs`](https://github.com/alex-rachel/tengine/blob/main/UpdateSettingEditor.cs)).
- **Build**: Execute `HybridCLR/Build/BuildAssets And CopyTo AssemblyPath` to compile DLLs and copy them to `Assets/TEngine/Runtime/Resources/Assembly` using `BuildDLLCommand.CopyAOTAssembliesToAssetPath` and `CopyHotUpdateAssembliesToAssetPath`.
- **Runtime**: [`ProcedureLoadAssembly.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureLoadAssembly.cs) loads AOT metadata via `RuntimeApi.LoadMetadataForAOTAssembly` then loads hot-update assemblies via `Assembly.Load`.

## Frequently Asked Questions

### What is the minimum Unity version required for TEngine's HybridCLR integration?

TEngine's HybridCLR integration requires Unity 2020.3 LTS or newer, as HybridCLR itself depends on the IL2CPP backend improvements introduced in Unity 2020. Ensure IL2CPP is selected as the scripting backend in `Player Settings` before running the HybridCLR installation steps.

### Where does TEngine store the compiled hot-update DLLs after building?

By default, `BuildDLLCommand.CopyHotUpdateAssembliesToAssetPath` copies compiled DLLs to `Assets/TEngine/Runtime/Resources/Assembly`, converting them to `.bytes` files for Unity's resource system. This path is configurable via the `AssemblyTextAssetPath` property in the `UpdateSetting` ScriptableObject.

### Why must I load AOT metadata before hot-update assemblies at runtime?

IL2CPP strips generic type metadata from AOT assemblies to reduce binary size. [`ProcedureLoadAssembly.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureLoadAssembly.cs) calls `HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly` to restore this metadata first, ensuring that hot-update assemblies—which may reference generic types from AOT assemblies—can resolve their dependencies correctly. Without this step, `Assembly.Load` throws `TypeLoadException` for stripped generic types.

### Can I automate the entire HybridCLR setup for CI/CD pipelines?

Yes. The `BuildDLLCommand` class exposes static methods like `EnableHybridCLR()` and `BuildAndCopyDlls(BuildTarget)` that you can invoke from editor scripts or command-line batch tools. Implement `IPreprocessBuildWithReport` to ensure DLLs are compiled before player builds, allowing full automation of the TEngine HybridCLR pipeline in build servers.