История Starcraft (Часть 1)

:


Сегодня мы представляем вам перевод очень познавательной статьи за авторством человека, который восемь лет проработал в Blizzard Entertainment и участвовал в создании таких легендарных проектов, как Warcraft, Diablo и Starcraft. Патрик Уайетт не только причастен к этим мастодонтам игростроения, он также является одним из основателей ArenaNet, создавшей Guild Wars.

Заметка  посвящена трудностям, которые встали на пути программистов, делавших Starcraft. Но, как бы невзначай, автор умудрился охватить всю картину того, что происходило тогда в фирме Blizzard с точки зрения разработчика.

Итак! Хотите узнать про то, сколько часов подряд может работать программист из Близзард, кто придумал Diablo, или про встроенный голосовой чат в первом старике? Тогда - вперед! 
:cut:

Начало

После двух с половиной лет упорной работы над Starcraft, игра все еще была настолько багована, что словами не передать. А времени до релиза оставалось все меньше и меньше, и если игры серии Warcraft отличались своей надежностью, то со Starcraft вплоть до момента выхода не могла нормально работать даже команда тестировщиков. Игра продолжала падать! Да и с выпуском игры беды не закончились: нам потребовалось приложить массу усилий для того, чтобы залатать дыры с помощью патчей.

Почему? На то была масса причин.

Орки в космосе

Изначально Starcraft планировался как относительно небольшой проект, на разработку которого потребуется не больше одного года. Мы рассчитывали выпустить игру к Рождеству 1996. 

Руководство проекта состояло из людей, работавших до этого над Shattered Nations и над пошаговой стратегией по мотивам X-COM, которую Blizzard анонсировала в мае 1995, но затем отказалась от ее разработки.

Эти ребята были готовы сделать игру очень быстро - так, чтобы у студии не возникло большой паузы между релизами: 

Q4 1994 - Warcraft.
Q4 1995 - Warcraft II.
Q4 1996 - Плановая дата выхода Starcraft. 

В реальности, как мы знаем, игра вышла во втором квартале 1998. Сейчас запланированные сроки кажутся абсурдными, но тогда президент компании Allen Adham находился перед лицом необходимости увеличить доходы. Первые игры Blizzard принесли бОльшие дивиденды, чем от них ожидалось, и это разожгло у некоторых людей некоторые аппетиты. 

Идеология нового проекта была такова - вот вам немного ресурсов и времени, сделайте нам "орков в космосе". Картинка с E3 1996 года иллюстрирует путь, по которому пошли разработчики. 


Да, я бы в такое играть не стал.

В это время у Blizzard появился новый проект, который стал оттягивать и без того скромные силы от Starcraft. История такова - одна небольшая фирма под названием Condor Studios начала разработку RPG под названием... Diablo. Ресурсы, которыми обладали их разработчики, были, даже по тем временам, весьма скудны - 1.2 миллиона долларов. Этих денег явно не хватало на завершение проекта. Когда это стало окончательно ясно, на сцене появились люди из Blizzard, и студия Condor сменила вывеску на Blizzard North.

Работников, которые трудились над Starcraft, стали переводить в новое подразделение для работы над Diablo. Этот процесс продолжался до тех пор, пока в старкрафт-команде не осталось буквально ни одного человека. Даже директор проекта Starcraft был занят на доделке инсталлера Diablo, который начал делать я, но из-за большой занятости не успел дописать до конца.

После выпуска Diablo в 1996 году у нас появилось время, чтобы вернуться к Starcraft и посмотреть на проект свежим взглядом. И то, что мы увидели, нас не обрадовало. Игра выглядела очень плохо, даже по сравнению с демо-версией какой-нибудь Dominion Storm, представленной на Е3 в том же году. Успех Diablo повысил планку, и по Starcraft было принято решение, которое подтвердило кредо компании - не выпускать игры, пока они не готовы.  Но на пути реализации этого решения нас ждали многие трудности. 

Все видели, что Starcraft в его нынешнем виде недостаточно хорош, чтобы задать тон в жанре RTS, в котором мы уже достигли успеха, выпустив игры серии Warcraft. 

В тот момент, когда мы начали перезапуск проекта, согласно данным Computer Gaming World Magazine, по всему миру в разработке находилось более 80 игр в жанре RTS. В гонке участвовала и сама Westwood Studio, которая и придумала этот жанр. Мы должны были сделать что-то, что могло бы всех сразить наповал. 

После успеха Warcraft и Diablo мы могли рассчитывать на самое пристальное внимание прессы и игроков. В нашей индустрии о студии судят по ее последнему проекту. Мы должны были двигаться дальше, и принимать связанные с этим риски.

Новые лица

В создании Warcraft II участвовали всего шесть программистов и два помощника. Для работы над Starcraft нам понадобилась команда побольше. А это значит, что в коллектив влилось много сотрудников без нашего опыта работы. Мы немного растерялись, и эти новые программисты часто учились на своих ошибках, которых лучше было бы избежать в таком проекте. Но гонка была такая, что некогда было разбирать чужой код и натаскивать менее опытных товарищей. Все писали код как сумасшедшие, у нас не было времени на то, чтобы остановиться и посмотреть на то, что уже написано.

