Jump to content

Development versions have different IL code, making it hard to update mods in time


llunak
  • Branch: Preview Branch Version: Linux Pending

Development versions, such as the recent preview of the Frosty DLC, have different IL for the same source code than normal stable game releases. Mods that use transpillers may break because of such small and temporary changes, which makes it hard to update them before a release.

Consider for example ClearableManager::CollectChores(). That function has not changed for more than a year, but 621068's IL code for it is significantly different from 622222's - the number of instructions is different, the number of local variables is different, and e.g. the "if(flag) break;" is compiled as ldloc.3+brtrue.s in a normal release, but it's 6 instructions in a development version.

This means that a mod using Harmony transpiller to alter such a function would no longer recognize the relevant code, and would need to be written to handle both variants, which is a hassle. As such, it's simpler to ignore development versions when it comes to mods, and check the mod for problems only with the stable release, which means that such mods will not be ready at the time of a release.

I assume development versions are built using a different build profile, which sets different compiler optimization options, leading to these differences. But I see no need for this difference, development versions should be able to use the same settings as the stable releases (the inefficiently written IL for development versions does not look like added checks or anything similar).

Please change the build settings for development versions to avoid these problems.

 


Steps to Reproduce

- Check in your repository history that ClearableManager::CollectChores() has not changed for quite a while.

- Use ilspy or similar to compare the IL for that class between the current stable releaser and the last development version.

 




User Feedback


Don't hardcode your indices and notice that the transpilers survive dev builds.

you can do that by finding the index of a method call (or anything else thats distinct) right before/after the local variable, then iterate the code instructions towards the ldloc/stloc and grab its index.

Edited by SGT_Imalas

Share this comment


Link to comment
Share on other sites

It seems to me that pretty much everything in your comment misses the mark, but in case it's somehow me who's missing something: So how do you suggest I easily add one more check at the end of the "if(... && fetchChore2.forbidHash == rootChore.forbidHash)" condition in FetchAreaChore, when in normal builds the "false" jump is bne.un.s and in development builds that is ceq+br.s+ldc.i4.0+stloc.s+ldloc.s+brfalse?

1 hour ago, SGT_Imalas said:

notice that the transpilers survive dev builds

No idea what a transpiler surviving is supposed so mean.

 

Share this comment


Link to comment
Share on other sites

In your case:

you want to extend that very long chain of conditions.

due to them all being chained with "&&", the position to insert them can be anywhere in that chain.
ceq+br.s+ldc.i4.0+stloc.s+ldloc.s+brfalse <=> bne.un.s   is not a solid location for dynamic insertion.

up the condition chain however there are a couple of equality calls for both Tag and Object. These offer good insertion points, since their index can be easily found and they push their boolean output onto the stack.

there you can insert your own additional condition via calling an external method that checks your custom condition.
This method should both consume a boolean and return one.
the consumed boolean is from the previous equality comparison where you insert your call, the one it returns should be (consumedBoolen && yourCustomConditionResult)

this avoids the problem you described by attaching your extra condition to a consistent point in the inline code.

Edited by SGT_Imalas

Share this comment


Link to comment
Share on other sites

Even if that approach worked for all modding needs, which is a question, I still see no good reason why development versions should have different code in this way.

 

Share this comment


Link to comment
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
  • Create New...