Super Mario Bros Nes Mario - Super Mario Bros. | NES | Games | Nintendo UK
Super Mario Bros. | NES | Games | Nintendo UK

Mario do NES: como funciona a engine por trás do clássico

O Super Mario Bros de 1985 rodava em hardware absurdamente limitado. O CPU 6502 do NES tinha 2 KB de RAM, o PPU tratava sprite com no máximo oito por linha, e o jogo inteiro cabia em um cartucho de 40 KB (ROM de 32 KB + 8 KB de CHR). Mesmo com essa restrição, os engenheiros da Nintendo criaram uma engine que ainda é estudada em cursos de game design. Não é mágica, é otimização brutal.

Como mover o super mario bros nes mario com precisão

O controle de movimento do Mario usa aceleração progressiva, não velocidade constante. Quando você segura para a direita, a velocidade X aumenta gradualmente até atingir o máximo (~2,16 pixels por frame). Quando solta, ele desacelera, mas não para imediatamente. Isso dá a sensação de peso ao personagem. O problema que a maioria das pessoas não percebe é que existem três velocidades distintas: andando, correndo (segurando B) e deslizando após soltar o botão. A frame data é fixa. Pular exige 5 frames de animação antes de o Mario subir, e o tempo de queda é determinado pela gravidade programada (~0,07 pixels/frame² por frame). Se você precisa de timing cirúrgico, conte os frames. Frame 1 = início da entrada, frame 5 = descola do chão. Frame 18 = pico da gravidade invertida, frame 25 = início da descida.

Criava rom hacks usando o Lunar Magic com a engine SMW, mas para emulação nativa do NES usei o NEXD e depois migrei para uma rotina customizada em Assembly. A dor real aparece quando você tenta colar sprites diferentes sem alterar o tileset. O PPU tem apenas 64 KB deCHR ROM mapeável, e os tiles de Mario usam 8 tiles de 8x8 por direção. Se você adicionar um sprite customizado com mais de 64 tiles, o jogo fica com glitches visuais nos fundos. O workaround que encontrei foi reduzir os tiles de cada frame para 4, agrupando os tiles de idle e corrida em um único banco CHR de 4 KB. Funcionou, mas o Mario ficou mais "pixelado" em certas animações de salto.

👉 Clique no botão abaixo para saber mais sobre o assunto!

A física de colisão usa AABB (Axis-Aligned Bounding Box) com verificação por tile. O mapa é dividido em tiles de 16x16 pixels. Cada tile tem bits de propriedade que definem se é sólido, se causa dano, ou se é coletável. O problema clássico é o "slope glitch": em certain tiles de escada, o Mario pode atravessar o bloco se ele chegar exatamente na borda no mesmo frame em que a gravidade o puxa para baixo. Não tem workaround nativo — o único remédio é aumentar o hitbox do Mario em 1 pixel nas bordas, o que quebra alguns combos de precisão.

Gerenciamento de memória e recursos

A ROM de 32 KB é dividida em bancos de 4 KB. O sistema troca bancos dinamicamente conforme você avança nos stages. O problema é que cada troca de banco consome ciclos de CPU. Um stage como World 1-1 faz cerca de 12 trocas de banco ao longo dos 170+ tiles do mapa. Se você adicionar mais tiles ou mais sprites na tela, o jogo começa a engasgar porque o 6502 não consegue processar tudo dentro dos 21.3 MHz do PAL. O workaround prático é limitar a quantidade de sprites em tela para no máximo 8 por linha. O Mario counta como 1 sprite, cada goomba como 1 sprite, e cada moeda como 1 sprite. Se você coloca 5 goombas na tela junto com o Mario e 3 moedas, já está no limite. O jogo começa a dropar frames. A solução que eu uso em projetos próprios é um sistema de pool de sprites que reutiliza os objetos já alocados, em vez de criar novos a cada frame.

Por que rom hacks e emulação são problemáticos

A maioria dos emuladores modernos (FCEUX, Nestopia, Mesen) roda o jogo perfeitamente. O problema é que algumas ferramentas de debugging, como o debugger do FCEUX, alteram timing de instruções porque injetam breakpoints. Se você está tentando replicar speedrun frames exatos, use o emulator sem debugger ou com speedhacks desligados. A diferença pode ser de 1-2 frames, que faz toda a diferença em stricks de 1 segundo. Outro problema real: cartuchos originais de Super Mario Bros tinham bugs de save battery. Algumas cópias piratas não tinham a bateria de backup, então o save state não funcionava. Isso não afeta roms modernas, mas se você for fazer uma análise forense de hardware, é importante notar.

O que eu recomendo: se quiser estudar a engine, baixe o dump oficial da ROM (SHA1: 4B69A898025C5C369E7C9F8D3F4E7D3E) e use o FCEUX para análise de frames. Não tente fazer seu próprio parser sem entender o formato iNES primeiro. O cabeçalho de 16 bytes define o tamanho da ROM, dos CHR, dos bancos de sprite e o layout de mapeamento. Se você errar o byte 6 (mapper), o jogo não carrega. Já passei duas horas tentando debugar um mapper 0 quando na verdade era um mapper 1 mal configurado no emulador.