Pull to refresh

Comments 179

Спасибо огромное, у вас отличные статьи по теме.

1. Читая ваш текст про абонентов и сообщения, все время возникал вопрос «почему не попробовали Akka?» это же оно самое один в один.
Просто сейчас пилю сервер на Scala+Akka и уже очень много раз порадовался, на сколлько работа с акторами (абоненты в вашей терминологии) через систему сообщений, облегчает разработку такой сложной системы как игровой сервер.
2. Будет ли продолжение с подробностями? Например как устроена сетевая часть.
3. В начале вы пишете «Мы решили отказаться от традиционной для MMO техники шардирования и запустить всех игроков в один большой мир.», а далее по тексту рассказываете про разделение по каналам и что игроки на самом деле не видят друг друга. В чем тогда заключается единый мир, если игроки не могут взаимодействовать друг с другом?
1) На старте проекта у нас была уже готовая реализация нашего серверного движка, которая нас устраивала, с которой мы умели работать, знали все её особенности и ограничения. Не было никакой мотивации переходить на любой другой, пусть даже самый модный, движок. Тем более тогда он был ещё в зачаточном состоянии.

2). Это зависит от коллег :) Если они захотят, то напишут.

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

Тогда собственно вопрос такой касательно этой циаты: в ВОВ-е периодически кланом собирались в одном месте в городе — обменяться вещами, етс. Я так понимаю подобной ситуации у вас не получится создать? Или как-то можно запихать весь клан в один «кнал»?
Весь клан по умолчанию будет пытаться сливаться в один канал. Но нет гарантии, что это получится.

Механизм для форсированного сбора всех в одной точке пока не допилен, но вроде как хотели сделать что-то вроде спела «собраться», который будет принудительно телепортить всю группу (не гильду) в одну кучу :) Если надо будет делать то же самое для гильдий, то запилим.
В GuildWars 2 реализовали приоритетами — больше шансов попасть в тот же «канал», что и человек, которого ты видел хоть один раз в игре/он с тобой в пати/из твоего клана etc.

P.S. Интересно было бы у них узнать про эту реализацию. Кто-нибудь хочет провести интервью и сделать перевод? :)
Если я правильно понимаю, то разделение по каналам на картах обратимое. Как в Firefall?
После авторизации игрок попадает в один инстанс карты. Связавшись с кем-то из друзей в общем чате он может быть добавлен во временную команду. После некоторых манипуляций (игровые команды или тп) игрок будет иметь возможность переместиться в инстанс карты, в которой присутствует другой игрок.
Если так, то мир почти единый. Чат, экономика разделяются между каналами, а события карты нет.
Не знаю как в Firefall, но у нас всё примерно так как вы описали.
Можно выложить ссылку на статью на форуме sf.my.com? :)
Там народ уже истосковался по ЗБТ и будет рад любой свежей информации, даже технической.
Мы не выкладываем туда, так как все-таки статья техническая. Недавно, кстати, открыли sf.mail.ru для русскоязычных игроков, и в ближайшее время планируем публиковать немало новостей о мире Skyforge.
Так что есть чем порадовать игроков =)
Но, если игроки захотят поделиться информацией о статье на форуме мы будем совсем не против.
У меня глаз зацепился за кусок кода и не отпускает:

Override
public void run(@NotNNull Abonent abonent) {
if (! (abonent instanceof Avatar)) {
Cast.logError(abonent, Avatar.class);
return;
}
final Avatar avatar = (Avatar) abonent
//…
}

По сути это нарушение LSP, в том моменте где вы начинаете проверять тип абонента. Что говорит о том, что есть проблема в архитектуре. Это вынужденная мера?

В теории, если уж вам приходит Abonent, то вы должны внутри ориентироваться на его интерфейс. Иначе какой смысл указывать в контракте тип аргумента?
Есть разные мнения на этот счёт :)
Если бы мы сделали типизированные сообщения, то внутри месседж системы нам пришлось бы cделать unchecked cast.
В этом случае мы делаем checked cast и можем отреагировать как-нибудь осмысленно.

Обычно делается мессажка MsgToAvatar extends Msg, в которой прячется этот каст, и все кому надо посылать сообщения аватару наследуются от него и не пишут этот каст 100500 раз.
| Если бы мы сделали типизированные сообщения, то внутри месседж системы нам пришлось бы cделать unchecked cast.
Зачем? Если вам приходит точно Avatar через аргумент, зачем вам приводить типы?

На сколько я понял из статьи(я мог ошибиться), то у вас идут Msg от Abonent к Abonent и они выполняются(метод run) на Abonent получателе.
Проверку самого Abonent поручили самому Msg. А логика того кто кому может послать Msg прячется исключительно в интерфейсе клиента. Другими словами, это клиент решает, что при наведении курсора на табуретку, отключается возможность послать Msg с действием ударить. Но мы это сможем сделать взломав клиент и тогда у вас будет в логи сыпать недопустимые операции.

Правильно я всё понял?
Если так, то очень интересна архитектура проверка доступности сообщений на клиенте. Т.к. мне кажется. вы решали проблему согласованности ограничений игровой логики и ошибок сообщений, если действие было выполнено, но не не поддерживается самим Msg.
Да вы всё правильно поняли. Можно послать сообщение неверному адресату, и это печально. В идеале и адреса и абоненты должны быть типизированы. Но… так исторически сложилось :) Ввиду количества кода переделать это не так просто.

Доступность сообщений на клиенте отдана на откуп интерфейсу. Если его сломать можно слать какие угодно сообщения кому угодно. Но везде, где это хоть сколько-нибудь опасно или должно быть ограниченно игрой есть серверные проверки. Тогда в логах сервера будут ошибки, мы их увидим и плохого игрока… кхм… накажем :)
Вспоминается история с ребятами из Archeage, которые убивали всех вокруг на Острове свободы каким-то боссовским или гмским скиллом.
На всё это есть серверные проверки :)
На самом деле это подперто и клиент никаких левых сообщений прислать не сможет.
В аннотации @ReplicateCmd указывается уровень доступа клиентской команды. Когда команда приходит на frontend, её уровень сразу же сверяется с уровнем доступа аккаунта, и при несоответствии она не будет выполнена и еще в лог напишут, что была попытка взлома.

