
Write FH2 Mod Platform mods for Forza Horizon 2 in C# or VB.NET. The SDK wraps the whole platform API (API 9, platform 2.8.0): game text, title-screen notices and entries, files, the game database, hooks, byte patches and instruction hooks, settings, pages, hotkeys, commands, sessions and crash dumps. On top of that, the FH2 classes give you the game itself, without reverse engineering: Player.Car.Repair(), World.Waypoint, UI.Notify(...), ANNA.Items("Car").Add(...) ([below](#the-game-the-fh2-classes)).
0.9.0 is a preview. The API can still change before 1.0, and some of the FH2 classes haven't been tested much in the game yet: see [Known issues](#known-issues).•To play: Forza Horizon 2 through Azimuth (the 24 November 2015 build everyone plays), with the FH2 Mod Platform 2.8.0 or later (the release zip includes it).
- Hosted mods and scripts also need the .NET 10 runtime (x64), or a private copy in fh2-mods\dotnet\runtime\. Without one, the title screen says so, and only the hosted mods are off.
- NativeAOT mods need nothing more.
•To write mods: the .NET 10 SDK, and Visual Studio's C++ tools (Build Tools are enough) for NativeAOT builds.
On any other build of the game, the FH2 classes check the game's code, find it different and switch themselves off (platform.log says which). The platform API keeps working.
Extract the release zip into your Azimuth folder (the one with azimuth.exe). You get DWrite.dll (the platform), fh2-mods\FH2DotNet.dll and fh2-mods\dotnet\ (Platform.NET and the SDK). Hosted mods then go in fh2-mods-dotnet\<Name>\, scripts in fh2-mods-dotnet\scripts\, and NativeAOT mods in fh2-mods\ like any other mod.
csharp
using FH2ModPlatform;
namespace MyMod;
public sealed class MyMod : Mod
{
public override ModInfo Info => new("MyMod", "1.0.0") { GithubRepo = "You/MyMod" };
protected override void OnInit()
{
Log("hello");
SetString("LoadingMessages.str", 0x6875, "Fast Traveling (with MyMod)");
AddSetting(new ToggleSetting("Fast", "Go faster", true) { Changed = on => Log($"fast: {on}") });
}
}xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<FH2ModType>MyMod.MyMod</FH2ModType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FH2ModPlatform" Version="0.9.0" />
</ItemGroup>
</Project>VB.NET mods work in both modes. Set <FH2ModType> to the full class name, including the root namespace (CarSpawner.CarSpawnerMod). VB has no pointers, function pointers or spans, and can't declare [UnmanagedCallersOnly], so:
•The build gives VB NativeAOT mods the SDK's own fh2mod_init. It finds your class through [assembly: ModEntry] and keeps your assembly's metadata for that, so the DLL comes out somewhat larger.
•Hooks take delegates: HookFunction(name, address, New MyFn(AddressOf MyDetour)). Call the code you replaced with hook.Original.Invoke(...).
•GameCode reads game memory, checks code bytes (GameCode.Matches(addr, GameCode.Hex("48 8B ..."))) and turns addresses into callable delegates.
•SetFile and PatchBytes have Byte() overloads.
[tests/scripts/HiScript.vb](tests/scripts/HiScript.vb) is a VB.NET script, and the [Scripts](#scripts-cs-and-vb-files-no-project) section has another.
The FH2 namespace is the game, ready to use: no addresses and no hooks of your own. Each class checks the game's code before it does anything, and on another build switches itself off (platform.log says so). They start the first time a mod uses them.
vb
ANNA.Items("Car").Add("Repair", Sub() Player.Car?.Repair())
AddHandler Game.Tick, Sub() If Player.Car?.SpeedKmh > 300 Then UI.Notify("Slow down", "")
If World.Waypoint IsNot Nothing Then Player.TeleportTo(World.Waypoint.Value)| Class | What it gives you |
|---|---|
| Game | The game's thread: Tick (once a frame while you drive), Run/RunAsync (code on the game's thread), PhysicsStep (every car's physics step), Rewound, CarRelocated, IsDriving, IsPaused, Language |
| Player | Credits, level, skill points, your car (Player.Car), TeleportTo (the road nearest a spot, as fast travel does) |
| Vehicle | A car: kind (yours, a Drivatar's, traffic), model, position, direction, speed, gear, rpm, pedals, Velocity (settable in PhysicsStep), IsOnGround, Repair, HeadlightsOn, ExhaustFlames, Backfire |
| World | Every car, the nearest, cars in range, the time of day and its pace, Waypoint (the map's) |
| Garage, CarCatalog, Profile | Cars you own and adding one, every car's names, the profile's values |
| ANNA | Entries in FH2 ANNA's menu, in its own lists o
FH2 support: Supported
Version
0.9.0
FH2 Mod Platform
Supported
Source
github