Repository navigation
Your first mod in CSharp
This walks you through a mod that adds Repair to FH2 ANNA's menu and warns you when you go over 300 km/h. It takes about ten minutes. Prefer VB.NET? See Your first mod in VB.
- The .NET 10 SDK, plus Visual Studio 2026 or VS Code if you like an editor.
- The game with FH2 Mod Platform for .NET installed: see Installing.
- For the ANNA entry: the FH2 ANNA mod. Without it, the entry is just left out.
The release zip has the SDK as a NuGet package in sdk\FH2ModPlatform.<version>.nupkg.
-
Copy it into a folder of its own, for example
C:\FH2Sdk\. -
Tell NuGet about that folder, once:
dotnet nuget add source C:\FH2Sdk --name FH2
The package is also on GitHub Packages. GitHub asks for a personal access token with
read:packageseven for public packages, so the folder is simpler.
dotnet new classlib -n MyFirstMod -f net10.0
cd MyFirstMod
del Class1.cs
Replace MyFirstMod.csproj with:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Your Mod class: namespace.ClassName -->
<FH2ModType>MyFirstMod.MyFirstMod</FH2ModType>
<!-- Your game's fh2-mods folder: builds are copied there for you. -->
<FH2ModsDir>D:\Games\Azimuth\fh2-mods</FH2ModsDir>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FH2ModPlatform" Version="0.9.0" />
</ItemGroup>
</Project>MyFirstMod.cs:
using FH2;
using FH2ModPlatform;
namespace MyFirstMod;
public sealed class MyFirstMod : Mod
{
public override ModInfo Info => new("MyFirstMod", "1.0.0")
{
Description = "Repair from ANNA, and a speed warning.",
};
private bool _warned;
protected override void OnInit()
{
Log("hello!");
// FH2 ANNA's menu (D-pad down while driving).
ANNA.Items("Car").Add("Repair", () => Player.Car?.Repair());
// Once a frame while you drive, on the game's thread.
Game.Tick += () =>
{
var car = Player.Car;
if (car is null) return;
if (car.SpeedKmh > 300 && !_warned) UI.Notify("Slow down", $"{car.SpeedKmh:F0} km/h");
_warned = car.SpeedKmh > 300;
};
}
}What's going on:
-
Infois your mod's name and version. They show in the game and in the log. -
OnInitruns once, when the game starts. Set things up there and return quickly. -
Player.Caris your car, ornullwhen you're not driving. That's why there's a?.and anis nullcheck. -
Game.Tickruns on the game's thread, so theFH2classes can be used straight away. See Threads.
dotnet build
The build copies the mod to fh2-mods-dotnet\MyFirstMod\. Start the game, drive, press D-pad down and pick Car > Repair.
To see your Log lines, press ~ in the game or open fh2-mods\platform.log.
Turn on MODS > Installed mods > Platform.NET > Reload .NET mods when rebuilt. Now every dotnet build swaps the new code into the running game. See Reloading and debugging.
For players, publish it as one DLL:
dotnet publish -c Release -p:FH2ModHosting=Aot
Give players bin\Release\net10.0\win-x64\publish\MyFirstMod.dll. It goes in fh2-mods\ and needs no .NET runtime. See Hosted or NativeAOT?.
Playing
Getting started
Writing mods
The FH2 classes
- Game
- Player
- Vehicle
- World
- Garage, CarCatalog, Profile
- UI and Hud
- Camera
- Audio
- ANNA
- DebugOverlay
- Controller
- GameInput
- GameWindow
- Menus and UiElement
- SettingsTile
- ButtonIcons and Picture
- MapView, PhotoCamera, GarageCamera
More