Fighting Game Notation Made Easy
Published: 2023-05-28 23:10:25

Fighting games require complex button combinations to execute "combos." To share combos with fellow enthusiasts, we use "numpad notation," which associates the numbers on a standard nine-button number pad with a direction (Down is 2, Forward is 6, Up is 8, etc.). However, deciphering numpad notation can be challenging for newcomers. Given that fighting games have the reputation of being unwelcoming for new players, I wanted to work to make combo notation one less barrier for entry. In this blog, we will explore my "Combo Builder" that simplifies notation through the process of converting fighting game numpad notation into easy-to-read, digestible images with recognizable iconography.

##The Combo Builder Interface:
The Combo Builder is a dynamic upload interface where users can notate their own combos. Each button on the interface represents a button press in the game and will have the same appearance as the corresponding in-game button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zi3vce8vswpupvmukqej.png)
*2P 6P 236S notated through the combo builder*

These input buttons are saved on the backend where a Game has many inputs. For example, the "P" button (Punch) is saved as follows:

```
Input.create!(
  input_type: "Button",
  name: "P",
  image_url: "https://i.imgur.com/Dv8VQDw.png"
)
```

This input has a type value of "Button," which corresponds to its position in the builder (Directions, Motions, Universal, Buttons, Game-specific notation). Additionally, the name "P" is how this input would be normally notated, and the image URL is the iconography used in the game to depict this button press.

## Handling User Interaction:
Once inputs are fetched and organized by their type, the user is able to create their combo notation by clicking inputs. During the combo creation process, two types of data are saved: an array of image URLs and a string of inputs. The array of image URLs only exists on the frontend for creation while the string of inputs is saved in the backend for later use.

The handleClick function adds a new button to the combo. It takes the source URL of the button's image and the corresponding button name as parameters. The function appends the source URL to the imageUrls array and updates the inputs string by adding the button name.

```
function handleClick(src, name) {
    setImageUrls(() => [...imageUrls, src])
    if (inputs.length > 0) {
      setInputs(() => `${inputs} ${name}`)
    }
    else setInputs(name)
  }
```

The handleSpace function adds an empty image and a hyphen ("-") to represent space between inputs. It helps improve the readability of the combo notation.

```
  function handleSpace() {
    // set spaceUrl from game data later!
    const spaceUrl = "https://i.imgur.com/IxEwf4u.png"
    setImageUrls(() => [...imageUrls, spaceUrl])
    setInputs(() => `${inputs} -`)
  }
```

The Combo Builder also includes functionality for clearing the input progress and removing the most recently added input. These make for great quality of life improvements for the user experience.

```
 function handleClear() {
    setImageUrls([])
    setInputs("")
  }

  function handleBackspace() {
    const updatedImageUrls = imageUrls.slice(0, imageUrls.length - 1)
    setImageUrls(updatedImageUrls)

    const inputsArray = inputs.split(" ")
    const updatedInputs = inputsArray.slice(0, inputsArray.length - 1).join(" ")
    setInputs(updatedInputs)
  }
```

## Serialization and Image URL Mapping:
Though only inputs are saved on the backend, during the combo serialization process we send the user the array of image URLs. This method splits the inputs string by spaces and maps each input to its corresponding image URL. By using a case statement, the appropriate image URL is assigned based on the input value, in the exact order they were saved.

```
def image_urls
    object.inputs.split(' ').map do |input|
      case input
        when '1'
          'https://i.imgur.com/Fby15hF.png'
        when '2'
          'https://i.imgur.com/KezFbHr.png'
        when '3'
          'https://i.imgur.com/06D3AyK.png'
        when '4'
          'https://i.imgur.com/HwKpXDr.png'
        when '5'
          'https://i.imgur.com/OfO6HKV.png'
        ...
end
```

The code snippet showcases various cases for different input values, including numeric inputs for directions and motions (according to standard numpad notation), and game-specific inputs. This approach allows for easy modification and addition of new image URLs in the future, providing flexibility and scalability to the Combo Builder.

## Examples

### 1) Guilty Gear Strive Combo
Numpad notation:
c.S 2H 486H 66 2K 268H

Inputs string saved:
c. S - 2 H - 486 H - 6 6 - 2 K - 268 H

Serialized Output:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2snf7sdbqc206ileqnjn.png)

### 2) Street Fighter 6 Combo

Numpad notation:
DR 2MP 2HP 214[MP] DR HP 214[LP] 236LKLK 236236HK

Inputs string saved:
DR - 2 MP - 2 HP - 214 [ MP ] - DR - HP - 214 [ LP ] - 236 LK LK - 236 236 HK

Serialized Output:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2y9ikqqpbauhgyj0zxjo.png)

## Conclusion:
This Combo Builder provides a user-friendly interface for creating and visualizing fighting game combos. It is a smaller piece of a larger project I'm working on called the Combo Library which will act as a hub for fighting game players to upload their combos (on a per game, per character basis) using this digestible notation.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stb1faxl5wkq6vpqfejd.png)