-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gamepad API input events #662
Comments
Hi - we're just having a look at this today and on first pass it looks good. 👍 One question: what is the current status of any additional implementer support? Right now the ChromeStatus page says "unknown" for Safari and Firefox. |
Do the coalesced events contain a timestamp? I think that would be useful. Also many modern controllers and event gaming keyboards can check the amount a button is pressed, and even the PS5 has adaptive triggers. Have you considered that use-case and how would you augment this API to support that? Maybe in that case buttonrelease and buttonpress makes more sense as names |
@torgo Chrome Status should have "Positive" for Firefox, referencing Ted's comment on the public-webapps mailing list. That's pretty old so I've submitted a standards position request and will update the status once that's resolved. I haven't heard from Safari yet. @kenchris, please take a look at this doc for our updated thoughts on how pressure-sensitive buttons and axis changes should be handled. The proposal in the explainer (called Proposal 1 in the doc) is probably not the most useful for developers since it makes it hard to get an accurate picture of the current gamepad state without adding unnecessary latency. A typical gamepad is implemented using the HID protocol (or something like it) where all button and axis inputs are delivered in a single packet. If we fire separate events for each button and axis then it makes it harder to understand which change events are from the same update. For example, if you're handling joystick axes then you always want to handle the X and Y updates from the same update at the same time. If you try to handle X and Y updates sequentially, you'll trace out a stairstep pattern which is a poor representation of the actual joystick movement. It's possible to work around this, but it means you have to delay handling some inputs until you're sure you've received all the relevant events. Pointer events avoid this issue by delivering X and Y axis updates in the same pointermove event. To follow the same pattern, we should combine all axis changes into a single axesmove event. And since some buttons can behave like axes, we should include them as well. Proposal 2 combines everything into a single event (we called it "change") that's fired on every input frame if there was any change to any button or axis. Currently I'm leaning toward Proposal 3 which keeps buttondown/buttonup events along with the change event. It's rare that you would ever want to subscribe to all of them since the change event would include all the same information included in buttondown/buttonup but I think it does the best job of satisfying everyone's use cases.
Those seem reasonable and I'm open to changing the names. I prefer buttondown/buttonup because it keeps the API more consistent with mousedown/mouseup and pointerdown/pointerup.
DualSense adaptive trigger haptics, Xbox Impulse Triggers, Switch HD Rumble and other advanced haptics aren't supported through the Gamepad API. There's a Microsoft Edge proposal for a Haptic Device API that we're hoping we can adopt in order to support more advanced haptics. |
Adaptive triggers is more than just controlling haptic feedback such as vibration. It is also about having non-binary values for buttons. Like a machine gun (in a game) might start shooting faster and faster the longer down you press the button. Adaptive triggers can also allow developers to configure the tension the user will experience as they press the button: |
Other comments:
|
That is very complex and I would never have guesses that was the behavior from the event names. Also, events cannot have side-effects so you would have to have the implementation be prepared to dispatch both events at all times. Listeners to one event type cannot change how events are being dispatched internally. Are there strong cases to be able to configure how events are being dispatched? If not, please just choose one. If you really need it, then couldn't this be configured with a method instead, with a sane default. |
Thanks for the comments, @kenchris
There's a strong case to dispatch input events immediately to support streaming game clients. For cloud gaming, inputs need to be uploaded with minimal latency. The The case for having a coalesced
I think configuring the dispatch behavior with a method on the Gamepad object could work. Probably Is there any precedent for configuring the event dispatch behavior after an event listener is registered?
I may have worded this confusingly, I want to specify the same behavior as in Pointer Events where "The user agent MUST fire a pointer event named pointermove when a pointer changes button state." The intent is to flush the
I agree, if the
I may have misunderstood your original suggestion. Non-binary button values have always been supported by Gamepad API and in this proposal we'd fire a change event whenever a trigger value changes. I've only heard the term "adaptive triggers" used in the context of DualSense's adjustable tension. I think you're suggesting If we're dropping |
@nondebug one process issue - can you please move the explainer over to w3 space (webapps wg repo) along with the spec? |
@kenchris it's not entirely clear to me what is being asked, but event listener registration is supposed to be side effect free, apart from performance optimizations. See https://dom.spec.whatwg.org/#observing-event-listeners in particular:
|
Maybe we could do something like Event listeners already have options like |
#151 Requested on the TAG review: w3ctag/design-reviews#662 (comment)
I am not a fan of having two different event handlers when you are only supposed to use one of them and choose. Also, as they deliver data differently you can argue that they are not side effect free (as they configure this change) and that is thus against the web design principles (as Anne pointed out). The Generic Sensor API works around this by having |
Hi @nondebug any feedback on the above? |
I like this.
With Generic Sensor you can create a new sensor object for each consumer but for Gamepad all consumers always see the same Gamepad object. We'd need to add a Gamepad.getGamepadSensor() method to return something that can be unique for each consumer so we can call its start() and stop() without interfering with other consumers. This could work but it seems overly complex to me. |
Understood. Thanks for clarifying - I think this is something that we may want to revisit if there are user needs in the future. For now, based on our last breakout discussion we think it's fine to move forward with this proposal as is. Thank you for bringing this to our attention! |
Ya ya yawm TAG!
I'm requesting a TAG review of Gamepad API input events.
The Gamepad API requires applications to poll to detect new inputs. Many applications follow the spec's recommendation to coordinate polling with
requestAnimationFrame
. However, polling in this manner is likely to lose inputs since gamepads typically update more quickly than the animation frame rate. Polling will also increase average input latency by half the polling interval. This proposal addresses both the missed inputs and latency by adding input events that fire when the gamepad state has changed.Further details:
You should also know that...
Gamepads can potentially produce a lot of input events and we are interested in feedback on how to mitigate the spamminess of these events. Consider a DualShock 4 that has two 2-axis thumbsticks and updates at 1000 Hz. When both thumbsticks are moving it will generate 4 axis change events per input frame, or 4000 events per second. If the application allows events to queue then it will be handling stale inputs, adding input latency.
This is mostly an issue for analog axis inputs but also affects pressure-sensitive buttons and analog triggers.
We have some ideas for mitigating this:
See here for more discussion on this proposal, the above mitigations, and comparison with the earlier Firefox implementation of these events.
We'd prefer the TAG provide feedback as:
💬 leave review feedback as a comment in this issue and @-notify @nondebug and @jameshollyergoogle
The text was updated successfully, but these errors were encountered: