Diagonal movement with gamepads

I have been experimenting with joystick/gamepad support in TSL, starting with the recent 0.40. I don’t really expect anyone to play it using only a gamepad but it raises some interesting questions about interface design.

There has been much discussion over this the last few years. POWDER has been around for a long time and many more roguelikes are being adapted – or developed specifically for – handheld devices. They are limited to (or blessed with?) touchscreens, d-pads and a few high-visibility buttons. Developing control methods that do not require a keyboard – without dumbing the gameplay down – is a challenge.

I recently learned there is a TSL package for the Pandora (unfortunately not the latest version after I switched to the Allegro library, which there is currently no Pandora port of), so these concerns don’t seem entirely irrelevant.

TSL is designed as a very traditional roguelike that uses separate keys for everything; around 57 (!) last time I checked. Not all of them are strictly required to play the game though, and some are redundant. I have done some work already to reduce the need for memorization and make things more intuitive: the new inventory browser, on-screen shortcuts and various tweaks so the game will most of the time accept keys that just “make sense”.

TSL has had remappable keys for a long time (I use a Dvorak-like keyboard layout myself). It is also capable of reading input from both curses and Allegro, each with their quirks and incompatibilities (for example, I use hardcoded values for numpad in curses – the constants simply do not work on my setup!).

To make this somewhat manageable each input handler converts non-alphanumeric input to an internal “key token” format. This is the most “raw” form the game logic is ever exposed to, and most of the time it is passed directly to the keymap handler to look up what in-game action it is bound to.

This allows some useful abstraction. For example: escape, space and numpad zero are all assigned to the “cancel” action, and all prompts that can be cancelled will accept any of those keys. There are a few clashes where the raw key tokens take precedence, but almost everything is confined to the keymap code.

Reading joystick input in Allegro is really easy; I just need to catch a joystick event instead of a keyboard event. It was trivial to add key tokens for joystick buttons and bind them to actions within the game.

Joystick axes, however, are another matter. Joysticks have separate X and Y values that can be polled for the position of the stick, remaining at 0 when the stick is centered and yielding positive and negative values when swung either way. Remember the calibration screens in DOS games? They were there to detect the extremes of the analog joystick signal.

Even with modern operating systems and the introduction of digital hardware this scheme remains largely intact. A typical gamepad has a d-pad instead of a stick but will still pretend to have two axes. They are digital in the sense that they move between discrete values of -1, 0 and +1 without cable interference, but the computer treats it the same way it would an analog joystick.

The most basic solution would be to catch the events for the axes reaching max or min value and return these to the game logic as a “direction north/east/south/west” key token. However, since axis events arrive sequentially this would only allow movement in cardinal directions. TSL tactics often require extensive use of diagonals (I have long considered a special item or status that would restrict the player to only four directions – or making it a conduct!).

I came up with two solutions to this:

  • Trigger on button release. I call this “sloppy” mode. The event handler will keep a record of which directions have been pressed and merge these into a key token once the axes return to neutral position. For example: if you press left, let go, you will move west. If you press left and up, let go, you will move northwest. It also has a small tweak: if you press left and up, change your mind and release the left – wait a little while (about a second), the handler will forget that you had pressed left and only move you north.
  • You use the d-pad to aim. Pressing two directions will overlay them and a separate “step” button will trigger the movement. Releasing the d-pad does nothing. This might be prefered over the previous method, since only tapping out a long sequence of directions is both faster and causes less strain since you don’t need to move the thumb as much.

Admittedly, both these are a bit clumsy, but they work. Sloppy keys can also be enabled (and behave identically) for the directional keys on the keyboard – this offers a middle ground for anyone with a laptop (or other keyboard without numpad) that doesn’t want to use vi-keys.

One drawback is that this operates on such low level that it is entirely hidden from the logic code: even things like menu browsing will be affected. It would be possible to set a flag and temporarily switch the input method to detect extremes, making the game react instantly when a direction is held on the gamepad. However, always switching between the two could get very confusing. On gamepads with many buttons maybe two of them (like the L/R) could be designated for menu browsing.

There are a couple of things I must get in place before this becomes really useful, such as an in-game key mapping screen. I have had plans for it a long time, but haven’t written any code yet. It should use key tokens and be mostly hardware-independent, to allow rapid adjustment on any exotic hardware.

I also need to write some JRPG-style menu screens. Every action would need to be reachable from a single menu tree, in theory reducing the required number of buttons to only two or three plus directionals.

Footnote: I have been told there are gamepads with eight separate button switches for the d-pad, but I have not tried one myself. Even if this would be the electrical layout, I would assume they still pretend to have axes when talking to the OS, since that is what most games understand.


2 Responses to “Diagonal movement with gamepads”

  1. Moehein Specifics (@MoeheinSpecific) Says:

    >limited to/blessed with touchscreens
    Limited to, always. Playing roguelikes (among other things) on an iPhone is a pain in the ass thanks to the touchscreen. Playing FAangband on the Nintendo DS was a pain in the ass too thanks to the touchscreen. It’s a cute idea, but touching a virtual key is much more annoying than touching a physical key.

    Your second solution (aim and ‘step’) is by far the best solution if you’re working with analog sticks.

    Funny how it’s apparently incompatible with menu browsing; who’d have thought!

  2. HPL Says:

    I think the problem is directly adapting existing RLs for new interfaces. When writing entirely new games for handheld devices it’s easier to get them right from the start. For example, you can remove the need for continuous tapping by letting the player “jump” anywhere within an area instead of walking one tile at a time. Inventory and other “disturbing” screens can be omitted. Combat and magic can be reduced to gestures instead of navigating menus. These games would be more abstract and puzzle-like, but not necessarily “less roguelike”.

Leave a Reply ... IF YOU DARE

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: