Комментарии 72
только хотел написать: собираешь компанию читеров и по одному мочишь в сортирах честных чуваков
Молодцы.
Кстати, напрашивается ещё одно усовершенствование, которое позволит проводить пересчёты и при игре один на один: считать "показатель честности" игрока. Если в ходе игр регулярно видим занижение урона — снижаем показатель. А при расчёте итогового урона — более значимы данные от игроков с высоким показателем.
Но вообще верить клиенту это фуфуфу. Но серверсайд-обработка реализуема в стратежках и прочих слоупочных играх, но никак не в экшонах и тем более FPS.
Оценка игроками для занижения кого-то — очень плохая идея, максимум что с ней можно делать так повышать награду за бой (если она есть) игроку с самыми положительными оценками от других (см. сессионки от близзард). Бездушный алгоритм на стороне сервера решает.
Именно тот-же социальный фактор будет портить игру — если человек, например, удак, или мамкин трубашататель, но играет хорошо, а ему за это будут понижать чисто геймплейный показатель а не чат мьютить — это какая-то фигня.
А еще показателю желательно быть лимитированным, типа от 50% доверия до 125%, и считать в среднем за последние N сессий, дабы избежать проваливания игроков с плохим коннектом в пучину негативной кармы, из которой они не выберутся даже если будут играть пару лет с нормального соединения.
В любом случае можно алгоритмически выявлять "потенциально плохую связь" (потери всех пакетов, пинг) и "потенциально читеров" (получение аномальных значений в пакетах, потеря определенных типов пакетов), потому-что если объединять в матчах читеров и игроков с плохим коннектом, или просто игроков с плохим коннектом — получится еще более жестоко, хотя и очень весело.
Я играю в Лигу Легенд и могу описать до чего там эволюцилнировали систему чести. Все прошлые этапы эволюции описывать лень.
1. После каждой игры на экране появляется 4 картинки персонажей своей команды (игра 5 на 5 игроков), где ты можешь похвалить (в течение 30 секунд) одного игрока или за хорошую игру (GG) или за коммуникацию или «не терял духа» (все проигрывают, а он подбадривал).
2. После игры можно зарепортить игрока за фид, ругань и прочие непотребства (и читерство в тч). Не только своего, но и противника.
В результате получаешь очки чести, которые повышают твой ранг чести от 0 до 5. Все начинают со 2 ранга. Если часто репортятся, то теряют очки и опускаются ниже и лишаются чата, возможности играть с приятными людьми. Если репортов нет, то получают условно 1 очко. За похвалу 2-3.
3. За 3-4-5 ранг дают плюшки ввиде чемпионов на халяву (точнее осколков, которые можно собрать в полноценных дешевле, чем покупать новых).
Это заставляет игрокова быть вежлевее/честнее. Самых отпертых негодяев (даже суперумелых) вышвыривают на год. Просто банят все учетные записи.
Более общее решение — считать контрольные суммы состояния игры и сверять их на сервере. Но это требует качественной реализации клиентской логики (должна быть строго детерминированной) и проблема с кворумом остаётся.
У этого варианта минимум два минуса:
- Не работает на PvP (как вы писали в статье)
- Куча читеров может всех унижать (как писали выше в комментариях)
А я тут подумал, а что если зарегистрировать служебного пользователя, захостить его где-нибудь на сервере и подключать к каждой игре? Получается он смог бы, как текущие клиенты, отслеживать все действия в игре и отправлять данные на сервер. А на сервере сделать, чтобы он доверял только этому специальному клиенту и при этом не показывал его присутствие остальным участникам. Это бы решило предыдущие проблемы.
Кстати, получившийся после выкидывания лишнего шага алгоритм называется Lockstep и часто используется в стратегиях.
Однако у него есть принципиальная уязвимость (которая у вас, видимо, есть тоже) — maphack. Поскольку без авторитарного сервера каждый клиент обладает всем состоянием игры — читер всегда найдет способ вывести себе на экран ту информацию которую он видеть не должен.
Вот в конце матча его результаты можно уже и кворумом утвердить.
Вы упускаете одну очень важную деталь, практически во всех стратегиях все вычисления влияющие на состояние мира — детерминированы, и там очень критичен рассинхрон хотя бы в одном параметре отдельного юнита, у автора же другая ситуация, ничего не детерминировано, и все параметры синхронизируются «на лету», поэтому небольшое различие в состояниях отдельных юнитов не критично, так как оно рано или поздно будет синхронизировано с данными от клиента — хозяина.
А нельзя просто стрелять периодически "волшебной пулей" и проверять урон? Если, он есть, все ок, и "рана заживает", если нет — мочим читера!
Поидее можно было бы еще с каждым выстрелом отправлять Vector3 прицела и время выстрела и убрать damage. На сервере Raycast-ить и все(немного математики). Лучше никогда не доверять игроку.
Просто таким способом вы решите кучу проблем, связанных с читерством игроков. Сейчас же получается, что после решения одной проблемы (уровень урона) у вас появляется другая проблема (телепорты). Потом появится третья проблема, а за ней ещё одна, и так до бесконечности: пока вы доверяете игрокам хоть немного, они будут находить всё новые и новые способы этим доверием воспользоваться. В корне всего лежит именно доверие к игрокам. Оно будет вас принуждать наворачивать кучу кода, каждый кусок которого защищает от определённого типа читерства. В итоге, это всё выродится в монструозную конструкцию, которую будет страшно трогать и которая будет жутко тормозить в плане производительности.
Если вы избавитесь от лишнего доверия к игрокам, вы сможете сосредоточиться на других более интересных задачах. Например, на оптимизации производительности и новых фичах. Сам архитектурный подход с использованием имитационного движка будет вас защищать от читерства, и вы сэкономите в будущем кучу времени, которое иначе тратили бы на разработку защиты от конкретных его видов.
Дальше, скорость реакции. Представьте, вы нажимаете выстрел, а реакция на это происходит только через 100 мс. Или вы бежите, хотите перепрыгнуть через яму, но оказываетесь в ней.
Я уж молчу о всяких гонках, где скорости под 70 м/с, то есть сервер применит команду повороча через семь метров после того, как игрок ее отдал. То есть уже за поворотом.
Просто у имитационного движка сервера приоритет выше. И если он прислал информацию, которая отличается от информации в клиенте, то клиент отбрасывает свою информацию и использует то, что прислал сервер.
По сути, при таком подходе всё превратится в синхронизацию состояний в имитационных движках сервера и клиента, где серверная сторона имеет высший приоритет. И точность синхронизации будет зависеть от того, насколько точно сервер учтёт задержки сигнала, чтобы понять, в какой точно момент времени клиент отправил команду. И если это удалось, то в имитационных движках клиента и сервера события будут протекать одинаково, и когда сервер пришлёт свою версию состояний сцены, на клиенте не придётся вносить никаких изменений, потому что данные о состояниях будут совпадать.
А ведь во всякие Пубги сейчас именно с таким пингом и играют
Спидхакеры до сих пор (2023) встречаются довольно часто.
Да, количество репортов уменьшилось, но сам по себе этот график абсолютно ни о чем не говорит без графика с активными аккаунтами.
На данный момент это выглядит так, как будто вы просто потеряли большую часть аудитории, из-за чего, само собой, уменьшилось количество репортов.
Возможно, стоит использовать медиану? Т.е. тот показатель урона, о котором сообщила большая половина пользователей? А в случае, если 50 на 50, то решение может вынести либо алгоритм проверки «честности», либо «дополнительные пользователь», о котором говорили выше.
Я имел в виду, что если читер будет пробовать манипулировать показателями урона/здоровья и его показания попадут в кворум, то при агрегации в кворуме эти показания изменятся в сторону реалистичных показаний. Насколько изменятся уже будет зависеть от выбранного способа агрегации (среднее арифметическое, медиана и т.д.).
Но и косяков у вас достаточно, причём в вопросах, которые, вроде бы порядком проще. Расскажите, например, как у вас реализован алгоритм подбора игроков для случайного боя и почему так часто попадаются заведомо проигрышные ситуации, когда у одной из сторон, например, в сумме на три-четыре робота больше? С другой стороны, последнее время таких ситуаций стало меньше, но было бы интересно почитать про алгоритм всё-таки.
Ещё интересно что это у вас за нездоровая любовь ко всяким лотерейным розыгрышам и сундукам? Ощущение что кто-то из разработчиков ушёл из казино и ему теперь покою не дают крутящиеся барабаны из прошлого, ибо розыгрыши на «чёрном рынке» у вас по тому же принципу работают. Впрочем, они даже хуже — там ведь нет никакого элемента случайности — заведомо понятно, что первые три-четыре открытых лота будут: «премиум» или «серебро», «премиум» или «чуть-чуть деталей» и т.п. в зависимости от того какие призы исключить. Какое-то кидалово, короче.
В общем вопросов ещё много, аффтар, пешы исчо.
P.S. А ещё интересно почему вы не рассматриваете вакансии удалённых разработчиков, но это так, в порядке любопытства.
Про сундуки — они просто делают как все. Это как видео рекламу других игр показывать.
Вопрос про время ожидания ответа: какие у вас задержки между Req/Resp клиент-сервер-клиент? То есть я сделал выстрел и хочу получить сразу эффект урона по противнику или узнать свой урон, но прийдётся ждать кворума и только потом получение ответа.
Вопрос второй: клиент начинает визуализацию без получения ответа от сервера, чтобы не давать ощущение "тормозов"?
Всё это про хэдшот и определение жизни/смерти себя/противника, при малом количестве жизней. Клиент может визуализировать смерть противника, а потом после решения кворума — живой.
Вы сделали ВСЁ ТОТ ЖЕ авторитарный сервер, только теперь, допустим, вместо лога событий он делает агрегацию инфы от всех клиентов. Браво!
По факту, вы, ребята, замутили квадратное колесо велосипеда.
Объясню, мобильные платформы позволяют обновлять продукт. Так что, проблем с переходом выйти не должно было. Вы потратили время на разработку вычисляющего алгоритма на сервесайде и правку клиентсайда. Сделали квадратное колесо из авторитарного сервера. Что мешало вам потратить столько же времени(чуть меньше\больше) на доработку серверной логики? Чисто чтобы В ДАЛЬНЕЙШЕМ без проблем было? В том числе с матчами 1\1.
В общем, от авторитарного сервера вы НИКУДА не ушли, зато вычисления заменили агрегацией. Да еще и прибавили 2 проблемы себе на голову.
Нет, если физику не считать — я в игру не играл бы :D Это не честно выходит.
Да и зачем считать всю физику, предопределяя мог попасть снаряд, али нет?
Самая базовая реализация авторитарного сервера предполагает реализацию лога ключевых объектов. Запрос от клиента указывает согласованный таймкод(хэш), которым можно быстро найти и чекнуть, было попадание или нет. Это честно по отношению к игрокам в разрезе пинга. К тому же, не обязательно кидать запросы каждый выстрел, нужно лишь отправлять запрос тогда, когда клиент считает, что попал.
Серверсайду же остается лишь посмотреть попал ли снаряд действительно.
Остается проблема с читерами аимщиками — это уже дело усложненного потока оценки движения или вовсе нейросети(чем сейчас и занимаются топ компании типа вольвы).
Как расправиться с читерами и не переписать весь код