Estruturas de dados em jogos mais antigos

10

Estou curioso sobre as estruturas de dados usadas na programação de jogos antigos, como Super Mario Brothers para NES e Super Mario World para SNES. Entendo que os jogos desse período foram escritos em assembléia. Os programadores definiram / usaram alguma estrutura de dados?

Por exemplo: quando um grupo de moedas aparece na tela, como elas são armazenadas? Os programadores apenas usaram matrizes? Ou talvez eles tivessem listas de links?

Felicidades!

Edit : Estou interessado em várias abordagens ... não necessariamente uma abordagem universal.

Edição 2 : em alguns jogos, uso uma abordagem (potencialmente ruim) para coleções e quero saber se algum dos jogos mais antigos usou uma abordagem semelhante. Eu gosto de fazer o seguinte:

// statically allocated arrays (max number of coins is 4)
int coinsXs[4] = {0, 0, 0, 0};
int coinsYs[4] = {0, 0, 0, 0};

// bitset that keeps track of which coins are active
int coinsActive = 0;

// ...

// update the active coins in an update function
for(int i = 0; i < 4; i++){
    if(coinsActive & (1 << i)){
        // update ith coin
    }
 }
MrDatabase
fonte
2
Não há resposta universal; tudo se resume a como um determinado programador implementou a solução para um determinado problema.
Ed S.
11
Embora eu não ache que todos esses jogos tenham sido escritos em montagem, direi que era bastante comum os programadores de montagem coletarem seus pequenos componentes para reutilização de copiar / colar de programa para programa. Quantas vezes você gostaria de escrever a função printf () depois de tudo? :)
James
Bom ponto. Estou muito curioso sobre alocação dinâmica vs alocados estaticamente coleções coleções
MrDatabase
11
Que problema específico você tem? Por que você se importa com o que os jogos antigos fazem?
Tetrad
2
O que você obteve na sua segunda edição é um exemplo de um layout de "estrutura de matrizes", que permanece comum até nos jogos modernos, pois possui benefícios para o paralelismo e a operação do SIMD. Sony fez uma apresentação de um par de anos atrás sobre como a maneira tradicional C ++ de dados estruturação pode ter graves escondidos perf custos: research.scee.net/files/presentations/gcapaustralia09/...
Crashworks

Respostas:

13

Mesmo nos dias de 16 bits, os consoles de jogos eram basicamente pequenos computadores embarcados executando software em tempo real, e as estruturas de dados que usamos são as mesmas que você encontraria em qualquer lugar da ciência da computação: matrizes, matrizes, montes, árvores. Não há muitas listas vinculadas porque são muito lentas (as pesquisas indiretas têm uma longa latência).

A diferença é que, antes do STL, e com desempenho tão crítico, geralmente tínhamos que escrever as estruturas e os algoritmos!

David Braben fez uma palestra divertida na GDC de 2011, onde falou sobre todos os truques malucos que usou para colocar o Elite na BBC Micro em 1984. Você pode assistir gratuitamente no GDC Vault .

Crashworks
fonte
Legal. Você usou matrizes alocadas dinamicamente? Ou a maioria tinha um tamanho estático? Estou curioso sobre situações em que, digamos, cinco moedas apareceriam na tela e permaneceriam na tela até que o jogador as coletasse (ou rolassem para fora da tela).
MrDatabase 20/08
2
@MrDatabase - Alocações estáticas sempre que possível. Para casos como você descreve, geralmente temos apenas uma matriz alocada estaticamente de, por exemplo, 32 moedas possíveis que poderiam existir. Quando as moedas chegavam ao mundo, preencheríamos um ponto na matriz. Quando eles saíam, nós deixávamos em branco. A alocação dinâmica não estava disponível, apenas evitamos usá-la porque, quando você tem apenas 2 MB de RAM, realmente precisa garantir que seu programa seja executado em memória constante!
Crashworks
Legal. Faço algo semelhante (veja a edição 2 da pergunta). Na minha função de atualização, verifico o conjunto de bits "coinsActive" if(coinsActive)antes de passar pelo maxNumCoins e atualizar. Dessa forma, evito completamente o loop se zero moedas estiverem ativas.
MrDatabase 20/08
+1 por causa do link do GDC Vault. A palestra popolosa pós-morte de Peter Molyneux deve ser a palestra mais hilária que eu já vi.
TravisG
MeDataBase - você copia o último objeto ativo para o slot que foi ocupado por uma moeda que ficou inativa (ou seja, se você tiver 10 moedas, a moeda 5 fica inativa, copia a moeda 10 para o slot 5 e diminui as moedas numactivas), basta iterar para cima para numCoins e atualize todos esses elementos. Você não precisaria do 'se'. É claro que isso só funciona se as moedas inativas não precisarem manter o estado e se a ordem da atualização não for importante (o estado poderá ser mantido se a matriz armazenar ponteiros para moedas e não moedas reais, mas você obter um comportamento de cache disperso, o que é provavelmente pior do que o 'se')
Kaj
5

Aqui está uma discussão interessante no GameDev.net para o código fonte do Super Mario Bros: Código fonte do Super Mario

pek
fonte