Структуры данных в старых играх

10

Мне любопытно, какие структуры данных используются при программировании старых игр, таких как Super Mario Brothers для NES и Super Mario World для SNES. Насколько я понимаю, игры этого периода были написаны на сборке. Программисты определяли / использовали какие-либо структуры данных?

Например: когда группа монет появляется на экране, как они хранятся? Программисты просто использовали массивы? Или, возможно, у них были связанные списки?

Ура!

Редактировать : меня интересуют различные подходы ... не обязательно универсальный подход.

Редактировать 2 : В некоторых моих играх я использую (потенциально плохой) подход к коллекциям, и я хочу знать, использовал ли какой-либо из старых игр аналогичный подход. Мне нравится делать следующее:

// 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
источник
2
Нет универсального ответа; все сводится к тому, как данный программист реализовал решение для данной проблемы.
Эд С.
1
Хотя я не думаю, что все эти игры были написаны на ассемблере, я скажу, что программисты на ассемблере довольно часто собирают свои небольшие компоненты для повторного копирования / вставки из программы в программу. Сколько раз вы хотели бы написать функцию printf ()? :)
Джеймс
Хорошая точка зрения. Мне действительно интересно узнать о динамически размещаемых коллекциях и статически распределенных коллекциях
MrDatabase
1
Какие конкретные проблемы у вас есть? Почему тебя волнует, что делают старые игры?
Тетрад
2
То, что вы получили во втором своем редактировании, является примером макета «структура массивов», который остается обычным даже в современных играх, поскольку имеет преимущества для параллелизма и работы SIMD. Пару лет назад Sony сделала презентацию о том, как традиционный C ++ способ структурирования данных может привести к серьезным скрытым издержкам: research.scee.net/files/presentations/gcapaustralia09/…
Crashworks

Ответы:

13

Даже в 16-битные дни игровые приставки были в основном небольшими встроенными компьютерами, на которых работало программное обеспечение реального времени, а используемые нами структуры данных были такими же, как и в любой информатике: массивы, матрицы, кучи, деревья. Не так много связанных списков, потому что они такие медленные (косвенные поиски имеют большую задержку).

Разница в том, что до STL и при столь критической производительности нам обычно приходилось самим писать структуры и алгоритмы!

Дэвид Брабен выступил с веселой лекцией на GDC 2011 года, где рассказал о всех сумасшедших уловках, которые он использовал, чтобы установить Elite на BBC Micro в 1984 году. Вы можете бесплатно посмотреть его в GDC Vault .

Crashworks
источник
Круто. Вы использовали динамически распределяемые массивы? Или у большинства был статический размер? Мне любопытно, когда, скажем, пять монет появляются на экране и остаются на экране до тех пор, пока игрок не соберет их (или они прокрутят за пределы экрана).
MrDatabase
2
@MrDatabase - Статические распределения везде, где это возможно. Для таких случаев, как вы описываете, у нас часто просто есть статически распределенный массив, например, 32 возможных монет, которые могут существовать. Когда в мир приходили монеты, мы заполняли место в массиве. Когда они уходили, мы бы это убрали. Динамическое распределение не было недоступно, мы просто избегали его использовать, потому что, когда у вас есть только 2 МБ ОЗУ, вам действительно нужно гарантировать, что ваша программа работает в постоянной памяти!
Crashworks
Круто. Я делаю нечто подобное (см. Правку № 2 к вопросу). В своей функции обновления я проверяю набор битов "coinsActive", if(coinsActive)прежде чем перебрать maxNumCoins и выполнить обновление. Таким образом, я полностью избегаю петли, если активны нулевые монеты.
MrDatabase
+1 из-за ссылки GDC Vault. Посмертная «Попольная» речь Питера Молинье, должно быть, самая веселая из всех, что я когда-либо видел.
TravisG
MeDataBase - вы копируете последний активный объект в слот, который был занят монетой, которая стала неактивной (т. Е. Если у вас есть 10 монет, монета 5 становится неактивной, копируйте монету 10 в слот 5 и уменьшаете числовые монеты), вы можете просто выполнить итерацию вверх чтобы numCoins и обновить все эти элементы. Вам не нужно «если». Конечно, это работает только в том случае, если неактивным монетам не нужно поддерживать состояние и если порядок обновления не важен (состояние можно поддерживать, если массив хранит указатели на монеты, а не на реальные монеты, но тогда вы получаете разбросанное поведение кэша, которое вероятно, хуже, чем «если»)
Кадж
5

Вот интересная дискуссия на GameDev.net для исходного кода Super Mario Bros: Исходный код Super Mario

пекин
источник