Как сделать свою мморпг игру
games maker Все о создании игр и не только
22 апреля 2012 в 20:39
Руководство как создать MMORPG
Лавры World of Warcraft и Lineage II не дают вам покоя? Вы спите и видите себя во главе успешной компании, покорившей сердца геймеров всего мира революционной MMORPG? Вы вынашиваете амбициозные и коварные планы по захвату львиной доли рынка онлайн-игр? Идеи роятся в вашем сознании, как облако растревоженных шершней? И при всём этом изобилии вас мучает один-единственный вопрос: а что же, всё-таки, нужно знать и уметь, чтобы создать MMORPG? А вот не скажу. Секрет! Однако, этим секретом решил поделиться со всеми Radu Privantu, ведущий программист и лидер проекта Eternal Lands, бесплатной открытой MMORPG. Статья датирована аж 2004 годом, но до сих пор не утратила своей актуальности. Итак, поехали. Как создать MMORPG?
Эта статья нацелена, в первую очередь, на независимых разработчиков, с ограниченными ресурсами и опытом разработки подобных продуктов. После прочтения данной статьи, вы должны уже иметь представление о том, с чего же, собственно, начать, а также что делать и чего НЕ делать в своей MMORPG. Перво-наперво, стоит трезво оценить свои силы и свои ресурсы. Будьте предельно честны с собой, иначе вас обязательно постигнет разочарование после того, как вы потратите кучу времени на то, чего вы просто не можете сделать.
Шаг первый: Оценка своих способностей
1) Владение как минимум одним языком программирования. До сих пор С++ является наиболее популярным языком в среде разработчиков игр из-за его преимуществ и эффективности. Visual Basic, Java или C# также подойдут.
2) Овладеть одной из графических библиотек. Популярны SDL, OpenGL и DirectX/Direct3D.
3) Определиться с сетевой библиотекой. Можно выбирать между WinSock, SDL_net, или DirectPlay.
4) Иметь общий опыт в программировании игр. Например, понимать, что такое очередь событий, многопоточность, дизайн GUI и т.д.
Очень рекомендуемые знания:
Шаг второй: создание предварительного дизайна
Я часто замечал на различных форумах людей, которые собирают команду для разработки MMORPG. Большинство из них начинают с чего-то вроде этого: «Мы начинаем набор в команду и нам нужны три художника, два программиста, один музыкант и т.д. для создания революционной MMORPG, в которой у вас будет полная свобода действий и возможность изменять мир, и т.д. Мы заплатим вам после завершения разработки и получения прибыли». К сожалению, с текущим уровнем технологий НЕВОЗМОЖНО создать изменяемый мир. Установка своей целью невозможного ведёт к неудаче. Вместо этого, попытайтесь начать с небольшого, функционального, расширяемого дизайна и архитектуры.
Основная архитектура программы
В первую очередь, попробуйте сфокусироваться на создании простой модели клиент/сервер, где можно будет:
1) Создавать нового персонажа.
2) Сохранять персонажа ( на стороне сервера )
3) Входить в игру персонажем.
4) Иметь возможность общаться с другими персонажами.
5) Иметь возможность передвигаться в трёхмерном мире.
На первый взгляд, в сохранении персонажей нет ничего сложного, однако это не так. Например, существует как минимум два способа хранения информации о персонажах: используя базы данных или же файлы.
Шаг третий: выбор внутреннего протокола для передачи данных
Offset 0: 1 байт, определяющий передаваемую команду
Offset 1: 2 байта, длина передаваемых данных
Offset 3: переменная длина, тело сообщения
Этот метод имеет преимущества совместимости: все передаваемые данные следуют одному стандарту. Недостаток состоит в том, что некоторые команды имеют фиксированную, заранее известную длину, поэтому часть пропускной способности теряется впустую. В будущем мы планируем переключиться на гибридный вариант.
1. Намного более просто отладить и реализовать
2. Более медленный отклик сервера
В моей компании, мы пошли однопоточным путём, т.к. не имели достаточно ресурсов для работы над многопоточным подходом.
Шаг четвёртый: Клиент
Вы планируете 2D или 3D-игру? Некоторые могут полагать, что сделать игру в 2D проще. Я делал и те, и те, и верю, что 3D сделать проще. Позвольте мне объяснить, почему.
Трёхмерный путь, как я уже говорил, проще, но требует знания простейшей математики ( особенно тригонометрии ). Современные графические библиотеки очень мощные, и предоставляют простые операции практически «нахаляву»: вам не нужно сортировать объекты; можно легко изменять цвета или текстуры объектов; объект будет освещен в зависимости от положения источников света, если вы просчитываете нормали для него и т.д. Кроме того, 3D даёт вам больше свободы в плане создания и передвижения. Из недостатков стоить отметить, что не каждый сможет играть в вашу игру, т.к. до сих пор не все компьютеры оснащены видеокартами, и то, что заранее отрендеренные изображения будут выглядеть лучше тех, что рендерятся в реальном времени.
Шаг пятый: Безопасность
Также следует учесть, что касается безопасности: скорость передвижения игрока должна задаваться на стороне сервера, а не клиента. Сервер должен отслеживать время ( в миллисекундах ) последнего передвижения игрока, и если запрос на приходит раньше, чем заданный на сервере порог, такой запрос нужно игнорировать. Не стоит вносить в лог такие ситуации, т.к. они могут происходить из-за задержек сети ( когда данные за последние 10 секунд приходят на сервер одновременно ).
Шаг шестой: Собираем команду
Веб-мастер, если вы сам не являетесь опытным веб-дизайнером, и не хотите тратить своё время на создание сайта. Иметь специалиста по звуку и музыканта не обязательно, но игра со звуком и музыкой определённо только выиграет от этого.
Как было написано выше, вам понадобится 10-15 человек для команды, не считая администраторов и модераторов. Эти 10-15 человек также должны иметь какой-то опыт в своей области. Обычно, если он все новички, оно того не стоит, т.к. вам необходимо будет потратить слишком много времени на то, чтобы объяснить им, что делать, как сделать что-то, почему способ, которым они делают что-то, не подходит и т.д.
Теперь, когда у вас есть художник, и, надеюсь, представление о том, как должна выглядеть игра, время начать её реализацию. Как только вы будете иметь хотя бы полурабочий клиент/сервер, и несколько скриншотов для показа ( или даже, что ещё лучше, способность игроков залогиниться и побегать по игровому миру ), большее количество людей захочет присоединиться к команде. Предпочтительно сделать свой клиент с открытым исходным кодом, если вы не используете технологии, которыми больше никто не владеет. Многие программисты с большей охотой присоединятся к проекту с открытым кодом, чем с закрытым. Сервер же, напротив, должен быть с закрытым исходным кодом ( если вы не планируете с самого начала создавать полностью открытую MMORPG ).
Шаг седьмой: Развеивая мифы
1. Ты не можешь сделать MMORPG, для этого необходима большая компания.
2. Нужно много денег ( 4-6 значная сумма ) для поддержки MMORPG сервера.
3. Создавать MMORPG очень весело.
Всё вышеописанное должно заставить вас дважды подумать, прежде чем взяться за такой впечатляющий проект. Осознавайте все трудности и проблемы, с которыми вы обязательно столкнётесь.
Надеюсь, эта статья дала вам взгляд «изнутри» на разработку MMORPG и поможет избежать многих ошибок.
Как сделать MMORPG своими руками. Медленно, сложно, интересно
Привет, хабрахабр! Меня зовут Егор Курьянович и ты, возможно, помнишь меня по паре интернет-проектов: Кьюби и Идейнику. А быть может, ты даже слышал о других моих начинаниях. Сегодня я хочу рассказать тебе, чем занимался последние пару лет.
Ты ведь любишь игры, не так ли? То, что ты видишь на КДПВ, называется FAR7. Чтобы было немного понятнее, скажу, что молодежь сравнивает её с Космическими Рейнджерами, те кто постарше, вспоминают StarControl2, а совсем уже хардкорные геймеры постоянно твердят об Elite. Сойдемся на том, что это браузерный космосим. В игре вы можете путешествовать между звездными системами, торговать, воевать и выполнять различные миссии.
Вся игра написана мною с нуля в одиночку и может быть использована как демо, для демонстрации возможностей стека HTML5. Все подробности о технологиях и трудностях разработки инди-проектов ждут вас под катом.
Награды
За три года разработки игра засветилась на нескольких конкурсах. Получила приз за лучшие технологии в конкурсе GAME_ON от корпорации Mozilla и за лучший игровой проект на конкурсе IT-JUMP 2012 в беларуском Парке Высоких Технологий.
Архитектура
Поскольку я все-таки программист, то начну изнутри — с архитектуры проекта.
Ядро системы состоит из веб-приложения написанного на Perl/Catalyst, демона имитации жизни на Perl/AnyEvent (мы, кстати, называем его Лапласом) и отдельного WebSocket-сервера на базе SockJS.
Кроме этого есть огромное количество утилит, вотчеров и вспомогательных демонов для поддержания работы. А также специальная админка для управления, добавления контента и отслеживания различных метрик.
Перепробовав гору разных вариантов, я выбрал этот, как самый эффективный и стойкий к ударам судьбы и пользователей. Я искренне надеюсь, что сервер выдержит хабраэффект, и можно будет с уверенностью сказать, что с архитектурой я не ошибся.
На клиенте работает MooTools+JxLib, а для рендера используется CAATjs, позволяющий скомпилировать игру в нативное приложение для мобильных платформ. К сожалению, при разработке клиентской части я допустил одну большую ошибку — как и все начинающие разработчики, я написал свой движок. Хотя у меня есть оправдание — на момент начала разработки, подобных движков не существовало в принципе. Это сейчас игровых движков на HTML5 уже чуть ли не больше чем игр, а тогда мы разрабатывали как могли.
Инди — путь страданий
Ну а теперь немного лирики. Думаю, вы сами знаете, что жизнь стартапера — это не только запах кофе, отблески калифорнийского солнца на кромке макбука и элевейтор питчи в тех самых элевейторах, несущих вас вместе со щедрым бизнес-ангелом на сотый этаж небоскреба.
Жизнь стартапера в основном состоит из адского труда и отчаяния. Если он, то есть я, и пьет кофе, то только для того, чтобы проработать ещё несколько часов ночью. Солнце редко касается его макбука, как, впрочем, и его самого — стартапер работает весь день: на рассвете, в полдень, на закате, и даже, когда через несколько часов снова будет рассвет. Про выступления, аплодисменты и щедрые чеки, пожалуй, тоже стоит забыть — выступать вы будете редко и уж точно не перед собранием директоров венчурных фондов, а редкие пойманные инвесторы будут просить пояснить, что такое «MMORPG» и нужен ли для ее запуска компьютер, а после спрашивать, сколько миллионов человек в день посещает ваш — то есть моего проекта — сайт.
И я не жалуюсь. Я осознанно выбрал путь страданий, потому что хотел сохранять игру независимой как можно дольше, чтобы иметь возможность экспериментировать и делать ее лучше, а не только рентабельнее. Ведь инди-игры в первую очередь должны быть классными, правда?
За все приходится платить. Желание, претворенное в жизнь, требует самой большой оплаты и если у тебя нет пары-тройки миллионов долларов для масштабного проекта, то платить тебе придется своим комфортом и временем. Многие хотят делать игры, но не многие готовы платить за это такую цену.
Мы начинали втроем, но уже к концу первого года разработки я остался один. Другие ребята просто не выдержали такого темпа, и я их за это не виню. Они клевые, но что поделать — путь стартапера оказался не для всех. Если вы сейчас хотите начать масштабный проект, но чтобы «в свободное время 2 часа в день после работы», то будьте готовы к тому, что потребуется 20 часов в день, а энтузиазм будет переливаться в желание поспать, а не доделать очередную фичу. Что через пару недель случится со всевозможными кофаундерами, партнерами, будущими СЕО и СТО «за процент» можете предположить сами.
Но любая разработка рано или поздно начинает приносить плоды: от биллинг-провайдера приходит письмо на заключение договора, форма логина начинает пускать игроков, и бездушным NPC перестает быть скучно и одиноко в огромной вселенной. Это называется открытое бета-тесирование или ОБТ.
ОБТ дает новый взгляд на вещи, ОБТ стимулирует продолжать. Благодаря ОБТ двадцатичасовой рабочий день снова становится в радость, а каждый отзыв помогает еще чуть-чуть допилить проект.
И каждый хабрапользователь, и его друг, и жена, и даже бабушка зашедшая в FAR7 очень поддержат меня. Это были долгие 3 года, и путь еще далеко не закончен: впереди нас ждет клевая система имитации жизни, подземелья (в космосе, вы представьте!), батлграунды, новый контент и многие другие прекрасные вещи.
Путь стартапера окупается тогда, когда его проект начинает жить. И я хочу, чтобы вы, друзья, помогли мне вдохнуть жизнь в плод труда мой и многих людей. Надеюсь встретить каждого из вас на просторах дальнего космоса!
Кстати, за время работы над проектом у меня накопилось множество тем, о которых я бы хотел рассказать на Хабре. Предлагаю хабровчанам самим выбрать, какой пост они хотят увидеть следующим:
Руководство для начинающих создателей MMORPG игры.
Эта статья описывает первые шаги в создании массивно-многопользовательской онлайновой игры. Она предназначена для независимых разработчиков игр, которые обладают ограниченными ресурсами и небольшим опытом. После прочтения данной статьи Вы будете знать, что нужно для начала, и получите несколько советов относительно того, что стоит и чего не стоит делать.
Автор: Radu Privantu
Предисловие от переводчика
В последнее время очень широкое распространение в мире игр получили многопользовательские онлайновые игры (MMOG — massive multiplayer online game), которые рассчитаны на огромно-большое количество игроков. Конечно, все слышат только об успешных проектах, которые собирают серьезные финансовые доходы. Это и привлекает большинство новичков в игрострое в этот жанр. Однако, мало кто реально представляет себе, какие проблемы и задачи стоят при создании такого рода игр, какими знаниями надо обладать и т.п.
В результате – взявшись сразу за создание такого проекта, новичок быстро понимает насколько все сложно и запутанно. И бросает все, разочаровавшись.
Цель данной статьи – дать начальное представление желающим сделать свою игру в стиле MMOG, о том, какими знаниями надо обладать, что нужно уметь и к чему быть готовым. Ведь не секрет, что если человек пробует что-то раз и результат отрицательный — то повторно возвращаться он к этому вряд ли будет. Поэтому хотелось бы предостеречь еще раз желающих окунуться в мир создания таких игр и предложить им еще раз все обдумать и взвесить. Может, стоит начать с более простых игр, чтобы просто получить требуемый минимальный опыт?
Статью такого типа мне хотелось написать уже давно, но я не обладал достаточным опытом в этой сфере. В просторах Интернета мне попалась статья Radu Privantu, который является основателем и руководителем проекта Eternal Lands (www.eternal-lands.com). С его письменного разрешения я перевел эту статью на русский язык.
В статье говорится о создании MMORPG (ролевой игры), но я думаю, что описанное в ней относится ко всем типам массивно-многопользовательских онлайновых игр.
Руководство для начинающих создателей MMORPG игры
Эта статья описывает первые шаги в создании Вашей массивно-многопользовательской онлайновой игры. Она предназначена для независимых разработчиков игр, которые обладают ограниченными ресурсами и небольшим опытом. После прочтения данной статьи Вы будете знать, что нужно для начала, и получите несколько советов относительно того, что стоит и чего не стоит делать. Самый первый шаг – это оценка Ваших знаний и возможностей. Вы должны быть готовы к ожидающему вас разочарованию из-за потери времени на создание того, что Вы просто не можете сейчас сделать.
Шаг 1. Оценка своих знаний:
Требуемые знания:
- 1. Знание как минимум одного языка программирования. Сейчас среди разработчиков наиболее популярный язык С++, по причине его преимущества в эффективности и скорости. Visual Basic, Java или C# также могут быть использованы в этом качестве.
2. Необходимо ознакомиться с графической библиотекой. Популярный выбор это SDL, OpenGL либо DirectX/Direct3D.
3. Определиться с сетевой библиотекой. Вы можете выбрать WinSock, SDL_net или DirectPlay.
4. Иметь опыт в программировании игр. Для примера, иметь понятие что такое: очередь событий, многопоточность, разработка пользовательского интерфейса (GUI) и т.п.
Очень рекомендуется знать:
- 1. Клиент-серверное взаимодействие и архитектуру построения таких систем.
2. Создание кросс-платформенных приложений. Вполне возможно Вы захотите создать вашу игру, и главным образом клиент таким образом, чтобы он мог запускаться на различных операционных системах. Для этой возможности я рекомендую использовать SDL, OpenGL и SDL_net.
3. Разработка под веб (Интернет). Это понадобится, если Вы захотите предоставить желающим возможность просматривать статистику по игрокам, информацию о сервере, или любую другую информацию через вебсайт.
4. Защита и администрирование. Вы же не хотите, чтобы кто-то взломал Ваш сервер?
5. Работа в команде, управление командой. Вам нужна будет команда, которой Вы сможете успешно управлять.
Шаг 2. Создание эскиза разработки
Я заметил, что много людей пишут в форумах сообщения о поиске команд для разработки MMOG. Многие из них начинаются такими словами: «Мы – начинающая компания/игровая студия и нам нужны 3 художника, 2 программиста, 1 музыкант и т.д. для создания инновационной, никогда ранее не существовавшей MMOG, в которой Вы будете иметь полную свободу действий и возможности изменения мира и т.п. Мы оплатим Вашу работу по окончании разработки, когда мы сделаем на этом немного денег». К сожалению, с современными технологиями и ограниченной пропускной способностью (сетевой) Вы не сможете создать динамического мира. Попытка создать что-то невозможное приводит к провалу. Правильней будет начать с малой, полностью рабочей, расширяемой системы и архитектуры.
Основная архитектура программы:
Сначала, попробуйте сосредоточиться на создании простейшей клиент-серверной модели, где будут введены следующие возможности:
1. Создание нового персонажа
2. Сохранение этого персонажа (на стороне сервера)
3. Вход в игру персонажем
4. Создать возможность общения с другими
5. Создать возможность передвигаться по миру в 3D
Задача сохранения информации о персонаже на первый взгляд выглядит довольно простой, но это не так. Например, есть два способа это сделать: использовать базу данных или использовать файлы. Далее в таблице приведены преимущества и недостатки для каждого из вариантов:
Теперь, когда Вы определились, как сохранять информацию о персонажах, Вам нужно решить какой сетевой протокол Вы будете использовать для клиент-серверного взаимодействия: TCP или UDP? TCP известен как более медленный, но зато более аккуратный, он требует дополнительной пропускной способности. На практике, я не замечал каких-либо проблем при использовании TCP. Если у вас предусмотрена достаточная пропускная способности сети, TCP – это хороший выбор, по крайней мере, для начала. UDP может быть очень неприятным, особенно для начинающих. Помните о том, что первичные тесты движка и игры будут делаться в Вашей локальной сети, поэтому все пакеты будут приходить к месту назначения в таком же порядке, что и отправлялись. Но это не может быть гарантировано при работе через Интернет, т.е. в реальной среде. В то время, как обычно пакеты прибывают в заданном порядке, некоторые из них могут теряться, и это постоянная проблема для Интернета. Конечно, Вы можете разработать свой протокол таким образом, чтобы клиент/сервер могли восстанавливать потерянные пакеты. Но это тяжелый процесс, который не рекомендуется для начинающих.
Разработка ММО РПГ – практическое руководство. Сервер (часть 1)
В тексте будет много отсылок к функционалу «Звездных Призраков», но я постараюсь излагать материал так, чтобы вам не было нужды вникать (и играть) в наш продукт. Однако, для лучшего понимания материала желательно потратить пару минут и посмотреть, как это все выглядит.
В статье мы сосредоточимся именно на архитектурных решениях применительно к backend’у MMO RPG в реальном времени. Исходного кода будет не много и он точно не будет содержать таких специфических для С++ вещей как множественное наследование или шаблоны. Задача данной статьи помочь в проектировании игрового сервера и ознакомить всех желающих со спецификой игрового backend’а.
Описываемые решения достаточно универсальны и вполне подойдут для многих RPG. В качестве иллюстрации в конце статьи я приведу пример использования описанной архитектуры в игре «про эльфов».
Выбор технологии
Чтобы реализовать задуманный нами геймплей, был необходим сервер с постоянным сокетным соединением и достаточно малым временем отклика на действие любого пользователя — не более 50мс, не считая пинга. Выбор технологий, которые позволяли удовлетворить такие требования, не так уж и велик. На тот момент у нашей кампании уже был опыт реализации backend’а на С++ для неигрового проекта, и поэтому выбор был сделан в пользу именно С++: у нас были и люди, и опыт в этой технологии.
Возможно, Java (или некая другая технология) была бы лучшим решением, но в нашей команде не было сильного Java-разработчика, не говоря уже об архитекторе с опытом создания серверных решений. В такой ситуации нанимать новых специалистов, тратить месяцы и десятки тысяч долларов на то, чтобы проверить что лучше, а так же выкинуть работающий и оттестированный код на С++, который мы легко могли повторно использовать – все это далеко выходило за рамки нашего бюджета и отведенного времени на разработку.
Я затрудняюсь ответить каким бы вышел сервер на Java (или какой-то другой технологии), но на С++ мы получили именно то, что нам требовалось, к тому же за вменяемые сроки.
Общая схема сервера
Сервер состоит из следующих модулей (см. рис.1).
Модуль Ship
Прототипы предметов и предметы
Этот модуль оперирует материальными объектами типа «предмет». То есть со всем, что можно положить в трюм, выбросить в космос, купить в магазине или передать другому игроку. Так же этот модуль считает базовые и производные от установленных устройств параметры корабля.
На рис. 2 представлена диаграмма классов (диаграмма упрощена для большей наглядности). Вы видите разделение классов на две части: внизу прототипы предметов, а вверху – сами предметы. Прототипы полностью статичны и безлики – они загружаются из БД, не могут изменяться и никому не принадлежат. А объекты предметов (все потомки от ICargo), наоборот, могут быть модифицированы и содержат в себе уникальный ID, который позволяет идентифицировать конкретный предмет и определить в каком месте он находится (трюм, склад, контейнер в космосе, магазин и т.д.). Такой подход добавляет гибкости и позволяет модифицировать функционал предметов, не затрагивая другие классы.
В нашем решении большинство потомков ICargo (вернее все, кроме TDevice и TShip) являются просто проксями для своих прототипов. Тогда возникает вопрос: а так ли они были нужны? Ведь проще создавать потомков прототипов, с добавлением уникального ID для идентификации, да и дело с концом? Нет, не проще. Но при таком подходе, во-первых, нам все равно потребовалось бы два класса на предмет (прототип и потомок), а во-вторых, у нас бы смешивались динамические данные со статическими (ведь прототипы неизменны). Вдобавок ко всему, конечно же, увеличился бы расход памяти и время создания предмета, потому что необходимо было бы клонировать прототип со всеми его полями. В подтверждение сказанному приведу такой пример: изначально у нас в игре не было чипов, и когда они появились, то все изменения свелись к добавлению пары классов TMicromodule/TMicromoduleProto с добавлением функционала по учету установленных чипов в TDevice. Класс TShip, как и все прочие классы, не был затронут вообще.
Расчет параметров корабля и обрудования
В «Звездных Призраках» есть много различных типов устройств (турели, ракетницы, радар, система маскировки, защитное поле, усилители урона и прочее). Казалось бы, для каждого из них необходимо делать класс-поток от TDevice и реализовывать там специфичный функционал для этого устройства. Но давайте еще раз взглянем на общую схему сервера и описание модуля Ship: этот модуль, в основном, просто предоставляет итоговые расчетные параметры корабля более верхнему уровню, при этом сам функции предметов не выполняет. Поясню на примере. Класс TShip содержит параметр ScanningRange – радиус работы радара, – но фактическую фильтрацию объектов по дальности он не делает. И, что самое главное, на уровне модуля Ship сделать эту фильтрацию не получится, так как у объектов нет координат в пространстве. Самое время спросить себя: есть ли смысл создавать пару классов TRadarPrototype (как потомка от TProtoBase) и TRadar (как потомка от TDevice), отдельную таблицу в БД для этого класса и страницу в админке только ради одного поля ScanningRange? Ответ очевиден: смысл всех этих строк кода и классов весьма сомнителен. Именно поэтому мы создали один класс TStaticParams, содержащий в себе все параметры, которые могут быть у любого устройства в игре, а также класс TPrototypeMod, который может загружать из БД TStaticParams.
Конечно это излишество, но не очень большое: на данный момент класс TStaticParams содержит всего 34 поля типа int. А вот взамен мы получили несколько отличных плюшек. Во-первых, простоту модификации. Теперь можно создавать новые типы устройств и параметров без создания новых классов. Во-вторых, простоту подсчета параметров. Достаточно просто сложить все одноименные поля всех TStaticParams в корабле, чтобы получить итоговые параметры! Никаких виртуальных вызовов или downcast’ов – простая операция «+=» в цикле. В-третьих, мы получили геймдизайнерскую гибкость. Например, у нас в игре есть чип, который может быть установлен в любое устройство, и дает он НР. Такой механизм позволяет геймдизайнерам резвиться так как им захочется, при этом абсолютно не дергая программистов по каждой мелочи типа «ребзя, допишите мне тут капарик, чтобы я мог задавать в устройстве маскировки бонус к уклонению».
Расчет выстрела
Кроме расчета параметров устройств и проверки на возможность установки в слот, класс TShip выполняет еще одну функцию – расчет параметров выстрела. Делает это метод SFireResult TShip::Fire(NSlotPlace slot). Этот метод проверяет возможность выстрела (оружие ли это вообще, закончился ли кулдаун устройства, есть ли патроны для выстрела), рассчитывает наносимый урон, количество произведенных выстрелов, а также бросает кубик на допустимые флаги выстрела (такие, как нанесение критического урона). Все параметры записываются в структуру SFireResult, устройство ставится в кул-даун, списываются боеприпасы, результат выстрела возвращается. При этом TShip не может проверить ни дальность, ни параметры объекта, в который стреляют (например, если у объекта есть защита и урон нужно снизить). Это делает верхний уровень Space, который располагает всеми необходимыми данными.
Остальные классы модуля Ship
Класс TProtoBase содержит в себе общие данные для любого предмета, такие как ImageID, Name, Level и т.д.
ICargo содержит в себе указатель на TProtoBase и проксирует его данные наружу, а также предоставляет Factory для создания предметов. В этом ему помогает класс-синглтон TDeviceHandbook, который загружает из БД все протитипы и содержит указатели на них.
Класс TCargoBay – это хранилище объектов типа ICargo. Он умеет сохранять свое состояние в БД и предоставляет ряд сервисных функций таких как: поиск ближайшего свободного слота, поиск совместимого стакабельного предмета (например, патронов, чтобы объединить с другими патронами) и т.п. Потомки от этого класса накладывают ограничения на типы хранимых предметов (например, в ангаре можно хранить только корабли, а на складе – все кроме кораблей), и, по необходимости, ограничения на количество доступных ячеек для хранения.
Класс IShipNotifyReciver является интерфейсным и обеспечивает связь с более высоким уровнем. Например, передачу на уровень Main сообщения о начале регенерации, чтобы можно было отправить соответствующий пакет клиенту.
Модуль Space
Этот модуль оперирует космическими объектами (КО), такими как космические корабли, астероиды, планеты и т.д. У всех КО есть текущие координаты в космосе и вектор их движения. Диаграмма классов представлена на рис.3 (для большей наглядности диаграмма несколько упрощена).
Не смотря на алгоритмическую сложность, с архитектурной точки зрения этот модуль достаточно прост. Все объекты в космосе (корабли, астероиды, планеты, контейнеры, звезда) являются потомками TSpaceObject и находятся в объекте типа TSystem. У TSpaceObject есть текущие координаты, размер и два объекта, управляющие его поведением – это FlyCommand (потомок от ISpaceFlyTo) и Action (потомок от ISpaceAction). FlyCommand вычисляет текущие координаты объекта и его текущую скорость (в данный момент времени). Алгоритм расчета зависит от типа команды: для движения по орбите он один, для линейного перемещения другой, для перемещения с плавными поворотами – третий. Action отвечает за более сложные алгоритмы перемещения объекта. Например, TFollowShipAction выполняет преследование указанной цели. Для этого она в каждом вызове Update проверяет, изменились ли координаты цели и если да, то заменяет в Owner команду FlyCommand (с указанными новыми координатами цели). Введение Action позволило существенно упростить создание AI и избежать дублирования кода, так как функционал, реализуемый в Action необходим и кораблям игроков и ботам.
Наличие FlyCommand позволяет легко задать необходимый тип движения для любого объекта в космосе и передать эту команду на клиент в виде коэффициентов уравнения движения. Это позволяет существенно уменьшить количество передаваемых данных и упростить реализацию нового поведения на стороне сервера.
Нанесение урона
У класса TSpaceObject есть два виртуальных метода – CorrectDamage и ApplyDamage, а у класса TSystem есть метод DoDamage. Когда какой-то объект хочет нанести урон другому объекту (например, астероид попал в другой объект), он сообщает это TSystem. Система вызывает CorrectDamage и, если урон не нулевой (например, планета имунна к любым видам урона), то она отправляет сообщение о нанесенном уроне «наверх» (чтобы передать в клиенты) и вызывает ApplyDamage, чтобы реципиент выполнил специфические действия (например, корабль уменьшает НР и если НР равно нулю, корабль выбрасывает контейнеры в космос).
Класс TSpaceShip содержит метод FireSlot, который реализует стрельбу спец.абилками. Он проверяет допустимую дистанцию, потом вызывает TShip:: Fire и в зависимости от типа абилки производит дальнейшие действия. Например, для MissileLauncher создает ракеты.
Остальные классы модуля Space
Класс ISpaceShipNotifyReciver используется в TSpaceShip для передачи в верхний модуль сообщений типа «меня атаковали», «я убит», «готов к гиперпереходу» и т.д.
Класс ISpaceSystemNotifyReciver используется в TSystem для передачи наверх сообщений о добавлении/удалении космических объектов, о новых FlyCommands и о нанесении урона.
Класс TGalaxy является синглтоном и содержит в себе список всех TSystem в Галактике.