rust-gamedev / wg

Coordination repository of the Game Development Working Group
511 stars 10 forks source link

You know what we don't have? A good input abstraction crate. #34

Open icefoxen opened 5 years ago

icefoxen commented 5 years ago

I'm NOT talking about something that actually PRODUCES input events, such as winit, SDL2, gilrs, etc. I am rather saying that we should have a simple but general-purpose crate that lets us configure physical<->logical input bindings and such, so it's easy to do sensible things like allow users to remap keys and load the mappings from config files.

Examples of what I want, from non-Rust game engines:

Current state of the art as far as I'm aware:

Thoughts?

Lokathor commented 5 years ago

The SDL2 "mapping string" is industry standard here. Even when not using SDL2 itself, the mapping string format should be supported. End users expect your programs to support this format. For example, Steam will place any alternate mapping you should use in an environment variable that you're supposed to read at startup and respect if it's set. This allows steam to set "system wide" remappings when people have odd controllers.

The format is a textual description of how things work, and assumes that you're trying to take some sort of "thing with buttons and axes" and make it act more like a "thing that's like an xbox 360 controller". An example string is in their wiki:

"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7"

So since we have "a thing that's kinda like an XBox 360 controllers", we can use that as one starting point for what sort of abstract inputs we'd have and would want to be able to map to game inputs.

icefoxen commented 5 years ago

I didn't quite mean something like that, which afaik is there mostly to deal with the zoo of mutually-incompatible controller layouts. (gilrs does use this format and load its definitions from SDL2, I believe.) More something that goes atop of it, and says "Right stick X and Y axis: camera" and "Left stick X and Y axis: motion".

Lokathor commented 5 years ago

That sounds like it quickly gets very game specific.

Can you expand your example idea some more?

Ralith commented 5 years ago

See the OpenXR action API for significant prior art in this vein.

On Fri, Aug 2, 2019, 13:11 Lokathor notifications@github.com wrote:

That sounds like it quickly gets very game specific.

Can you expand your example idea some more?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rust-gamedev/wg/issues/34?email_source=notifications&email_token=AAAZQ3TZFLVHFZHIBALGGGDQCSIIBA5CNFSM4IJATFW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3OXKQY#issuecomment-517829955, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAZQ3SZTLKMAD75VS4GU2TQCSIIBANCNFSM4IJATFWQ .

Ralith commented 5 years ago

Now that I'm at a keyboard: The OpenXR action API works as follows:

  1. An application declares at startup all the typed logical actions that the user can take
  2. Optionally, the application may suggest default physical bindings for those actions on one or more abstract input device archetypes (e.g. xbox controller).
  3. As the application undergoes state changes, it activates different subsets of the declared actions
  4. The state of active actions is sampled by game logic as needed

The OpenXR runtime maps physical inputs to logical actions in the spirit @icefoxen describes. In lieu of user-customized bindings, the application's suggested bindings can be mapped directly to hardware that closely corresponds to the archetype, loosely to hardware that is analogous, or ignored entirely if there's no reasonable mapping to available hardware. Mappings can transform input; for example, mapping an analog axis to a boolean action could result in a boolean that is true if the axis is above a certain threshold.

I believe Khronos made a mistake in requiring applications to consume input by sampling states. For the proposed library, I suggest instead exposing a lossless event queue.

In the spirit of the above, the proposed library could have three mostly-independent APIs: a hardware-facing one that allows input from winit/gilrs/... to be dumped in, an application-facing API to declare, suggest bindings for, and consume events for actions, and an application-facing API suitable for implementation of user-facing binding UIs. Additionally, a standardized human-friendly and aggressively forwards-compatible config format for representing mappings would be useful. Ideally winit and co (or helper crates) could implement support for the hardware-facing API, allowing application developers to focus on the logical aspects.

It would be interesting but likely difficult to attempt to build an interface with first-class support for driving OpenXR underneath rather than the built-in processing that would be required for conventional applications.