Repository navigation
Controller
Bartholomew Ho edited this page Nov 9, 2026
·
1 revision
Reads the controller: its buttons, triggers and sticks. It also runs the rumble motors and can hold buttons for other mods. A keyboard-and-mouse mod uses it to "press" a controller button that another .NET mod is waiting for, and any mod can use it for rumble feedback.
Thread: any thread.
The keyboard's Y key holds the controller's Y for other .NET mods, and a buzz command rumbles the controller for half a second.
using FH2;
using FH2ModPlatform;
public sealed class KeysAsButtons : Mod
{
public override ModInfo Info => new("KeysAsButtons", "1.0.0");
protected override void OnInit()
{
Game.Tick += () => Controller.Simulate(Button.Y, GameWindow.IsKeyDown(0x59)); // 0x59 = the Y key
AddCommand("buzz", "rumbles for half a second", args =>
{
Controller.Rumble(1, 0.5f);
Task.Delay(500).ContinueWith(_ => Controller.StopRumble());
return "bzzz";
});
}
}Imports FH2
Imports FH2ModPlatform
Public Class KeysAsButtons
Inherits [Mod]
Public Overrides ReadOnly Property Info As ModInfo
Get
Return New ModInfo("KeysAsButtons", "1.0.0")
End Get
End Property
Protected Overrides Sub OnInit()
AddHandler Game.Tick, Sub() Controller.Simulate(Button.Y, GameWindow.IsKeyDown(&H59)) ' &H59 = the Y key
AddCommand("buzz", "rumbles for half a second",
Function(args)
Controller.Rumble(1, 0.5F)
Task.Delay(500).ContinueWith(Sub(t) Controller.StopRumble())
Return "bzzz"
End Function)
End Sub
End Class| Member | What it does |
|---|---|
IsConnected (property, bool) |
True if a controller is connected. |
LeftTrigger (property, float) |
The left trigger of the first connected controller, 0..1. 0 with no controller. |
RightTrigger (property, float) |
The right trigger of the first connected controller, 0..1. 0 with no controller. |
LeftStick (property, Vector2) |
The left stick of the first connected controller, -1..1 on each axis. Up is +Y. Zero with no controller. |
RightStick (property, Vector2) |
The right stick of the first connected controller, -1..1 on each axis. Up is +Y. Zero with no controller. |
| Member | What it does |
|---|---|
IsPressed(Button button) (method, returns bool) |
True if any connected controller has the button held, or if a mod is holding it with Simulate. |
Rumble(float left, float right) (method) |
Runs the rumble motors of every connected controller. left is the heavy motor, right the light one, each 0..1. Stays on until you change or stop it. |
StopRumble() (method) |
Stops the rumble you started. |
Simulate(Button button, bool held) (method) |
Holds (true) or lets go of (false) a button for other .NET mods: IsPressed reports it, with or without a controller. The game doesn't see it. |
StopSimulating() (method) |
Lets go of every simulated button. |
FeedNativeMod(string dll, Func<PadFeed> feed) (method, returns bool) |
Adds buttons and triggers to what a native mod in fh2-mods (for example "FnFNitro.dll") reads from controller 0. Only that mod sees them, not the game. False if the mod isn't loaded or doesn't read the controller in a way this can feed. |
A controller button. The triggers count as pressed once they're pushed past the usual threshold.
| Value | Meaning |
|---|---|
A, B, X, Y
|
The face buttons. |
LB, RB
|
The bumpers. |
LT, RT
|
The left and right triggers. |
LS, RS
|
The left and right sticks, clicked. |
DPadUp, DPadDown, DPadLeft, DPadRight
|
The d-pad. |
Back, Start
|
The Back (View) and Start (Menu) buttons. |
What FeedNativeMod adds to a native mod's controller reads.
| Member | What it does |
|---|---|
PadFeed(ushort Buttons, byte LeftTrigger = 0, byte RightTrigger = 0) (constructor) |
Buttons are XInput button bits (0x1 d-pad up ... 0x1000 A ... 0x8000 Y). The triggers are 0..255. |
Buttons (property, ushort) |
The buttons held. |
LeftTrigger (property, byte) |
The left trigger, 0..255. |
RightTrigger (property, byte) |
The right trigger, 0..255. |
- The game still gets every real button press. Where your mod uses a button, pick one that does nothing harmful in the game at that moment.
- Keyboard keys aren't here. Use the platform's hotkeys (
AddHotkey) or GameWindow.IsKeyDownfor those. -
Simulateonly changes whatIsPressedsays to .NET mods. It doesn't move the triggers or sticks, and the game doesn't see it. To make the game itself see buttons held, use GameInput.HeldButtons. - The sticks and triggers come from the first connected controller only.
IsPressed,IsConnectedandRumblelook at every connected controller. - The stick values are read as they are, with no dead zone. Ignore small values yourself.
- Rumble you start overrides the game's own rumble until you stop it. After
StopRumble, the game's rumble carries on from its next change. -
FeedNativeMod: yourfeedfunction is called each time that mod reads the controller, so keep it quick. If it throws, the mod gets the real controller's state. With no controller connected, the mod sees one while your feed holds something. At most 4 feeds can be set up in one game session.
- GameInput: feed the game's own controls (driving, menu sticks, held buttons).
- GameWindow: the mouse and the keyboard.
- Menus and UiElement: press the menus' keys.
- Threads
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