Executando verificação de segurança...
29

A inteligência artificial do Street Fighter II

Encontrei um blog chamado sf2platinum que contém algumas curiosidades sobre o funcionamento do Street Fighter II: The World Warrior, um jogo de arcade lançado em 1991.

O autor do blog começou a fazer engenharia reversa das ROMs do jogo em 2005 e reescreveu o jogo inteiro em C. Decidiu que escreveria o blog para compartilhar o que descobriu no código, já que provavelmente não pode compartilhar o código por questões de direitos autorais.

O artigo que estou trazendo nesta publicação é o The AI Engine, escrito em 2017. O artigo é bem curto, então traduzi integralmente para cá, mas o artigo não tem nenhuma imagem, então peguei elas de outras referências sobre o assunto em questão (vale visitar a fonte das imagens também).

O mecanismo da inteligência artificial

A "inteligência artificial" de um jogo de 1991 não é como a inteligência artificial que está na mídia hoje em dia. Falando especificamente sobre o Street Fighter II, a IA é apenas um algoritmo para controlar um NPC (non-player character), sem machine learning ou outras coisas mais elaboradas.

O autor disse no artigo que os movimentos feitos pelo computador não são feitos de forma independente, mas sim agrupados em pequenos scripts, escritos em um bytecode semelhante à linguagem de máquina. Um avatar de computador tem um repertório de scripts diferentes para cada oponente que ele pode enfrentar no jogo e um conjunto de circunstâncias, como um hadouken (o autor chama de "fireball") próximo.

As instruções nos scripts podem comandar o avatar para executar um ataque (soco/chute/especial/arremesso), caminhar ou pular em algum lugar e esperar – seja por um cronômetro ou por alguma condição, como a capacidade de lançar outro hadouken.

Outras instruções podem manipular diretamente variáveis na máquina de estado de IA, testar certas condições e formar blocos IF...END primitivos. O autor disponibilizou uma das rotinas de ataque "fáceis" típicas do Ryu: jogar três hadoukens em você e, se os três te atingirem e você ficar tonto, correr até você e arremesá-lo.

ORG 0x99c88 sf2ua.bin
0x02,                   ; script header, type 2 
0x10, 0x50, 0x04, 0x00, ; throw a hi str fireball
0x00, 0x80,             ; wait until I have no fireball
0x10, 0x50, 0x04, 0x00, ; another hi str fireball
0x00, 0x80,             ; wait again
0x10, 0x50, 0x04, 0x00, ; another hi str fireball
0x92,                   ; are they dizzy?
0x04, 0x00, 0x18,       ;    walk until we're within 24 pixels  
0x00, 0x82,             ;    wait if they're still getting up
0x10, 0x84, 0x00, 0x00, ;    throw(4)
0x94,                   ; end if
0x00, 0x00, 
0x00, 0x00,             ; wait four frames
0x00, 0x00, 
0x00, 0x00, 
0x86,                   ; chain to another randomly chosen script

Tirando o byte do cabeçalho, o primeiro byte de cada linha é o byte de instrução. As instruções são agrupadas em comandos de avatar (0x0-0x7f) e acesso ao fluxo de controle / variável (0x800xff). Cada um deles geralmente possui um número fixo de parâmetros, por exemplo a instrução "ataque" (0x10) sempre recebe três argumentos:

  1. O tipo de ataque (movimentos especiais são 0x50, 0x52, 0x54..., arremessos são 0x80, 0x82, 0x84...).
  2. A força do ataque (neste caso é um hadouken forte / rápido).
  3. Uma contagem de repetições para ataques envolvendo segurar e golpes múltiplos (não utilizado no exemplo acima).

A instrução "espera" (0x00) geralmente recebe um argumento, decodificado como:

  • 0x00x7f: Aguarde N quadros (frames).
  • 0x80: Espere até eu conseguir lançar um hadouken.
  • 0x81: Espere até que o oponente esteja dentro de M pixels (segundo parâmetro adicional).
  • 0x82: Espere até que meu oponente esteja atacável.
  • 0xc0: Espere até que o salto do oponente atinja a altura M (segundo parâmetro).

