Repository navigation
Your first mod in VB
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. It's the same mod as Your first mod in C#, in VB.NET.
- The .NET 10 SDK, plus Visual Studio 2026 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
dotnet new classlib -lang VB -n MyFirstMod -f net10.0
cd MyFirstMod
del Class1.vb
Replace MyFirstMod.vbproj with:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>MyFirstMod</RootNamespace>
<!-- Your Mod class: root namespace + class name -->
<FH2ModType>MyFirstMod.SpeedMod</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.10.0" />
</ItemGroup>
</Project>
FH2ModTypemust include the root namespace. VB puts every class inside<RootNamespace>, so a classSpeedModis reallyMyFirstMod.SpeedMod.
SpeedMod.vb:
Imports FH2
Imports FH2ModPlatform
Public Class SpeedMod
Inherits [Mod]
Private _warned As Boolean
Public Overrides ReadOnly Property Info As ModInfo
Get
Return New ModInfo("MyFirstMod", "1.0.0") With {
.Description = "Repair from ANNA, and a speed warning."
}
End Get
End Property
Protected Overrides Sub OnInit()
Log("hello!")
' FH2 ANNA's menu (D-pad down while driving).
ANNA.Items("Car").Add("Repair", Sub() Player.Car?.Repair())
' Once a frame while you drive, on the game's thread.
AddHandler Game.Tick, AddressOf OnTick
End Sub
Private Sub OnTick()
Dim car = Player.Car
If car Is Nothing Then Return
If car.SpeedKmh > 300 AndAlso Not _warned Then UI.Notify("Slow down", $"{car.SpeedKmh:F0} km/h")
_warned = car.SpeedKmh > 300
End Sub
End ClassWhat's going on:
-
[Mod]has brackets becauseModis a VB keyword. -
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. Why notSub New? See the FAQ. -
Player.Caris your car, orNothingwhen you're not driving. -
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. VB NativeAOT DLLs come out a little larger than C# ones, because the SDK supplies the entry point VB can't write. See Hosted or NativeAOT?.
-
Hooks take delegates:
HookFunction(name, address, New MyFn(AddressOf MyDetour)), and you call the original withhook.Original.Invoke(...). Most mods never need hooks: theFH2classes do it for you. -
GameCodereads game memory and checks code bytes, for when you do go lower. -
SetFileandPatchBytestakeByte()arrays.
- Game, Player, Vehicle: what you can read and change.
- UI and Hud, ANNA: showing things to the player.
Playing
Getting started
Writing mods
The FH2 classes
- Game
- Player
- Vehicle
- World
- Garage, CarCatalog, Profile
- UI and Hud
- Camera
- Audio
- ANNA
- Skills
- DebugOverlay
- Controller
- GameInput
- GameWindow
- Menus and UiElement
- SettingsTile
- ButtonIcons and Picture
- MapView, PhotoCamera, GarageCamera
More