Action map stack - event masking

This is perfect, and very similar to the systems I've created in the past for dealing with these types of issues. Bravo!

One situation I've run into in the past, and was not clear if this will be handled elegantly, follows.

  • Some action is mapped to the press and release of a give button (e.g. A on Joystick, crouch when pressed, jump when released)
  • User presses A, then presses Start button to bring up menu.
  • User releases A button.

You probably want this action blocked since the menu is up, and may want to use the A button for selecting items in your menu. However, you can't just ignore it or the event will be lost forever -- i.e. when you go back in game, player will now be stuck in crouched position because they never got the A button release event even though the A button is no longer held down.

The solution I've used in the past is to store a state per map and mask the state updates based on the stack and whether it blocks or not, then generate events from each state separately. I've also found it useful to support Press and Hold as a low level event, that way you'd only update the timer for that action when not masked by a higher priority action map.

1 Like

These kind of things is something we've looked into and addressed to some degree already, to acoid the same button press registering twice and things like that. There are a lot of different nuances and edge cases of it though. I'll add your use cases as a test case to cover. Thanks!

For reference, these are some of the cases we covered:

  • When pressing e.g. mouse button or gamepad trigger in one action map creates a new action map based on the same device, the new action map should not immediately have wasJustPressed be true. Hence the state in the newly created control scheme should be initialized to the state of the devices it's based on.
  • When pressing e.g. mouse button or gamepad trigger and it causes a switch in control scheme within an existing action map, the new control scheme should immediately have wasJustPressed be true. Hence the state in the newly created control scheme should not be initialized to the state of the devices it's based on.

To be clear, which behaviour would you expect exactly?

I'd say we can't just fire the A button release when it actually happens, since it should affect an ActionMap that is currently not supposed to receive events. The choices are if a simulated button release should happen when the ActionMap becomes masked (e.g. when entering the pause menu) or if it should keep appearing pressed until the pause menu is closed, and then immediate give a release event is the button is no longer pressed at that point when the ActionMap is unmasked again? I'm guessing the latter.