Todas as instruções e muitos dos parâmetros são múltiplos de dois (não há instrução 0x01, por exemplo) para que possam ser usados diretamente em tabelas de salto de 16 bits. A resistência baixa/média/alta se traduz em 0, 2 e 4, assim como a maioria dos componentes internos do jogo. Quaisquer números ímpares causariam uma exceção de erro de barramento da CPU, o que resultaria na reinicialização da ROM do SF2.

O mecanismo de inteligência artificial possui três modos principais de operação:

  1. Esperando por um ataque. Roteiros simples são escolhidos aleatoriamente e consistem principalmente em caminhar para frente/para trás em pequenas quantidades.
  2. Atacando ativamente. Scripts como o acima são selecionados.
  3. Reagindo a um ataque. Os scripts adequados para combater o ataque são selecionados. Às vezes. Dependendo da configuração de dificuldade da IA, o computador permite muitos ataques sem proteção, é claro.

Para os dois primeiros modos, existem 8 níveis de scripts, que são escolhidos com base em quanto tempo resta para a rodada. Ao reagir a um ataque, os scripts são escolhidos com base em algo chamado yoke.

Cada quadro de animação para avatares e projéteis contém um valor para o yoke nos metadados, que a IA espia para selecionar um script adequado para responder a esse ataque. O computador vê o controle do seu movimento assim que você o insere, antes mesmo de o primeiro quadro de animação ser exibido. Como tal, obtém mais um quadro de vantagem além do seu tempo de reação.

Object Test do Ryu
Object Test, um tipo de depuração que permite visualizar todas as animações do personagem e os dados associados à elas. Note o yoke, como mencionado acima. Fonte: tcrf.net

A IA tem certos tipos de trapaça. Movimentos de carga, como o flash kick do Guile (GIF abaixo), são simplesmente executados como instruções, portanto não podem falhar. Guile pode dar um chute em pé simplesmente porque é isso que está no roteiro. Provavelmente é possível para a IA comandar movimentos especiais no ar. Uma instrução está disponível para desabilitar colisões contra o jogador do computador por um certo número de quadros. Usando-o, você poderia escrever um script para simplesmente passar por um hadouken que se aproxima.

Chute do Guile
Fonte: vídeo How the CPU cheated you in Street Fighter 2.

Uma das telas de teste (mais ocultas) do jogo realiza uma verificação de integridade no bytecode da IA. Não é imediatamente óbvio para que serve, pois apenas exibe “OK” e nada mais, mas a engenharia reversa revela que os desenvolvedores talvez estivessem testando e desenvolvendo o código de IA em máquinas CPS. As mensagens de erro no código de teste revelam nomes para algumas das instruções como MOSI, KON, KYON, TIGA, TAN, GTAN e END IF, mas além do último nome óbvio, o autor não imaginou o que elas poderiam significar. Os comentários da publicação no blog tem algumas suspeitas sobre o que podem significar, coisas como KON = THIS, MOSI = IF e TIGA = ELSE.

Como dica final, o autor disse que os leitores podem encontrar o bytecode da IA do Ryu começando no endereço ROM 0x9966e em sf2ua. Defina um ponto de interrupção em 0x2ad2a para parar na entrada principal do código da IA. As variáveis de estado do Avatar da IA começam em 0x200 da estrutura do jogador (0x5c6 e 0x8c6 para P1/2 respectivamente em sf2ua).


Se você gostou desse artigo, é provável que goste também do Curiosidades sobre o Street Fighter II e a placa de arcade CPS-1, que fala mais sobre o sistema de blocos e a placa CPS.

8
3

Tem várias curiosidades que dariam ótimos vídeos. Um ponto negativo é que algumas coisas são difíceis de conseguir mais detalhes ou mesmo imagens, mas acho importante produzir conteúdo sobre para manter a história viva.

1