Jump to content

Dynamic Mods reload and debugging with VS Code


KKRT

Recommended Posts

Hi Guys,

As I wasnt happy with 30s world load times and its effect on dev iteration time and i didnt want to use Visual Studio for its Edit&Continue debugging functionality, so i created simple solution to reload mods dynamically that works with VS Code.

Leaving solution below, maybe someone else will also find it handy ;)

 

How it works:

I have one mod that on demand (in the example on button press), copy other mod's DLL into memory and then loads it, this way DLL is not blocked, so it can recompiled. Even debugging of other mod works fine ;)

 

Usage is very simple:

While ingame press U to load a mod

Then press O to display popup that this mod generates.

Short demo

Github:
https://github.com/kkrt00/DynamicModLoader

Edited by KKRT
  • Like 1
  • Cookie time 1
  • Thanks 1
Link to comment
Share on other sites

Interesting! Is the game's runtime able to unload assemblies? Or do you end up with multiple copies of the game mod loaded (which sounds problematic)? I know standard .NET Framework can't do it, and the ability was in development for .NET Core last I checked, but looking at the game files the game might be using Mono, whose ability to unload assemblies I'm not sure about.

Link to comment
Share on other sites

I really do not know, i think it overrides the assembly as i reuse namespace and object name, but i'm not sure.

I tried to observe memory usage of Vintage Story process, but it didnt really raised when i relaunched mod like 30 times, but to be fair the mod just creates pop-up, so its not very heavy.

From what i read you can unload assembly, but only via unloading whole AppDomain. I tried to make it work, but i wasnt really going anywhere as you need to first create full new Appdomain and its need all dependencies from library, so vsapi.dll and passing objects isnt straight as its here. In this solution i just pass existing game's api object and it works 

But even if it doesnt unload dll correctly and it stays in memory, but its not used, its not really a problem in the end as this is debugging solution, so production solution 

----edit----

Ok, i checked loaded assembly in the current AppDomain and loaded mods are added on every button press:

https://i.imgur.com/t5vIEZU.png

Edited by KKRT
Link to comment
Share on other sites

On 4/11/2021 at 2:33 AM, KKRT said:

Ok, i checked loaded assembly in the current AppDomain and loaded mods are added on every button press:

https://i.imgur.com/t5vIEZU.png

Thanks for checking. Right, so it keeps every single copy of the assembly in memory. You'd have to be careful when debugging then, because I believe that any already-created object would still use the old assembly it originated from, which could lead to a very wild mix of behaviors.

Link to comment
Share on other sites

You actually reload the whole mod and its objects, at least in my example, because you call StartClientSide to load the mod inside the Vintage Story framework.

It could probably cause some issues when you had dependencies from ModLoader mod to mods it launches, but because the only thing it does is loading up assembly and then calling StartClientSide to allow Vintage Story to communicate with it, i think it shouldnt cause any problems.

I've yet to have any problems with reloading, but i also havent done anything substantial.

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.