Steamworks Documentation
Getting Started for Developers

Overview


The Steam Input API is designed to allow you to easily enable full support for Steam Input devices in your game. We define full support as the follows:

  • Your game uses the proper controller-specific glyphs when showing in-game input prompts.
  • The Steam Input configurator screen uses in-game actions that the player performs in your game, instead of keys or buttons.
  • You've published an official configuration for the controllers you support.
  • Your game doesn't restrict the user's ability to customize their controls. This means it allows any mix of mouse, keyboard, or gamepad input simultaneously.
  • When your game wants keyboard input (e.g. when naming avatars), you use the API to automatically bring up the text entry UI.
  • Your game has no launchers that require mouse or KB input - or even better, no launcher at all.

To ensure users have a good experience from the couch, we also recommend the following:

  • Make your UI readable from several feet away. Our rule of thumb: when your game is running at 1920x1080, your fonts should be a minimum of 24px in size.
  • Start your game in fullscreen by default when the user is running Steam Big Picture (the "SteamTenfoot" environment variable will be set)
  • For bonus points, at first launch detect the user's screen resolution and set your resolution to match it.

Common Use Cases

I'm Adding Steam Input API support before shipping my game


Great! Follow the technical directions in Implementing Steam Input API support.

I'm Adding Steam Input API support alongside other input libraries


It's perfectly acceptable to ship conventional gamepad input as well as Steam Input, and if you're adding Steam Input API support after initial launch or shipping your game on multiple platforms, you could easily find yourself in this situation. There's a few things to keep in mind:

