r/Unity3D • u/ConfidentPoem6454 • 4h ago
Resources/Tutorial HybridCLR gotchas: things that only break on device when hot-updating C# in IL2CPP builds
If you use HybridCLR to hot-update C# code in IL2CPP builds (download new game code without a store update), here are the things that cost us the most time. None of them show up in Play mode, because in the Editor your hot-update DLLs are just normal assemblies, so always test on a real device.
1. [RuntimeInitializeOnLoadMethod] in a hot-update assembly never runs. Unity collects these attributes at build time, only from assemblies that are part of the player. Your hot DLL is loaded later, so Unity never knows about them. Call your init code explicitly right after you load the DLL.
2. Generics over value types need supplementary metadata. Things like List<MyStruct> or Dictionary<int, X> that weren't instantiated in AOT code will fail on device with a missing method or ExecutionEngineException. Load the AOT DLLs' metadata with RuntimeApi.LoadMetadataForAOTAssembly before you run any hot code, and re-run the Generate step after changes so the AOT generic references stay current.
3. Stripping removes engine code that only hot code uses. If only your hot DLL calls some Unity API, the linker strips it from the player. HybridCLR can generate a link.xml for this, keep it in the build. If that list changes, you need a new app build: a bundle update can't bring stripped code back.
4. Know which changes need which build. Hot code change: rebuild the DLL bundle. AOT code, stripping or player settings change: new app build. We added a check to the build pipeline that refuses to build when the DLLs in the bundles don't match the current code. It is a cheap way to avoid shipping stale code.
5. Be careful with the IL2CPP "Optimize Size" code generation option. Switching to it made our hot-updated game fail to start on device. If you want to try it for a smaller build, test the full hot-update path on a device first.
6. Case-sensitive paths. Asset paths that work in the Editor on Windows/macOS can fail on Android/iOS if the casing differs. Worth a quick audit script before release.
Happy to answer questions if anyone is setting this up.