Intent to Ship: Gamepad API

172 views
Skip to first unread message

Brandon Jones

unread,
Feb 27, 2014, 7:42:18 PM2/27/14
to blink-dev

Contact emails

sco...@chromium.org, baj...@chromium.org


Spec

https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html


Summary

The Gamepad API exposes input from gamepad, joystick and other similar devices. It is currently exposed with the webkit prefix.


Is this feature supported on all five Blink platforms (Windows, Mac, Linux, Chrome OS and Android)?

Android support is in progress. There are currently two conflicting CLs that add support on Android: https://codereview.chromium.org/133943002/ and https://codereview.chromium.org/165483003.


Yes for all other platforms.


Demo link

http://html5gamepad.com/


Compatibility Risk

The latest spec has a backwards-incompatible difference with our current implementation: The spec defines the "buttons" member as an array of GamepadButton objects, which contains a "pressed" boolean and "value" float. The current implementation, based on an older spec, exposes the buttons as an array of floats. Many current sites assume the older format of the buttons array.


Firefox 28 will launch with getGamepad enabled by default, and will adhere to the most recent spec (using GamepadButton instead of floats).


In order to prevent breaking existing sites we are planning on leaving the prefixed version of the API (navigator.webkitGetGamepads) as-is, returning buttons as an array of floats. The non-prefixed version of the API will expose the standard version of the Gamepad object, which will be compatible with Firefox's implementation. This allows developers to make compatibility changes when they update their code to use the non-prefixed function.


OWP launch tracking bug?

There isn't one currently.


Link to entry on the feature dashboard

http://www.chromestatus.com/features/5118776383111168

Adam Barth

unread,
Feb 27, 2014, 9:24:50 PM2/27/14
to Brandon Jones, blink-dev
Can we deprecate the prefixed version at the same time?  We can recommend that developers switch to the unprefixed version in the console message.

Adam

Brandon Jones

unread,
Feb 27, 2014, 9:58:59 PM2/27/14
to Adam Barth, Brandon Jones, blink-dev
I'd definitely be in favor of deprecating the old API and directing it's users to the newer function.


On Thursday, February 27, 2014, Adam Barth <aba...@chromium.org> wrote:
On Thu, Feb 27, 2014 at 4:42 PM, Brandon Jones <baj...@chromium.org> wrote:

Contact emails

sco...@chromium.org, baj...@chromium.org


Spec

https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html


Summary

The Gamepad API exposes input from gamepad, joystick and other similar devices. It is currently exposed with the webkit prefix.


Is this feature supported on all five Blink platforms (Windows, Mac, Linux, Chrome OS and Android)?

Android support is in progress. There are currently two conflicting CLs that add support on Android: https://codereview.chromium.org/133943002/ and https://codereview.chromium.org/165483003.


Yes for all other platforms.


Demo link

http://html5gamepad.com/


Compatibility Risk

The latest spec has a backwards-incompatible difference with our current implementation: The spec defines the "buttons" member as an array of GamepadButton objects, which contains a "pressed" boolean and "value" float. The current implementation, based on an older spec, exposes the buttons as an array of floats. Many current sites assume the older format of the buttons array.

Can we deprecate the prefixed version at the same time?  We can recommend that developers switch to the unprefixed version in the console message.

Erik Arvidsson

unread,
Feb 28, 2014, 10:31:12 AM2/28/14
to Brandon Jones, Adam Barth, blink-dev
I hope you can shed some lights on the following issues:

I see that the latest draft still uses polling to get the buttons state. Can we use events so we don't drain the battery? Maybe this is planned for v2?

Another issue is that when all we provide is polling of the current value we might miss changes. We should report "change records" like MutationObservers and Object.observe (i.e [{button: "foo", value: 1}, {button: "foo": value: 0}] -- details TBD) so that no information is lost.

--
erik


Brandon Jones

unread,
Feb 28, 2014, 12:56:56 PM2/28/14
to Erik Arvidsson, Adam Barth, blink-dev
Correct, the API is explicitly a polling one.

An event driven API has been discussed previously, but there are technical reasons why it's not optimal. (See: http://lists.w3.org/Archives/Public/public-webevents/2011OctDec/0056.html). In addition, it's worth considering that some native Gamepad APIs (like XInput) ONLY provide polling mechanisms, and as such any event-driven system would need to run a continuous polling loop internally anyway which makes the battery argument moot. Not to mention the most common use case for this API will be within a game loop, probably attached to a requestAnimationFrame, at which point simply rendering the page is going to be vastly more abusive to your battery than a simple hardware state poll.