1. Be deliberate with your analog action choices
We'll be going into further detail on this topic later but the quick summary is:
  • You should always include a mouse-style action for cursor or precision camera controls. It may be acceptable to skip mouse-like input in Twin Stick or Sports titles where the joystick position is used for directional aim.
  • Avoid using the the system mouse ("os_mouse" option) unless you have a good reason to need it. Being able to determine if input comes from a real mouse vs a controller is an important part of good UX practices.
  • You should either rely on the configurator to provide sensitivity (ie you don't filter incoming Steam Input data), or you should use a dedicated sensitivity option for Steam Input that's distinct from the system mouse.

2. Be consistent with auto-aim on joysticks
If you have any auto-aim or aim-assist applied to XInput analog sticks, consider applying that to Steam Input devices as well, at least for traditional controller models configured through Steam Input. You can call GetInputTypeForHandle to determine an individual controller's model type or implement separate mouse-style and joystick-style camera actions.

3. Use SDL version 2.0.8 or above, if possible
If you're using SDL (Simple DirectMedia Layer), one of the most popular cross-platform game libraries for handling things like input, make sure you're using the latest version, or at least version 2.0.8 or above. This version allows Steam to tell SDL to ignore input for controllers configured by Steam Input, which avoids double-input bugs.

4. Have a plan for Xbox controllers
If your game has already shipped and has XInput support that you're leaving in place, you may want to leave Xbox controllers in the XInput path by default. If you're a local multiplayer game you'll want to make sure that you can either accept input from both paths at the same time or opt all controller into Steam Input though.

I Want my Non-Steam Input API Games to Play Nicely with Steam Input


First of all, I highly recommend reading Zach Burke's The Five Golden Rules of Input.

To summarize, they are:

  1. On-screen icons should match the input device
  2. Mouse cursor should match the input device
  3. All devices should work 100% of the time
  4. Dpad, analog stick, and mouse can all be used to navigate menus
  5. A disconnected gamepad should pause the game

These are good general guidelines to follow if you are able. To add our own emphasis:

Gamepad and mouse input should be possible simultaneously

Most games allow mouse input, or gamepad input, but not both at the same time, and this is the chief cause of compatibility issues with the Steam Input system.

Additionally:

  1. Set a recommended controller configuration for all controller types
    This way Steam doesn't have to prompt the user to select a configuration on startup. By the way, you don't need to provide a configuration for both the Xbox 360 and the Xbox One controllers -- if you only supply one, it will work for the other model.
  2. Opt-in Controller Type you don't have native support for to Steam Input
    If you don't have built-in support for these controller types, you should use the partner site to opt them in to using Steam Input. See the bottom of this section for more on that.
  3. If you're not going to allow simultaneous gamepad/mouse...
    ...at least make the deadzone, acceleration, and sensitivity of the joystick configurable. Joystick emulation for the trackpad works by rapidly flicking the virtual joystick so it is quite sensitive to these settings. For good results you want to allow very high sensitivities, deadzones that go to 0 and a linear acceleration curve. Shadow of War's controller settings are a good example of this.
  4. Allow users to select from Xbox or PS4 glyphs via the menu or detect the device type via our API
    When Steam is sending gamepad input it will appear in your game as regular Xbox controller input, rather than the normal device. This is useful since it allows the player to use devices that would not normally work, but it also means that normal check for USB device ID's, etc will not work and you'll need to call a helper function from Steam. It's important to note here that even controllers which you have built-in support may appear in your game through Steam Input either because the user is streaming the game via Steam Remote Play or because the user has opted into Steam Input to reconfigure their devices.

You can read more about this on the Steam Input Gamepad Emulation Best Practices page.

Text Input


On-screen text input is not technically part of the ISteamInput, but is found instead in ISteamUtils.

Some quick references:

You might find these useful regardless of whether you're using Steam Input in any way.

Implementing Steam Input API support


The implementation process is straightforward, and shouldn't take more than a few days of work. Four steps are involved:

  1. In a text editor, create an in-game actions file, which tells Steam what in-game actions your players can bind to the controller.
  2. In Steam, use the Steam Input configurator UI to create your default configuration.
  3. In your game, use the Steam Input API to read actions from the controller, and to retrieve appropriate glyphs for display.
  4. Update your game depot with the new binaries, and publish your configuration as the official config.

Step 1 - Creating an In-Game Actions File


Start by downloading the starting in-game actions (IGA) file. Place it in your "<Steam Install Directory>\controller_config" directory (create the directory if it doesn't exist). Rename the file to the following: "game_actions_X.vdf", where X is your game's Steam AppID. If you don't know what your game's Steam AppID is, it can be found by logging into your Steam partner site.

Now open up the file in your favorite text editor. The file is in a standard Valve format called KeyValues, which is a simple & easily read format. You might also find it useful to download one of our In-Game Actions File Templates or the Portal 2 IGA for a reference.

For more details see: In-Game Actions File

File Format


IGA files contain an "actions" section, which should list all the in-game action sets (IGAS) in your game. An IGAS describes all the actions a player can take within some game context - such as when the player is in a vehicle, or on foot, or navigating the menu system. For each IGAS, the Steam Input configuration UI will provide a tab that allows a player to customize how those actions are bound to the controller.

An IGAS entry in the IGA file should contain a "title" key & value, and the following subsections: "StickPadGyro", "AnalogTrigger", and "Button". The "StickPadGyro" and "AnalogTrigger" sections each contain a list of IGAs that the player can only assign to the stick/pad/gyro and analog triggers respectively. The "Buttons" section contains IGAs that can only be bound to digital inputs (like the physical ABXY buttons, or a trackpad that's in ABXY mode, or a trigger that's not being used as an AnalogTrigger action).

Designing your IGA

Take a minute to think about the functionality of your game - how many distinct modes does it contain? For each place where you want to have distinct controls you'll want to make an action set. Most games will have at least a distinct "Menu" and "In-game" action set, but many will need more. Does your game have any special cases like operating a vehicle or have specialized in-game menus like a map or inventory screen, those may also be useful to make into action sets.

Not everything needs to be a distinct action set though, you can also use action set layers to handle similar modes. For example if you can drive both a car and boat in your game you may want to include one "vehicle" action set with an action set layer of "boat" or "car" on top of it. Action set layers retain any settings of the parent action set and can make understanding and editing configurations more manageable for both your development team and your users.

For more information on action set layers see: Action set layers

Limits on the number of actions

Currently the maximum number of actions is 16 analog and 128 digital actions. It is very important to note that actions can be shared between action sets so in most cases you will only need a fraction of the maximum number of actions. This limit is not set in stone so if you've got a good reason for needing more, please let us know.

Button Actions


The format for "Button" actions is as follows:

"<action name>" "#<localization key>"

The <action name> is the internal name you want to refer to this action by in your game code, when talking to the Steam Input API. The <localization key> should be the name of an entry in your localization section (see Adding Localization). Make sure to include the '#' character at the start of your localization key.

Analog Trigger Actions


The format for "AnalogTrigger" actions is the same as for "Button". "AnalogTrigger" actions should be actions that your game will be interpreting as full analog inputs, like vehicle acceleration. If you don't have any of that kind of input, just leave the section empty. The Steam Input configurator UI will allow players to assign any "Button" action to the physical triggers if they're not being used as an "AnalogTrigger" action.

StickPadGyro Actions


The format for "StickPadGyro" actions is as follows:

"<action name>" { "title" "#<localization key>" "input_mode" "<analog mode>" }

<action name> and <localization key> are the same as the matching keys in the "Button" format. <analog mode> tells us how to interpret the data coming from the physical controls, before we pass it to your game via the steam input API.

Valid <analog modes> are as follows:

  • "absolute_mouse" - for when you're expecting the action to behave like a mouse. Useful for first or third person camera, or an actual mouse cursor.
  • "joystick_move" - for when you're using the action to move a character around.

"absolute_mouse" vs. "joystick_move"

We can’t stress enough that when creating a camera input for your first/third person game or anything cursor driven, you should always include an "absolute_mouse" type action and react to deltas as if it’s a mouse as the 1:1 data is required for implementing good quality Gyro aim or trackpad input. Steam Input is able to convert joystick input from gamepads into "absolute_mouse" style input for you but due to the acceleration curves and deadzones applied in-game it's not possible to convert the other direction.

It's fine to include a "joystick_move" style action if you want exact parity for joystick aim with your console builds but please test that you can accept input from both "absolute_mouse" and "joystick_move" at the same time so Playstation and Switch controllers can use Gyro aim along side the joystick. You may also want to implement a digital action for "Reset Camera" to re-center the vertical position of the camera. If you have auto aim enabled for XInput controllers please apply the same logic to joystick input through Steam Input API and consider applying a lighter amount of auto aim for trackpad/gyro aim.

There is one optional setting for StickPadGyro actions that are using "absolute_mouse" as their input. If you set the "os_mouse" key to "1", we'll pass the input from the player into the OS as well as your game. This is useful if you have a visible OS mouse cursor that should be controlled by this action.

Here's an example:

"menu_mouse" { "title" "#Menu_Mouse_Title" "input_mode" "absolute_mouse" "os_mouse" "1" }

Warning

  1. We strongly discourage using the "os_mouse" option for camera controls. If specific parts of your game are hard to patch, remember that you can always have separate analog actions that are used only in the menu vs. the in-game action sets.
  2. Using "os_mouse" will cause your controller inputs to be controlled by the in-game mouse sensitivities and will only work for a single local player.

Step 1.1 - Adding Localization


The "localization" section in your IGA file contains a list of languages, each of which is a section containing localization keys & values. For example:

"localization" { "english" { "Action_Jump" "Jump" "Action_Camera" "Camera" } "german" { "Action_Jump" "Springen" "Action_Camera" "Kameraansicht" } }

The actions in your IGA file should then specify their names by referring to the desired localization key, preceded by the '#' character. Here are example actions using the above localization keys:

"StickPadGyro" { "Camera" { "title" "#Action_Camera" "input_mode" "absolute_mouse" } } "Button" { "Jump" "#Action_Jump" }

If the language the game is running under is not found in the localization section, English will be used as a fallback. If English is not found, the string will be shown as is. For details on supported languages, please see Fully supported languages

Step 1.2 - Titles & Descriptions


Configurations also need a localized title and description. If you're only making a single official configuration for your game, you don't need to worry about this - we'll provide a default title and description, and you can skip this step entirely. But if you want to have multiple official configurations for your game, then you'll also need to provide localized titles and descriptions for them.

Configuration titles and descriptions should be listed along with the rest of your localization keys. The title key must start with "Title_", and the description key must start with "Description_". Here's an example:

"localization" { "english" { "Title_Config1" "Official Configuration" "Description_Config1" "This config was created by the developers of Game X." "Title_Config2" "Official Southpaw Configuration" "Description_Config2" "This config was created by the developers of Game X, and is setup for Southpaw users." "Action_Jump" "Jump" "Action_Camera" "Camera" } }

When you publish a configuration (see Step 4 - Publishing), you'll be able to select which of these localized titles and descriptions you want to use.

Step 2 - Creating a Default Configuration


Once you've created your IGA file, and ensured it's in the right directory & named to match your game's AppID, you're ready to create a configuration.

Run Steam in Big Picture mode, and navigate to your game's game details page.

Select "Manage Game," and then "Configure Controller." If you receive any errors at this point, they'll be identifying issues in your IGA file and you'll need to go fix them - the most common mistake is a missing closing quote or brace.

If you don't receive any errors, you're now looking at an empty controller configuration for your game, and it should be fully aware of your in-game actions. Use the UI to create a default configuration. Make sure you set defaults for all your in-game action sets, not just the first one.

Once you've got a configuration, save it privately. Don't publish it, because your game is not yet ready to receive IGAs.

Step 3 - The Steam Input API


Make sure you have the latest version of the Steamworks API - Grab it from the Getting Started With SteamWorks page.

Steam Input provides per-app mappings for controllers to decide which mapping to run and Steam will track the foreground window. This can make it trickier to debug the controller while you're working on it, because the controller will change its configuration when you hit a breakpoint in your debugger. There are two ways to make Steam lock onto your window for debugging, either run the following Steam URL:
steam://forceinputappid/<your_game's_AppID or 0 to reset to normal operation>

or add the following command line parameters to your Steam shortcut:
-forcecontrollerappid <your_game's_AppID

NOTE:

By "Steam shortcut" we mean a shortcut to the Steam client itself. The command line parameters need to be passed to the Steam client, not your game.

You can also download the official controller glyph renders or their PSD source. This is only really necessary if you want to use these as a starting point for your own art. Otherwise, you can just use the API to get a direct file path to appropriate art for any controller input (the image files are shipped with the Steam client itself).

Step 3.1 - API Overview


The Steam Input API is built around the in-game actions & sets that you specified in your in-game actions file in Step 1.

For a complete API reference, see ISteamInput Interface

The functionality overview is as follows:

Safe Interfaces

Controller data is gathered when ISteamInput::RunFrame is called. This is normally done for you every frame by SteamAPI_RunCallbacks. However, if you have version-safe interfaces enabled and find you're not getting good polling data you will need to call ISteamInput::RunFrame every frame.

You can tell if you have version-safe interfaces enabled by seeing if you have this #define in your code:
VERSION_SAFE_STEAM_API_INTERFACES

Step 3.2 - Input Handling


For digital actions, the data returned by ISteamInput::GetDigitalActionData is straightforward:

bState: will be true if the action is being sent by the controller (button is pressed, trigger pulled, etc)

For analog actions, the data returned by ISteamInput::GetAnalogActionData is only slightly more complex:

x,y: will depend on the mode you assigned the game action to in your IGA File. - "absolute_mouse": x & y will be deltas from the previous mouse position. - "joystick_move": x & y will be values ranging between -1 & 1, representing the current position of the joystick.

While you're in your code, make sure you're not preventing the user from combining different kinds of input simultaneously. A common mistake we've seen is for games to start ignoring gamepad input when they see mouse & KB, or vice versa.

Step 3.3 - On-screen Glyphs

To display an on-screen prompt for your controller, you need to get the physical origins that are bound to an in-game action. The player may have bound more than one physical origin to the same action, so it's best to have your UI cycle through displaying each origin. ISteamInput::GetDigitalActionOrigins and ISteamInput::GetAnalogActionOrigins will return the count of origins for the specified action, and fill out the passed in originsOut array.

For each origin, you can use the ISteamInput::EControllerActionOrigin enum to remap the origin to a corresponding image. When you call this function with an origin enum, it will return a local filepath to a .png or .svg file for the corresponding controller glyph from Valve's official image set (located in the Steam client's install folder). This method supports all hardware devices recognized by Steam Input (so a PlayStation controller will show PlayStation buttons, and an Xbox controller will show Xbox buttons, etc). Even better, it's future proof -- when Valve adds support for new hardware, this function will automatically fetch updated glyphs without you needing to recompile your game with new glyph assets.

You may provide your own images for the controller glyphs, but we strongly recommend making sure to do some future-proofing as Steam Input is always adding support for new devices and the only thing stopping them from working well with your game is if glyph images are broken or blank. You can either:

Poll continuously!

Please note that the user can change their configuration at any time. To help with this, we've ensured the ISteamInput::GetDigitalActionOrigins and ISteamInput::GetAnalogActionOrigins functions are extremely cheap to call.

When you display an onscreen prompt, don't cache the origins and keep displaying the first results. Instead, we recommend you re-gather the origins each frame, and display the matching prompts. That way, if a user decides to change their configuration as a result of seeing the prompt, when they return from the configuration screen the prompts will automatically update to match the new origins.

Step 4 - Publishing


Once your game is working with the controller, you're ready to publish. You'll need to release your new game update and make your configuration the official one. Official configurations are automatically loaded when a player launches your game for the first time. This allows users to simply fire up your game and play without needing to go into the configuration screen at all.

Here's the recommended process:

Step 4.1 - Update your game

  • Update your Steam depot with your new version of the game

Step 4.2 - Publish your configuration

  • Run Steam in Big Picture mode and navigate to the default configuration you created in the controller configuration.
  • Hit the (Y) button, or click the "Save As" button at the bottom of the screen.
  • Select the desired localized title & description in the popup, change it to a PUBLIC profile, and click the PUBLISH button.
  • You will get a confirmation, and the file ID of the public configuration. Copy/save the ID.

Step 4.3 - Make the configuration official

  • Open up your game's page on the Steamworks partner website.
  • Select "Steam Input" from the "Application" tab.

    steamworks_steam_input.png

  • Scroll to the section called "Steam Input Template". Select the "Custom Configuration" option in the dropdown. (If you were not planning on adding native support and just want to select from common legacy mode presets, here is where you would do so).

    steamworks_steam_input_custom_config.png

    And from the selection below, select "Add Custom Configuration."

    steamworks_steam_controller_custom2.png

  • Paste the file ID of your public configuration into the box, and click the OK button.

    steamworks_steam_controller_custom3.png

  • Publish your app changes in the partner site as usual.

If you'd like, you can also specify multiple official configurations for your game. You may want to create an official "Southpaw" (left-handed) mode, for example.

To do this, simply create multiple configurations and publish them each via step 4.2. Then, in step 4.3, paste all the file IDs for your configurations into the box, separated by the comma character (,) characters. The first one on the list will be considered the highest priority, and will be picked by default for new players. Don't forget to make Titles & Descriptions for each of them.

When your official configurations have been posted they will appear in the "Custom Configuration" section:

steamworks_steam_input_branch_settings.png

For each configuration you can get a direct link, see what controller type it is for, control which beta branches it is available on, or remove it entirely. If you create a new official configuration, you can use the remove / add functions in this section to replace an existing one.

Opting Controllers into Steam Input


Next, you should set up what kind of controllers use Steam Input - if you are using Steam Input API you'll want to make sure to check the "Any Future Devices" option to make sure new controllers work by default without you having to adjust settings after support ships in Steam.

steamworks_steam_input_optin_settings.png

Checking these boxes will cause those controller types to make use of Steam Input rather than their standard gamepad input protocols.

Updating your official configurations

There are two ways to update your configuration.
  1. To make a breaking change such as adding/removing a new action set or adding actions that must be bound upload a new configuration for each supported controller type and remove the old configuration. You should also go into the Steam Input Configuration browser with the account that created the configuration and mark it deleted by hitting:

    steamworks_remove_community_config.png
  2. To make an optional change such as adding a new language for your action name localization or adding a new optional action that does not need to be bound in every configuration, upload a single new configuration and use the "Use Action Block" checkbox to make sure the action block of that configuration is used preferentially on the selected branches.

    steamworks_steam_input_use_action_block.png

Tips

Dedicated Menu Actions

We recommend creating a separate in-game action set for your menu controls, instead of just re-using actions in your main game set. Most customers won't need to modify this menu controls set, but it's an easy way to provide the capability to players who actually need it (as can be the case for some disabled gamers, for example).

Custom Icons

The Steam Input system can also create several styles of on-screen menus. Putting your own .png icons in <your base game directory>/TouchMenuIcons/*.png will show them first in the list for your game's touch/radial menus. This will allow you to set up your own on-screen radial menus or touch menus with icons bound to specific actions without doing any game/UI code. As a developer you may wish to do this even if you don’t actually have any radial or touch menus in your own default configuration. Since any user modified configurations will also have access to these, users will be able to create nicely themed menus using your official icon art.