Working around a MonoGame joystick crash

TL;DR: Try adding unset SDL_JOYSTICK_DEVICE to your game’s launcher script.

Have you ever encountered an error that starts out like this when trying to start a Linux port based on MonoGame?

Number of joysticks: 5
Number of buttons for joystick: 0 - 11
Number of axes for joystick: 0 - 8
Number of PovHats for joystick: 0 - 0
Number of buttons for joystick: 1 - 11
Number of axes for joystick: 1 - 8
Number of PovHats for joystick: 1 - 0
Number of buttons for joystick: 2 - 11
Number of axes for joystick: 2 - 8
Number of PovHats for joystick: 2 - 0
Number of buttons for joystick: 3 - 11
Number of axes for joystick: 3 - 8
Number of PovHats for joystick: 3 - 0

Unhandled Exception:
System.IndexOutOfRangeException: Array index is out of range.
  at Microsoft.Xna.Framework.Input.GamePad.AutoConfig () [0x00000] in :0
  at Microsoft.Xna.Framework.Input.GamePad.PrepSettings () [0x00000] in :0
  at Microsoft.Xna.Framework.Input.GamePad.GetState (PlayerIndex playerIndex, GamePadDeadZone deadZoneMode) [0x00000] in :0
  at Microsoft.Xna.Framework.Input.GamePad.GetState (PlayerIndex playerIndex) [0x00000] in :0
  [...]

It’s basically saying that it found five joysticks, then got their characteristics wrong, then died when trying to access item 5 out of 4 in the listing.

In my case, the problem was as follows:

  1. On Linux, there are two APIs for accessing joysticks. An old, deprecated, joystick-specific one, and the generic “any input device” API which has no concept of calibration.
  2. My first joystick device is always my 3DConnexion SpaceNavigator, which isn’t a joystick but has stupid USB HID tables which cause the Linux kernel to expose a useless joystick device as the first joystick on the system.
  3. Some games only listen to the first joystick.

My solution for a lot of games was to set this environment variable in my .xsessionrc to force SDL to see my XBox 360 gamepad as the first joystick and to access it via the calibration-aware /dev/input/jsX API rather than the “expect hardware to not need calibration” /dev/input/eventX API.

# Make sure SDL uses a joystick device which can be calibrated
export SDL_JOYSTICK_DEVICE=/dev/input/js3

Adding unset SDL_JOYSTICK_DEVICE to the launcher script for the game fixed it… at the risk of requiring joystick support to be had via antimicro (a joy2key-like utility).

UPDATE: For the really stubborn bugs, you may also need a switched USB hub off eBay for a few bucks.

CC BY-SA 4.0 Working around a MonoGame joystick crash by Stephan Sokolow is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

This entry was posted in Geek Stuff. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

By submitting a comment here you grant this site a perpetual license to reproduce your words and name/web site in attribution under the same terms as the associated post.

All comments are moderated. If your comment is generic enough to apply to any post, it will be assumed to be spam. Borderline comments will have their URL field erased before being approved.