Getting a Steam Controller to work with GameMaker

I am writing this as a place for me to record information about how to get GameMaker working with a Steam controller.

It doesn’t matter if you own a Steam Controller or not, I will try to explain everything as I go along, however if you are putting gamepad support in I would highly recommend that you at least test with some kind of gamepad. Currently the most popular gamepad used for PC gaming is the Microsoft Xbox controller.

This is an ongoing document and I will update it from time to time as I get new information.

I’m going to split the guide into two; those who have a game on Steam and those who don’t.

I have an exe file / I’m running the game through the Play Button in GameMaker:

So I’m guessing the majority of you will be in this group just wanting to get the basic controller working with your game. Once you publish your game on the Steam platform you get a huge amount of customisability on how the inputs from the controller get sent to your game, but I will cover that in the next section.

These are the controls as they come out of the box. Steam does provide some very extensive tools for the player to change what everything does. But these are the default settings:

On Steam Controller:GameMaker Code:Key Code:Input
Joystick Upvk_up38Arrow Up
Joystick Downvk_down40Arrow Down
Joystick Leftvk_left37Arrow Left
Joystick Right vk_right39Arrow Right
Joystick ClickNot Accessible (brings up onscreen keyboard)
A buttonvk_enter13Enter
B buttonvk_space32Space
X buttonvk_pageup33Page up
Y buttonvk_pagedown34Page down
Steam ButtonNot Accessible (brings up Steam)
Menu Leftvk_tab9Tab
Menu Rightvk_escape27Escape
Left Pad Scroll Upmouse_wheel_up()Mouse Wheel Up
Left Pad Scroll Downmouse_wheel_down()Mouse Wheel Down
Left Pad Scroll LeftNot Accessible (does scroll wheel left which GameMaker can’t read)
Left Pad Scroll RightNot Accessible (does scroll wheel right which GameMaker can’t read)
Left Pad Clickmb_middleMouse Middle Click
Right PadMoves the mouse around
Right Pad Clickmb_leftLeft Click
Left Bumper (top)vk_lcontrol162Left Control
Right Bumper (top)Not Accessible (Should be Left Alt but brings up the Onscreen Keyboard)
Left Trigger (bottom)mb_rightMouse Right Click (Yes this is the correct way around)
Right Trigger (bottom)mb_leftMouse Left Click (Yes this is the correct way around)
Underneath button LeftNot Accessible (does mouse back (like browser back))
Underneath button RightNot Accessible (does mouse forwards (like browser forwards))
Motion ControlsNot Accessible

If it isn’t obvious enough from the table above you will see that the Steam Controller is not recognised as a Gamepad or Joystick but instead a series of mouse and keyboard inputs. While this is great for compatibility it does mean that you can’t easily detect multiple Steam Controllers because they would send the same keypresses. While I guess in theory you could put together a huge guide with instructions for the player but realistically this is too complex to expect any player to do.

Another benefit to the way Valve has decided to setup the controller is the fact you can get your browser games that use the HTML5 module to work with the Steam Controller. While some gamepads do work in browsers, support is limited and you would need to have tested your game in the same browser with the same controller to really know how it works.

This is the screen players can use to change their controls.

Some things to note; without asking your players to fundamentally change the Steam Controller settings it is not possible to find out how much the joystick is being moved in this mode, normally you would expect to get a value that tells you what angle the stick is at, instead if the joystick is even slightly moved in any direction it will return a full on keypress. You get the same with the two shoulder trigger buttons (the bottom one), if that button is even slightly pressed it will return a full keypress, however later on we will talk about how to actually find the exact amount the button is depressed by.

I have a Steamworks account / I have a game on Steam:

So when you have a game published on Steam you will get more control over what information will be passed to your game from the controller. Also the player will have more control over how they want the controller to perform, everything from how far the joystick needs to be pressed before it is registers as an input, motion controls, clever inputs on the two mouse pads, context sensitive commands on any input etc etc.

