Skip to main content

Keyboard input

The simplest way to control a mod while developing it is the keyboard. Press a key, trigger an action, observe the result. But raw keyboard events in Windows have quirks: holding a key down fires repeated events, and pressing too fast can trigger your action twice before the first one finishes.

The KeyDown event

ScriptHookVDotNet hooks directly into standard Windows Forms keyboard messages. In your script constructor, wire up the KeyDown event:

using System;
using System.Windows.Forms;
using GTA;

public sealed class InputHandler : Script
{
private int _nextAllowedPressTime;

public InputHandler()
{
KeyDown += OnKeyDown;
}

private void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F6)
{
HandleAction();
}
}

private void HandleAction()
{
// Debounce check: ensure at least 300 ms elapsed
if (Game.GameTime < _nextAllowedPressTime)
{
return;
}

_nextAllowedPressTime = Game.GameTime + 300;
GTA.UI.Notification.PostTicker("Action triggered.", false);
}
}

The debounce pattern

When you press a key, Windows might fire the event two or three times within a fraction of a second depending on your keyboard repeat settings. If your script spawns a bodyguard or toggles a radio, you end up with two bodyguards or a toggle that turns on and immediately off.

The solution is a debounce window using Game.GameTime (the number of milliseconds since the game started):

  1. Keep an integer field: _nextAllowedPressTime.
  2. Whenever the key fires, check if Game.GameTime < _nextAllowedPressTime. If so, exit immediately.
  3. If allowed, set _nextAllowedPressTime = Game.GameTime + 300; (or whatever delay feels right, usually 250 to 500 ms).

Modifier keys: combinations without clutter

If you want to keep single keys free for the game itself, combine them with modifier keys using e.Control, e.Shift, or e.Alt:

private void OnKeyDown(object sender, KeyEventArgs e)
{
// Trigger only on Ctrl + Shift + K
if (e.KeyCode == Keys.K && e.Control && e.Shift)
{
TriggerEmergencyReset();
}
}

Keyboards vs game controls

There is an important distinction to understand early:

  • Windows keys (KeyDown): Fired directly by Windows when a physical key on your keyboard is pressed. They do not work on game controllers, and they fire even if the player is typing in a cheat console or paused.
  • Game controls (Game.IsControlJustPressed): Native GTA V input bindings (like "Sprint", "Enter Vehicle", "Aim"). They work with both keyboard and controller, and respect in-game control states.

For development, testing, and debugging shortcuts, Windows keys (Keys.F6, Keys.NumPad5) are the fastest, most reliable choice.

Next, we look at debugging: how to find an error, read the log, and recover when things go wrong.