Что такое рпг сервер
Разработка ММО РПГ – практическое руководство. Сервер (часть 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 в Галактике.
РПГ Майнкрафт сервера
РПГ есть и в Майнкрафт, достаточно просто зайти на один из таких серверов и погрузиться в один из многочисленных миров с прокачкой персонажа, квестами, редкими доспехами, магией и эпическим оружием. Хороший RPG сервер в Майнкрафт не отличается от классических РПГ игр, так как Minecraft является отличной платформой для создания мини-игр в этом жанре.
Лучшие РПГ Майнкрафт сервера
Так как Майнкрафт — это действительно одна из самых лучших платформ для построения собственных РПГ карт или РПГ Майнкрафт серверов, то наверное, первые режимы игры, которые стали появляться — это магические Майнкрафт сервера с прокачкой персонажа и простым набором навыков. Баланс на таких серверах был очень перекошен.
На сегодняшний момент сервера Майнкрафт с РПГ очень сильно продвинулись, в том числе и за счет развития самой игры. Они все больше погружают в ту самую обстановку настоящего RPG на уровне отдельных игр со своим движком. А зачастую появляются просто уникальные проекты со своими историями и приключениями, прокачкой, модами и волшебством.
Разумеется, это не всегда Майнкрафт сервера, посвященные магии и колдовству. РПГ в Майнкрафт может быть прикручено практически к любому игровому режиму. Прокачать персонажа можно как на сервере с зомби апокалипсисом, тик и на Minecraft DayZ сервере, или даже на ванильном выживании.
Как играть на РПГ сервере Майнкрафт?
Обычно все зависит от сервера и режима игры, но такие сервера в обязательном порядке имеют полный мануал сразу при входе на сервер. Примером хорошего обращения с новичком на РПГ сервере является встреча с NPC, которые и разъяснят суть игры.
Игра на сервере может быть линейной, а может быть и открытой. Обычно игроку будет предложено выбрать класс, профессию или расу. От этого будут зависеть навыки персонажа и его способности.
Как зайти на РПГ сервер?
Для этого достаточно просто выбрать сервер, скопировать его айпи, добавить в лаунчер и начать играть. Если для игры могут потребоваться моды, то игрок будет предупрежден об этом при попытке зайти на сервер с РПГ.
В целом вход на такой сервер ничем не отличается от стандартной процедуры. И не нужно качать РПГ сборки или моды, ведь серверов с RPG на данный момент достаточно.
Как найти надежный сервер с РПГ?
Тут все так же, как и с другими серверами. Надежные сервера работают долго, развиваются и постоянно радуют игроков новостями и обзорами нововведений. РПГ сервер в первую очередь нуждается в повседневных доработках и в исправлении ошибок.
Надежный сервер сам проявит себя, лишь стоит на него зайти и провести на нем некоторое время. Обычно режимы игры с RPG захватывают на очень долгое время!
Сервера Майнкрафт RPG
Сервера TechnoMagicRPG идеально подойдут для тех, кто жаждет настоящих приключений. Вас ждет действительно интересная и необычная система развития. Выживать на серверах RPG значительно тяжелее, но при этом в разы интереснее! Вы сможете открыть и посетить множество новых миров, которые до этого и не могли себе представить. Вам будет дана возможность выбирать: лёгкую броню со способностью летать или же тяжёлую халитовую, в которой Вы будете защищены от всего. Вам предстоит отыскать и победить самых разнообразных мобов и боссов (капитанов и майоров), для борьбы с которыми нужно продумать свою так
Самый магический сервер с модом DivineRPG и ThaumCraft, т.е. аддонами к ним.
Вы большой фанат магии и РПГ? То тебе точно у нас понравится! Большой набор модификаций не даст вам заскучать. На сервере присутствует Advent of Ascension, где вас ждёт множество миров, мобов, сражений с боссами и тонна контента! Не забывайте про астральное волшебство и горы наших квестов! Прокачивай скиллы и сражайся с боссами! https://gamepoint.su/#/server/rpg
Вы большой фанат магии и РПГ? То тебе точно у нас понравится! Большой набор модификаций не даст вам заскучать. На сервере присутствует Advent of Ascension, где вас ждёт множество миров, мобов, сражений с боссами и тонна контента! Не забывайте про астральное волшебство и горы наших квестов! Прокачивай скиллы и сражайся с боссами! https://gamepoint.su/#/server/rpg
Самый магический сервер который вы когда либо видели. Встречайте BloodMagica! Волшебство и ведьмоводство! Целая куча модов, призывы демонов, данжи, куклы вуду, различные аспекты таумкрафта, множество колец и амулетов и многое многое другое! Майнкрафт моды которые установлены на этом сервере добавили очень много нового, сумасшедщего и интересного!
Множество миров DivineRPG, Thaumcraft и сумеречного леса встретят вас крепкими объятиями злостных боссов и их многочисленной армии монстров. Кланы, расы и классы.
Magic — это огромный мир, наполненный тайнами и загадками. Именно на этом сервере ты познаешь весь сказочный мир магии и почувствуешь дух приключений и странствий! Присоединяйся, великий маг, мы ждем тебя, начни играть!
Привет! Заходи на наш Discord сервер https://discord.com/invite/gUp78bw
Сервер с ролевым уклоном!