Skip to content

Your first mod in VB

Bartholomew Ho edited this page Nov 10, 2026 · 2 revisions

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.

1. What you need

  • 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.

2. Get the SDK package

The release zip has the SDK as a NuGet package in sdk\FH2ModPlatform.<version>.nupkg.

  1. Copy it into a folder of its own, for example C:\FH2Sdk\.

  2. Tell NuGet about that folder, once:

    dotnet nuget add source C:\FH2Sdk --name FH2
    

3. Make the project

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>

FH2ModType must include the root namespace. VB puts every class inside <RootNamespace>, so a class SpeedMod is really MyFirstMod.SpeedMod.

4. Write the mod

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 Class

What's going on:

  • [Mod] has brackets because Mod is a VB keyword.
  • Info is your mod's name and version. They show in the game and in the log.
  • OnInit runs once, when the game starts. Set things up there and return quickly. Why not Sub New? See the FAQ.
  • Player.Car is your car, or Nothing when you're not driving.
  • Game.Tick runs on the game's thread, so the FH2 classes can be used straight away. See Threads.

5. Build and run

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.

6. Change it without restarting

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.

7. Ship it

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?.

VB things to know

  • Hooks take delegates: HookFunction(name, address, New MyFn(AddressOf MyDetour)), and you call the original with hook.Original.Invoke(...). Most mods never need hooks: the FH2 classes do it for you.
  • GameCode reads game memory and checks code bytes, for when you do go lower.
  • SetFile and PatchBytes take Byte() arrays.

Next

Clone this wiki locally