Unfortunately all of the really cool stuff is linked to Steam’s Big Picture Mode, however once you get over that everything is really impressive.

So the first time a player boots up your game while in Big Picture Mode they will be given a prompt to setup their controls. They will be given the option to; use a default scheme made by Valve, use a control scheme made by another player of the game, use a control scheme you (the developer) has made or, make their own control scheme.

I will be focusing on the schemes you can make and the default Valve scheme.

This seems almost too obvious to state but you don’t want to make a game that requires a Steam Controller to play, you should always have controls that can be used on other gamepads, keyboards (QWERTY and AZERTY), joysticks etc. and are also rebindable and disability friendly because more people than you think have motor and other problems that stop them using the full range of input devices.

The following is one of the default configurations, this one is called "Gamepad", there are 4 others but most of them are based on this.

On Steam Controller:GameMaker Code:Button
or Axis:
Value Range:
Joystick Up/Downgamepad_axis_value(i, gp_axislv)axisbetween 1 and -1
Joystick Left/Rightgamepad_axis_value(i, gp_axislh)axisbetween 1 and -1
Joystick Clickgamepad_button_value(i, gp_stickl)button1 or 0
A buttongamepad_button_value(i, gp_face1)button1 or 0
B buttongamepad_button_value(i, gp_face2)button1 or 0
X buttongamepad_button_value(i, gp_face3)button1 or 0
Y buttongamepad_button_value(i, gp_face4)button1 or 0
Steam ButtonNot Accessible (brings up Steam)
Menu Leftgamepad_button_value(i, gp_select)button1 or 0
Menu Rightgamepad_button_value(i, gp_start)button1 or 0
Left Pad Up Clickgamepad_button_value(i, gp_padu)button1 or 0
Left Pad Down Clickgamepad_button_value(i, gp_padd)button1 or 0
Left Pad Left Clickgamepad_button_value(i, gp_padl)button1 or 0
Left Pad Right Clickgamepad_button_value(i, gp_padr)button1 or 0
Right Pad Up/Downgamepad_axis_value(i, gp_axisrv)axisbetween 1 and -1
Right Pad Left/Rightgamepad_axis_value(i, gp_axisrh)axisbetween 1 and -1
Right Pad Clickgamepad_button_value(i, gp_stickr)button1 or 0
Left Bumper (top)gamepad_button_value(i, gp_shoulderl)button1 or 0
Right Bumper (top)gamepad_button_value(i, gp_shoulderr)button1 or 0
Left Trigger (bottom)gamepad_button_value(i, gp_shoulderlb)buttonbetween 1 and 0
Right Trigger (bottom)gamepad_button_value(i, gp_shoulderrb)buttonbetween 1 and 0
Underneath button Leftgamepad_button_value(i, gp_face1)button1 or 0
Underneath button Rightgamepad_button_value(i, gp_face3)button1 or 0
Motion ControlsNot Accessible

In the above table I have used i but you should replace this with the controller number you are wanting to find (from 0 to 3 with 0 being the first controller connected)

The left and right trigger buttons (the bottom button) returns a value between 1 and 0 that shows how far it has been pushed in (0.5 means it’s pushed in half way)

The Joystick returns a value between 1 and -1 to say its x axis and another value between 1 and -1 to say its y axis.

By default the right mouse pad acts like a joystick (returning a value between 1 and -1 for its x axis and 1 and -1 for its y axis) with the slight exception that if the player stops moving their finger but doesn’t remove it from the pad it will return 0 even though you may expect it to keep returning the position they are holding. Again like everything this can be changed by the player however it is still worth noting.

The buttons underneath are duplicates of the X and the A button (Left underneath is A and right underneath is X).

If you have a Steam Controller you will know the bottom trigger buttons click when they are fully depressed. However gamepad_button_value(i, gp_shoulderlb) and gamepad_button_value(i, gp_shoulderrb) return the value 1 both when the button is fully “bottomed out” and right before the click happens when the button is depressed 99% of the way. I have seen games that make use of not fully pressing the button (like using the trigger as a break where the amount of breaking matches the amount the trigger is pulled down, and then once it is pulled down enough to click it activates a handbrake) however it seems to me that there is no way in GameMaker to differentiate between a button before and after this click state.

