Как стать автором
Обновить

Разработка ММО РПГ – практическое руководство. Сервер (часть 2)

Время на прочтение14 мин
Количество просмотров25K
Всего голосов 18: ↑14 и ↓4+10
Комментарии13

Комментарии 13

Очень странная статья.

AI — тема вообще не раскрыта. Как бы и так очевидно, что AI должен получать данные, обрабатывать, принимать решения и реализовывать. Вопрос весь в том, как именно он принимает решения.

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

Разделение мира — велосипед. Обслуживать разные локации разными процессами (или потоками) — как бы, совершенно типичное решение. Этому решению больше лет, чем иным игрокам.

Хранение данных в памяти с периодическим сохранением в БД — аналогично, еще одно классическое решение. Иногда используют промежуточные хранилища, типа MemCached для обмена данными между разными демонами (потоками).

Странности с ID предмета непонятны. Админка должна уметь работать как с БД, так и с демонами, чтобы изменения адекватно отражались в рамках одной сессии. Надежных решений же по созданию уникального ID довольно много. Например, каждый демон может иметь свой префикс для предмета в дополнение к счетчику. Но вообще, принято считать, что все финансово-предметные операции должны сохраняться сразу же, если есть хоть какой-то вид взаимодействия между игроками. Иначе при любом сбое вы получите весь спектр проблем — клонирование предметов, пропажу предметов, необходимость разруливать множество транзакций, часть из которых уже сохранена, а часть — нет. Чтобы не сталкиваться с ограничением в 50мс"- это сохранение может проходить асинхронно или через отдельный демон, который как раз занимается сохранением подобных вещей (и заодно создает ID для новых предметов).
Фиг с ними, с ID — меня волнует другая оговорка.
Можно, конечно, сразу же сохранять предмет в БД, но это противоречит идее «все в памяти, сохранение в конце сессии» и, что самое главное, вызовет остановку потока, в котором может находиться не один пользователь, до окончания сохранения. И остановка может превысить то самое максимальное время отклика сервера на действия игрока (50мс), которое задано в ТЗ.
Означает ли это, что при входе или выходе любого из игроков сервер подлагивает?
Это может показаться смешным, но мне приходилось делать аудит одной игры, в которой из-за использования json и системы polling-based, а не event-based, разработчики уперлись именно в пропускную способностью сетевой карты. И после этого все читаемые и красиво названные поля в json пришлось называть в стиле A, B и т.д. для того, чтобы минимизировать размер пакета.

Эээ, это что за варварство? Поставить их в угол за такие оптимизации. Чем не устраивает gzip или, на крайний случай, msgpack?
По пописанию протокола вы придумали свой Protobuf/Thrift )
Отсюда вопрос к автору статьи: на protobuf даже не смотрели — или он чем-то не устроил?
Только наверняка не предусмотрели в нем обратную совместимость при добавлении полей, возможность когда-нибудь удалить поля, которые стали ненужными, не сделали кодогенераторов для кучи других языков, и как любой велосипед получили нечто ни с чем не совместимое, с чем никто не знаком, и с кучей багов которые еще предстоит найти.
Как-то у вас так получается, что если библиотека не публичная, то она обязательно кривая, косая, глючная и вообще непонтяно как работает…
Не допускаете даже мысли, что люди могут сделать хорошо свою работу?

P.S. И кстати. Зачем им кодогенераторы для кучи языков? Зачем им с кем-то совмещаться? Зачем им знакомить с кем то свою разработку? Это небольшая библиотека для конкретной задачи, в абсолютно закрытом проекте.
Это же не линух с нуля писать, небольшая библиотечка. В конце концов, если вы не можете написать даже небольшую библиотечку без гов или исправить их. Это же не значит что все такие.
Дело тут не в том, хорошо они будут делать свою работу или нет. Чтобы хорошо сделать такого рода работу, предусмотрев все нюансы, надо затратить очень много времени, это можно увидеть по репозиториям проектов. Когда же разработка своего протокола это просто побочный эффект от основного проекта, то, обычно, он страдает всеми теми проблемами, о которых написали выше.
Ну какая «такая» там работа?
Проект будет страдать, если надо будет делать универсальную публичную библиотеку.
С поддержкой разных языков, с кучей всяких универсальных фишек и т.д.
А сделать протокол для конкретной задачи, не такая уж большая проблема.

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

P.S. Я не агитирую за велосипеды. Я и сам писал протоколы. Но в итоге остановился на протобафе.
Но не вижу какой-то особо сложной задачи, в написании протокола, для конкретного проекта.
Безо всякой универсальности и кучи языков в поддержке.
Я сам больше 4-х лет по работе имел дело именно с написанием протоколов. Я не говорю, что это сложно (вообще не сложно, если откровенно), просто это лишнее время на написание + отладку, которое можно было бы потратить на разработку игры. Иногда гибкость не нужна, но, обычно, для проекта вроде онлайн игры, который будет постоянно развиваться, лучше бы иметь надёжное и отлаженное решение. Конечно же, это не аксиома, просто мнение.
В нынешнем проекте мы последовательно вставляли в проект три разные готовые библиотеки твинеров. Пришлось в конечном счёте отказаться от всех трёх и запилить свою. Потому что либо баги, либо ограничения на возможности, которые вам не подходят либо кривая система колбэков, которые для одного из ваших элементов всё ломают. И так каждый раз.

Опять же, еспользовали стандартную C# библиотеку System.Linq — быстро выясняется, что она не работает под iOS. Заменяем её на UniLinq, выясняется, что .ToArray() и .Reverse().TakeWhile() у неё запредельно тормозят В результате вместо этих функций пишутся свои, работающие за осмысленное время.

И такая дребедень каждый раз. Каждый раз ты используешь готовое или даже стандартное решение и выясняется, что в нём баги, причём ловля их в чужом коде занимает в разы больше времени.
Код сервера у нас базируется на коде, написанном для другого сетевого приложения ещё лет 10 назад. Я не знаю, была ли десять лет назад протобаф. А код у нас остался и отлично работает. Единственное, что пришлось допилить — так это скрипт на РНР, который генерирует сами пакеты (тогда, 10 лет назад и клиент и сервер были на С++, поэтому таких проблем не возникало). Но скрипт нам в любом случае нужен был, т.к. необходимо, например, генерировать enum и для клиента и для сервера и ещё с БД синхронизировать. В общем, по нашей оценки искать и пробовать опен-соурс решение было бы дольше написания скрипта.
Я же не говорил, что нужно искать и пробовать именно опенсурс. Есть готовое решение, которое вам подходит — лучше использовать его. В вашем случае это ваша же библиотека.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий