HTML5 games still have a lot of promises to fulfill, but the W3C gamepad specification is a great example of something that’s going well. The spec is still a working draft, but the prospect of reading game controller data in a browser environment is tantalizing enough to start experimenting.
Why Use a Gamepad?
A gamepad is a type of input device commonly found on popular gaming consoles, like the Xbox, PlayStation, and Wii. Some hardware makers, such as Logitech, also make these controllers for use with a PC (and by “PC,” I mean Windows, Mac, or Linux hardware). While many avid PC gamers will claim that a mouse and keyboard are superior, console controllers can feel more familiar to a broader audience.
Secondary to games, a gamepad could also be used as an alternative input device in the context of the “10-foot experience,” when users are sitting far away from a large screen. For many individuals, this is the preferred remote control for watching movies and television shows. I’ve written about television experiences previously, but I think gamepad support is a great addition for any web app designed to function in the living room.
The Gamepad Specification
The W3C specification for gamepads has been through several iterations over the last few years. Early on, JavaScript libraries like gamepad.js were necessary for basic features like button mapping, but this is no longer the case. Most of these libraries are now deprecated (including gamepad.js) because the working draft evolved to include support for more key features.
Also read: HTML5 Games: A Land of Broken Hopes and Dreams
The W3C smartly narrows the definition of a gamepad to devices with buttons and axes, specifically excluding motion sensing, gesture recognition, and a few other points of potential confusion. Additionally, they define only one canonical button layout known as the “standard” mapping.
If gamepads become more than just a curiosity for you, I recommend you read about all the new gamepad interfaces in the specification, but the most important is the “gamepad” interface that has the following attributes:
- id – This is a string that identifies the brand or style of gamepad.
- index – When multiple gamepads are connected, the index can help select a specific gamepad device.
- connected – This is a boolean that says whether or not the gamepad is connected.
- timestamp – A timestamp indicates the last time the gamepad data was updated.
- mapping – The only currently supported mapping is “standard” so this isn’t really too important (for now).
- axes – This is an array that typically stores the values of analog sticks.
- buttons – This is an array containing “GamepadButton” objects. Each GamepadButton has a “pressed” boolean property as well as a “value” float property that can be used for other miscellaneous analog controls, like the triggers on the back of modern gamepads.
Cross-Browser Gamepad Support
If you’d like to test your hardware and software configuration for compatibility, plug in your favorite USB controller and head over to the HTML5 Gamepad Tester. Results may vary, but in Google Chrome on Mac OS X 10.9, I was able to use my PlayStation 4 controller right away. At the time of this writing, Firefox doesn’t have support enabled by default, but you can turn it on by searching for “gamepad” in the about:config settings.
Programming with the gamepad API isn’t too difficult. The W3C recommends coordinating the polling of controls with requestAnimationFrame, so that the framerate of a game does not become oddly de-synced with the input. Gamepad data should also be polled as closely as possible to the renderer to maximize responsiveness and minimize controller latency.
The other quirk right now is spotty browser support. As I mentioned previously, the gamepad API only works in Firefox and Chrome. In Firefox 27 and lower, you’ll need to enable it by setting dom.gamepad.enabled to true in the about:config settings. That being said, Firefox has the best support right now. In Chrome, the events that detect when the controller is connected and disconnected are not implemented. Instead, you have to initiate input by mashing a button on the controller. Additionally, Chrome uses the webkit prefix when polling for gamepads using navigator.webkitGetGamepads() so you’ll need to account for both in your code. For more details, I recommend you read the MDN documentation on the gamepad API, because it includes lots of in-depth cross-browser example code.
Do you think gamepads will help support the future of HTML5 games? Or is this just yet another browser API that will be relegated to obscure use cases? I’d love to hear your thoughts in the comments.