Getting Started

This document will help you get started with the NPC Arcade SF2 API. Using the API you will be able to create agents which can observe high-level game state, make decisions based on that state, and interact with the game using a virtual joystick. For the time being your agent will only be able to compete with the default computer player included with the game, or alternatively a human via keyboard. If this proves to be a popular platform then I'd like to add a ranked competitive ladder where user-created agents can automatically fight against each other.

Street Fighter 2's game engine runs at a constant 60 frames per second. Before each frame is drawn to the screen, the game engine reads the joystick hardware and will use that input to update the game state. It follows that a single frame is the smallest slice of time which is relevant to a player or agent, so agents will have a chance to observe game state once per frame. Here is an example of a basic AI which illustrates this concept:

module.exports.frameHandler = function() {
  if (Math.abs(player.position.x - opponent.position.x) > 80) {
    joystick.direction = player.position.x < opponent.position.x ? RIGHT : LEFT;
  } else {
    joystick.punchHeavy = battle.frame % 2;
  }
};

Your main module (index.js) should export a frameHandler function using standard NodeJS conventions. During the execution of your script there are several globals exported: battle {Battle}, player & opponent {Character}, playerIndex {number}, opponentIndex {number}, and joystick {Joystick}. In the example you can see some simple logic. The if statement checks to see if the agent is currently more than 80 pixels away from the opponent. If so, it will push the joystick in the direction of the opponent. In the case that the agent is within 80 pixels from the opponent the agent will continuously mash the punchHeavy button. Note that if you just set punchHeavy to true then the character will only punch once, since that is the equivalent of simply holding down the punch button. battle.frame increments once per frame, therefore we can use that as a quick and dirty way to press and release a button every frame.

Continue reading: Animations & Hitboxes.