Engenharia Reversa: Como o motor do Elifoot 98 decide os gols (e por que o 5-0-5 quebra o jogo)
Depois de conseguir colocar o laboratório de engenharia reversa de pé no Debian,
a parte que eu mais estava curioso pra destrinchar era o simulador de partidas.
Afinal, o que raios o Elifoot 98 calcula a cada segundo enquanto o relógio da
rodada está correndo na tela?
Olhando o código descompilado no Ghidra (principalmente as funções
FUN_3e3c_069b, FUN_17fb_a6eb e FUN_17fb_81ed), deu pra mapear o pipeline exato
de como uma partida é simulada do minuto 1 ao minuto 90.
O Fluxo da Partida em 5 Etapas
O jogo não tem física de bola nem movimentação de jogadores num campo 2D. Ele
roda como uma máquina de estados estatística dividida assim:
[ 1. Pré-Jogo ]
Calcula o poder dos 4 setores (G, D, M, A)
Aplica Força x2 + Bônus de Nacionalidade (+3 por jogador local)
│
▼
[ 2. O Relógio do Minuto (1 a 90) ]
minuto = minuto + 1
Roda um sorteio pra ver se o minuto vira um lance de perigo
│
▼
[ 3. O Filtro do Mando de Campo ]
Mandante: Random(6000) < Força do Ataque
Visitante: Random(7000) < Força do Ataque
│
▼
[ 4. O Duelo (Atacante vs Zagueiro/Goleiro) ]
Random(Força do Atacante) vs Random(Força da Defesa)
│
▼
[ 5. A Finalização (Matriz de Desfechos) ]
GOLO | Defendeu | Ao poste | À barra | Ao lado | Por cima
O Pré-Jogo: A matemática da força dos setores
Antes do árbitro apitar o início, a função FUN_17fb_397d varre os 11 titulares e
calcula a força total de 4 setores: Goleiro, Defesa, Meio-Campo e Ataque.
A fórmula interna que o código aplica pra cada jogador é: Poder no Setor =
(Força Nominal * 2) + (Mesma Nacionalidade * 3) + Ajuste de Posição
Dois detalhes chamam a atenção aqui:
-
A força que você vê na tela entra com peso dobrado no cálculo interno.
-
Se o jogador tem a mesma nacionalidade da liga onde o clube joga, ele ganha
+3 pontos brutos fixos de bônus no setor dele. Se você escalar 11 titulares
do mesmo país, seu time entra em campo com +33 de força somada só de bônus
de entrosamento.
- Por que a tática 5-0-5 quebra o motor do jogo?
Aqui está a resposta definitiva pra quem sempre achou o esquema 5-0-5 (5
defesas, 0 meias e 5 atacantes) apelativo demais.
No código, o papel dos jogadores é distribuído assim:
-
Zagueiros: entregam 100% da força na Defesa.
-
Atacantes: entregam 100% da força no Ataque.
-
Médios: dividem a força em 50% pro Ataque e 50% pra Defesa.
O pulo do gato: o Elifoot não tem penalidade de posse de bola por falta de
meio-campo. O motor avalia o Ataque quando você tenta criar jogadas e a Defesa
quando o adversário tenta chutar.
Se você tem um time com jogadores de força 40:
- No 4-4-2 clássico: seu ataque soma
2 \times 40 + (4 \times 20) = \mathbf{160\text{ pontos}}.
- No 5-0-5: seu ataque atinge o pico de
5 \times 40 = \mathbf{200\text{ pontos}} (um salto de +25% no poder ofensivo
pra furar o sorteio de chances a cada minuto).
Ao mesmo tempo, seus 5 zagueiros continuam somando 200 pontos lá atrás, o que já
é mais do que suficiente pra travar os ataques da IA. Jogar sem meio-campo
simplesmente elimina o "desperdício" da força dividida dos meias e coloca o
poder de ataque no teto máximo possível.
- A Assimetria Brutal do Mando de Campo
Durante os 90 minutos, o jogo tenta sortear se naquele minuto específico vai
acontecer uma chance de perigo. E aqui o código é covarde com quem joga fora de
casa:
No teste principal de cada minuto (FUN_17fb_a6eb):
-
O time da Casa precisa que Random(6000) < Força do Ataque.
-
O time de Fora precisa que Random(7000) < Força do Ataque.
-
Como o divisor do mandante é menor, quem joga em casa tem cerca de
+16,7% mais chances de criar lances de gol ao longo da partida.
- No teste secundário / contra-ataque (FUN_17fb_46df):
-
Em casa, o jogo sorteia em Random(90).
-
Fora de casa, o jogo sorteia em Random(120) (33% mais difícil).
-
E no lance de pura sorte (lucky roll), a casa tem 1 chance em 180
(0,55%/min) contra 1 em 270 fora (0,37%/min).
Além disso, esse teste secundário tem uma trava anti-goleada: a cada chute dado
e gol marcado, o jogo subtrai o valor do limiar pra impedir que partidas
terminem em 15 a 0.
- O Duelo e a Tabela de Finalização
Se o time passou no teste do minuto e criou a jogada, a função FUN_17fb_81ed
roda o duelo entre o atacante que recebeu a bola e o zagueiro/goleiro:
Duelo = Random(Força do Atacante) vs Random(Força do Defensor)
- Em 25% dos casos, o jogo desvia o lance pra eventos secundários (escanteio,
falta ou bola aliviada).
- Nos outros 75%, quem tirar o maior número no sorteio vence a jogada.
Se o atacante vence a dividida e fica cara a cara com a meta, a função
FUN_17fb_c1bf consulta a matriz de desfechos que achamos no segmento 8484 da
memória:
-
GOLO: bola na rede e placar atualizado.
-
Defendeu: goleiro espalma ou segura.
-
Ao poste: bola na trave vertical (~5% de azar estatístico fixo).
-
À barra: bola no travessão.
-
Ao lado / Por cima: finalização pra fora.
O resumo da ópera
No fim das contas, o resultado de uma partida no Elifoot 98 é um balanço de ~70% de fatores estratégicos e acumulados (Força dos Atletas + Moral da Equipe + Mando de Campo + Bônus de Nacionalidade + Esquema 5-0-5) contra ~30% de aleatoriedade pura (RNG).
É essa margem de 30% que garante aquela zebra ocasional no meio do campeonato, mas a combinação de moral alta + jogadores locais de força máxima no 5-0-5 transforma qualquer time numa máquina de vitórias quase impossível de ser parada pelo algoritmo."
O código em C descompilado do motor de jogo tá todo no repositório pra quem
quiser conferir direto: