Se você jogou Crash Bandicoot no PlayStation em 1996, percebeu algo toda vez que carregava um nível: você sempre corria na mesma direção. Para frente, em direção à tela. Caminhos lineares por templos na selva, ruínas antigas e corredores de fábrica, sempre seguindo em uma única direção, sem espaço para voltar ou explorar para os lados. Esse design de corredor se tornou uma marca registrada de Crash. E também não teve quase nada a ver com intenção criativa.
A verdadeira razão era um problema matemático. O PS1 tinha 2 megabytes de RAM do sistema. Um único nível de Crash Bandicoot continha de 32 a 40 megabytes de dados.
Isso não é um erro de digitação. Um jogo rodando em hardware com 2MB de memória de trabalho precisava renderizar ambientes que eram de 15 a 20 vezes maiores. A única questão era como.
O Problema em Números
| O quê | Tamanho | |---| | RAM do sistema do PS1 | 2 MB (2.097.152 bytes) | | Nível típico de Crash Bandicoot | 32 a 40 MB | | Dados carregados a qualquer momento | Menos de 2 MB | | Bytes restantes na memória no lançamento | 4 |
Vale a pena refletir um pouco sobre a última linha. Quando a Naughty Dog finalizou Crash Bandicoot e prensou o disco para lançamento, o jogo cabia em seus 2MB de memória com exatamente 4 bytes de sobra. Não 4 kilobytes. Não 4 centenas de bytes. Quatro bytes, de um total de 2.097.152.
O Motor de Streaming de Andy Gavin
Crash Bandicoot tinha dois programadores: Andy Gavin e Jason Rubin. Gavin cuidou do motor, e a situação da memória o obrigou a inventar algo que o PS1 nunca foi projetado para suportar.
Sua solução foi um sistema de streaming de CD em tempo real. Enquanto o jogador corria por um nível, o motor lia continuamente dados do disco do jogo, puxando três blocos de 64 kilobytes por segundo a uma taxa sustentada de aproximadamente 300 kilobytes por segundo. Conforme Crash avançava, os dados para a próxima seção do nível chegavam do disco para a RAM. Conforme ele se afastava de seções anteriores, esses dados eram descarregados da memória para abrir espaço.
A palavra crítica é "frente". O motor de streaming só podia pré-carregar de forma confiável em uma direção. Precisava prever, com precisão quase perfeita, quais dados o jogador precisaria em seguida. Um caminho ramificado, uma sala para a qual o jogador pudesse voltar, ou qualquer layout não linear, teria quebrado essa lógica preditiva e feito o jogo travar enquanto tentava carregar os recursos certos.
"Tínhamos níveis com mais de 10MB de dados, e isso tinha que ser paginado e despaginado dinamicamente, sem nenhum problema." Andy Gavin, sobre as restrições de design por trás de Crash Bandicoot.
Os corredores lineares não eram uma escolha estilística. Eram a única geometria de nível que fazia o sistema de streaming funcionar. A arquitetura da gerenciamento de memória do jogo determinou a forma de cada nível.
O Preço Para o Drive de CD
A taxa de streaming era tão extrema que os engenheiros de hardware da Sony ficaram alarmados. A Sony avaliou o drive de CD do PlayStation para aproximadamente 400.000 leituras durante sua vida útil. Quando os números de streaming de Gavin foram compartilhados internamente, a resposta da Sony foi de preocupação imediata: no ritmo que Crash Bandicoot exigia do disco, um jogo contínuo esgotaria um drive em aproximadamente três semanas.
A maioria dos jogadores, claro, não estava rodando o jogo continuamente. Mas o gap na especificação mostra o quão fora do envelope de uso pretendido a Naughty Dog havia levado o hardware.
Encaixando 4 Bytes em Um Orçamento de 2MB
A pressão da memória não parou na arquitetura de streaming. Gavin e Rubin passaram a fase final do desenvolvimento espremendo código e dados de maneiras sem precedentes.
Algumas técnicas eram estruturais, como o próprio sistema de streaming. Outras eram mais desesperadas:
- Empacotando dados nos dois bits inferiores de ponteiros, explorando o fato de que todos os endereços de memória no processador R3000 do PS1 eram alinhados em 4 bytes, deixando esses bits sem uso
- Permutando código C em formas semanticamente idênticas, mas sintaticamente diferentes para convencer o compilador a gerar uma saída 200 bytes menor, depois 125, depois 50, depois 8
- Auditando cada variável, cada ativo, cada byte de sobrecarga de tempo de execução até que nada mais restasse
O número final foi de 4 bytes de memória livre, de mais de dois milhões. Gavin documentou a história completa em seu blog, e ela lê menos como uma análise pós-morte de desenvolvimento e mais como um quebra-cabeça sendo resolvido em público.
Por Que Esta História da Memória Pertence à Sua História de Jogos
Crash Bandicoot completa 30 anos este ano. Muitos jogadores se lembram do ataque giratório, dos caixotes, da máscara Aku Aku. Poucos sabem que a característica visual mais distinta do jogo, aquelas corridas lineares na selva, veio diretamente da solução de um programador para uma crise de memória.
Esse contexto não torna o jogo mais nostálgico. O torna mais interessante. As restrições produziram o design, e o design se tornou um marco do gênero.
Se Crash faz parte da sua história de jogos, o lugar para registrá-lo é na The EndWiki, onde você pode acompanhar todos os clássicos do PS1 que você jogou ou planeja jogar. O pilar de Memórias de Jogos detalha por que essas primeiras sessões de PlayStation produzem o tipo de memórias que permanecem por décadas. E se sua coleção abrange múltiplas plataformas, importe tudo de uma vez para ter o panorama completo da sua história de jogos em um só lugar.
Os 4 bytes não significarão nada até que você saiba o custo para encontrá-los. Agora você sabe.
