Assembly definition questions

I’m splitting up a large project into assemblies, but I noticed that there’s still alot of files inside the main unity assembly when I look in the visual studio solution which, to my understanding, also recompiles every time a change is made in any script.

Here’s an example screenshot showing the dotween dll being inside assembly-Csharp.

9562051--1352182--2024-01-04 18_16_03-Window.png

So I have a couple of questions:

1) How do you handle Dll’s from external packages?
Am I supposed to add a separate assembly definition to that folder to take it out of the main assembly?

2) Does any change in code also recompile these Dll’s when they are in unity’s assemblies?

3) Am I supposed to move them out of special folders?
I had a lot of external packages in a folder called Plugins, and I just found out that Plugins/Standard assets are special folders which cause them to also be in unity’s built in assemblies even tho they have assembly definition files.

3) Do the .txt files have any impact on compilation
Am I supposed to also add them to the correct folders/delete them?

  1. Is it actually advised to keep the main unity assemblies as empty as possible?
    Just so you have optimal compilation times for your project files?

DLLs are already compiled. Nothing in the normal compilation pipeline changes them.

Plugins used to be a special folder name, but native plugins are now supported anywhere in the project structure, just like assemblies.

Files other than things like asmdef/asmref/csc.rsp/cs/additionalfile are only relevant to compilation if used in csc.rsp.

Discussions here on forums seem to suggest that the total time for compilation doesn’t go down all that much since domain reload is such a heavy hitter, so even with less to recompile, you don’t gain as much as you’d hope. With that said, keeping code organized and modular is always a good idea. The default assemblies are like a last stop catch-all place for code, and as I recall, can’t even reference code from assemblies whose assembly definition don’t specify Auto Referenced.

4 Likes

The catch-all solution:

Put those Assets that are not using AsmDef under the common “Plugins” folder, or any custom folder to which you put an AsmDef at its root. The Plugins folder compiles to its own DLL, always has, and always compiles before any other code. Which means some assets don’t work when moved in the Plugins folder (rare).

If you want more granularity, I’d just add an AsmDef to the root of each asset. Assets without AsmDef should be rare these days though, DOTween is an exception and also one kind of asset I have a gripe with: the ones that distribute their code as DLLs.

It may be that VS is simply showing the DLLs here though - looking at the screenshot there should not be any actual scripts in that folder, just the DLL, and that’s already compiled. Ignore these cases.

DLLs are already compiled. Nothing gets recompiled. That’s also why I have a gripe with them. You don’t know whether they are Debug or Release DLLs, or whether they contain any platform-specific code, and you never know if they handle certain Unity editor version API changes correctly, and you cannot just go in and fix that one thing.

But for sure, you can just browse them like regular code, so NONE of the code is “hidden” - unfortunately some asset publishers still think this somehow “protects” their IP but this couldn’t be further from the truth, while at the same time it makes the asset less attractive to those who have ever had to deal with the situation I described earlier.

Assets under “Plugins” that have AsmDefs are treated as if they were in any other folder. So no, you don’t need to move those.

Non-code files have no effect on compilation. Txt files are just text assets in your project.

Not advisable but personally I never have any code not under AsmDefs. So if the main assembly somehow appears with content in it, I know I missed something.

AsmDefs don’t help much in regards to compile times, and as a matter of fact, if you have many of them (dozens) then compilation will actually be slower as more granular DLL files get created and need to be reloaded.

AsmDefs mainly serve to enforce one-way dependencies, ie they force you to think about relationships between modules, and force you to write decoupled code.

3 Likes

That’s kind of a big gotcha…
That’s literally what they advertise on the unity documentation and in any guide to optimize large projects oO

It really depends on how you use the AsmDefs and what code you work on. If its in a low level assembly every other AsmDef depends on, then you get a longer compile time than if you work in the topmost AsmDef. But compilation, as said, isn’t the biggy, it’s domain reload.

It’s like everything in software development: it depends. You shouldn’t aim for separate assemblies for every line of code. So you shouldn’t “keep them as empty as possible”. You should separate your code on changing frequency if you are aiming for speedup.
Put the frequently changing code in one assembly and the rarely changing code into another FEW assemblies and put the never changing code (assets with source code go here too) into one assembly.
If you are aiming for speed, have few assemblies and always just 1-2 changing at the end of the reference chain.
If you put something you always change in an assembly and then everything references it then you basically recompile everything all the time. Well, at least linking.
So it’s more involved than purely just throw some asmdef files randomly in the folder structure.