You can’t detect the Steam Key being pressed, however you can use steam_is_overlay_activated() to know if the Steam overlay is currently being displayed which is maybe more helpful.

The left mouse pad doesn’t send any commands if it is touched, it only sends the keypress if the pad is clicked down (yes those big mouse pads are also buttons that can be pushed down).

This is going to be an insignificant observation for most people but if two buttons are bound to the same input the computer will only remember the last one to be changed (as you would expect). For example: If you hold down and A button and tap the Underneath Left Button even though the A button is still pressed it is registered as NOT being pressed any more. This is the same for the Underneath Right Button and X which are bound to the same input. It’s likely this seems totally irrelevant to most people, however I know many gamers (like my girlfriend) can accidently press the buttons underneath or on the sides and then wonder why there character lets go of objects ingame.

Valve also provide some other defaults, “Gamepad with High Precision Camera/Aim” and “Gamepad with Camera Controls” are identical to the one above but the right mouse pad just turns into a mouse pad rather than a right joystick.

gamepad_set_vibration() – I can’t get this to work, it should control how much the controller is vibrating, however it just doesn’t vibrate my Steam Controller. It doesn’t crash so it is safe to use though. If anyone can get this working please contact me so I can add it to this document to help others.

gamepad_set_colour() – This would normally be used to change the colour of any lights on the controller, the Steam Controller doesn’t have any changeable lights so we wouldn’t expect this to do anything, however its work knowing it doesn’t crash either so it is safe to keep in for other controllers.

When you use gamepad_get_description() to find out what Gamepad is connected GameMaker will return “Xbox 360 Controller (XInput STANDARD GAMEPAD)” while that name can be confusing I can only assumed its because the Steam Controller is using the Xbox drivers for maximum compatibility, however this might make is nearly impossible to detect if the player is using a Steam Controller.

Setting up a Steam Controller template on Steamworks:

Under “Edit Steamworks Settings”

Go Application > Steam Controller

You will see this page:

You don’t get many options, but here you can setup the default controller settings that will be displayed to the player and also add recommended setups that the player can pick to configure their controller exactly how you set.

From the drop down you can pick which of the standard Valve ones you want to use or even make your own and select “Custom Configuration” and it will ask you what ID configuration you wish to use.

All of these tests have been on a Windows 10 computer with a first generation Steam Controller, I don’t know what support for the Steam Controller is like on other operating systems, again if you have more information on this please tell me so I can add it to this guide.

This guide has really focused on consolidating all of the controls, however I have glossed over the amazing power the Steam Controller has in an attempt to match the Steam Controller to the lowest common denominator of a gamepad. If everyone had a Steam Controller I reckon you could do some really cool things with the hardware, however this will never be the case so its something not even worth daydreaming about.

I wrote a little program to get the information for this guide, There is nothing complex in it but if you are too lazy to write it out yourself this GameMaker project will show you all the inputs from all gamepads connected. GameMaker gmz file

As a rather awkward test I have tried connecting two Steam Controllers and have simultaneously pressed 10 buttons on each controller at the same time (20 buttons in total) and it could still register more inputs. If I had more hands (and controllers) I would see if there is a maximum number of concurrent inputs, however I know this number is more than 20 which seems enough for any game.

90% of the information on this page will work on Unity and other game development packages, the only reason I have linked this so close to GameMaker is because that is my tool of choice and I have tested everything on GameMaker to know it is correct.

Stats:

I do wish Steam would publish how many people are using their Steam Controller, 6 months after it was launched they said they have sold 500,000 units, however even as I write this that number is massively out of date. Steam publish a Hardware Survey ( http://store.steampowered.com/hwsurvey/ ) and this seems like a basic bit of information they should record and publish.

About the Article:
Easy Difficulty
GameMaker
By David Strachan