company_banner

Как расправиться с читерами и не переписать весь код



    Несколько лет назад появился прототип игры War Robots (тогда она еще называлась Walking War Robots). Это был первый опыт Pixonic в жанре тактического PvP, поэтому многие будущие проблемы были заложены в коде изначально. Но несмотря на ряд трудностей (популярность проекта стремительно росла, небольшая команда не могла полностью изменить архитектуру игры в краткие сроки), нам в итоге удалось свести к минимуму количество читеров, а также исправить другие недостатки оригинального кода. Расскажу немного подробнее.

    Самая первая реализация WR не использовала авторитарный сервер — каждый из клиентов самостоятельно контролировал свои показатели здоровья и пересылал по сети их изменения остальным игрокам. Для пересылки сообщений мы использовали удаленный вызов процедур (RPC).




    Схематичное изображение отправки нового значения здоровья с помощью RPC при получении урона через Photon Cloud Server с последующей доставкой другим игрокам.

    Такой подход было легче реализовать с точки зрения архитектуры, так как он не требовал логики на сервере, а вычисления проводились на клиентах. В результате команде удалось быстро получить пилотную версию игры и оценить интерес аудитории.

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

    «Неубивашки»


    Проблему «бессмертных» игроков можно условно описать тремя ситуациями:

    1. Игрок испытывает проблемы с подключением к сети. В результате он просто «не видит» своих повреждений и не посылает обновленное состояние. Для остальных участников игры это выглядит так, словно попадание по цели проходило с задержкой, неполностью или вовсе отсутствовало в какой-то промежуток времени.
    2. Игрок намеренно обрывает свое подключение к интернету (например, переведя приложение в неактивный режим) и игнорирует входящие повреждения.
    3. Игрок жульничает другим способом и становится бессмертным.



    Существует несколько способов решения этой проблемы.

    1. Можно выискивать и банить читеров или автоматизировать их поиск по разным критериям (например, по среднему урону в бою). Для этого потребуется выстроить комплексную программную защиту, которая, исходя из поведения игрока и других аспектов матча, могла бы распознать нечестную игру.

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

      Мы думали о разных способах реализации этого подхода, также рассматривали вариант с запуском Unity в batchmod’е, но в итоге отказались от идеи, так как она требовала полностью переделать клиент-серверное взаимодействие в проекте.

    Тогда мы стали искать другой выход из ситуации, который свел бы проблему к минимуму.

    К чему же мы пришли?..

    Демократия




    Мы использовали ту же базу, что уже была в прототипе, но изменили один ключевой момент — здоровье игроков теперь контролировал сервер на основе всех поступающих к нему данных.

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

    Сразу стоит отметить ограничения такого способа. Он не работает для игр 1 на 1. Совсем. Если у двух игроков будет расхождение в показаниях — непонятно, какой из них говорит истину.

    Главный плюс — это было относительно «дешевое» решение, так как нам не пришлось глобально переписывать сетевой код и в то же время удалось решить проблему с «читерами».

    Алгоритм





    Фактически алгоритм нанесения урона условно можно разделить на 3 части:

    1. Регистрация урона каждым клиентом всех игроков и отправка этих показаний на сервер.
    2. Сбор показателей урона, агрегация, вычисление текущего здоровья жертвы и рассылка итогового значения всем участникам матча.
    3. Получение актуального здоровья с сервера.

    Более подробно это происходит так: каждый из клиентов отслеживает попадания по каждому игроку и регистрирует этот урон на сервере. На сервер отправляется RPC-сообщение с информацией о попадании в виде:

    В сообщении указаны ID жертвы, ID нанесшего урон, ID выстрела и сам урон. Стоит отметить, что в War Robots за каждым снарядом закреплен определенный идентификатор, который синхронизирован между клиентами.

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



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

    Разумеется, это решение не идеальное. Главной трудностью является необходимость синхронизировать ID каждого выстрела (что является отдельной проблемой). Но вот что произошло с жалобами игроков на читеров после ввода новой системы подсчета урона:


    Синий график — количество жалоб игроков на читеров.

    Конечно, работа над WR продолжается, но главное, что мы вынесли из этой истории — не стоит всегда опираться на готовые ответы из учебников. На каждом из этапов — от прототипирования до удержания существующей базы игроков — мы исходили из текущих задач и потребностей.

    Если бы всё сразу делали «как надо» несколько лет назад, некоторых ошибок можно было бы избежать, но сама игра могла бы просто не выстрелить, а ресурсы были бы потрачены.

    Pixonic

    143,86

    Международная компания по разработке мобильных игр

    Поделиться публикацией

    Похожие публикации

    Комментарии 70
      +13
      При кворуме клан читеров всегда побеждает. Причём над противниками можно прям издеваться.
        +3

        только хотел написать: собираешь компанию читеров и по одному мочишь в сортирах честных чуваков

          +1
          Клан читеров, который бы начал издеваться над противниками не сложно вычислить. А будет ли он всегда побеждать зависит от размера кворума и от того как он собирается.
            0
            Тогда нужно голоса собирать поровну от каждой команды.
            +5

            Молодцы.
            Кстати, напрашивается ещё одно усовершенствование, которое позволит проводить пересчёты и при игре один на один: считать "показатель честности" игрока. Если в ходе игр регулярно видим занижение урона — снижаем показатель. А при расчёте итогового урона — более значимы данные от игроков с высоким показателем.

              +2
              Мысль интересная. Я бы развил ее в отдельный функционал в игре — оценка игроками соперников/союзников. Тут уже добавится и социальный фактор, который можно использовать. Если среди оценок будет фигурировать стабильно «читер» или не командный игрок, то делать выводы. Это должно усложнить жизнь как и читерам, так и ливерам и т.д.
                0
                Толи PUBG то ли Fortnite недавно стравливала читеров — в 200 рыльное поле боя попадали в основном читеры или заподозренные в читах и грызлись там на своих мапхаках, проваливаниях в текстуры и прочих дырах клиента.
                Но вообще верить клиенту это фуфуфу. Но серверсайд-обработка реализуема в стратежках и прочих слоупочных играх, но никак не в экшонах и тем более FPS.
                  +2
                  Ха-ха, все совсем наоборот. Именно в FPS серверсайд-обработка вполне реализуема из-за малого количества участников. А вот в стратежках общее количество юнитов просто заставляет использовать всяческие Lockstep.
                  +1

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


                  А еще показателю желательно быть лимитированным, типа от 50% доверия до 125%, и считать в среднем за последние N сессий, дабы избежать проваливания игроков с плохим коннектом в пучину негативной кармы, из которой они не выберутся даже если будут играть пару лет с нормального соединения.

                    +2
                    Согласен, что занижать геймплейный показатель ориентируясь на оценку других игроков не лучшая затея. Но можно объединять игроков со схожими оценками в одни матчи с возможностью реабилитироваться. Например ливеров с ливерами, читеров с читерами.
                      0

                      В любом случае можно алгоритмически выявлять "потенциально плохую связь" (потери всех пакетов, пинг) и "потенциально читеров" (получение аномальных значений в пакетах, потеря определенных типов пакетов), потому-что если объединять в матчах читеров и игроков с плохим коннектом, или просто игроков с плохим коннектом — получится еще более жестоко, хотя и очень весело.

                        0
                        Работа с комьюнити — это всегда самый страшный ужас разработчика онлайн игр.
                        Я играю в Лигу Легенд и могу описать до чего там эволюцилнировали систему чести. Все прошлые этапы эволюции описывать лень.
                        1. После каждой игры на экране появляется 4 картинки персонажей своей команды (игра 5 на 5 игроков), где ты можешь похвалить (в течение 30 секунд) одного игрока или за хорошую игру (GG) или за коммуникацию или «не терял духа» (все проигрывают, а он подбадривал).
                        2. После игры можно зарепортить игрока за фид, ругань и прочие непотребства (и читерство в тч). Не только своего, но и противника.
                        В результате получаешь очки чести, которые повышают твой ранг чести от 0 до 5. Все начинают со 2 ранга. Если часто репортятся, то теряют очки и опускаются ниже и лишаются чата, возможности играть с приятными людьми. Если репортов нет, то получают условно 1 очко. За похвалу 2-3.
                        3. За 3-4-5 ранг дают плюшки ввиде чемпионов на халяву (точнее осколков, которые можно собрать в полноценных дешевле, чем покупать новых).
                        Это заставляет игрокова быть вежлевее/честнее. Самых отпертых негодяев (даже суперумелых) вышвыривают на год. Просто банят все учетные записи.
                  +1
                  Не лучший вариант, но лучше так, чем никак. В случайных боях будет работать.

                  Более общее решение — считать контрольные суммы состояния игры и сверять их на сервере. Но это требует качественной реализации клиентской логики (должна быть строго детерминированной) и проблема с кворумом остаётся.
                    +4

                    У этого варианта минимум два минуса:


                    • Не работает на PvP (как вы писали в статье)
                    • Куча читеров может всех унижать (как писали выше в комментариях)

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

                      +1
                      В таком случае «служебный клиент» становится просто частью сервера. То есть этот подход не позволяет переложить расчеты на клиентов.
                        +2
                        Так получается, что расчет переложен на отдельный «микро-сервис». Насколько я понял, на сервер не хотели перекладывать обязанность подсчета, потому что пришлось бы менять протокол общения с клиентом. А так получается протокол остается старым, но при этом расчет происходит на сервере.
                          +4
                          Действительно было желание оставить протокол клиент-серверного общения без существенных изменений. В данном случае, если делать совсем честного наблюдателя на сервере в качестве «микро-сервиса», то придется и физику расчитывать на сервере. В таком случае можно уже подумать в направлении полностью авторитарного сервера, так как почти все условия для этого уже будут созданы.
                      +1
                      Правильно ли я понимаю, что каждый выстрел рассылается сервером по всем клиентам? В таком случае у каждого клиента уже есть его картина мира, в которой известно кто кому сколько урона нанес. А значит, голосование за размер этого урона кворумом не нужно и его можно выкинуть, игра от этого только ускорится.

                      Кстати, получившийся после выкидывания лишнего шага алгоритм называется Lockstep и часто используется в стратегиях.

                      Однако у него есть принципиальная уязвимость (которая у вас, видимо, есть тоже) — maphack. Поскольку без авторитарного сервера каждый клиент обладает всем состоянием игры — читер всегда найдет способ вывести себе на экран ту информацию которую он видеть не должен.
                        +2
                        Правильно понимаете, что каждый выстрел рассылается сервером по всем клиентам. У каждого клиента действительно есть его картина мира, и есть информация о том кто кому сколько урона нанес. Это была первая реализация WR. Проблемы начинаются когда какой-то клиент изменяет свою картину мира каким-либо способом, встает вопрос кому доверять. Это решается с помощью кворума сейчас.
                          +3
                          Так зачем кворум-то? Пусть сидит в своей картине мира если такой умный, остальные будут пользоваться правильной.
                            +1
                            Вопрос — когда на сервере отмечать игрока как «мертвого» и переставать посылать от него выстрелы другим игрокам?
                              +1
                              В тот момент, когда на сервере здоровье кончилось, отправить команду всем участникам матча на уничтожение «мертвого» игрока. Ничего не мешает для каждого игрока хранить начальное значение здоровья, потом накатывать изменения.
                                0
                                А если лже-клиент пришлет, что здоровье кончилось, хотя он не мог попасть по врагу? Сообственно, вы же автор топика, вы сами понимаете, что с тонким сервером «сидит в своей картине мира» врядли получится сделать — всегда возникнет куча вопрос.
                                0
                                А зачем переставать пересылать выстрелы-то? Пусть шлет, остальные клиенты эти выстрелы проигнорируют если в их картине мира стреляющий — мертв.
                                  0
                                  А какие результаты занести в таблицу лидеров? Сколько денег дать каждому игроку?
                                +2
                                Кворум нужен, чтобы определить какой урон в итоге нужно применить к игроку. У нас на сервере пока нет расчета физики (возможно в будущем придем к использованию упрощенной физики на сервере), так что приходится полагаться на клиент даже в таком простом вопросе как попал по противнику или нет. Соответсвенно либо придется доверять какому-то одному клиенту в плане расчета урона (использовать мастер-клиент), либо опираться на несколько мнений, что делаем сейчас. А так действительно, читер сейчас будет модифицировать только свой локальный мир.
                                  0
                                  А зачем тонкому серверу вообще доверять хоть кому-то? Каждый клиент доверяет только себе, а сервер вообще ничего не знает.

                                  Вот в конце матча его результаты можно уже и кворумом утвердить.
                                    +1
                                    Тогда у нас может быть масштабный рассинхрон в игре, который непонятно как компенсировать. В худшем случае все будут играть в свою игру и состояние игры будет неопределенно. Непонятно как определять кто кого убил в итоге. Боюсь в конце матча кворум уже может не помочь. Кажется проще/надежнее выбрать кого-то из активных игроков и назначить его главным рефери игры.
                                  +1
                                  Эх, если бы все было так просто. На деле, если все игроки будут самостоятельно симулировать весь игровой мир, а не только свои объекты, мы получим большую проблему рассинхронизации даже у честных игроков. Есть несколько причин, по которым это происходит. Во-первых, потеря пакетов. Во-вторых, недетерминированность игрового процесса. Рассчеты различаются, даже период игрового цикла нужно синхронизировать, иначе в перспективе могут быть проблемы. Еще есть проблема с погрешностью операций с числами с плавающей запятой. Более того, речь идет о Unity с кросс-платформенным рантаймом Mono — про детерминированный float можно забыть. Решить все эти проблемы для риалтайм игры, тем более 3D, намного сложнее, чем кажется, поэтому предпочтительно производить симуляцию объектов, которые принадлежат игроку, на его железе и отправлять результаты остальным участникам. В том числе и события в роде «в меня попали, я потерял 30 ХП.» Автор предложил улучшение в виде кворума, чтобы можно было определить кто есть кто и контролировать эти события. Я это к тому, что остальные не будут пользоваться правильной картиной мира, как вы предлагаете, просто потому что они не смогут ее просчитать с одинаковым результатом. В этом и заключается вся проблема. Пришлось бы синхронизировать состояния при расхождении, но опять же, кому тогда верить, что выбрать за эталон? Снова прибегнуть к кворуму?:) Возможно Вы имеете в виду только события выстрела и нанесения урона по игроку, а не движение игрока. Опять же, картина различается. Игрок пришлет всем информацию о том, что он выстрелил, а остальные по-своему рассчитают попал ли он или нет… В то время, как картина мира у всех своя. Какая бы ни была абстракция, рассхождения будут. Да и вообще, оба решения имеют те же недостатки. Мы не можем честно проверить, попал ли игрок по игроку без арбитра со своей симуляцией. Когда у нас две симуляции на разных машинах — это конец, в теории погрешности уже не миновать и не важно, какой подход вы выберите: «в меня попали» или «я выстрелил, посчитайте куда я попал,» потому что позиция противника в одно и то же время на разным машинах может различаться (как минимум в связи с особенностями сети), ровно как и его направление выстрела. С одной стороны, игрок может всем говорить, что никто в него не попал и, может быть, с его пингом он даже будет прав, хотя другие будут считать иначе. Все проблемы мог бы решить сервер, который симулировал бы игровой мир и ставил точки над i, но это чрезвычайно сложная задача. Более того, оно того зачастую не стоит, если у вас, конечно, игроки сами сервер не хостят ведь мы часто хотим разработать свою систему мультиплеера и монетизировать ее, в этом весь смысл. Если оно того стоит, то надежнее авторитарного сервера пока ничего не придумали. Я считаю, стоит приобщиться к консольному рынку, который, к тому же, является основным в игровой индустрии и забыть про нечестных игроков, ведь платформа закрыта. Чтобы ваша игра с такой сложной системой, которую еще нужно обслуживать имела смысл, она должна покрывать все расходы. Обратите внимание, какие игры сегодня используют авторитарный сервер? Либо MMO, либо сессионные игры, в которых игроки сами хостят серверы (для них этот подход абсолютно оправдан). Разработать свое решение действительно непросто, отнюдь. Рассчитывая объекты игрока на его железе мы значительно экономим ресурсы, время и нервы. Авторитарный сервер, ко всему прочему, дорог в содержании, а не только в разработке. Знаю, ваш вопрос был не про сервер, но это я лишь к тому, что нет здесь идеального решения, есть только компромисс. Поправьте меня, если я неправ, я тоже хочу узнать в этой теме что-то новое.
                                    0
                                    Я спорю не про разницу между Lockstep и авторитарным сервером, а про необходимость прикручивания дополнительного механизма кворума в то время когда Lockstep уже реализован.
                                      0
                                      Когда Lockstep уже реализован и игра может гарантировать детерминированность на всех устройствах при получении одинакового ввода, то можно задуматься и об использовании Lockstep. Но опять же соглашусь с Atox, что необходимость гарантировать такую детерминированность в сетевом шутере может стать отдельной головной болью и это желательно заложить еще при проектировании игры и выборе движка. Если изначально этого заложено не было, то можно потом начать разгребать букет проблем.
                                0
                                Кстати, получившийся после выкидывания лишнего шага алгоритм называется Lockstep и часто используется в стратегиях.
                                Вы упускаете одну очень важную деталь, практически во всех стратегиях все вычисления влияющие на состояние мира — детерминированы, и там очень критичен рассинхрон хотя бы в одном параметре отдельного юнита, у автора же другая ситуация, ничего не детерминировано, и все параметры синхронизируются «на лету», поэтому небольшое различие в состояниях отдельных юнитов не критично, так как оно рано или поздно будет синхронизировано с данными от клиента — хозяина.
                                0
                                Немного смущает использование средне-арифметического, а не медианы. Но расчет медианы конечно же гораздо более ресурсоемкий.
                                  +1
                                  Я не писал про использование средне-арифметического. Вопрос агрегации показаний сам по себе интересен и достоен отдельного обсуждения.
                                    +1
                                    Он, конечно, может попытаться скорректировать урон, но полностью его избежать ему не удастся.

                                    Просто вот это я воспринял, как подтверждение версии со средним арифметическим.
                                    Жду «отдельного» обсуждения!
                                    Спасибо за статью, было интересно.
                                  +3

                                  А нельзя просто стрелять периодически "волшебной пулей" и проверять урон? Если, он есть, все ок, и "рана заживает", если нет — мочим читера!

                                    +1
                                    Это будет работать до тех пор пока читер не знает о «волшебной пуле».
                                      –1
                                      А идея неплохая, вообще-то.

                                      Откуда он узнает, если, например, сервер будет рандомно выбирать ID снаряда для проверки урона?
                                    0
                                    У вас в данный моммент есть проверка на телепорты?
                                    Поидее можно было бы еще с каждым выстрелом отправлять Vector3 прицела и время выстрела и убрать damage. На сервере Raycast-ить и все(немного математики). Лучше никогда не доверять игроку.
                                      +3
                                      Согласен, что не стоит доверять клиенту, и если есть возможность все расчеты проводить на сервере. Но это и более дорогое решение, так что должна быть уверенность, что затраченные усилия окупятся. У нас в игре 3D мир, со своим рельефом, так что даже raycast кинуть становится интересной задачей. Сейчас у нас есть отдельные проверки на очень «быстрые» перемещения в игре, которые не стыкуются со скоростью игроков.
                                        0
                                        Мне кажется, гораздо проще построить архитектуру таким образом, чтобы клиент занимался только рендерингом и диспатчингом событий. Например, в EVE Online есть имитационный движок Destiny. На серверной стороне постоянно хранятся состояния. Когда игрок выполняет какое-то действие, на сервер отправляется команда (например, переместиться на метр вправо). Эта команда обрабатывается имитационным движком, состояния обновляются, и эти обновления (не вся куча данных сцены, а только обновлённые состояния) рассылаются всем участникам сцены. Далее, клиент делает рендеринг на основании этих состояний. Игрок стреляет — на сервере вычисляется, куда и с каким качеством прилетит его выстрел (на основании текущих состояний в имитационном движке). Ну, и так далее, по такому принципу.

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

                                        Если вы избавитесь от лишнего доверия к игрокам, вы сможете сосредоточиться на других более интересных задачах. Например, на оптимизации производительности и новых фичах. Сам архитектурный подход с использованием имитационного движка будет вас защищать от читерства, и вы сэкономите в будущем кучу времени, которое иначе тратили бы на разработку защиты от конкретных его видов.
                                          0
                                          В экшн-игры с таким подходом будет играть сложно до невозможности.
                                            0
                                            А в чём именно будет сложность? Я не до конца понимаю. Будет сложно для игроков? Или будет сложно для разработчиков?
                                              0
                                              Для игроков. Пинг 100 мс — вполне средний. При беге человек пробегает 3 м/с, это значит, что за 100 мс голова как раз уйдет с прицела. То есть хед-шоты раздавать уже впринципе не получится — достаточно игроку двигаться вправо-влево и вы никогда не будете знать, где именно находится его голова.
                                              Дальше, скорость реакции. Представьте, вы нажимаете выстрел, а реакция на это происходит только через 100 мс. Или вы бежите, хотите перепрыгнуть через яму, но оказываетесь в ней.
                                              Я уж молчу о всяких гонках, где скорости под 70 м/с, то есть сервер применит команду повороча через семь метров после того, как игрок ее отдал. То есть уже за поворотом.
                                                +1
                                                Я уточню: имитационный движок — это такая штука, которая работает и на сервере и на клиенте. Клиент отправляет событие и в свой имитационный движок и в имитационный движок на сервере. Имитационный движок на клиенте позволяет видеть прыжок ещё до того, как сервер пришлёт ответ о том, что он изменил какие-то состояния и кому-то разрешил прыгнуть.

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

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


                                                А ведь во всякие Пубги сейчас именно с таким пингом и играют
                                        +2
                                        Теперь самое время заняться валидацией перемещений, таймеров перезарядки и далее по списку, пока не получится авторитарный сервер ;)
                                          0
                                          Достаточно необычная ситуация, получается что провести серверный рассчет урона это трудно(т.е. долго), а дождаться ответа всех участников матча и только после этого всем ответить это ОК. Обычно сетевые задержки это чуть ли не главное зло, а у вас получается что без оптимизации (и в худшем случае) у вас скорость сетевого взаимодействия всех клиентов с сервером будет чуть ниже скорости сетевого взаимодействия самого медленного участника матча. И что делать если мнения о ситуации поделились без большинства за один вариант?
                                            0
                                            И что делать если мнения о ситуации поделились без большинства за один вариант

                                            return random() > 0.5; // :)
                                            0

                                            Да, количество репортов уменьшилось, но сам по себе этот график абсолютно ни о чем не говорит без графика с активными аккаунтами.


                                            На данный момент это выглядит так, как будто вы просто потеряли большую часть аудитории, из-за чего, само собой, уменьшилось количество репортов.

                                              0
                                              ZeXTeR вы правы, что график с кол-вом активных пользователей хорошо бы дополнил график по жалобам на нечестную игру, по возможности добавлю его туда. Судя по нашей аналитике мы кратно расширили аудиторию при падении жалоб на читеров.
                                                +3
                                                Собственно наш MAU примерно с того времени
                                                0
                                                Не совсем понял, каким образом вы получаете значение урона, которое нужно нанести. Среднее арифметическое? Или как понимать вашу фразу о том, что читер «может занизить урон, но не может его избежать»?
                                                Возможно, стоит использовать медиану? Т.е. тот показатель урона, о котором сообщила большая половина пользователей? А в случае, если 50 на 50, то решение может вынести либо алгоритм проверки «честности», либо «дополнительные пользователь», о котором говорили выше.
                                                  +3
                                                  Выше по комментариям писал про агрегацию урона. Используем не среднее арифметическое. Агрегировать можно по разному, зависит от того результата, который необходимо получить в первую очередь.

                                                  Я имел в виду, что если читер будет пробовать манипулировать показателями урона/здоровья и его показания попадут в кворум, то при агрегации в кворуме эти показания изменятся в сторону реалистичных показаний. Насколько изменятся уже будет зависеть от выбранного способа агрегации (среднее арифметическое, медиана и т.д.).
                                                    0
                                                    Прошу прощение за дублирование) и спасибо за ответ.
                                                    Аккаунт на хабре у меня неполноценный) видимо, пока вопрос висел в «одобрении», кто-то другой успел задать такой же :)
                                                    Спрашивал-то я ещё в день публикации
                                                  0
                                                  я чет недопонимаю смысла вашего демократического подхода, если у вас всем рассылается информация об уроне и дамаге, то не проще для каждой игры вводить «наблюдателя» от сервера (виртуального клиента с минимальными функциями) и опрашивать только его на предмет достоверности?
                                                    0
                                                    Обсуждение про «наблюдателя» от сервера выше в комментах.
                                                    0
                                                    Можно ещё рассылать инфу игрокам независимо от игровой комнаты. Скажем о состоянии каждого клиента знают другие десять клиентов.
                                                      0
                                                      Это решает проблему 1vs1 и клан-гопников.
                                                      0
                                                      Статья интересная, спасибо.

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

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

                                                      В общем вопросов ещё много, аффтар, пешы исчо.

                                                      P.S. А ещё интересно почему вы не рассматриваете вакансии удалённых разработчиков, но это так, в порядке любопытства.
                                                        0
                                                        Про матчмейкинг думаю стоит отдельно статью подготовить, там есть интересные нюансы. Если коротко, то сначала была проблема с матчингом, так как алгоритм подбора был реализован довольно просто. Потом появились лиги, которые изменили в целом подбор игроков в случайном бою и стало получше. Тут вероятно как у всех, слушаем комьюнити, анализируем, где есть проблемы с подбором игроков, и решаем их по мере поступления.
                                                        0

                                                        Про сундуки — они просто делают как все. Это как видео рекламу других игр показывать.


                                                        Вопрос про время ожидания ответа: какие у вас задержки между Req/Resp клиент-сервер-клиент? То есть я сделал выстрел и хочу получить сразу эффект урона по противнику или узнать свой урон, но прийдётся ждать кворума и только потом получение ответа.
                                                        Вопрос второй: клиент начинает визуализацию без получения ответа от сервера, чтобы не давать ощущение "тормозов"?


                                                        Всё это про хэдшот и определение жизни/смерти себя/противника, при малом количестве жизней. Клиент может визуализировать смерть противника, а потом после решения кворума — живой.

                                                          0
                                                          Действительно визуализация эффекта урона начинается без сервера, чтобы не было ощущения «тормозов». Изменение хп или смерть происходит только по команде. Самые дорогие по времени задержки в цепочке Req/Resp клиент-сервер-клиент связаны с передачей 2х пакетов клиент — сервер — клиент. Если сейчас наше среднее по больнице время передачи пакета оценить в 300 мс, то за 700 мс клиент обновит хп уже.
                                                          0
                                                          Спасибо за статью! А скажите, правильно ли я понял раз у вас нет авторитарного сервера, вы наверняка предсказания, интерполяцию и всякие такие штуки не делаете?
                                                            0
                                                            Интерполяцию делаем, предсказания нет.
                                                            0
                                                            По факту авторитарный сервер отвечает за вычисления и броадкастинг. Что вы сделали?
                                                            Вы сделали ВСЁ ТОТ ЖЕ авторитарный сервер, только теперь, допустим, вместо лога событий он делает агрегацию инфы от всех клиентов. Браво!
                                                            По факту, вы, ребята, замутили квадратное колесо велосипеда.
                                                            Объясню, мобильные платформы позволяют обновлять продукт. Так что, проблем с переходом выйти не должно было. Вы потратили время на разработку вычисляющего алгоритма на сервесайде и правку клиентсайда. Сделали квадратное колесо из авторитарного сервера. Что мешало вам потратить столько же времени(чуть меньше\больше) на доработку серверной логики? Чисто чтобы В ДАЛЬНЕЙШЕМ без проблем было? В том числе с матчами 1\1.
                                                            В общем, от авторитарного сервера вы НИКУДА не ушли, зато вычисления заменили агрегацией. Да еще и прибавили 2 проблемы себе на голову.
                                                              0
                                                              Вы не упомянули, что авторитарному серверу еще и физику нужно посчитать, чтобы вычисления по честному провести. Соответственно, нужно либо упрощенную физику сделать на сервере + протестить ее, либо клиент в батч-моде запускать на сервере (дешевле по времени, но совсем дороже по ресурсам). Так же нужно из клиента все это вытащить + протестить. Все это против нескольких дней разработки.
                                                                0
                                                                Я вовремя смотрю уведомления, да.
                                                                Нет, если физику не считать — я в игру не играл бы :D Это не честно выходит.
                                                                Да и зачем считать всю физику, предопределяя мог попасть снаряд, али нет?
                                                                Самая базовая реализация авторитарного сервера предполагает реализацию лога ключевых объектов. Запрос от клиента указывает согласованный таймкод(хэш), которым можно быстро найти и чекнуть, было попадание или нет. Это честно по отношению к игрокам в разрезе пинга. К тому же, не обязательно кидать запросы каждый выстрел, нужно лишь отправлять запрос тогда, когда клиент считает, что попал.
                                                                Серверсайду же остается лишь посмотреть попал ли снаряд действительно.
                                                                Остается проблема с читерами аимщиками — это уже дело усложненного потока оценки движения или вовсе нейросети(чем сейчас и занимаются топ компании типа вольвы).
                                                              0
                                                              Прикольно. :) Практически такой алгоритм я приводил в пример на собеседовании в Pixonic в 2011-ом. Только у меня ещё ситуация была более сложная, когда клиенты ещё и сверяли между собой броски случайных чисел, до поры до времени известные только одному из игроков (кому какая карта выпала).

                                                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                              Самое читаемое