Поэтому даже если игрок сумеет с клиента отправить какой-то чит, он не пройдет, так как у его аккаунта недостаточно прав на сервере.
Не ну с читами понятно, но можно же отправить каст спела в сундук в качестве таргета. И тут вот сработает чек, что сундук не аватар.
Доступность сообщений на клиенте отдана на откуп интерфейсу. Если его сломать можно слать какие угодно сообщения кому угодно. Но везде, где это хоть сколько-нибудь опасно или должно быть ограниченно игрой есть серверные проверки. Тогда в логах сервера будут ошибки, мы их увидим и плохого игрока… кхм… накажем :)


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

Я поэтому и решил откомментить дополнительно, что все подперто, выполнить некорректную команду не получится.
Кстати, интересно было бы узнать про то как у вас написан RBAC.
Я сейчас пишу систему на Pyrmid и права на действия тоже указываются в анотациях, но мне не нравится оверхед на запрос данных о пользователе, о его правах и о предмете доступа.
Ну мир у нас не stateless, поэтому из базы права доступа мы запрашиваем только один раз, когда игрок входит в игру. Дальше права кэшируются на легате и сверяется какие права указаны в аннотации на комманде и какие есть у пользователя. Оверхэд есть, но не большой.
Если бы соблюдался LSP то у вас там вообще бы не было кастов. А у вас еще и SRP нарушен и семантика.
Имхо, этой логики вообще там быть не должно. Почему «Сообщение» внезапно кого-то убивает? Зачем вообще какая-то логика в типичном DTO?
Потому, что это походу не DTO, а типа Command Pattern.
Всё у нас не по учебнику :)

Мессажка это действительно «типа Command Pattern».

В некоторых местах мы посылаем мессажку-носитель, в которой есть классик с данными. На приёмнике делается обработчик, подписывающийся на приход опеределённого типа данных. Это наверное ближе к DTO. Но этот подход используется реже, не очень удобно.
UFO just landed and posted this here
Да вроде ноги у всех на месте, после многих лет разработки и тестов. Хоть ситуация с тем, что мессажку послали не туда, и возможна, возникаетс она довольно редко.

Всё проще. В псевдокоде это выглядит примерно так
run(Abonent) {
!(Abonent instanceof Interractable)
  Fail();

 obj = (Interractable) Abonent;

obj.checkPrecondition(actorData)

obj.interract(actorData), 
}


Никаких свичей, обычная перегрузка методов. ООП все учили. Логика камушка — в камушке, логика колокольчика — в колокольчике.

p.s. Хотя, конечно, это только пример. Интерракшны с реальными объектами гораздо сложнее.
switch по типам для команды «использовать»

вот уж такое точно не нужно
достаточно вычитывать эти команды по частям и рассовывать их по обработчикам из, например, мапы
Думаю на такие нарушения можно пойти ради производительности. В данном случае Msg обрабатывается только для объектов класса Аватар, но вообще, видимо, интерфейс Abonent может быть реализован разными классами.
Абонент, кстати, не интерфейс а класс. В нём есть адресс и несколько функций по менеджменту жизненного цикла.

Да не, это не из-за перфоманса. Cast-ы в Java очень быстрые. Скорее ближе к «так исторически сложилось» :)
Да, кстати, @NotNNull — что за аннотация такая?
Захожу на сайт sf.mail.ru/, а там alert(1);
Никак XSS?
<div class="title_forum"> <a href="http://portal.sf.mail.ru:80/redirect/comments/5357771eb1d03dc83ea42c78/FirstUnvisited">"><img src=x onerror=alert(1)></a> </div>
Да, спасибо, похоже кто-то правила конкурса(https://hackerone.com/mailru) не соблюдает :) Чиним.
Очень интересное описание, но при этом поверхностное, хотелось бы больше технических деталей!

Если не секрет, какую JVM вы используете, много ли тюнили в ней? Можно ли узнать примерно конфигурацию одной ноды/сервера для роли (хотя бы в контексте «память/процессор/дисковая система»)? Насколько я понимаю, вы храните все данные централизованно? Если не секрет, где и как? Не могли бы вы подробнее описать механизм локалей, из статьи не сильно понятно, это концепция чисто техническая (для отсечения указателей на другие объекты для обеспечения консистентности) или у нее какие-то более глубокие смыслы (типа транзакционности)? Как обрабатываются откаты?

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

Что будет если мой друг Вася пригласит меня встретится на карте А, на которой кроме него уже 250 человек? Мы будем безуспешно искать друг-друга на разных вариантах этой карты? Чем это отличается от реалмов в лучшую сторону? Скажем, в том же ВоВе есть возможность создания кросс-серверных групп, которые будут играть на одном сервере.

Конечно, я понимаю, что по архитектуре таких приложений можно писать книги.
JVM — Oracle HotSpot. Сейчас сидим на Java 7.

Тюнили, попрошу коллег ответить как.

Конфигурацию ноды узнать нельзя. NDA.

Данные храним централизованно, в базе данных, PostgreSQL, в статье есть ссылка на мою предыдущую статью на эту тему. Лучше её почитать, чем тут дублировать.

Концепция чисто техническая, для отсечения указателей. Транзакционности там нет. Ещё оно применение локалей — для телепорта. Локаль может целиком сериализоваться и улететь на другой сервер, поэтому в ней не должно быть ссылок на другие запчасти сервера.

Друг Вася не может пригласить вас на конкетный канал. Но если вы состоите в группе, то вы будете прозрачно для игрока попадать с ним вместе на один и тот же канал. От шардов это отличается тем, что вы можете взаимодействовать с любым игроком, и взаимодействовать со всем миром через общие сервисы, типа форума, чата, гильдий, поиска приключений и т.п. Кроссерверные группы в ВоВ-е появились именно как попытка обойти ограничения шардов.
Спасибо, к сожалению пропустил ссылку на прошлую статью, как и саму статью, видимо. анал-раны в чате на 100к игроков конечно приобретают некую пикантность :)
Т.е. выцепить друга Васю и жестоко ему отомстить за прошлые прегрешения — не получится.
Ну можно позвать его в группу и там поговорить по душам :) Или ходить по приключениям и ждать… Земля круглая, рано или поздно встретитесь :)
Прощай free-pvp и ганк врага на каче!
А что именно интересует Вас в тюнинге JVM? Инструменты мы используем стандартные — jvisualvm, Java Mission Control (Flight Recorder жжёт). Плюс парсим логи gc, чтобы смотреть постфактум, что и как.
Настройки тоже общеизвестные — хип, янген, CMS с выключенным IncrementalMode. Еще LargePages используем.
Я просто на JVM больших вещей не писал с момента смерти Sun, было интересно узнать, может быть что-то новое появилось. Спасибо за ответ!
когдато я сам участвовал в разработке эмулятора сервера world of warcraft
вижу все те-же решения что и в wow
1) guid-ы, всё имеет свой гуид, даже небо, даже камень
2) сервера максимально раздроблены, логин сервер, аккаунт сервер, рилм сервер, чат сервер, ворлд сервер
когда я изучал netty, написал себе некое подобие такого сервера, github.com/TERRANZ/universal
для простоты я сделал фронтенд сервер, который занимается роутингом потоков между серверами и игроками
спасибо за идею с модулями, сам бы я до такого не догадался!
У нас, кстати, GUID-ы почти не используются. Слишком длинные :) Адреса у нас умещаются в int-ы.
Интересно, как быстро у вас int переполнится при игре 100 тысяч человек и вызовет коллизии в id?
Мне тут коллеги подсказали, что я наврал и у нас не int а long. В любом случае в каждой игровой механике своё пространство адресов.
2) сервера максимально раздроблены, логин сервер, аккаунт сервер, рилм сервер, чат сервер, ворлд сервер

