Fix Compile Loop in Unity 6.00 by Deferring RedistInstall Execution (Related to issues #654 and #656 .) #701
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This PR addresses the compile loop issue reported in #654 and #656, which occurs when importing Steamworks.NET into Unity 6.00. The issue is caused by immediate operations in
RedistInstall.cs
—such as writingsteam_appid.txt
and modifying scripting define symbols (STEAMWORKS_NET
)—that are executed during the[InitializeOnLoad]
phase.In Unity 6.00, these operations can unintentionally trigger the compilation pipeline again, leading to repeated recompilation.
Changes
RedistInstall.cs
WriteSteamAppIdTxtFile()
,AddDefineSymbols()
, andCheckForOldDlls()
inEditorApplication.delayCall
Updated static constructor
Why This Fix Works
While trying to understand the root cause behind the issue in Unity 6.00, I spent some time analyzing the compile loop behavior and how it relates to Unity's script reload mechanism and build profile system. Based on my understanding, here's what I believe is happening:
In Unity 6.00, script reloads and define symbol changes are more tightly coupled to the compilation pipeline. When RedistInstall.cs executes immediately during the [InitializeOnLoad] phase, it attempts to:
In earlier versions of Unity, these operations were relatively safe during reload. However, in Unity 6.00, particularly with Custom Build Profiles enabled, Unity interprets these runtime changes as signals to recompile scripts again. Since the static constructor runs every time the domain reloads, this creates a loop: symbol change → recompile → reload → symbol change → ...
By wrapping these calls in EditorApplication.delayCall, the logic is deferred until the next editor frame, after Unity has completed its reload and compilation tasks. This small shift in timing ensures Unity is in a stable state and avoids re-triggering the compilation pipeline.
I tested this fix in multiple Unity 6.00+ projects, including those using several custom build profiles, and confirmed that the compile loop no longer occurs. Editor completes its internal compilation and domain reload cycle, and all intended setup operations complete successfully without triggering further recompilation.
Although this change was primarily motivated by Unity 6.00, I believe this deferred approach can also improve stability in older versions of Unity. Delaying initialization tasks like file I/O or scripting define changes until the editor is fully initialized helps prevent unexpected side effects — especially in projects with custom editor configurations or large codebases.
Compatibility
Thank you for considering this contribution.
I tried to approach the issue carefully and suggest a minimal change that could safely address the problem. I'm happy to revise further if needed to better align with the direction of the project.