Проблема была не только с рядовыми программистами. Даже руководитель разработки не имел опыта по созданию нормального игрового движка. Bob Fitch занимался написанием игр несколько лет, и достиг больших успехов, но в прошлом он больше портировал игры и никогда не создавал игру такого масштаба с нуля. Он руководил работами над Shattered Nations, но этот проект был заморожен и никто теперь не скажет, была ли архитектура той игры удачной. 

Команда выкладывалась по полной, часто в ущерб здоровью и личной жизни. Никогда не видел такого самоотверженного труда. Но некоторые решения, которые были приняты тогда, создали разработчикам очень много проблем. 

Перемены

После месяцев работы над созданием Diablo и выпуском исправительных патчей я вернулся в команду Starcraft. Я не ожидал, что буду снова заниматься латанием дыр, но именно так и получилось. 

Я думал, что это будет легко, поскольку знал буквально каждый функциональный блок в Warcraft, но, к моему ужасу, я обнаружил, что большая часть нашего движка была выброшена на помойку. Структура классов, отвечающая за юниты, была полностью переписана, а их диспетчер вообще удален из проекта.

Диспетчер был моим творением. Он отвечал за то, как юниты планировали свои действия. Каждая боевая единица периодически посылала запрос этому диспетчеру: "что мне делать сейчас?", "надо ли пересчитать мой путь заново?", "нет ли более подходящей цели для атаки?", "поступали ли новые команды от игрока?", "не умер ли я, и не пора ли мне освободить память?" и так далее. 

Часто есть причины, по которым стоит полностью переписать некоторый код, но это всегда несет некоторые риски. В своей книге "Вещи, которые вам никогда не следует делать" Джоэл Спольски выразил это более красноречиво: 

"То, что вы сделаете заново, необязательно будет лучше, чем было сделано до этого. Если у вас будет новая команда программистов, возможно они повторят ошибки, которые совершила первая команда, и добавят своих."

Месяцы ушли на то, чтобы заставить движок Warcraft работать так, как следует. А новая команда вместо того, чтобы приспособить его под новые задачи, решила учиться писать движки заново.

Архитектура игрового движка

Я написал движок Warcraft под MS-DOS на Watcom C. Для перехода на Windows Боб решил использовать Visual Studio и перейти на C++. Решение обоснованное, но надо признаться, мало кто из разработчиков хорошо знал особенности этого языка. 

C++ это мощный инструмент, но в неумелых руках... Как выразился его создатель Бьёрн Страуструп:

"При помощи С легко ранить себя в ногу; с С++ это сложнее, но если уж случится, то вы отстрелите себе всю конечность."

Опыт показывает, что программисты чувствуют себя обязанными попробовать все возможности нового языка в первом же проекте. Так это случилось и у нас с механизмом наследования.
Опытный программер содрогнется, если встретит такую иерархию классов: 

CUnit < CDoodad < CFlingy < CThingy 

Объекты класса CThingy отвечали за спрайты, которые могли появляться в любом месте, но не могли сами двигаться или выполнять какие-то задачи. CFlingy отвечали за обломки, которые получаются во время взрыва и, кувыркаясь, разлетаются в разных направлениях. CDoodad, дай бог памяти, был абстрактным и совершенно ненужным классом. Ну а поверх всего этого горделиво взгромоздился класс CUnit. Поведение юнитов было размазано понемногу по всем этим классам, поэтому вы должны были знать их все, если хотели что-то сделать с боевой единицей.

Кроме этого бардака в структуре классов, определение класса CUnit было разбросано по множеству файлов:

class CUnit ... { 
#include "header_1.h"
#include "header_2.h"
#include "header_3.h"
#include "header_4.h"};

Каждый из этих файлов содержал несколько сотен строк, которые могли ссылаться, как это не удивительно, на родительский класс.

Тогда еще не была в ходу мантра "предпочитай композицию наследованию", но программисты Blizzard выучили этот урок одними из первых.

Два месяца до запуска

Вот с таким наследием мы подошли к моменту, когда до выхода игры осталось всего два месяца. С учетом того, какие работы предстояло провести (переход на изометрию, новый редактор карт, режим игры через battle.net), стало понятно, что игра не выйдет вовремя. А ведь еще требовалось время для художников, дизайнеров, специалистов по звуку, тестировщиков и так далее. Но команда программистов продолжала работать в режиме аврала в течение последующих 14 месяцев.

Некоторые работали по 40 или даже по 48 часов подряд. Больше я нигде не видел таких припадков мазохистского энтузиазма.

Мой опыт ночного программирования при создании Warcraft и Diablo показывает, что в этом нет никакого смысла. Все потом приходилось переписывать при свете дня и с ясной головой. Экстремальный режим работы неприемлем там, где требуются знания и творческий подход. Это приводит к множеству ошибок.

Такой режим нам никто не навязывал, мы просто хотели делать самые лучшие игры. Но, оглядываясь назад, понимаешь, что это было глупо. Можно было бы достигнуть лучшего результата меньшими усилиями.

Сейчас я горжусь тем, что моя команда, которая работает над Guild Wars, по ночам просто спит.

Причины падений Starcraft

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

Стоп! Голосовой чат в 1998 году? Да я сделал такую систему, основанную на кодировании голоса в фонемы при помощи сторонней библиотеки, в декабре 1997. Но каждая звуковая карта в нашем офисе требовала обновлений драйверов для того, чтобы голосовой чат начал на ней работать. Мы бы потратили на техподдержку больше денег, чем заработали на игре. От голосового чата пришлось отказаться.

В общем, я исправлял все больше ошибок. Иногда это были и мои ошибки, но чаще - странные конструкции, порожденные мозгами уставших программистов. После окончания работы все были поражены, сколько ошибок мне пришлось в итоге исправить.

Вы можете подумать, что при таком количестве багов будет сложно назвать какой-то один их источник? Вовсе нет. Больше всего проблем доставляли связные списки. Они активно использовались для отслеживания поведения связанных юнитов. Всего в Starcraft могло быть до 1600 юнитов, что вдвое больше, чем в Warcraft 2, и было важно быстро находить юниты определенного типа, держа их в связанных списках. Там были списки всех возможных видов: все юниты, все строения, все "генераторы энергии" и многие другие. Все списки были двусвязными, чтобы облегчить удаление или добавление одного элемента.

К сожалению, каждый программист сам работал, как мог, с этими списками. Не было единого для всех набора функций. А такой подход всегда хуже, чем наличие хорошо отлаженной библиотеки. Чтобы безопасно убрать элемент из списка, надо было каждый раз учитывать, что на него могут ссылаться поля других списков. Поэтому игра постоянно вылетала.

Кто виноват?

Самое смешное, что эти проблемы возникли на ровном месте. Еще до всех этих событий была написана библиотека Storm.dll, которая использовалась в том же Diablo. Она отлично работала с двусвязными списками при помощи шаблонов С++. В начале разработки Starcraft она использовалась, но новая команда, как мы помним, решила изобрести велосипед, и выкинула в том числе и эти функции под предлогом того, что они мешают создавать файлы сохранения.

Файлы сохранения

Многие игры, в которые я играл до создания Warcraft, имели очень плохой механизм сохранения. Особенно долго сохранялись игры фирмы Origin, даже если учитывать мощность тогдашнего железа. У Warcraft этих проблем не было.

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

К тому же, код, отвечавший за эту функцию, был прост и понятен. Но этот способ работал, потому что в Warcraft не использовались указатели. Starcraft, со своими указателями на списки юнитов, это совсем другое дело. Надо было позаботиться обо всех указателях, чтобы выгрузить 1600 юнитов за один раз. Такие вот пироги.

Верни, как было!

После исправления множества ошибок со связными списками, я стал упорно настаивать на том, чтобы мы вернулись к использованию функций из библиотеки storm при работе со списками, даже если это усложнит процесс сохранения. Под словом "упорно" нужно понимать "нахально" и "грубо". По другому спорить мы тогда и не умели, если только дело не касалось того, что заказать на обед.

Я проиграл этот спор, поскольку "до выхода игры осталось всего два месяца". Было принято решение продолжать латать этот тришкин кафтан, что доставило нам кучу неприятностей в будущем. Это стало хорошим уроком и для меня, как программиста.

Алгоритм поиска пути

Хочу привести еще один пример, когда вместо исправления ошибок мы занимались латанием дыр. Когда мы перешли на изометрию, рендер заднего плана остался прежним. А написан он был еще в 1993 году. 

Рендерить изометрию при помощи старого движка было несложно. Были небольшие трудности с редактором карт, где игроки оперировали объектами, повернутыми по диагонали. Проблема была с поиском пути. Вместо области 32 на 32, которая была или проходимой или нет, теперь мы имели дело с микро-областями 8 на 8 пикселей, что резко увеличило число вариантов при переборе. К тому же, стали возникать ситуации, когда путь был, но являлся слишком узким для больших юнитов. Если бы не талант наших программистов, эти проблемы могли стать непреодолимой преградой. Но получилось так, что система была окончательно готова перед самым выходом. О проблеме поиска пути, пожалуй, стоит написать больше в следующей статье. 

Конец первой части

На этом я пока свое нытье заканчиваю. Сделать Starcraft было трудно, и главным образом из-за неверных решений, принимаемых на всех уровнях компании - решений, относящихся к концепции игры, технологиям и дизайну.

К счастью для нашей команды, мы перестали добавлять новые фишки в тот момент, когда у нас еще оставалось достаточно времени до даты выхода. И я рад, что мы писали не на скриптовом языке, поэтому игроки не могут видеть, какие кучи мусора скрываются под красивой оболочкой.

В следующий раз я расскажу о том, какие решения использовались при работе над Diablo, Battle.net и Guild Wars.

Продолжение (Часть 2)


Источник: http://www.noob-club.ru
Интересно? Делись:

Блог: http://romanlovetext.blogspot.com/