Так и на официальных так выглядит тоже. Хорошо видно при наплывах народа.
Эх. Когда же уже научатся делать ММО с большим открытым миром, а не эту разбивку по локам и каналам… Ева не всчёт.
Сколько у вас хотябы лимит намечается на 1 локацию? Например осады, если они там вообще будут.
Большой открытый мир наши дизайнеры не заказывали. Если мнение, что в нём играть не так уж и интересно. Люди любят играть, а не бегать от замка к замку. Но это лучше не со мной обсуждать :)

Ева как раз в счёт. Ева показывает, что происходит если сделать большой мир. Когда начинаются эпичные сражения, тормоза неизбежны просто алгоритмически. Приходится придумывать замедление времени и другие некрасивые хаки.
И про каждое такое событие активно трубят везде где только можно даже люди не имеющие к игре отношения.
Да и это риторический вопрос был. А вот на вопрос про ориентировочный лимит карты, я так понимаю, ответ дать не можете? Тот же сервер аион вполне нормально тянул осады с участием более 1000 человек и ивенты когда почти весь онлайн сервера был в одной локе, а вот клиент на СЕ1 уже не очень)
некоторые эмуляторы wow сервера тянули до трёх тыщ человек в одном мире
В мире, но не в одной точке.
У нас есть массовое ПВП, но я не знаю могу ли я уже публично называть цифру сколько там будет людей.

Сами же отвечаете на свой вопрос… ) На сервере сделать можно при очень большом желании. Но клиент всё равно не отрисует, если на срежет графику в ноль. Будет медленно и не красиво. А у нас игра про то, чтобы всё бегало быстро и красиво, и боёвка очень динамичная, как в мортал комбате. Не думаю, что можно просто сделать мортал комбат на 1000 человек :)
Вот так, кстати, выглядит «пвп на 1000 человек».
Как игрок скажу, что так даже удобнее играть. Куча мельтешащих тел только мешают оценивать обстановку, а разноцветные надписи весьма наглядны и позволяют ориентироваться. А тут и все меточки видно, и кто куда бежит и тд и тп.
И тормозит именно из-за движка не предназначенного для такой массовости + не каждый интернет канал выдержит такой поток данных.
Я тоже в Quake играю с r_picmip 5 :) Но не все этого любят.
Дело не в качестве графики, а в количестве информации.
В небольших боях визуальное отображения игроков играет большую роль: видно кто кого атакует, по анимации понятно какое умение использует и что лучше предпринять и тд. В больших боях это всё лишнее и только мешает — достаточно видеть куда перемещается «зерг», метки на важных игроках и команды своего лидера.
С квейком особо не знаком, но так понимаю что различия будут только в виде «вместо красивых воинов в сверкающих доспехах серые болванки». Что, всё-таки, совершенно из другой области чем пример на видео выше и своего рода способ получения игрового преимущества.

Что-то совсем от темы ушли.
количество информации тоже можно регулировать, в том же вов есть возможность в один пакет уложить до 64 пакетов и сжать zlib-ом
можно в одном пакете движения задать весь путь
> Дело не в качестве графики, а в количестве информации.

Не вижу информации, вижу кучу мельтешащих разноцветных буковок.

Количество информации — это как-то так
Ну это только пока канал в интернет у среднего пользователя тормозной (в смысле задержек и пропускной способности).
Как только появятся гигабитные каналы в каждом доме и пинг до серверов упадет до 1-2мс максимум, все будет Ок. К тому моменту и серверное железо подтянется, сможет все это переварить.
Вопрос только когда это произойдет).
Ну вообще-то, я об этом прямо и написал.
Минимальное время путешествия сигнала на другую сторону Земли 133 мс, и это не считая 33 мс лаг на отправку и обработку сигнала на клиенте и сервере = физическое ограничение 200 мс.
Как только научатся запускать сервера в ядре Земли можно будет ожидать лаг «сети» 43 мс.
И кстати да, скорость распространения сигнала в современном оптоволокне 69% от скорости света.
Для витой пары категории 7 или 7A это 80% от скорости света, хотя уже сейчас испытывают волокна с полой сердцевиной дающие 99.7% скорости света.
Ещё задержки на роутеры, сетевухи и т.п.
Лаги при том что есть дополнительная задержка на передачу пакета, обработку железом, серверный тик для обработки данных, клиентский фрейм на отрисовку 30 раз в секунду, задержка при синхронизации кадров (не у каждого стоит nVidia G-Sync).
Про задержки при передаче можно почитать здесь quik.ru/depot/seminar2014/dbabur_2014.pdf
И какое это отношение имеет к отрытому миру игры без каналов и разбивки на локации?
Ну и опять возращаемся к локальным серверам.
На лекции много говорилось на тему «почему не JSON» и вдруг перешли на JSON :)
На лекции в Технопарке?
JSON не используется в ресурсной системе. В JSON представлены некоторые данные, которые нужно хранить в базе. JSON занимает меньше места, что для базы важно. Каждому формату — своё место :)
UFO just landed and posted this here
UFO just landed and posted this here
Долго ждал когда мне зададут этот вопрос.
Отвечаю: я передумал :)
Надоело писать конвертеры для бинарных сериализаторов. При простых изменениях JSON может прожить без конвертеров.

Оказалось, что хранить в базе большой JSON это плохо, но не так уж и плохо как я ожидал. Так что решили попробовать пока так.
А как же скорость сериализации/десериализации? А как же объем данных. Выигрыш в несколько байт на одном сообщении, может значительно сократить затраты при объемах в миллионы подобных сообщений.
Каких сообщений? В JSON мы преобразуем некоторые данные прямо перед сохранением данных в базу. И десериализуем сразу после того как их оттуда загрузили.

Или вы о чём-то другом говорите? Нигде больше JSON-а у нас нет.
Мне кажется, вы немного лукавите. Фактически, ваш мир не один большой на 100 тысяч человек, а на самом деле разделён на локации, которые к тому же лимитированы по количеству игроков, и для каждых n игроков создаётся «копия» этой локации, и игроки из одной копии не видят и не слышат друг друга. Верно я понимаю?

Мне интересно, а не думали вы в Мэйл.Ру о создании по-настоящему бесшовного мира? Без любого разделения, то есть все игроки в одном месте видят друг друга и взаимодействют друг с другом, а резкого перехода между нодами нет? На сколько я знаю, ни в одной трёхмерной и популярной MMORPG так ещё не делали из-за высокой сложности.

Отрадно, что вы используете Java. В ваших лекциях есть интересная и полезная инфа лично для меня. Люблю всегда говорить, что Java — отличная штука для серверов, «вот смотрите, сервер аллодов на Java!»
Один большой бесшовный мир это слабоиграбельно. Достаточно посмотреть на центральные города в том же WOW — пестрит в глазах и никакой видяхи не хватит чтобы всё это отрисовывать.
Ну с этим сложно поспорить, но это всё-таки проблема гейм-дизайнера, а мне интересны мысли программиста на эту тему.
тут всё будет упираться в раму и процессоры
посмотри хотябы на майнкрафт, вот тебе безшовный мир
Я же не говорю о том, чтобы поднимать сервер на 100 тысяч человек на одной машине — это абсурд.
Со стороны программиста здесь O(n^2), масштабирование на 1000 машин и больше вызовет рост нагрузки на синхронизацию, поэтому линейный прирост только за счет железа не получится достигнуть. Ваш КО.
Я и не говорю о простом распараллеливании на 1000 машин. Такая идея должна быть глубоко заложена в архитектуре.

Ну если например опустить необходимость поддержки 100 тысяч игроков в одном месте, что совершенно не оправданно с точки зрения гейм-дизайна, то мне кажется очень решаемой идея с плавными переходами между локациями.
А кто запретит плавно собраться всем в 1 локации? :)
Никто, но это лишь одна часть проблемы же :)

Я же не говорю о том, что вот почему вы не запилили совсем бесшовный мир, ваше решение не крутое и так далее. Мне с профессиональной точки зрения интересны разные мысли по этому поводу, так как я себе ставлю в будущем цель придумать что-то подобное, чтобы без швов и без лагов на 100 тысяч человек. Пока что идей не очень много :)
Очень много зависит от того что хочется получить на выходе, возможно введение локальных ограничений и использование особенностей мира позволит частично решить проблему, например:

Больше 3 не собираться — рассчитываем пересечение между объектами, не даем объектам пересекаться. в результате чего 100000 человек не смогут собраться в 1 точке, а будут более менее равномерно распределены по «поверхности»
Минусы: затраты на расчет коллизий

Моя хата с краю — добавляем радиус обзора, заранее будет известно максимальное количество объектов в зоне видения, зону обзора можно поделить на видимую и эффективную (то что влияет на персонажа). Для FPV это может быть 180 градусов обзора, в 2D это может быть видение по лучу.
Минусы: нужно хранить угол обзора

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

Есть еще мысли, но в любом случае получаем кучу краевых эффектов.
Спасибо, полезная информация чтобы задуматься :)
виртуальный омон не позволит собираться компаниями больше 3-х орков!
плюс, границы, визы, платная парковка, фейс контроль. В реальности нужно смотреть почему и как где-то собираются миллионы, а где-то не более определенного количества.
Мир на 100к, но играть вместе нельзя. В танчиках ведь нет шардов. Все могут играть со всеми.

Бесшовный мир у нас был в Аллодах на самом деле. Одна карта была сразу на нескольких серверах… Оказалось технологически сложно и игрокам мало полезно.

В любом случае это вопрос в первую очередь гейм дизайна. Они считают, что открытый мир не нужен, по крайней мере в нашей игре.
«Бесшовный мир у нас был в Аллодах на самом деле»

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

А вот решения, что делать если все внезапно соберутся в одном месте, у меня до сих пор нет…
Такого решения ни у кого нет :)

Как избавится от этого никто не знает.

for(Avatar av1: allAvatars)  {
   for(Avatar av2 : allAvatars)  {
     replicate(av1, av2);
   }
}
Решения нет, а проблема есть. У нас, например, изменяемый мир, который является большой и важной частью геймлея, и игроки в основном взаимодействуют через него. Я не могу просто разделить игроков на два мира, он у них должен быть общий. Хотя если задуматься, то наверное могу, а синхронизировать не самих игроков и мир, а только мир…
Ага. Идёшь ты такой по дороге и вдруг… БАЦ Вокруг тебя дом построили.
P2P? Объединять игроков по территориальному признаку и, если станет совсем плохо, начать отсылать полную инфу 30% игроков, а остальные должны её получить через вторые руки. Через третьи, если совсем смерть. Позднее запросить логи у второй категории и устроить выборочную проверку на вшивость. Для PVP-сражений не годится (см. Demigod), но, хотя бы уж, поможет с провисаниями в Лимбе, когда неписей нет, игроков нет и, скорее всего, тебя сейчас выкинет в главное меню.
Не взлетит.
— программировать сложно
— коннектить игроков p2p через фаерволы, модемы и т.п.?
— p2p не для реалтайм распространения инфы. пинги будут весьма большими.
— можно читить, фильтруя траффик который посылаешь другим.
— придётся засветить ипшники игроков друг другу.
Ну, слово «реалтайм» и так мало подходит к
неписей нет, игроков нет и, скорее всего, тебя сейчас выкинет в главное меню.
, читеров, по логам, можно наказать постфактум, а запретить светить свой IP можно одной галочкой в настройках. Проблем, скорее всего, возникнет сильно больше, но конкретно из этого списка совсем нерешаемой со стороны сервера можно назвать только вторую.
— Не очень понял про наличие неписей и т.п., но в любом случае добавление новых этапов пересылки обновлений увеличивает пинг и ухудшает боеёвку.

