Skip to content

Controller

Bartholomew Ho edited this page Nov 9, 2026 · 1 revision

Controller

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.

Example

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

Members

Properties

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.

Methods

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.

Related types

Button (enum)

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.

PadFeed (record struct)

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.

Notes

  • 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.IsKeyDown for those.
  • Simulate only changes what IsPressed says 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, IsConnected and Rumble look 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: your feed function 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.

See also

Clone this wiki locally