Diagonal movement with gamepads

2012-11-05

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.

TSL 0.39 released

2012-09-16

As usual, you can get it at the TSL homepage.

Changelog follows below.

Read the rest of this entry »

Doors and keys

2012-09-13

I have added locked doors to TSL.

They have their own tile type, in addition to the open, closed and secret doors that already exist. A random number of doors on each level will start out as locked.

There is a new “key” item that will unlock a door. Keys are expendable (one use only), stackable (“5 keys”) and any key will open any door. You can select them from the inventory screen or just bump into a locked door; if you have any keys you will be prompted to use them.

If you do not have any or choose not to use them, you will instead be prompted if you wish to break the door. This has a random chance of success and something bad should happen each time you fail (making noise, taking damage, or at least being slowed down for a while – details at eleven). Having a crowbar with you should also be helpful, but I haven’t decided exactly how.

If you can’t get a door open, there are also the option to teleport past or blow it up with explosives.

Destructible terrain

2012-09-06

I will be releasing TSL 0.39 for the 2012 “annual roguelike release party” around September 15-16th (probably the first time I’ve announced a release in advance).

It will have some (attempts at) critical bugfixes, such as the 64-bit save/load and display bugs.

The new “do what I mean” inventory system is mostly complete and I have converted several other subsystems to use the same menu framework. It’s not polished yet but a uniform menu system will make things easier to navigate and future improvements will benefit all menus at once. Ideally every screen where you browse or select something will use a similar layout and control scheme.

I have improved the damage system for weapons. Using an unidentified weapon partially uncovers its damage sequence and completing the sequence will fully identify the weapon. All that is missing now are the finishing moves that also will trigger when you complete a sequence, but these will take a little while longer.

I have also made an attempt at destructible terrain and it’s working quite well. Explosions (from grenades and fireballs) will destroy doors and “weak” walls (those that have open areas on two opposing sides, north/south or west/east). I have wanted this ever since the earliest days of TSL, but I have not figured out how it should work until now (turned out to be trivial).

There is not much point yet in blowing up doors, but if I add locked doors some day (without enough keys), there might be. So, how about a wand a digging?

More inventory trouble

2012-06-23

Still working on the new inventory interface. I have freed up two lines at the bottom to make more room for the description box. This leaves me with only one line for the key reference, but I think that will do.

I have hit a snag with item pickup and dropping. These actions are supposed to cost one turn per item, but this menu locks up the game logic flow. I can’t easily drop a single item, go back to the main loop to run a game turn and then resume the dialog. I have a few options, none of which is really good:

  • Create some kind of delayed event queue that drops items one by one. This is way out of scope. I never planned for it and there are just too many things that can go wrong. For example, items can be destroyed between turns so at the very least I would need a safe GUID handle for every item in the game (now I just have pointers).
  • Make a slightly hacky variant of the above with the “multiaction” facility. This is my current way of extending actions over several turns, but I think only resting and “Aimed Shot” make use of it so far. This for a reason – it’s a real mess to work with. I could possibly supply it with a list of item letters to pick up from the current location. If an item is not there (it has been removed or destroyed) it can simply be skipped, so there’s less risk of crashing.

From a gameplay point of view, my main complaint about these two is that they will lock the player up for several turns. If I try to pick up five items and an enemy wanders on screen, I want to interrupt and deal with that first. They also open up gray areas like what would happen if the player is teleported away during the extended action (should probably just abort the action, but I would need to track down every case where it can happen).

  • Pick up item, set a flag, return to the main loop, at the next turn (if the flag is set) return to the dialog. I think this would work but probably cause UI bugs (and I have enough of those already).
  • Make drop and pickup cost only one turn regardless of how many items are transferred.
  • Make drop and pickup free actions. This is how (un)equip works now: you can completely replace your equipment without even spending a turn.

The last two would keep drop and pickup as atomic actions, but would require me to change the ruleset. I do not want to make the actions entirely free since I wish to keep their tactical purpose – “should I stop to pick up and use that potion of healing or just keep fighting for two turns?”

Free dropping could throw the encumberance penalties off balance. I’m not happy with them anyway so this could be a good thing. If I decide to keep encumberance I could change it to some kind of delayed effect if necessary.

Allowing multiple item transfer in a single action would create some odd discrepancies in the UI. For example, the “do what I mean” Enter key only picks up one item at a time, while the ‘,’ key would let you pick up several. I could change Enter to pick up everything on the floor.

A compromise would be to only let the player transfer a limited number of items, say three per turn.

I’m probably overthinking this. You usually pick up only two or three items at a time and letting that consume only a single turn would not change much, and this issue will definitely not govern how fun the game is. I’m all for removing micromanagement and if anyone wishes to grind and scum that isn’t really my problem.

Oh, and another thing: I made so the default pickup key ‘,’ works within the pickup menu as well. You can now hit it once to bring the menu up, then keep tapping the same key (rather than Enter) to pick up the selected item. It feels much more natural, much more… dwim-y.

Introducing RUUKLOST

2012-06-21

This is another game I am working on. RUUKLOST is an attempt to replicate (and an homage to) NES-era platformers. As a spirit warrior of RUUKLOST, you travel through hostile wilderness and ancient ruins to collect the essence of your fallen brethren. The world will require thorough exploration and many areas remain inaccessible until you possess the appropriate abilities.