— Не понял как искать читеров по логам. Я с читерским клиентом могу просто «тормозить» и передавать пакеты другим пирам с большой задержкой. Или не передавать вовсе. Или рвать соединения. Формально это не читинг.

— Если запретить «светить ип», то как пользователи будут друг с другом коннектится?
— Я предлагаю такую штуку использовать только в горячих точках, типа тех же столиц фракций. Если выбирать между «с лагами, но дойти до квестового непися и суметь сдать квест» или «пойти гулять на улицу и социально развиваться с другими детьми, пока не перестанет твориться дикий ад», то предпочитетельнее первое. А если смотреть не только на вашу игру, а глобальнее, то и даже для боевки типа Евы Онлайн задержки могут особо ни на что не влиять. Главное — оставаться онлайн и быть в курсе дел.

— Клиент посылает серверу сообщение «Чувак, я могу передавать вместо тебя сообщения игрокам с ID 124 2352 и 23542. Средняя задержка — 10 миллисекунд, связь устойчивая». Сервер передает этим игрокам сообщение, что они могут подключаться к серверу-добровольцу и слушать его. Если оказалось, что после этого они десять секунд втыкают в пустой экран, то стучимся обратно, обманщик записывается в серый список. В серый, а не черный, потому что еще неизвестно, кто врет. Если читер отсылал что-то, да не то, то это тоже можно проверить.

— Конкретно параноики коннектиться ни к кому и не будут. Вопрос комфорта. Если дорожишь анонимностью, то просто не ходи по горячим точкам, пока локацию штормит.
Как Вам такое решение квадратичной сложности.
Делаем понятие агента игрока. Он крутится на специальном сервере агентов, один такой сервер хостит несколько агентов. Клиент коннектится по TCP/IP непосредственно к агенту, а не к локации. Агент – это серверная часть, потому доверенная. Когда агент заходит на локацию, то он передает локации сообщение, что он пришел. Локации регистрирует его, и передает всем зарегистрированным агентам идентификатор новичка, а новичку, список всех агентов на локации. Аналогично при уходе агента с локации.
Когда аватар выполняет действие, анимацию какую-нибудь, перемещается, то посылает сообщение своему клиенту и всем другим агентам в списке, чтобы они послали информацию уже своим клиентам. Таким образом для сервера, где хостится агент — это линейная задача, не квадратичная, а количество серверов можно масштабировать.
Многие проверки может делать сам агент. Например, проверить, чтобы аватар не прошел сквозь стену, для этого агенту нужно просто иметь локальную копию карты.
Чтобы игроки не проходили друг через друга они могут послать запрос на перемещение серверу, где хостится локация, и только получив ответ начать перемещение. Локацией кстати может быть достаточно маленькая площадь бесшовного мира или большой карты, тогда агент игрока бы работала бы с данной и соседними локациями. Причем можно сделать чтобы в локацию физически не вошло бы много игроков. В зависимости от карты агенту бы приходилось работать со списком из например 9 локаций на равнине, или 3 локаций в прямом коридоре. В том смысле, что списку игроков из этих локаций ему нужно было бы передавать свое состояние. Размер локации – это расстояние выстрела/видимости на клиенте. Ну и сообщение должно формироваться не таким циклом:
for(Avatar av1: allAvatars) { for(Avatar av2 : allAvatars) { replicate(av1, av2); } }
А сначала формируем тело сообщение, а потом сформированный набор байт рассылаем всем агентам в списке. Тоже, экономия процессорной мощности.
Ну и само собой, сервера локаций тоже могут хостится на разных железных серверах.
Вот Вам и бесшовный мир, и зависимость, которая хоть и немного выше линейной, но точно не квадратичная. По край не мере позволит собрать на одной карте множество игроков.
— Подвожу краткий итог предложения:
— Рассылку сообщений игрокам можно распараллелить и поручить другим серверам, для которых это будет линейной задачей. Конечно в общем задача в этом случае будет квадратичной, но выполнится быстро.
— Рядом с игроком не должно физически помещаться слишком много персонажей. Это естественным образом уменьшит квадратичную сложность задачи.
Отвечу в обратном порядке :) Андрей, если что, поправит.
Рядом с игроком не должно физически помещаться слишком много персонажей. Это естественным образом уменьшит квадратичную сложность задачи.

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

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

То, что вы называете агентом — это и есть аватар. Аватар — это «проявление клиента на сервере» :) Аватару, и его данным, мы доверяем. Мы не доверяем данным, которые приходят с клиента. Эти данные сперва проверяются и только потом применяются на аватаре. С последующей отправкой изменений на клиент.
Один сервер игровой механики содержит в себе сразу несколько потоков, способных обслуживать достаточно большое число аватаров, расположенных на разных картах.

