It's funny how easy it is to overlook something because of how well-concieved it is. I dabbled in Street Fighter 2 at the shabby convenience store across the street from my high school, and have played it a handful of times in the 10 years (ack!) since then. I've always had a high regard for it, without being a fanatic.
All the while, though, I never really noticed the genius of their command input system. I thought it was cool, just because it was so much deeper than a button-masher, but didn't appreciate the subtleties and complexities of designing such a system.
...Until now. I'm building my own version of that system for the game I'm working on in XNA. I got the first iteration done in about 2.5 hrs one night, such that my little character was running around throwing punches and dragon punches. None of the collision detection or rules logic is there yet, just the ability to change a unit's state via specific sequence of inputs.
But as soon as I tried to expand it to handle things like "while grabbing an enemy in mid-air, press ...", it got really challenging, really fast.
I love the concept - imagine a tech tree like in Civilization or Moo2. Each node in the tree stores a fighting technique that you have learned. You start out with the ability to execute just the first few actions in the tree (ex: "Punch".) Whenever you provide input (ex: Down-Forward-Punch), the input is sent to the tech tree. Starting with the deepest nodes in the tree which you have unlocked (in this case, just "Punch"), each node adds the new input to its own little "input history" and checks to see if its special move should execute. If it executes, the tree quits processing (doesn't send the new input to any remaining nodes) and clears the input history for all nodes. If an input doesn't match the required inputs for the node's technique, that node's history is erased and you have to start over.
Suppose you only have the "Punch" node unlocked, and you press Down-Forward-Punch. The "Down" and "Forward" inputs are mismatches as far as the "Punch" node is concerned, so it clears its history as each of those inputs is received. But when the "Punch" input comes in, why, that matches the node's required input ("Punch"), so the special move is executed.
As your character progresses, you can buy upgrades (ex: "Dragon Punch") which unlock deeper nodes in the tree. When you input commands, they go to the deepest nodes first, so once you've unlocked Dragon Punch, if you press Down-Forward-Punch, what happens is:
- "Down" is sent to the "Dragon Punch" node. This matches the node's first required input, so the command is stored in the node's history. Some required inputs still need to be received before the technique is executed, though, so the input filters up the tree to the "Punch" node. "Punch" discovers an input mismatch and clears its history.
- "Forward" is sent to the "Dragon Punch" node. This matches the node's next required input, so the command is stored in the node's history. A required input still needs to be received before the technique is executed, though, so the input filters up the tree to the "Punch" node. "Punch" discovers an input mismatch and clears its history.
- "Punch" is sent to the "Dragon Punch" node. This matches the node's next required input, and then the node detects that it has matched all of its inputs so the technique executes ("SHORYUKEN!") This means that the "Punch" input won't be sent up the tree to any other nodes (so you don't get a punch action at the same time as your dragon punch!) and all nodes in the tree clear their histories.
...To a point. When I tried to implement the aforementioned "while grabbing an enemy in mid-air, press ...", the model broke (along with my brain.) I think I've got it sorted now, but I'll need a good couple of hours to implement the change and clean up the details I haven't quite pinned down yet.
Whoa - time to turn down the talk and turn up the work. Cheers.
PS: Check out David Sirlin's amazing writing, if you too have underestimated SF2 all this time...