I am stalling at the moment since I lack sprites. I am not much of a pixel artist myself and it takes a lot of time to draw. If you feel like being lead artist and monster designer, let me know.

Current status:

  • Engine: Using the Allegro library so it is very portable. It already runs on Linux and Windows. Graphics are really 300×200 and scaled up to the window size (or fullscreen) the player prefers. Levels are tile-based and the backgrounds have parallax scrolling (one layer). It is designed for a gamepad but also works with a keyboard. Infrastructure is mostly in place but I have done little monster programming and quest scripting so far.
  • Level editor: Built into the engine, to build and playtest at the same time. Not very polished but almost complete and gets the job done.
  • Level design: About 10% done.
  • Grapics: I have about 1/3 of the tiles I think I need. I have player sprites and a few monsters but most are rather crude. Backgrounds are needed. Title screen and font done.
  • Music & sound: Not even started.

Resuming TSL development

2012-06-21

I have had a break from TSL development for a while (I have been working on RUUKLOST and some other things). I recently got back from the IRDC 2012 with a lot of ideas, so I have taken up development again.

The focus right now is fixing some of the interface issues. TSL, being a very conservative roguelike, is built around the “verb-object” interaction model – that is, you first decide what to do, then which entity to interact with.

A classic example of overly complex roguelike interaction (besides the “wipe ears” command) is having separate keys for going “up” and “down” stairs.

(As a bit of an aside: this is surprisingly one of the few “anti-features” I have avoided in TSL – since up and down stairs can not coexist on the same tile, I decided early on to just have a common key for both and I recently I dropped directional stairs entirely. My levels lack the concept of “depth” and have a somewhat non-linear progression, so up and down are meaningless. Stairs simply take you between levels – that’s it.)

Many players find the menus in TSL confusing and wish to navigate them using the arrow keys. They also ask for an easier way to perform “default” actions as it is not always clear what an item is capable of. I admit this is a problem. “Emergent item interaction” is a central concept in roguelikes and I have a few items with intentionally vague usage – however, these should not be off-putting for the whole game.

I am currently working on a “do what I mean” concept. I have already done some things in this area. Last year I made Enter a general-purpose DWIM key. It will, in highest to lowest priority:

  • Pick up an item at the players feet
  • Climb stairs (if there are no items)
  • Wait a turn (if there are no items or stairs)

There are still separate “pick up”, “climb” and “wait” keys. There are situations where you might want to wait on top of stairs or climb them without picking up items first, but most often you do not.

I also wrote an inventory system that could sort items by type, filter out “uninteresting” items (for example, only potions show up for the “drink” prompt), switch between items and allow common actions without leaving the menu. This was slightly more convenient than the old “inspect” command that would display two items side by side, but

This approach still fails to address the “verb-object” problem, explain which items support which actions or make the menu navigation easier – in fact, it adds even more keys!

So, for a couple of days, I have been making another attempt to resolve this:

You browse with the arrow keys or jump to an item by pressing its letter. The list auto-scrolls at the 2nd item from the top or bottom (the small cross at the bottom indicates you have more items than would fit on screen – I might replace the character but I like the discrete look).

At the bottom is a quick reference what actions you will take by pressing different keys:

  • Enter performs default action (drink for potions, read for scrolls and book, equip for equipment, remove for already equipped equipment, and so on)
  • A way to drop items (not sure if I can use the alphabetic default for this, since it would clash with the point below)
  • Alphabetic characters navigate to specific items

This is clearly a departure from my earlier assumption that every player is an expert in hardcore roguelikes and/or enjoys learning 20 keybindings from a help file. I hope to find a balance between “displaying helpful tips” and “wasting screen space by displaying text that no one will bother to read after their second play session” (I’m not keen on adding an option toggle for “novice” and “minimal” modes). I think two lines at the bottom should be enough for this.

It might also seem like a waste of space to have separating lines all over, but it really helps to keep things structured. If I absolutely need all 24 lines to display text, I would be displaying too much information anyway.

Verb-object interaction will still exist in parallell, but I honestly think most players will prefer the new mode.

Obviously this is a work in progress and still has rough edges. Text doesn’t wrap properly yet. The angle brackets around item names indicate which ones are currently equipped, but this should be made more prominent (right now I’m thinking of appending “(worn)” or maybe indenting the line – we will see).

I might also use the “flip” key (tab) somehow to display long descriptions (most items should have short descriptions but there is bound to be a few that need more than 30 words). This would either shrink the list and enlarge the description box, or scroll the description box.

I will also be using this menu for the facet/augmentation inspection and pick up item screens. When picking up items, the player would typically hit the ‘,’ (or ‘g’) key and press enter-enter-enter-enter to transfer each item to the inventory (they would then disappear from the pickup screen). This will also let the player inspect items before picking them up, which I think will be a welcome addition.

I’m not sure how well this will mesh with the turn model. Currently a turn is consumed for each item picked up. If I allow multi-item pickup on a single turn this is no problem, but if I want to run other game logic between each item without the player leaving the menu, it’s going to require a really serious and ugly hack.


Follow

Get every new post delivered to your Inbox.