И да, то, что скрывается за функцией «replicate» — это «сформированный набор байт», высылаемый каждому аватару и содержащий данные как о собственном аватаре игрока, так и данные об аватарах его окружающих.
Ок. Я вероятно слишком уделил внимание мелочам в моем сообщении. Основная мысль сообщения: Можно сделать так, чтобы в одном городе было множество игроков, и при этом не тормозило бы на сервере.
Я как понял у вас аватар — это просто класс, который хранит данные персонажа. Его сериализуют и передают с одной локации на другую. А сам клиент коннектится к локации (игровой механики, которая соответствует одной локации). Поэтому на один неделимый сервер возникает большая нагрузка. Если же коннект производить к самому аватару, а аватары будут работать на отдельном от игровой механики сервере, то нагрузка будет для данного сервера линейна.
Кроме того. По поводу передачи данных. Задача то какая. У нас есть N клиентов, и каждому из них надо передать абсолютно одинаковый набор байт, т.е. информацию об N аватаров. Можно организовать что-то типа udp broadcast. Ну, например, есть игровая механика, к игровой механики присоединено 100 серверов рассылки сообщений. К каждому серверу рассылки сообщений присоединено по 1000 игроков. Всего 100 тысяч игроков на локации. Серверу механики нужно собрать информацию о 100 тысячах аватаров в один пакет, послать его 100 серверам рассылки сообщений, и каждый из этих серверов пошлет еще 1000 клиентам этот пакет.
То есть какая работа проделывается: сначала линейная работа по сбору данных в один пакет. Потом линейная задача по отсылки этого пакета каждому клиенту. Количество трафика – квадратично и распределено. Нагрузка на каждый отдельный железный сервер линейна почти.
А если разместить дата центры в разных частях мира, чтобы клиенты коннектились к ближайшим серверам рассылки сообщений, то вообще можно еще и с пингом порядочно бороться.
В общем, от каналов отказываться не целесообразно с экономической точки зрения. Но с таким подходом можно повысить количество человек в определенной локации, например, разрешить нескольким тысячам человек находиться на эпичном поле боя.
Под уменьшением квадратичной сложности я имею в виду следующее.
Разбиваем карту на клеточки. Допустим, в каждой клеточке может вместиться максимум 10 персонажей. Каждый персонаж может взаимодействовать только в пределах своей клеточки и соседних. То есть 9 клеточек на плоскости. Итого в самом сложном случае каждый персонаж будет взаимодействовать максимум с 90 персонажами.
Итого сложность алгоритма не N*N, а X*N, где X – максимальное число персонажей, которое может находиться рядом с игроком, а N – число персонажей, обрабатываемых на сервере. Т.е. с каждым новым игроком нагрузка вырастает линейно, на величину X
Еще иначе можно сказать так. Отображаем игроку только самых близко находящихся X персонажей. Если рядом с ним уже толпа из сотни человек, то он не заметит, что где-то там кого-то не видно (можно еще туман усилить). А если дополнительно игровым дизайном ограничить нахождение такого числа человек рядом с ним, то можно спокойно делать бесшовный мир с огромным количеством игроков.
вы сами себе противоречите. То вы говорите — «Размер локации – это расстояние выстрела/видимости на клиенте», а тут — «в каждой клеточке может вместиться максимум 10 персонажей». Вы же про одно и то же сказали в этих фразах. Так не пойдёт.
Признаю, что выражаю мысли не совсем корректно. Поясняю.
Разбивать на мини локации нужно, чтобы
1. Облегчить расчет коллизий на сервере между динамическими объектами.
2. Чтобы определить набор ближайших персонажей, и передавать только первую сотню (или другое количество) из них, а других скрывать в тумане, или отображать упрощенно еще одну-две сотни.
Если коллизия, то клеточки должны быть маленькими. Так как все равно нельзя столкнуться с тем, кто в 5 метрах и больше. То есть если столпилось несколько тысяч человек в одном месте, столкновение на самом деле проверяется только с теми, кто в этой же и соседней клеточке, а это не так много персонажей.
Видимость и дальность выстрела зависит от механики игры. Я сказал «допустим» 10 человек (это выстрел на три шага получается). Если механика предполагает дальнобойные выстрелы, и персонаж видит далеко, мы можем по спирали анализировать ближайшие клеточки, уже не 9 штук, а больше, пока не получим сотню персонажей, или пока не достигнем предела дальности видимости. В нормальной ситуации, когда персонажей не много, игрок будет видеть далеко, но если нагрузка увеличивается, то появится туман, который сделает часть юнитов более размытыми, а часть вообще невидимыми.
Опять же, туман может появляться, только когда сервер не справляется с нагрузкой, если справляется, то может передавать всех без ограничения.
вопрос на миллион — что чаще происходит — проверка на коллизии, или показ соседей? как бы ваша оптимизация не превратила игрока в
ёжика в тумане
, который видит пару десятков игроков вокруг. Вы предлагаете одну квадратичную сложность заменить другой.
Если цель — обработать десятки тысяч игроков на одной площади, то ваш подход может быть рассмотрен, но использовать тот же подход в обычном режиме с несколькими десятками/сотнями игроков рядом — слишком сложный оверхед.
Туман как раз ограничивает по количеству человек, так что он будет ёжиком, который видит не пару десятков, а максимальное число игроков заданное по производительности. Для Skyforge такой максимум 250 игроков. Просто если игроки решат устроить флешмоб, и собраться в одном месте, то будет туман, и игрок будет видеть только ближайшие 250 игроков.
По поводу коллизий и показа соседям. Вопрос не однозначный с точки зрения сервера. Показ соседям – это может быть только изменение состояния: сообщение что персонаж начал двигаться из пункта А в пунтк Б. Начал анимацию удара и т.д. Коллизия происходит при расчете движения. В любой момент два движущихся тела могут столкнуться. Все зависит и от механики игры и от способа реализации. Я не вижу однозначного ответа на данный вопрос.
Данная оптимизация полезна не только для густонаселенных карт. Она уменьшит трафик и просто на больших картах, так как персонажи за пределами области видимости клиента не будут ему передаваться.
Кроме сервера есть еще и клиент, которому нужно обработать и отрисовать присланные изменения. Когда в одном кадре находится толпа аватаров, нагрузка на клиент резко возрастает.
И да, на клиент изменения реплицируются не для всех сущностей, а только для тех, которые попадают в радиус репликации (чем-то похоже на ваш «туман»), зависящий от текущей нагрузки на сервере.
Необходимость разбивать мир на отдельные карты вызвана так же требованиями по памяти в клиенте, чтобы бегать по миру плавно, нужно держать мир «наготове». Вспомните, даже в одиночных играх локации всегда разделены.
>На сколько я знаю, ни в одной трёхмерной и популярной MMORPG так ещё не делали из-за высокой сложности.
EVE online… правда оно про кораблики
и… если SecondLife можно считать трехмерной и популярной MMORPG… то там спокойно можно по миру гулять/летать… (про то как это на практике выглядит там… вопрос другой)

> EVE online… правда оно про кораблики

Таки не совсем бесшовный, поделён на отдельные солнечные системы, а внутри каждой системы есть отдельные зоны видимости (гриды), которые динамически расширяются, но объединяться не могут. В итоге корабли могут быть друг от друга в 1 км, но друг друга не видеть, ибо в разных гридах находятся. Чуток прополз — увидел того кто за гридом прятался, но перестал видеть тех кто в твоём бывшем гриде остался.
Интересно. А чат будет общий для всех игроков мира? Или опять же в рамках канала?

