Skip to content
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

Resolve device ID conflict between joypads and mouse and keyboard #7161

Open
stephanbogner opened this issue Jun 26, 2023 · 5 comments
Open

Comments

@stephanbogner
Copy link

stephanbogner commented Jun 26, 2023

Describe the project you are working on

I am working on a game that supports local multiplayer (and I want to use the device ID to forward the input to the correct player).

Note: I am developing with Godot v4.0.3.stable.official [5222a99f5] on Linux

Describe the problem or limitation you are having in your project

If I understand correctly, IDs are working the following way:

  • Touchscreen (emulated mouse): -1 (Source)
  • Keyboard and mouse: 0 (Source: Testing)
  • Joypads (controllers/gamepads, joysticks): Can be 0, 1, 2 up to infinity 🚀 but whatever is returned by get_connected_joypads()

Problem:

Since keyboard and mouse and the first controller share the same ID (0) I can't use it to uniquely refer to a device.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Solution:

Change the ID for keyboard and mouse.

Option 1: Combined ID for keyboard and mouse

Possible solutions:

  1. Use -2 as a new ID for keyboard and mouse, rest stays the same
  2. Or 0 = keyboard and mouse, 1 = touchscreen, 2 and above = joypads

Option 2: Separate ID for keyboard and mouse

I could imagine use cases (e.g. "asymmetric" coop where player 1 uses keyboard and player 2 uses only mouse) where it would be cleaner to differentiate between mouse and keyboard with IDs and not just by the events themselves ... but for most games it likely can be treated as one device

Possible solutions:

  1. -2 for mouse and -3 for keyboard, rest stays the same
  2. Or 0= keyboard, 1 = mouse, 2 = touch, 3 and above = joypads

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I think code is straight forward, it's only about using different values. Problem is mainly that it would be a breaking change (even for option 1, solution 1)

If this enhancement will not be used often, can it be worked around with a few lines of script?

(1) I currently use the following code as a workaround (which is option 1, solution 1):
(Only problem is I have to map it every time I want to access the device ID, if forgotten can create input conflicts)

func _get_device_id_from_event(event:InputEvent) -> int:
	var device_id_keyboard_mouse := -2
	# --- Mouse ---
	if event is InputEventMouse:
		return device_id_keyboard_mouse
	if event is InputEventMouseButton:
		return device_id_keyboard_mouse
	if event is InputEventMouseMotion:
		return device_id_keyboard_mouse
		
	# --- Keyboard ---
	if event is InputEventKey:
		return device_id_keyboard_mouse
		
	return event.device

(2) Another workaround would be to prefix the joypad ID, e.g. joypad_0
(3) Or increase the ID for joypads, e.g. += 1, so joypad IDs start at 1 and not at 0

Is there a reason why this should be core and not an add-on in the asset library?

It's already core functionality

@Zireael07
Copy link

Note that on some Android devices, ID 0 is taken by fingerprint reader and not joypad

@Calinou
Copy link
Member

Calinou commented Jun 26, 2023

  • Use -2 as a new ID for keyboard and mouse, rest stays the same

This prevents supporting multiple keyboards and mice as independent devices if we ever want to go for that route. While this isn't planned in the short term, I wouldn't want to write ourselves into a corner due to API design.

@stephanbogner
Copy link
Author

This prevents supporting multiple keyboards and mice as independent devices if we ever want to go for that route. While this isn't planned in the short term, I wouldn't want to write ourselves into a corner due to API design.

A more general solution would be even better ... I just didn't want to overcomplicate 😅

Get devices:
Something like get_connected_devices() (and then get_connected_keyboards(), get_connected_mice(), etc.) analog to get_connected_joypads() would be great.

Get device type:
Then we'd need something like get_device_type(device_id) (which I think doesn't exist yet) which would return mouse / keyboard / touchscreen / joypad / fingerprint_reader / ...

connected mouse and keyboard:
get_connected_keyboards(), get_connected_mice() would be handy too, because (if I am not mistaken) currently one has to assume that keyboard and mouse are connected, which makes it not ideal if you make cross-platform games. (Partially related to #6689 )

FYI: I am currently planning to use OS.get_name() to set a variable assume_keyboard_mouse_connected to show to correct available input methods ... but it's more wishful thinking that our game is gonna make it to consoles 😅

@Marenz
Copy link

Marenz commented Dec 29, 2023

Related to this: If you want to add an input mapping for all devices, you currently have to use -1 which is not documented and also not intuitive given the double meaning of "mouse emulation" for the touch screen case.

@Marenz
Copy link

Marenz commented Dec 29, 2023

Also this becomes more relevant with godotengine/godot#79480 (comment) coming

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants