Skip to content

Hosted or NativeAOT

Bartholomew Ho edited this page Nov 9, 2026 · 1 revision

The same project builds two ways. You don't change any code, only how you build it.

Hosted NativeAOT
Build dotnet build dotnet publish -c Release -p:FH2ModHosting=Aot, or dotnet build -c Aot
In Visual Studio Debug or Release, then Build Aot, then Build
Goes in fh2-mods-dotnet\<Name>\ (the whole output folder) fh2-mods\<Name>.dll (one file)
Players need the .NET 10 runtime (x64) and Platform.NET nothing more than the platform
Size your assembly about 1 MB, the runtime compiled in
Reload while the game runs yes no
Breakpoints in Visual Studio yes no
.NET features everything, including reflection and loading assemblies NativeAOT limits
Own pages and links on the MODS tab no (all hosted mods share one entry) yes
Named in crash reports no yes

Which one?

Develop hosted, ship NativeAOT. Hosted gives you reloads and breakpoints while you work. NativeAOT gives players one DLL that loads like any C++ mod, with no runtime to install.

Stay hosted for players only if your mod needs something NativeAOT can't do, like reflection-heavy libraries.

Don't install both builds of the same mod: it registers twice. The build warns you if it finds the other one in your game folder.

Building NativeAOT

NativeAOT needs Visual Studio's C++ tools to link (the free Build Tools for Visual Studio with "Desktop development with C++" are enough).

In Git Bash, use the Visual Studio Developer prompt or PowerShell instead, or keep ProgramFiles(x86) set: bash drops it, and the linker can't be found without it.

How hosted mods are loaded

fh2-mods\FH2DotNet.dll is an ordinary platform mod. It starts the .NET runtime, then loads each fh2-mods-dotnet\<Name>\<Name>.dll in alphabetical order. Each one gets a load context of its own, so two mods can use different versions of the same library.

Each hosted mod registers with the platform under its own name, so its text, file and database edits work like any native mod's. Without any hosted mods, the runtime isn't started at all.

Clone this wiki locally