P.S. Пригласите на закрытую бету? :)
Чаты вроде как разные есть… Для зоны, для гильды, для группы, по интересам и т.п. Есть ли чат «для всех вообще» я не помню.
Хорошо, а чат для зоны работает в рамках одного канала? Или всех каналов в данной зоне? То есть можно ли искать игрока для совместного прохождения по всем каналам?
Большая часть приключений идёт через кнопку «хочу побегать вооон там вот». Тебе подберут напрника автомагически :)

Чат в рамках канала, если я ничего не путаю.
Ссылка на запись на бету есть в статье :)
«Клиент в руках врага»
А как у вас дела обстоят с умениями невидимости? Все много про это пишут, а на деле почти всегда оказывается, что на клиент просто отправляется пометка, что игрок невидим и игра определёнными классами сводится на нет различными «радарами» и недоработками клиента.
Я не помню есть ли у кого-то эффект невидимости, эффекты и классы я не пишу. Но на вскидку выглядит так, что временно перестать реплицировать игрока другим клиентам довольно просто. Так что если невидимость у нас есть, то она честная.
> а на деле почти всегда оказывается, что на клиент просто отправляется пометка, что игрок невидим и игра определёнными классами сводится на нет различными «радарами» и недоработками клиента.

В еве ничо не отправляется, если не видишь, значит не видишь, пока мимо бобра в 2 километрах какая-нибудь гадость не пролетит и не вышибет из невидимости, или он сам не напорется при маневрировании на какой-нибудь болтающийся в космосе труп, который у него в овервью не отображается.
У вас на скрине довольно много кода на JavaScript. Расскажите, пожалуйста, зачем используете? Я просто тоже использую JavaScript-скриптики на своём сервере, интересно послушать об опыте других. Если вызываете их из сервера, то используете ли вы стандартный JS-движок (Rhino) или какой-то другой, если другой, то почему?
JavaScript используется для внутриигрового портала и для администраторских тулзов с вёб интерфейсом.
А внтуриигровой портал и веб-интерфейс администрирования тоже являются частью сервера?
Ну в некотором смысле да. Только про них я тут ничего не писал :)
Спасибо за статью. А теперь пара вопросов :)

1) Функционал сущности хранится в HashMap, а чем гарантируется то, что у сущности например есть функционал «здоровье» при «ударе»? Упомянутая Ресурсная система?

2) Стоим мы с другом и бьем вместе моба, при моем ударе происходит «запрос на удар» ==>… серверная часть… ==> ответ с сервера. В этом ответе будет обновленное состояние моба? Т.е. я узнаю о ударе через ответ на запрос, а друг — через репликацию окружающего мира? Если да, то не может ли быть проблем, допустим, при пвп с большим кол-вом человек?
1) Хороший вопрос. Это как раз основная проблема этого подхода. Функциональности может не быть. Поэтому если функциональности нет, то это надо как-то обрабатывать. Кидать эксепшн и удалять аватара или репортить в лог.

2) В ответ на запрос вы узнаете что удар прошёл и нанесено столько-то то дамага. Изменение полоски с хэлсом над мобом обновляется через реплику и у вас и у друга.

Проблемы возникают не при большом кол-ве человек, а при высоком пинге. Тогда ответы от сервера могут прилетать через 1-2 секунды после удара, и игрок не будет чувствовать от боя фидбека. Задержка в обновлении хэлса, это мелочь по большому счёту.
> Поэтому если функциональности нет, то это надо как-то обрабатывать. Кидать эксепшн и удалять аватара

Стукнул случайно по камушку вместо моба — получай дисконнект?
Интерфейс не даст ударить по камушку. Но вот если сломал клиент и всё-таки ударил… То дисконнект.
UFO just landed and posted this here
Не, это не миксины. Это запчасти в очень широком смысле. «Ноги», «Поверхность», «Таланты», «Периодическая чекалка чего-то там» и т.п.
Подскажите, а у вас присутствует какая-либо система приоритетов для каналов?
Например, друзья, могут оказаться на разных каналах (не будучи объединены в группу).
Мы стараемся игроков из одной гильдии или из одной группы сливать в один канал. Такой эверистики для просто друзей нет :)
UFO just landed and posted this here
Да, сервер игровой механики открывает ряд портов, к одному из которых клиент устанавливает соединение. Но сами сообщения — это отнюдь не пары «ключ-значения». Это могут быть как сообщения об изменении определенных параметров системы («обновление реплики»), так и просто игровые события, не содержащие никаких данных. Сам же протокол — свой.
UFO just landed and posted this here
Свой сетевой слой удобнее, потому что его можно подхачивать на всех уровнях и заставлять работать именно так, как надо нам. На большом проекте проще написать своё, чем заставить 0mq выполнять то, что хочется с максимальным перфомансом. Можно впилить шифрование, компрессию, поиграть с объемом генерируемого мусора и т.п.
В качестве транспорта мы используем TCP, хотя это холиварная тема, т.к. кто-то предпочитает UDP. Свой же протокол — это верхние уровни. Хотя меня не покидает ощущения, что я не понял Ваш вопрос :)
Насчёт того, почему не используют готовые решения — у меня ответа нет. Когда я пришел на проект, протокол уже был. Может быть кто-то из коллег ворвётся в тредик и даст ответ. Но скорей всего, будет тоже самое, что и про akka :)
Не так сложно сделать свой протокол уровня приложения, по сравнению с получаемым от него профитом. ИМХО, гораздо важнее чтобы каждый переданный байт был действительно необходим, чем сэкономить десяток часов программирования. В конце концов, каналы не резиновые, производительность тоже, а задача не сложная.
UFO just landed and posted this here
Стоит отметить, что есть общение не только клиент-сервер, но и сервер-сервер. И если клиент-серверный протокол мы революционно трогать в ближайшее время не планируем, то в сторону protobuf для сервер-серверного взаимодействия мы смотрим. Потому что появилось требование обратной совместимости при обновлениях для отдельных частей релма.
UFO just landed and posted this here
Не вводи народ в заблуждение :) protobuf у нас если и будет то сбоку, для взаимодействия сторонних сервисов (пусть даже и нашей же разработки) с рилмом.
UFO just landed and posted this here
UFO just landed and posted this here
Да, такие вещи приходится писать свои. Мне кажется, что даже вокруг «коробочного» решения всё-равно придется сделать гирлянду из логов и «ифов». Потому что «коробочное» решение является таким, как правило, только на старте. При росте сложности системы и повышению требований время, затрачиваемое на модификацию «коробочного решения», начинает резко расти.
Тот же google protobuf хорошо упаковывает данные, но не волнуется о надежности доставки

