Даже сегодня люди по-прежнему продолжают создавать новые игры для старых консолей. Мы называем их «homebrew». Иногда это способ реализовать детскую мечту о создании игры для консоли, на которой играл ребёнком. Но кроме того это ещё и интересная задача для любого дизайнера или разработчика игр: ретро-железо обладало множеством ограничений, бросающих вызов креативности авторов. В 90-х для профессиональных разработчиков эти ограничения были привычными. Сегодня, когда у нас есть более совершенные инструменты, создание игр для подобных машин стало гораздо доступнее.
В прошлом году я написал статью о создании игры для Game Boy. Сегодня я поделюсь своим опытом создания трёх игр для домашней консоли SEGA Mega Drive/Genesis. Вероятно, благодаря современным мощным инструментам, это самая простая машина для разработки homebrew-игры. Например, мне даже удалось создать (очень простую) игру всего за 60 минут, и она на самом деле запускается на консоли!
Игры
В прошлом году, чтобы отметить 30-летнюю годовщину выпуска Genesis / Mega Drive, я создал игру под названием «30 Years of Nintendon’t». Как понятно из названия, это дань памяти лучшим играм консоли и агрессивному маркетингу, который SEGA использовала в то время (например, слоган «Genesis Does what Nintendon’t»).
В этой игре мы управляем евангелистом SEGA, который должен убедить игроков забыть о своих NES и SNES, потому что на Genesis игры лучше! Игра была бесплатно выпущена онлайн на 30-й день рождения консоли. В неё можно сыграть здесь: https://drludos.itch.io/30-years-of-nintendont
С тех пор я также создал для консоли две (небольшие) аркадные игры:
Все эти 3 игры продаются на картридже, изданном Cote Gamers:
http://cotegamers.com/shop/en/genesis-mega-drive/43-test.html
Он поставляется в красивой пластиковой коробке, как настоящие винтажные игры, и с набором почтовых открыток.
Можно ли использовать Unity, Unreal Engine или Godot?
Сожалею, но эти движки не способны экспортировать игры на SEGA Mega Drive/Genesis (может быть, пока?). Но не волнуйтесь, существует ещё один инструмент, который столь же полезен, как и эти популярные современные движки, и в то же время разработан специально для Mega Drive/Genesis: SGDK. Это фреймворк, позволяющий писать код для этой машины на языке C. Это намного проще и быстрее, чем изучать язык ассемблера, который был обязателен в 90-х. Но и это ещё не всё. SGDK также имеет инструменты, упрощающие создание графики и звуков. Вы можете создавать графику в любимом редакторе 2D-графики (от Photoshop до GIMP или Asesprite), и она будет преобразована автоматически, если вы соблюдаете аппаратные ограничения (подробнее об этом ниже). То же относится и к звуку: вы можете создавать звуковые эффекты в файлах .wav, а для музыки использовать различные трекеры. И последнее: SGDK имеет мощный «Sprite Engine», упрощающий большинство технических задач по отображению подвижных изображений на экране. Но насколько «просто» это в реальности? В статье я расскажу о собственном опыте работы.
На сцене появляется Blast Processing
Как вам скажет любой программист старых систем, если писать программу на C вместо ассемблера, то это снизит производительность игры. И это правда. Но затраты в разных ретро-консолях сильно различаются. Они зависят от используемых ЦП, а также от эффективности современных компиляторов, создающих код для таких винтажных процессоров. К счастью, в Mega Drive/Genesis используется процессор Motorola 68000, который достаточно хорошо подходит для работы с особенностями языка C. Особенно справедливо это по сравнению с другими ЦП, например с 65816 консоли SNES. Хотя сам по себе он и мощен, ЦП SNES сложно заставить выполнять написанные на C программы с достаточной скоростью. То есть когда дело доходит до homebrew-разработки на языке C, «Blast Processing» оказывается не маркетинговым мифом, а реальностью!
Насколько быстро может выполняться код на C?
Вот пример из личного опыта — анимированный GIF моей игры MeteoRain, в котором спрайты 45 метеоритов без задержек движутся с частотой 60fps:
А вот ещё один пример взрыва из Break An Egg, состоящего из 40 частиц, движущихся с частотой 60fps:
Если взять для примера старые игры, то хорошим примером мощи ЦП Mega Drive/Genesis является Contra Hard Corps. Хотя игра разрабатывалась на ассемблере, а не на C (ведь это было в 90-х), разработчики могли использовать огромную вычислительную мощь для перемещения множества спрайтов по экрану и создать запоминающихся боссов с кучей подвижных частей и масштабными взрывами.
Для сравнения, Contra III на SNES была ограничена мощью ЦП и вместо перемещения кучи спрайтов Konami использовала уникальные графические эффекты, на которые был способен только видеочип SNES, например, эффект прозрачности.
Несмотря на то, что обе игры одинаково интересны, они отлично подчёркивают технические различия между SNES и Mega Drive/Genesis. Подробнее о том, как Konami создавала каждую из игр под соответствующую консоль, можно прочитать в статье «Making of Contra III and Hard Corps» из Retro Gamer №176.
Графические ограничения
Поскольку вычислительная мощь не является проблемой, основным «бутылочным горлышком» консоли Genesis / Mega Drive для homebrew-разработчиков стали её графические ограничения. А если конкретнее, то ограниченное количество отображаемых ею цветов. Хотя в общем консоль может генерировать 512 уникальных цветов, одновременно на экране может быть не более 64 цветов. Ой-ёй. Для сравнения: SNES могла отображать одновременно 256 цветов из палитры 32768 уникальных цветов. То есть художникам графики нужен был большой талант, чтобы игры на SEGA выглядели так же хорошо, как на консолях конкурентов. И во многих случаях им это удавалось. Несмотря на цветовые ограничения, многие старые игры для Mega Drive/Genesis выглядят красивыми, например, Comix Zone, the Story of Thor, Streets of Rage II, Ranger-X, Gunstar Heroes, Sonic 1-2-3, и т.д.
Comix Zone (1995 год)
Но в других случаях игры Mega Drive/Genesis выглядели довольно блекло по сравнению с версиями для SNES. Один из самых известных примеров — это Street Fighter II, где цветовые ограничения консоли очень заметны:
Оптимальное использование ограниченных палитр (4 палитры по 16 цветов у Genesis против 16 палитр по 16 цветов у SNES) было большой сложностью для разработчиков, для завершения проектов у которых обычно было очень мало времени. Сегодня талантливые участники SEGA-сообщества способны модифицировать некоторые игры для оптимизации использования цветов. Например, Габриель Пирон творит чудеса с играми наподобие Castlevania Blood Lines, Golden Axe, Outrun или с вышеупомянутой Street Fighter II:
(Сверху — цветовая палитра оригинала, внизу — модифицированная Габриелем)
С учётом этого, вы можете использовать для создания изображений любимый графический редактор, но быть очень аккуратным при выборе цветов! Если вам не удастся соответствовать 512-цветовой палитре, прошитой в оборудовании, то это не проблема: SGDK автоматически преобразует изображение в палитру Mega Drive/Genesis. Но когда дело касается общего количества используемых и отображаемых на экране цветов, то вам придётся заниматься этим самостоятельно!
Заставляем объекты двигаться
Чтобы отобразить что-нибудь на экране, нужно скопировать графические данные из ПЗУ в видео-ОЗУ. Графический процессор не имеет прямого доступа к данным в ROM, но способен считывать данные из RAM. Поэтому чтобы фон или анимации спрайтов менялись, вам нужно регулярно копировать новые данные из ROM в RAM. А общее количество видео-RAM (VRAM) ограничено: всего 64 КБ. По сравнению с размерами игровых ROM (от 512 КБ до 8 МБ) это довольно мало.
Узкое место №1: передача во VRAM
Если вы создаёте очень маленькую игру с небольшим количеством графических элементов, то можно просто раз и навсегда загрузить их в память при запуске игры. Но большинству игр для демонстрации различных анимаций требуется регулярно обновлять графические данные во VRAM. И обычно это вызывает множество проблем!
Количество графических данных, которое можно передать из ROM во VRAM в каждом кадре (т.е. 60 раз в секунду), ограничено. Если конкретнее, то это 7524 байт на кадр, то есть около 7 КБ. Когда необходимо отображать огромные анимированные спрайты плюс анимированные фоны, как в Street Fighter II, то это ограничение постоянно мешает. И ведь это только первая проблема.
Узкое место №2: ограничения спрайтов
У 8/16-битных консолей ещё одна сложность заключается в общем количестве спрайтов, которое может отображать оборудование. Обычно ограничений два: одно для общего количества спрайтов на экране, другое для общего количества спрайтов в одной горизонтальной строке. У 8-битных консолей, таких как NES и Master System, эти ограничения очень суровы: не более 8 спрайтов на горизонтальную строку, а общее количество не должно превышать 64 спрайта. Значит ли это, что мы можем отобразить на экране 64 раза Соника или Марио? Нет, имеются в виду «аппаратные спрайты», которые меньше того, что обычно называется спрайтом. Вот пример из Super Mario Bros для NES, где для отображения одного спрайта Марио требуется несколько аппаратных спрайтов размером 8×8 пикселей.
(Источник: https://nesdoug.com/2018/09/05/06-sprites/)
У 16-битных консолей ограничения спрайтов немного снижены. На Mega Drive/Genesis можно отображать до 80 аппаратных спрайтов. Но отдельный аппаратный спрайт может иметь размер до 32×32 (ранее — всего 8×8 пикселей). Вот несколько примеров разрезания «аппаратных спрайтов» на Mega Drive/Genesis. Вы заметили, что Соник отрисовывается всего из двух аппаратных спрайтов, а для Марио на NES требуется 8 спрайтов?
(Источник: https://www.patreon.com/posts/new-resource-and-26847248)
Узкое место №3: приоритеты спрайтов
Как будто это было недостаточно сложно, у Mega Drive/Genesis есть ещё одна специфическая черта: цепочка спрайтов. При наложении двух спрайтов консоль должна узнать, какой из них нужно отображать поверх другого. В Master System и в большинстве консолей Nintendo (NES, Game Boy, SNES) спрайты задавались в большой таблице и их порядок в таблице использовался для задания приоритета отображения. Не нужно говорить, что это довольно сложный в применении инструмент, потому что нужно постоянно переопределять эту большую таблицу для изменения приоритета спрайтов.
На Mega Drive/Genesis компания SEGA использовала более гибкую и простую систему. Как и в других консолях, все спрайты имеют номер индекса в большой таблице, но он не используется для задания приоритета спрайта. Вместо этого каждый спрайт хранит ссылку на следующий спрайт, который будет отображаться. В конечном итоге консоль создаёт цепочку спрайтов, начиная со спрайта 0. Каждый спрайт знает только то, что идёт после него. Благодаря этому гораздо проще изменять приоритеты спрайтов без упорядочивания всех спрайтов в большой «таблице ссылок на спрайты». Но честно говоря, хотя такая система проще в использовании, она всё равно раздражает при создании игры с часто меняющимся приоритетом спрайтов, например в beat’em up.
«Простой» способ: спрайтовый движок SGDK
Отображение подвижных спрайтов и прокручивающихся фонов с учётом всех этих узких мест — довольно сложная задача. С ней боролись все разработчики 90-х, и многие homebrew-разработчики продолжают это делать. Например, Мэтт Филлипс выпустил в 2018 году великолепную игру Tanglewood, но создал её при помощи инструментов 90-х. Он программировал игру на языке ассемблера и использовал официальный аппаратный комплект разработки, спроектированный примерно 30 лет назад. С его стороны это был осознанный выбор, он хотел полностью ощутить на себе методику разработки винтажной игры.
Но для людей не столь опытных и терпеливых, как Мэтт, современные инструменты могут снизить количество проблем, создаваемых техническими аппаратными ограничениями. Мы уже упоминали, что язык C обычно проще, чем ассемблер. Также стоит добавить, что использование высокоточного эмулятора Mega Drive/Genesis наподобие Blast’em в сочетании с Everdrive Flash Cart для тестирования на реальном оборудовании делает разработку игры практически безболезненной по сравнению с разработкой при помощи старых аппаратных эмуляторов в сочетании с набором DOS-инструментов. Но повторюсь, главный подарок современности — это SGDK.
Запишите игру на SD-карту, вставьте её в Mega Everdrive, и тестируйте игру на реальном оборудовании!
Среди прочего, SGDK также имеет мощный «Sprite Engine», сильно облегчающий жизнь разработчику. Это набор функций для обработки отображения спрайтов аналогично тому, как это делается в современных фреймворках. Во-первых, вам больше не нужно волноваться о количестве аппаратных спрайтов, требуемых для каждого кадра анимации: SGDK автоматически займётся этим. Кроме того, при работе с приоритетами спрайтов вам не придётся вручную задавать цепочку спрайтов, потому что SGDK делает это при помощи простого значения «приоритет спрайта», которое можно задавать каждому спрайту, как в любом современном фреймворке. И последнее: SGDK также обрабатывает все передачи во VRAM автоматически! Да, вы всё правильно поняли, благодаря Sprite Engine вам больше вообще не понадобится заботиться о VRAM! Можно просто приказать SGDK отобразить «анимацию X спрайта Y», и он выполнит всю технически сложную работу за вас. Если вам когда-нибудь приходилось работать с этими вещами вручную, то это покажется магией — всё просто и понятно!
Один только Sprite Engine фреймворка SGDK превращает Mega Drive/Genesis в самую простую для разработки игр ретро-консоль, особенно если у вас есть опыт работы с игровыми фреймворками на современных платформах. SGDK бесплатен и имеет открытые исходники, но если вы хотите помочь его автору Стефану Даллонгевилю в дальнейшей разработке ретро-магии, то это можно сделать на Patreon: https://www.patreon.com/SGDK/
Звук
Звук на ретро-железе тоже сам по себе является настоящим испытанием, и каждая консоль в этом отношении уникальна. В Mega Drive/Genesis для этой задачи есть отдельный процессор Z80, который напрямую подключен к звуковому оборудованию. То есть для создания звука и музыки для консоли сначала нужно написать «драйвер аудио»: программу для процессора Z80. В 90-х каждая игровая студия разрабатывала собственный драйвер аудио и подстраивала его под каждую игру. Ближе к концу жизни консоли появились стандартизированные драйверы, например GEMS компании Sega of America, использованный примерно в сотне игр западных разработчиков.
Создание хорошего звука для 8/16-битных консолей — это вопрос не только музыкальных, но и программистских навыков! Некоторые игры с хорошей музыкой или звуковыми эффектами были испорчены плохим драйвером аудио. Самым известным примером опять же является Street Fighter II. Драйвер аудио в этой игре страдает от багов, искажающих все голосовые сэмплы. Много лет спустя Стефан Даллонгевиль (автор SGDK и признанный волшебник) выполнил реверс-инжиниринг этого драйвера аудио и исправил его баги. В результате вы теперь можете играть в Street Fighter II с кристально чистым криком «Hadoken!». Вот видео, в котором можно услышать разницу:
Но давайте вернёмся к homebrew-разработке и любимому SGDK. Он имеет возможность выбора драйверов аудио, которые можно подбирать под требования своей игры. Например, есть PCM-драйвер, позволяющий воспроизводить по одному звуковому эффекту за раз в очень высоком качестве (например, голосовые сэмплы). Но также существует XGM-драйвер, способный одновременно проигрывать музыкальный трек + 4 звуковых эффекта. Лучше всего то, что вы можете переключаться между драйверами аудио во время игры. Например, в 30 Years of Nintendon’t голосовые сэмплы на экране заставки и конца игры воспроизводятся PCM-драйвером для высокого качества. Но во время игры мне нужно было воспроизводить одновременно несколько звуковых эффектов, поэтому я использовал XGM-драйвер.
Что касается самих ресурсов, то для их создания можно использовать современные инструменты. Как я говорил выше, для звуковых эффектов можно просто взять файлы .wav, которые автоматически преобразуются в нужный формат. Для музыки стандартным инструментом является Deflemask — трекер, способный создавать музыку для звукового оборудования различных 8/16-битных консолей. У меня нет большого опыта в создании музыки, потому что использованные в моих играх композиции написаны талантливыми чиптюн-исполнителями: Minerscale (Break An Egg) и Warlord (MeteoRain). Оба они пользовались Deflemask и экспортировали свои творения в формат VGM, который SGDK может преобразовывать для использования с собственными драйверами аудио.
Создать игру для Mega Drive/Genesis за 60 минут? Вызов принят!
Гейм-джемы — превосходный способ применения своих навыков гейм-дизайна и разработки игр: насколько хорошую игру вы сможете создать с нуля за ограниченное время (обычно 48 или 72 часа)?
С точки зрения времени, самым жёстким джемом является 0h Game Jam. Как понятно из названия, он проводится каждый год во время перехода на зимнее время. Вы начинаете создавать игру в 02:00, в ночь перевода часов. Проработав 60 минут, вы выпускаете игру онлайн в тот самый момент, когда часы возвращаются с 03:00 на 02:00. В прошлом году я решил поучаствовать в этом джеме. Только что завершив «30 Years of Nintendon’t», я накопил определённый опыт в создании игры для Mega Drive/Genesis и был вдохновлён простотой SGDK. Но сможет ли SGDK быть достаточно простым, чтобы я смог создать 16-битную homebrew всего за 60 минут? Вот ответ:
60 минут работы
Давайте будем честными, результат совершенно не впечатляет. Баланс игры ужасен, а в генераторе случайных чисел есть огромный баг, из-за чего игра становитя непроходимой после пятого яйца. Кроме того, в ней нет фонового изображения, звука и т.д. Но всё-таки это новая игра для Mega Drive/Genesis, созданная с нуля за 60 минут, и запускаемая на настоящей консоли. Не знаю, как для вас, но для меня это уже своего рода достижение!
Более того, поскольку идея базового геймплея имела определённый потенциал, я продолжил работать над игрой в течение ещё множества часов. В результате у меня получилась довольно интересная аркадная игра, в которую можно сыграть здесь. Также она доступна на картридже 30 Years of Nintendon’t вместе с третьей игрой, уникальной для этого выпуска на физическом носителе — MeteoRain.
Много часов дополнительной работы!
От homebrew к indie
Хотя homebrew обычно является нишей для любителей (вроде меня), некоторые консоли и сегодня являются вполне коммерческой платформой для инди-студий. Прекрасным примером этого стали две недавно выпущенные игры. С одной стороны, Tanglewood была полностью разработана на ассемблере, как в 90-х, что сделало конечный результат ещё более впечатляющим. С другой стороны, столь же потрясающая Xeno Crisis была разработана с помощью SGDK и полностью воспользовалась преимуществом комфорта и простоты современных инструментов.
Tanglewood (2018 год)
Xeno Crisis (2019 год)
Итак, если вам нравятся ретро-игры, почему бы не создать сегодня свою первую игру для Mega Drive/Genesis?
В конце концов, чтобы получить SGDK, достаточно перейти по ссылке: https://github.com/Stephane-D/SGDK
В заключение
Надеюсь, вам понравилась эта статья о создании трёх игр для SEGA Mega Drive/Genesis при помощи современных технологий. Если вы хотите сыграть в мои игры на собственной консоли или просто поддержать мою работу, то можете купить картридж в красивой коробке с релизом моих игр у издателя Cote Gamers: http://cotegamers.com/shop/en/genesis-mega-drive/43-test.html
Если вас интересует только цифровой релиз (т.е. ROM-ы), то все мои ретро-игры можно найти здесь: http://drludos.itch.io/
Если вам понравилась моя работа и вы можете себе это позволить, то поддержите меня финансово на Patreon. Мои игры обычно выпускаются онлайн как freeware, а некоторые из них также продаются на физических картриджах. Поддержав меня на Patreon, вы также получите доступ к бета-версиям моих игр, а также к различным создаваемым мной прототипам (в том числе заброшенным проектам).