Elegant Solution to the Problem of Dealing With Multiple Key/Mouse Presses at the Same Time
I am working on a game concept but before going any further I want to make sure that I do not make any bad choices regarding the control schema. One of the central ideas that the game revolves around is being able to combine character actions into other actions based on what their single key press actions are. One of the issues is recognizing what the player intends. This issue can, from my point of view, be broken down into two issues: synchronicity of presses and choosing what action to trigger.
For synchronicity there are only really two options that I've been able to come up with on my own and it seems that the only real differences between the two options are from a game design point of view.
After the first key press set a timer in motion for some small amount of time, (1/10th of a second? I don't know, I would need to test manually/ask best practices about this amount of time). After that time has passed gather the key combination that is pressed down. Don't start the countdown again until one of the used keys has been released.
From no keys pressed set a timer in motion. After that time has passed gather the key combination that is pressed down, from here if any changes are made to the key combination check if its a valid change and move to the action specified from that key combination.
(Only occurred to me after first posting the question) Only look up what keys are being pressed every 0.1 (or better measure) seconds.
For making sure I direct the game to do what the user intends, however, I have come up with a few more ideas.
First all of the following options are built on the following ideas. First, each possible action, compound or simple has its own class, each class contains it own logic and a list of the keys needed to activate it. Second keys can be separated into mobility keys and action keys. Mobility keys are simple enough that they don't need a complex structure to hold the logic, their logic can be run inline with each item of mobility logic having the same effect regardless of the rest of mobility logic. Each action class has a isMobilityBlocking check to see whether it cancels out the mobility logic in its entirety.
From these assumptions here are the possibilities I've considered for narrowing down from the ability list.
A simple array/list of action objects picked through by simple a simple key checking logic that checks each action class' key presses. Why I considered it: It stops too much information from being held in one file Why I'm hesitant: It would create too much processing just to parse key presses, it would have to check every single ability
A tree of action objects where each level represents a different key that can be pressed and the children are yes and no. Why I considered it: It would be much faster than the array to parse through Why I'm hesitant: It would put a lot of information into one file. This approach is not collaboration friendly, if two separate contributors tried to add a new key into the mix separately merging the changes would not be pretty. Each null combination by necessity must by explicitly spelled out
A dictionary/hash/whatever you call it in the language of action objects where the key is constructed based on the key combination of the action. Why I considered it: It brings the time to find the ability down immensely, reintroduces collaboration friendliness. Why I am hesitant: The logic of creating the key builder could be finicky and might break down.
An array again, but this time each key is given a value of 0-x and an integer is created using 2^keyvalue sums for the action's array index. Why I considered it: Uses fewer data structures Why I am hesitant: It adds more logic to the code, more points of failure while providing little speed improvement over #3. Reintroduces manually nulling empty key combinations.
All of these considerations have been made with the assumption that the performance of inserting into the data structure is negligible compared to the performance of the repeated searches that will be necessary in the context of a game. If there is anything I missed or a better option advice would very much be appreciated.