Правильно, ибо это не его ума дело. Он ничего не знает о транспорте через который работает и соответственно не может ничего гарантировать.
Не надо смешивать все в одну кучу, мухи отдельно — котлеты отдельно.
Сообщение это id класса + поля класса сложенные в байтовый поток.

Допустим есть класс
class A  {
 byte x=3;
 short y=5;
}


тогда в мессажка будет выглядеть как #1F030005
где 1F это id классаб 03 — это значение X, 0005 это значение Y

Добрый день, Randll! Вопрос не по самой игре, а по коду. У вас встречаются аннотации NotNull. Я так понял, это аннотации IDEA, которые на этапе компиляции говорят, что тут не может быть null? Если да, то я такие штуки использовал только в академических целях. А как они на большом проекте (почти 2 миллиона строк на Java, как вы сказали)? Во всём коде пишутся эти аннотации? Не слишком ли напрягает это аннотирование и вообще стоит ли оно того?
Аннотации @Nullable/NotNull это аннотации IDEA. Это лучшие аннотации в мире. Они спасли от невероятно количества багла. Писать их совсем не сложно, alt+enter и идея сама их дописывает. Однозначно оно того стоит. Даже в маленьких проектах.
UFO just landed and posted this here
Всё равно чекаем и кидаем эксепшн и это правильно. Сегодня мы точно знаем, что будет NotNull, но завтра кто-то что-то где-то отрефакторит и привет NullPointerException.
Спасибо за статью, очень интересно. Есть вопрос о том, что происходит на клиенте, в то время как сервер обрабатывает сообщение об убийстве собачки. Отображает ли клиент полет фаербола или удар до того, как он подтвержден и обработан сервером?
На клиенте есть некоторое магическое читерство и предсказание, в результате которого мы стараемся совместить анимацию удара и отлетающий урон. Если совсем грубо говоря, то клиент в большинстве случаев ждёт подтверждения от сервера и только потом рисует анимацию. Это может быть подтверждение того, что фаербол полетел, а не того, что он долетел до цели. Иногда он начинает рисовать анимацию до ответа чтобы бой выглядел более динамичным. Но если сервер ответит, что удар не прошёл, анимация некрасиво прервётся :)
а код предсказания на клиенте и код обработки на сервере очень похожи или на клиенте только необходимый минимум без проверок и тд? хорошая ли идея выносить этот код в коммон модуль, который клиент и сервер могут шарить между собой?
Код разный. Кроме того, клиент на c++, сервер на Java. Кодобазу шарить проблематично :)
UFO just landed and posted this here
Чисто клиентская. Под wine врядли что-то будет.
Вот значит с платформами значит определились, а то в информации по ЗБТ это даже не упоминается.
UFO just landed and posted this here
Очередная анальная система защиты? А зачем, если у вас такой хороший сервер, который клиенту ни в чём не доверяет? Не, сами в такое играйте.
Кстати, у нас тут готовится статья про разработку игровой механики. Не про игровой дизайн, а про архитектуру и технические приемы. Если есть какие-то вопросы, то их можно задать в комментариях, а я их передам будущему автору.
Обещанного 3 года ждут? ))
Будет статья-то в итоге?
Да нет же, обещали техническую статью, а это геймдизовская статья.
А что если убрать ракурс с игрока и переместить его на мир. Ну т.е. не сокруг игрока обрабатывать радиус (при N игроках требуется N*N обработок и пересылок данных), а поделить мир на радиусы и обрабатывать их? тогда единожды обработанный радуис рассылается всем N игрокам. И проблема с N числом игроков в одной точке переходит от квадратичной к линейной.

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

И еще вопрос, в вашем мире мобы, стулья, вода и все прочее (с чем игрок может взаимодействовать и что может так же взаимодействовать с игроком) входит в тот лимит канала о котором вы упомянали?
Т.е. если например на карте очень много интерективных объектов, снижается ли тот лимит игроков которые могут одновременно находится на этой карте/канале?
«И проблема с N числом игроков в одной точке переходит от квадратичной к линейной.»
Не переходит. Каждому игроку надо переслать сколько-то информации. И количество этой инфы пропорционально количеству аватаров, которые игрок видит. Количество инфы в вашем радиусе увеличивается если аватаров становится больше.

Мобы и объекты на карте в лимит не входят. У нас просто есть квота для дизайнеров, сколько мобов они могут расставить на карте.
Статья супер. Спасибо огромное.

1) Не задумывались ли об использовании google protobuf при сериализации Java / C++? Что мотивировало написать свое решение?
2) Вопрос по «Занятная статистика». На Javascript написано немного-немало 70к строк кода. Для чего используется Javascript?
3) Интересно как у вас устроена система обновлений сервера. Например, найдена серьезная ошибка в сервисе игровой механики или аккаунт-сервисе. Будет stop the world всего сервера (всех JVM)?
1) Своё решение лучше, потому что туда удобно впиливать конкретно наши фишечки. Кроме того, protobuf требует создания описателя в отдельном файле, мы же генерим код для сериализации прямо по Java файлам. Нам так удобнее. Возможно мы будем использовать protobuf для общения с внешними сервисами.

2) Отвечал уже :) У нас внутриигровой фейсбучек и вёб админка.

3) Да. Тут про Аллоды forum.allods.ru/showthread.php?t=91938, у нас примерно так же.
3) It depends. В общем случае, да. Мы, конечно, стремимся минимизировать время простоя. Сервера должны уметь переживать смерть и перезапуск друг друга. Но для надежности и спокойствия лучше уйти на профилактику. Пусть и 10 минутную.
Какие-то фиксы (по слухам) на Java можно вообще HotSwap'ом накатывать :) Но, искренне надеюсь, до этого не дойдет.
Если я правильно понял, то с одной карты можно пешком дойти до другой. Если так, то как вы реплицируете игроков стоящих на границах карт друг другу, в случае если они рядом, но технически уже на разных картах.
Неправильно поняли. Переходы через телепорты.

В Аллодах реплицировали. Как? Ну точно также как и на клиент :) на удалённом сервере создаётся прокси аватар. В код основного аватара в сеттеры полей встраивается отсылаение реплики на к проксе.
Sign up to leave a comment.