Anecdotally, I've heard several developers express that they were happy to see that the Gamepad API doesn't rely on event-driven input. 


Si Robertson

unread,
Feb 28, 2014, 2:15:26 PM2/28/14
to blin...@chromium.org
I am just jumping in to the discussion to say the polling APIs are much better, especially for games, for the reasons Brandon mentioned.

I do prefer the Webkit implementation of the "buttons" array though, I can't think of any benefits of using GamepadButton objects, programmers already know if a button is being pressed because its floating-point value will be zero if the button is not being pressed. An array of doubles is fine and probably more optimal, like the "axes" array.

Jeremy Apthorp

unread,
Feb 28, 2014, 4:34:40 PM2/28/14
to Si Robertson, blink-dev
FWIW, 60Hz is not sufficient to catch all button presses. It's absolutely not out of the realm of possibility that a button is pressed and released in between polls 16ms apart. In my usage of Xbox360 controllers (which internally are event-driven -- they push data out across USB whenever something changes), I found that they sent data no faster than 143Hz.

Si Robertson

unread,
Feb 28, 2014, 4:52:22 PM2/28/14
to blin...@chromium.org, Si Robertson
I guess that could be a potential problem but I have not encountered any problems of that nature with the Gamepad API. I don't know how the API is working behind the scenes but the values from a gamepad may be buffered to mitigate data loss - I buffer mouse/pointer events in JavaScript and then poll the buffered data during an update loop (triggered by requestAnimationFrame) which results in no data loss from those input devices.

Elliott Sprehn

unread,
Feb 28, 2014, 4:57:41 PM2/28/14
to Si Robertson, blink-dev
This being synchronous seems like a bad idea, doesn't that mean we need to do sync IO to the hardware on the main thread? What if the USB bus was asleep and you call it?

Jeremy Apthorp

unread,
Feb 28, 2014, 5:29:03 PM2/28/14
to Elliott Sprehn, Si Robertson, blink-dev
Having implemented one version of the xbox360 drivers in Chrome, the way that driver works is to have the hardware push state over asynchronously, then when JS polls, it just reports the latest state. I can't speak to the way the other drivers work, but it seems not too difficult to have them poll frequently in a separate thread (and divorce the polling rate from the JS poll calls)

Darin Fisher

unread,
Mar 1, 2014, 12:12:09 AM3/1/14
to Elliott Sprehn, Si Robertson, blink-dev
No, please take a look at the implementation. It is quite efficient.

In a nut-shell, if any child process is subscribed to the gamepad data, then the browser process will start polling the OS for updates. It will write those updates to a block of shared memory that child processes may sample.

We use the same mechanism for broadcasting device motion & orientation events to interested child processes.

-Darin


On Fri, Feb 28, 2014 at 1:57 PM, Elliott Sprehn <esp...@chromium.org> wrote:

Eric Seidel

unread,
Mar 3, 2014, 1:00:43 PM3/3/14
to Darin Fisher, Elliott Sprehn, Si Robertson, blink-dev
I'm excited to see this on the web. A few questions:

1. Editors Draft seems rather early in the standards process to ship
this. But if our implementation agrees with another browser's, that's
more important.
2. Odd to have a "mapping" attribute and have it have only one value.
I guess the current expectation is that folks with re-map their
controller buttons at the system/browser level instead of in the web
app?
3. Why "getGamepads" instead of "gamepads"? Is that an attempt to
indicate that it's not a live list?
4. There are a lot of options modern game-pads provide which are not
exposed via this API. I presume those are considered for some later
version?

LGTM to match what FF is shipping with M28. Please
deprecate/use-count the webkit version and remove it asap.

Scott Graham

unread,
Mar 3, 2014, 1:12:51 PM3/3/14
to Eric Seidel, Darin Fisher, Elliott Sprehn, Si Robertson, blink-dev
On Mon, Mar 3, 2014 at 10:00 AM, Eric Seidel <ese...@chromium.org> wrote:
I'm excited to see this on the web.  A few questions:

1.  Editors Draft seems rather early in the standards process to ship
this.  But if our implementation agrees with another browser's, that's
more important.

