I have some very basic mod support that loads DLLs from a specific folder as Assemblies and inspects it’s types. If it finds an “IMod”, it calls it’s respective Awake() method.
I will spare you the code, since it needs to un-/subscribe to the
event, check for other assembly references etc. - and it works in the editor either way.
However it does not work with an IL2CPP built standalone player.
Do I need to do some extra steps? Is it even possible?
No, it’s not possible. IL2CPP is an AOT platform (Ahead Of Time compilation). So when you build your game / application all your managed IL code will be converted to native C++ code and compiled into native code. So at runtime of your game there is no mono / .NET environment. Some reflection methods still work which can be inferred at compiletime by the cross compiler. However anything that requires dynamic code generation does not work.
However it should still be possible to use native OS calls (like LoadLibrary, GetProcAddress, …) to load native DLLs manually. However designing a proper interop interface and get all communication between your game and your mod / plugin working can be tricky. Of course your mod / plugin has to be written in native code as well (probably with a C style interface). So mods has to be written in something like C, C++ or any other programming language which generates native code libraries.
Depending on the level of modding support you want to offer it’s probably better to just integrate a scripting language / environment like LUA into your game. It also helps with security issues for both sides (so you can better protect core parts of your game and also make it much harder for your community to spread malicious code).
If you really want to load managed assemblies at runtime you can’t use IL2CPP and have to stick with Mono as backend.