на чем писать сервер для игры
Разработка сервера под игру, с чего начать?
Привет.
Такой вопрос, как создаются сервера для игр? Есть к примеру игра GTA SA я так понимаю сторонние разработчики сделали клиент, который как-то взаимодействует с игрой передает данные и тд, вроде понимаю, но как клиет все таки влияет на игру? Я ОЧЕНЬ загорелся идеей сделать сервер для игры GTA 5 сделать моды к нему и тд, но не могу понять с чего начать. Как мне управлять игрой клиентом? Серверную часть я вроде как представляю, вопрос-ответ.
К примеру сделать сервер майнкрафт не состовляет проблем. Скачал, настроил, запустил, тут такого не нашел 🙁 Но по сути такое мне и не нужно, я хочу сделать свой сервер с 0 и свои моды, воплотить свои идеи в жизнь!
Кто имеет опыт расскажите!
Средний 1 комментарий
Есть к примеру игра GTA SA я так понимаю сторонние разработчики сделали клиент
То, что может сторонний разработчик, это сделать моды для готового сервера, используя те инструменты, которые разработчик предложил, либо пытаясь «грабить» протокол взаимодействия. Моды бывают серверными и клиентскими, и возможны только в том случае, если у вас есть доступ к компьютеру, на котором запущен сервер и клиент (клиент у вас всегда есть, так и делают большинство модов).
К примеру сделать сервер майнкрафт не состовляет проблем.
Майнкрафт заметно проще, чем GTA. Хотя бы потому, что майнкрафт сделал один человек, а GTA сделали десятки программистов. И вот для майнкрафта можно сделать свой сервер,а не мод (хотя и моды к нему тоже есть). Как пример, отличная статья.
Реализация серверной части в многопользовательских онлайн играх
За свою недолгую жинь я ни разу не встречал программиста, который бы не любил игры. И уж тем более, программиста, который никогда их не писал.
Кто-то начинает с тетриса, кто-то со змейки. У кого-то это увлечение проходит, а кто-то этим «заболевает» и превращает свою болезнь в любимую работу или занятное хобби.
В эру интернета и социальных сетей играть одному неинтересно, хочется общаться и играть вместе с друзьями.
И не просто общаться, а ходить группой в подземелье или показать кто на арене хозяин.
В данной статье я бы хотел рассказать о своем подходе к серверной реализации такого взаимодействия.
Задача
Рассмотрим пример простого игрового приложения, в котором игрок управляет персонажем, который может покупать\продавать предметы, сражаться на арене, ходить в подземелья один или с друзьями.
Концепция
Например, игрок создает группу для похода в подземелье. Игрок посылает запрос нашему серверу, который добавляет новую группу в список доступных групп для походов, после чего остальные игроки имеют возможность получить этот список и присоединиться. Группа заполняется, и, нажатием кнопки, создатель отправляет ее в подземелье на встречу опасным монстрам.
Казалось бы, все просто. Создаем таблицу в БД, записываем туда желающих и отправляем в подземелье.
Так думают многие начинающие программисты, но забывают про самую главную проблему многозадачных систем — race condition.
Логично предположить, что правильной реализацией такого взаимодействия был бы серверный демон, который отвечал за состояние игрового мира, принимал запросы от игроков (в порядке очереди), обрабатывал их и отдавал результат.
В нашем случае сервер должен хранить текущее состояние игроков, чтобы иметь возможность корректно обрабатывать результаты.
Схематично это выглядит так:
Пожалуй, самое интересное — это обработчик запросов.
Он содержит в себе основную логику нашего сервера:
— хранение состояния игроков (свободен, находится в подземелье, в группе и т.д.)
— хранение и обработка информации об игровом мире (битвы на арене, походы в подземелья, группы для похода)
Хранить состояние игрока нам необходимо для того, чтобы, например, пока персонаж занимается геноцидом монстров в подземелье, мы не смогли пойти на арену или прикупить себе новый доспех.
Кроме того, на сервере должна производиться обработка игрового мира.
Допустим, мы пошли в подземелье на 5 минут. За 5 минут сервер должен произвести обработку битвы с монстрами, посчитать опыт, дроп, а также изменить состояние игрока.
Стоит не забывать, что количество игроков может быть очень большим и нашему серверу придется нелегко.
Реализация
Для реализации такого демона был выбран язык PHP 5.3 с расширением libevent, как наиболее знакомый автору.
Про libevent существует много статей, создан небезызвестный phpDaemon, поэтому углубляться в его работу не имеет смысла.
Стоит только отметить возможность создания отложенных событий (флаг EV_TIMEOUT), что в нашем случае решает очень много проблем.
Однако, наш сервер должен, кроме всего прочего, достаточно активно работать с БД для записи результатов, покупки вещей и т.д.
Как известно, БД — узкое место любого серьезного приложения, а наш сервер может «лечь» от большого количества запросов.
Поэтому для обработки «тяжелых» запросов можно предусмотреть дополнительный серверный демон с необходимым нам числом нитей (thread/workers), которые будут с радостью выполнять всю кропотливую работу.
Стоит отметить, что запросы к work daemon так же становятся в очередь и не обрабатываются, пока мы не получим ответ.
Принцип работы work daemon такой же, как и основного демона, за исключением наличия нескольких нитей (thread/workers) для обработки запросов.
Выводы
Достоинства такого подхода заключаются в следующем:
— всю тяжелую работу мы сбрасываем на work daemon, а обработку состояний игроков оставляем на нашем основном демоне, что делает его очень легковесным и быстрым
— work daemon можно вынести на отдельный сервер, в случаем необходимости, а количество workers варьировать в зависимости от железа
— возможность масштабирования
А теперь о недостатках.
Самый главный недостаток реализации: PHP течет. Даже новый сборщик мусора в 5.3 не решает всех проблем. И мы имеем:
Решение: периодически перегружать worker’а, когда объем используемой памяти достигает определенного предела.
Наиболее правильным решением я вижу использование языка программирования Erlang\OTP.
Поставленная задача отлично укладывается в его концепцию FSM/gen_server, чем автор и планирует заняться в ближайшее время.
Надеюсь, что статья поможет начинающим разразботчикам игр не наступать на грабли и правильно проектировать свое приложение.
С чего начинается написание игрового сервера?
Вообще, написание любой штуки начинается с ТЗ, а потом уже становится куда яснее что и как делать дальше.
Сервера для Mu и Lineage пишут командой из довольно большого количества человек.
>везде только ссылки на готовые.
Скачайте и почитайте. Как поймёте устройство какого-нибудь готового сервера, станет ясно куда копать дальше.
реверс-инжиниринг протокола в первую очередь, это вообще далеко от написания кода и требует умения в сети/дебаг.
Софт написать это наименьшая проблема при старте. Написать можно худо-бедно и работать будет, но без протокола ничего не сделаешь(под чужую игру это как выучить иностранный язык без переводчика с помощью носителя языка, т.е. тыкая пальцами в предметы и жестами пытаться узнать весь язык для того чтобы можно было общаться).
Но протоколы связи сервера и клиента почти всегда зашифрованы, как раз таки от любителей запилить пиратки.
А так же очень любят шифрование менять при каждом удобном случае.
И только когда протокол уже расковыряли, то можно и сервер писать полноценный(или вообще начать писать в этот момент).
А это уже C(++)/Java/C# в основном т.к. нужен быстрый реалтаймовый софт.
Ну и последнее это повторить механику оригинала скиллы/итемы/крафты/прокачку/npc ну и т.д.
В общем конкретно к разработке игр написание эмуляторов для чужих игр относится примерно никак.
Это больше про взлом игр.
Ну для своей игры конечно первые два шага опускаются.
Ingernirated: протокол это в данном контексте уникальнный язык между игрой(клиентом) и сервером.
Везде свой.
Т.е. самый простой сценарий:
написать эмулятор входа в игру/на окно выбора персонажа.
Чтобы узнать как сервер должен отвечать и что шлет клиент
1. включаем снифер трафика(Wireshark например из самых на слуху)
2. запускаем игру
3. вводим логин пароль
4. смотри что наловил снифер т.е. ищем в пакетах логин/пароль(данные которые мы знаем наверняка, пароль правда шифрованный будет скорее всего так что логин только).
5. пытаемся разобрать на глаз структура пакета. По «байтово»
6. пишем код сервера который понимает пакеты и отвечает правильно. (Ответы тоже с оригинала надо парсить и разбирать)
7. повторять 3-6 пункты с каждым действием в игре/клиенте до получения играбельного сервера.
Вот например как выглядит пакет в двоичном виде естественно.
https://github.com/S-anasol/melia/blob/master/src/.
Всё это познается опытным путём.
И это цепочка действий без учета того что на клиента как правило висит защита и трафик шифруется.
Т.е. чтобы получить вот такой сырой пакет надо для начала обойти защиту, это опять же hexинг/хакинг игры.
Конечно есть более простые варианты когда в клиенте можно найти какие-то базы данных внутренние в описанием протокола/вещей/скиллов и т.д. Но это тоже надо найти и написать софт чтобы читать удобно.
Этот пакет, он приходит каждые 50мс(старается) или в зависимости от изменения окружающего мира, действия игрок(в том числе и во время раздумия, какого персонажа выбрать)?
Во-первых конечно общее состояние окружающего мира постоянно приходит от сервера, прям вот очень постоянно, по времени я даже не знаю, пингом ограниченно. И это очень много пакетов.
значит каждая магия(её использование), каждый шаг(вперед,бок, назад) или нажатие кнопки принять в тексте, для всего этого нужно написать свой код обмена данными в такой форме?
Да, вообще на некоторые действия происходит по несколько обменов пакетами, Цепочки целые.
Сначала проверяет например что возможность использовать магию есть вообще, потом отправляет на клиенту пакет «окей, показывай специальный курсор, который является прицеливанием», и только потом клик отправляется на сервер и говорит что скилл использован.
Т.е. этот код мы можем словить, когда играем с клиента и останется только научить свой сервер понимать, как он должен реагировать на пакет, который отправлен ему с клиента?
да, клиент знает что и когда отправлять/принимать.
Но не факт что это можно извлечь в готовом виде для разработки.
Вот например список пакетов Ragnarok Online, эмуляторы практически со старта оффа развиваются.
Постоянно меняется всё, куча условий и т.д.
И вот на выходе получаем 4000+ пакетов.
Естественно необязательно собирать всё руками.
В основном под каждый эмулятор(игру) пишут свой анализатор пакетов т.к. правила всё-таки какие-то прослеживаются и уже частично можно понять/разобрать пакеты исходя из старых данных.
На чем писать сервер для игры
У меня есть синглплеер андроид игра(играть против ботов) в которую было бы интересно добавить возможность или онлайн игры на большой карте, или просто друг против друга где сейчас игра с ботом. На чем собственно принято сейчас писать сервер? На роботе где я устроился на испытательный срок используется на клиенте netty, но он на джаве и я не уверен что это то что нужно. Из языков которые знаю это С++, джава. Пробовал делать сервер на node.js. Собирался учить пайтон.
Требований к серверу особых нету, желательно только чтоб можно было найти недорогой хостинг потом куда это все поставить.
первый в силу не очень быстрой разработки
кто вам такую глупость сказал? как раз, сервак для игры самое оно на плюсах писать
C
Половину разработки будешь ловить утечки памяти
это так. но есть ещё вариант С++, где такой проблемы нет, а вы его проигнорировали.
худший вариант для игрового сервера
есть ещё вариант С++, где такой проблемы нет
Есть. Только что утечки придётся ловить не половину времени, а четверть 🙂 А четверть — думать, как бы не допустить утечек 😀
Я видел «изнутри» разработку двух MMORPG серверов в равных условиях, одного на Java, другого на Си++. Работали примерно одинакового уровня команды схожей численности. Разница в скорости разработки, отладки, профилирования и надёжности результата была офигенной в пользу Java. Разница в производительности хоть и была не в пользу Java, но невысокой. И легко компенсировалась массой сэкономленного при разработке времени, которое можно было пустить на более эффективную, алгоритмическую оптимизацию 🙂
Выбор маргинального языка сразу катастрофически сужает потенциальный круг разработчиков.
Erlang давно уже не маргинальный язык. Вполне себе мейнстримный.
Erlang давно уже не маргинальный язык. Вполне себе мейнстримный.
Он мейнстримовый в крайне узкой нише 🙂
Как я понимаю реализацию мультиплеера в играх, тебе придется переносить всю игровую логику на сервер, а приложение будет лишь отображать то что ему шлет сервер. То есть только java.
Обещают, что rust будет для этого пригоден.
Ага. Микроконтролёры программируют на нём.
прибыли у тебя никакой не будет, инфа соточка
а через месяц ты бросишь это дело
да, десять колек его используют
Его использует немецкая контора с капитализацией равной российскому бюджету. А ты лох.
целая одна контора? в целом одном API? это уже прогресс
Дай угадаю. Ты пишешь на php?
бывает иногда,но реже и реже, а что с ним?
Почему «будет»? 1.0 уже давно вышла.
А четверть — думать, как бы не допустить утечек 😀
Что там думать — RAII во все поля, да и всё. Не хочешь сам RAII строить — умные указатели есть.
Только что утечки придётся ловить не половину времени
кстати, а смысл? большие утечки детектируются на раз, а с небольшими утечками (10кб/день, в среднем) можно уже и в продакшен пускать, всё равно джава памяти выжрет больше.
Я видел «изнутри» разработку двух MMORPG серверов в равных условиях, одного на Java, другого на Си++.
вообще ни о чём не говорит. зависит от целей проекта, требований по пингам, и много чего ещё.
которое можно было пустить на более эффективную, алгоритмическую оптимизацию
вообще-то, нельзя было. алгоритмы оптимизируются либо сразу, либо никогда.
занимаюсь коммерческой разработкой игровых серверов для флеша и андроида
на джаве+netty
спрашивайте свои ответы
кстати, а смысл? большие утечки детектируются на раз, а с небольшими утечками (10кб/день, в среднем) можно уже и в продакшен пускать
А если утечка не 10кб/день, а 100Мб/день? У меня народ столько терять умудрялся даже под Java 🙂 Но там хоть из-за JVM можно строго определить, кто же память выжрал. И то несколько десятков человек в течении пары лет не могли отловить всё, пока я этим вопросом плотно не занялся. В Си такое допустить много проще, а отлавливать источники утечек сложнее.
вообще ни о чём не говорит. зависит от целей проекта, требований по пингам
У реалтаймовых MMORPG требования обычно довольно схожие 🙂
вообще-то, нельзя было. алгоритмы оптимизируются либо сразу, либо никогда.
Ой, а мужики-то и не знают. Особенно про то, что под алгоритмической оптимизацией обычно имеют в виду не оптимизацию алгоритма, а оптимизацию алгоритмам — заменой алгоритмов на более сложные, но оптимальные.
На лобовой оптимизации кода на практике редко получишь выигрышь выше десятков процентов. А вот заменой алгоритмов иногда можно получить выигрыш в разы/десятки раз.
Пиши на Java, не прогадаешь.
Я еще понимаю некоторых хипстеров делающие бекенд для своего сайтика на node.js. Но писать на нем игровый сервер.
Можешь вообще бесплатно поставить, если будешь юзать Java. Вот тебе линки https://console.ng.bluemix.net/pricing/ или https://www.openshift.com/products/pricing Единственно, как выйдешь за free ресурсы, то убегай сразу (ибо цены на облака сейчас неадекватные) и покупай какую-нибудь ВПС на hetzner или еще где.
Я еще понимаю некоторых хипстеров делающие бекенд для своего сайтика на node.js. Но писать на нем игровый сервер.
Да то была моя первая попытка, хотел на Qt, на сокетах, да чет Qt не захотел работать и мне было лень разбираться.
Почти все нормальные компании так или иначе используют Erlang
Ну да, я пользуюсь мобильным телефоном, значит, я пользуюсь Erlang 🙂
Не могу понять в каком веке вы живете?
Тут не век, тут Вселенная другая. В моей Erlang занимает 43-е место популярности по Tiobe и 30-е по числу новых проектов в GitHub. При чём его популярность падает:
2012 — 20 место (6801 новый проект)
2013 — 27 место (2595 новых проектов)
2014 — 30 место (2569 новых проектов)
На чем писать сервер для игры?
Оценить 4 комментария
jagev: хотите асинхронности — берите Эрланг/Эликсир, чего уж там. До 100к rps можно как угодно быдлокодить, все сожрет и не поморщится.
Главное про основные возможности отстрелить ногу почитать заранее, и все.
У нас есть опыт работы с Node.JS
не уверены, что он подойдет для игры у которой будет тысяча человек в онлайне
Я бы выбрал Go, он отлично подходит для разработки серверной части игр.
Для общения с клиентом можно использовать protobuf.
Но лучше всего вам будет нанять человека с таким опытом к себе в команду.
Поэтому ищите человека с опытом, берите его в команду.
Иван Филатов: ООП конечно круто, но от него обычно отказываются, если нужна производительность. А как жить без, можно спросить у Линуса.
p.s. не холивара ради! 🙂
Количество онлайн вообще не так считается. Все зависит от игры.
У меня был проект с онлайн под 100.000 в сутки. Легко держалось на php/fastcgi, правда для одной штуки пришлось написать примочку на ассемблере и внедрить как либу для apache, но к онлайну это отношения не имеет.
Опять таки, при высокой динамичности, проблема начинает возникать в трафике, а не в CPU.
что значит «имелся человек»? Сами и написали.
Ассемблер не такой уж и сложный, если нужно написать конкретную процедуру расчета, а не что-то более сложное. Там всего пару страниц кода было. Вполне достаточно начальных знаний.
Есть пользователь, у него есть ID и timestamp последнего обновления его данных.
Тоже выбираю сервер сейчас для игры, прочитал море отзывов про существующие сервера и технологии, пока остановился на Forge. Он запускается в инстансе Unity и поддерживает всю юнитевскую физику, коллайдеры и иже с ними, а значит Fully Authoritative на нём будет реализовать довольно просто.
P.S.: В рамках js можно было бы ещё упомянуть MeteorJS. Но на мой взгляд, если игра real-time, а не turn-based, то он не потянет.
Как я увидел в комментариях, раз уж хотите отказаться от ООП (сам не люблю его), то берите Go.
Сильно там всё равно не набыдлокодить, а вот инструменты по типу сетевых соединений и параллельная работа очень простые и легко освоите, чтобы сделать сервер.
У самого был опыт создания игрового сервера на Go, но там игра пошаговая, так что мой пример вам не поможет 🙂