At this point, the publication will move forward to the next phase unchanged (assuming we don't find anything that needs to be changed).
 
2.  Odd to have a "mapping" attribute and have it have only one value.
 I guess the current expectation is that folks with re-map their
controller buttons at the system/browser level instead of in the web
app?

That was the idea. Realistically, 90%+ are gamepad style at the moment.
 
3.  Why "getGamepads" instead of "gamepads"?  Is that an attempt to
indicate that it's not a live list?

It was briefly gamepads[] in an early spec, but popular content enumerates 'navigator', and accessing that element unnecessarily caused spinning up browser resources. So, it was made a function, and got a different name so that the state of the API could be distinguished. (Not a great reason I admit.)
 
4.  There are a lot of options modern game-pads provide which are not
exposed via this API.  I presume those are considered for some later
version?

Yes, standardizing some basic functionality first and learning from dev feedback seemed more useful than trying to spec everything in V1.

Brandon Jones

unread,
Mar 3, 2014, 1:21:16 PM3/3/14
to Eric Seidel, Darin Fisher, Elliott Sprehn, Si Robertson, blink-dev
On Mon, Mar 3, 2014 at 10:00 AM, Eric Seidel <ese...@chromium.org> wrote:
I'm excited to see this on the web.  A few questions:

1.  Editors Draft seems rather early in the standards process to ship
this.  But if our implementation agrees with another browser's, that's
more important.

I generally agree, but the fact that we're making backwards incompatible changes plus the fact that it matches Firefox's implementation lead me to think this is the cleanest way forward.
 
2.  Odd to have a "mapping" attribute and have it have only one value.
 I guess the current expectation is that folks with re-map their
controller buttons at the system/browser level instead of in the web
app?

The browser attempts to map known devices to the standard layout internally, which is the only time that the mapping string will be set. This lets developers know that the buttons and axes are located at well-defined indices and create predictable input schemes around that. If the mapping string is not set then the developer has the option of creating a app-level mapping (probably based off the id string) or allowing users to customize the mapping through a controls UI, as is done with many PC games.

Currently there's only one defined mapping type: "standard". Your controller has either been mapped to the standard layout or exposed with whatever raw layout the controllers driver provided. (In which case the mapping value will be empty string). This could feasibly be a boolean in it's current state, but I could see this expanded in the future to handle other common controller types that don't match the typical console gamepad layout. (eg: "wheel" for steering wheel-style inputs with well-defined accelerator, brake, and gearshift layouts.)

 
3.  Why "getGamepads" instead of "gamepads"?  Is that an attempt to
indicate that it's not a live list?

Scott mentioned the historical reasons for it but it is worth noting that it is, as you suggested, not a live list.
 
4.  There are a lot of options modern game-pads provide which are not
exposed via this API.  I presume those are considered for some later
version?

Yes, although there's also the possibility of providing Gamepad functionality through other currently APIs as well. For examples, there's been talk about expanding the Vibrator API to allow finer-grained control of multiple motors (primarily for Android). Given the appropriate targeting/querying mechanism it's easy to see this being the driver of gamepad haptic feedback.

Dimitri Glazkov

unread,
Mar 4, 2014, 1:11:43 PM3/4/14
to Eric Seidel, Darin Fisher, Elliott Sprehn, Si Robertson, blink-dev
On Mon, Mar 3, 2014 at 10:00 AM, Eric Seidel <ese...@chromium.org> wrote:
LGTM to match what FF is shipping with M28.  Please
deprecate/use-count the webkit version and remove it asap.

LGTM2.

Mounir Lamouri

unread,
Mar 4, 2014, 5:00:48 PM3/4/14
to blin...@chromium.org
On Tue, 4 Mar 2014, at 5:12, Scott Graham wrote:
> It was briefly gamepads[] in an early spec, but popular content
> enumerates
> 'navigator', and accessing that element unnecessarily caused spinning up
> browser resources. So, it was made a function, and got a different name
> so
> that the state of the API could be distinguished. (Not a great reason I
> admit.)

I understand the reasons behind that decision and I guess as an isolated
case, it might not be a problem but I would be interested to know more
mostly regarding this being a precedent. APIs tend to plug themselves to
the navigator object and it is generally not considered that accessing
the property has to be a very cheap operation - if that has to be
reconsidered, it might be good to know.

Do you have any data about that? How common is it to enumerate the
navigator object? I can't see any purpose to do that except for
fingerprinting so I really wonder if that's a common thing.

-- Mounir

Scott Graham

unread,
Mar 4, 2014, 5:10:19 PM3/4/14
to Mounir Lamouri, blink-dev
I don't have any data, sorry. Somewhere relatively big (foxnews.com and some others iirc?) were doing so in one of the third party .js files they pulled in, but this was a couple years ago, and I'm afraid I've lost the details to the mists of time.

Ojan Vafai

unread,
Mar 4, 2014, 7:37:35 PM3/4/14
to Dimitri Glazkov, Eric Seidel, Darin Fisher, Elliott Sprehn, Si Robertson, blink-dev
LGTM3
Reply all
Reply to author
Forward
0 new messages