- Set up modding with BepInEx and r2modman: Wiki: Getting Started
- download the
NineSolsAPI
mod if you want to use it,
- download the
- clone this repo (generate from this template, then update the
.csproj
- Change
<AssemblyName>
to your mod name - Make sure the
<NineSolsPath>
points to the installed game
- Change
- Install
tcli
tool for building thunderstore mods:dotnet tool install -g tcli
- Follow the Building section to make sure everything works as expected. Load into a game and press
Ctrl-H
to toggle your hat wherever you are.
Next steps:
- setup hot reloading for faster iteration times
- use a tool like ILSpy or dnSpy to decompile the game code
- check out the UnityExplorer mod to investigate objects in the game
If you run
dotnet publish
it will build the DLL of your mod (Source/bin/Release/netstandard2.1/publish/ExampleMod.dll
), then use tcli
to
package the mod into a thunderstore-compatible zip in thunderstore/build/
.
You can import that mod into your r2modman instance like this:
Make sure to fill out all fields in the thunderstore.toml.
Then go to https://thunderstore.io/c/nine-sols/create and upload your mod zip, or use tcli with a token created in
thunderstore.io at Settings / Teams / Service Accounts
:
tcli build --config-path ../thunderstore/thunderstore.toml --token $token
Building the mod and restarting the game after every minor change becomes cumbersome quickly. Luckily, BepInEx supports hot reloading of DLLs via ScriptEngine.
Download the ScriptEngine mod in your r2modman instance, and the game will be able to reload DLLs from r2modmanProfileFolder/BepInEx/scripts/
.
Go into the ExampleMod.csproj
file and fill out the <ProfileDir>
and uncomment the <CopyDir>
below it.
Now, whenever you hit "Build" in your IDE, the mod DLL will be placed into that scripts
folder.
Note: Disable your mod in r2modman if it is active to prevent it from being loaded twice!
By default, ScriptEngine will only reload scripts when you press F6
, but you can go into r2modman's Config Editor and
edit BepInEx\config\com.bepis.bepinex.scriptengine.cfg
to have
EnableFileSystemWatcher=true
AutoReloadDelay=0
LoadOnStart=true
to reload scripts immediately.
Hot reloading works by first destroying your mod instance game objects and then reinstantiating them, so make sure to clean
up any state you left in the OnDestroy
callback.