Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Толстый/тонкий сервер. Синхронизация состояние мира. Какие минусы видите в такой реализации? (6 стр)

Толстый/тонкий сервер. Синхронизация состояние мира. Какие минусы видите в такой реализации? (6 стр)

Advanced: Тема повышенной сложности или важная.
Страницы: 15 6 7 812 Следующая »
tacПостоялецwww5 окт. 20162:44#75
MrShoor
> Ну вот я открываю пост #40, а там:

у тебя все смешалось ... читать надо пост#35 , а #40 это ответ тебе на заблуждение "База вообще никак не относится к синхронизации мира. База - это сугубо хранение данных", но это никак не связано с моим решением. Это в одном из вариантов она может этим заниматься при авторитарном сервере. 

MrShoor
> > Но как можно увидеть из описания предлагаемого подхода - "на сервере не
> > происходит ни анализа, ни обработки бизнес-логики".
> Поскольку база все делает, так?

а это уже связано с моим решением "толстого клиента", но совсем не постольку, а поскольку клиент все делает.

а про читерство мы уже говорили - нет есть другие решения )

MrShoorУчастникwww5 окт. 20162:48#76
tac
> читать надо пост#35
Почитал. Не вижу смысла в толстом клиенте из-за читерства.

> а про читерство мы уже говорили - нет есть другие решения )
Нет других решений. Решение там только одно - считать на сервере.

MrShoorУчастникwww5 окт. 20162:52#77
tac
Если хочешь все таки на клиентах - то тебе нужно смотреть в сторону биткоина, и как у них организована система транзакций. Есть узлы, которые фактически подтверждают, что данная транзакция валидна, и ей можно доверять, но в реализации для игры это решение будет крайне сложным, и ты будешь пожалуй первым, кто такое сделает. Поэтому я сомниваюсь, что ты такое сделаешь. Ну и кроме того такое решение становится слабым, когда клиентов становится мало, и не вообще не рабочим, когда остается на сервере 2 клиента.

А все остальные решения - с читерством.

foxesПостоялецwww5 окт. 20163:59#78
tac
Это мечта - тоже мечтал когда то за реализацию толстого клиента сесть. Забил на проблемы читерства, сервер выступал в роли общего коммутатора без данных. Клиенты работали на подобии логики двойного торрента. Первый для синхронизации данных, второй для игровой логики обновления персонажей на локальных участках. Пользователи переподключались между собой по зоне видимости.

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

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

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

tacПостоялецwww5 окт. 20165:10#79
foxes
> Это мечта - тоже мечтал когда то за реализацию толстого клиента сесть.

так и чем закончилось? почему бы не осуществить? руки не дошли или на чем то застряли при тестах?

foxesПостоялецwww5 окт. 20165:22#80
tac
Я и не начинал, пока только идея. Работы оплачиваемой и так хватает, верно руки не до ползли.
MrShoorУчастникwww5 окт. 20165:43#81
tac
> так и чем закончилось? почему бы не осуществить? руки не дошли или на чем то
> застряли при тестах?
Ты попробуй хотя бы примитивное что-нибудь без лагов сделай. Просто прототип на коленке набросай. Поймешь насколько сложно. То, что описал foxes - абстрактный конь в вакууме, реализовать который в одну каску практически нереально.
tacПостоялецwww5 окт. 20166:15#82
MrShoor
> Ты попробуй хотя бы примитивное что-нибудь без лагов сделай. Просто прототип на
> коленке набросай. Поймешь насколько сложно.

Ну бегающие персонажи в сети у меня уже есть. Правда было без записи в базу пока, но вот вроде и асинхронное подсохранение написал, на днях потестирую. А с менее активно изменяющимися объектами - будет и того проще. Загрузку начального состояния и собственно клиента еще конечно писать надо.  Не то чтобы сложно, просто чтобы все по уму муторно.

-----------------------------------------------------------------------------------------------------------------------

У асинхронного подсохранения вот такая получилась логика

Ведение лога и периодическое сохранение состояния игрового мира в базе данных сервера

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

меня лично смущает тут "Если объект в течении этих 5 секунд изменился 3 и более раз", может стоит придумать какую то лучшую оценку активности?

i2um1Постоялецwww5 окт. 201618:41#83
tac
> если идентификатор объекта встречается первый раз

Сферический конь в вакууме:
1. Игрок А, тратя 5 очков выносливости, кидает в игрока Б камень с id 1 и наносит ему урон в 3 единицы, тем самым убивает его и разрушает камень. Это какой объект изменился?
2. Проворачиваем все действия из ситуации 1. На четвертую секунду сервер получает информацию и логирует это действие. На пятой секунде сервер обновляет данные в базе данных. Но игрок Б узнает об этой ситуации только на шестую секунду (где-то что-то с траффиком произошло, не важно), который на четвертой секунде прыгнул в телепорт перед нанесением ему урона камнем. Что произойдет на самом деле на экранах игроков А, Б и В (просто смотрел на эту ситуацию) и что запишется в лог?

tacПостоялецwww5 окт. 201619:19#84
i2um1
> 1. Игрок А, тратя 5 очков выносливости, кидает в игрока Б камень с id 1 и
> наносит ему урон в 3 единицы, тем самым убивает его и разрушает камень. Это
> какой объект изменился?

У нас три объекта: игрок А (id=10), игрок Б (id=11), камень (id=1)
все три объекта изменяются: у #10 - уменьшается выносливость, #11 - получает урон и умирает, #1 разрушается

i2um1
> На четвертую секунду сервер получает информацию и логирует это действие. На
> пятой секунде сервер обновляет данные в базе данных. Но игрок Б узнает об этой
> ситуации только на шестую секунду (где-то что-то с траффиком произошло, не
> важно), который на четвертой секунде прыгнул в телепорт перед нанесением ему
> урона камнем. Что произойдет на самом деле на экранах игроков А, Б и В (просто
> смотрел на эту ситуацию) и что запишется в лог?

тут изменена последовательность. На самом деле: сервер получает информацию о всех этих изменениях (с периодичностью скажем 0.1 сек) и сразу асинхронно рассылает всем играющим клиентам, затем изменения поступают в лог.
Когда там случится реальная запись в базу данных уже не важно. Те кто имеет нормальный пинг увидят как умер игрок еще до прыжка в телепорт, каждый со своей задержкой. А те кто имеет приличный лаг увидят смерть в/за телепорте. Не вижу ничего страшного - классическая проблемка, лучше никто не решил.

i2um1Постоялецwww5 окт. 201622:09#85
tac
> Когда там случится реальная запись в базу данных уже не важно.

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

четвертая секунда от жизни мира: игрок А убил игрока Б
четвертая секунда от жизни мира: игрок Б успел спастись, прыгнув в телепорт
Назовем это конфликтом версий игрового мира, которое приводит к нарушению целостности состояния игрового мира. В моей игре о сферических конях в вакууме такое событие как смерть игрока имеет первостепенную важность, так как мертвый игрок не может больше никак продолжать играть в игровом мире. Увы, но он будет вынужден создавать нового персонажа и начинать играть сначала.
Представим, что игрок А увидел смерть игрока Б, в то время как игрок Б благополучно смог спастись через телепорт. Сервер не контроллирует целостность данных, его поведение будет приблизительно такое:
а) Игрок А убил игрока Б, далее игрок Б прыгнул в телепорт, избежав смерти.
б) Игрок Б прыгнул в телепорт, избежав смерти, далее игрок А убил игрока Б.
Конечный результат определяет только порядок выполнения действий. Обе ситуации ведут к недовольным игрокам:
а) Игрок А: "Я же убил его!!! Как ТАК?!!!"
б) Игрок Б: "Я же успел спастись!!! Как ТАК?!!!"
Чтобы не усложнять и без того сложность ситуации, опустим дальнейшую судьбу камня.
Эту ситуацию скорее всего можно избежать, реализовав децентрализованный сервер. Каждый игрок будет выступать в роли клиента и сервера одновременно. А каждое действие будет помечаться специальным хешем, который зависит от текущего времени. А события будут считаться валидными, если они не выполнялись в один квант времени. Самое ранее событие будет вступать в силу, в то время как второе - просто игнорироваться. Но этот самый квант времени будет очень сильно зависеть от пинга всех игроков, локального времени игроков, производительности компьютеров игроков. Но тогда возникает здравый вопрос: зачем нам нужен сервер? Клиенты могут сами сразу писать состояние мира в общее хранилище, скажем, в облако. А увеличение числа игроков и сложности игрового мира будут просто увеличивать тот самый квант времени.
Возможно и другое решение, которое никак не конфликтует с децентрализованным сервером: уже ранее озвученная система предсказания действий игроков. Но чем сложнее система, чем больше игроков, тем сложнее предсказать ход дальнейших событий. Такой себе костыль сглаживания неровных краев проблемы конфликтов версий игрового мира.

tac
> У нас три объекта: игрок А (id=10), игрок Б (id=11), камень (id=1)
> все три объекта изменяются: у #10 - уменьшается выносливость, #11 - получает урон и умирает, #1 разрушается

На самом деле нет. Перечислены только конечные состояния объектов и то далеко не все, а есть еще ряд промежуточных. Например тот же камень за один квант времени получил последовательно несколько состояний: брошен игроком А, совершает полет, попадает в игрока Б, наносит урон, разрушается. Каждое из этих событий необходимо залогировать на сервере и выполнить на клиентах, потому что каждое из них важно и невозможно без предыдущего. Этой ситуацией я хотел определить как система справляется с несколькими событиями за максимально короткий отрезок времени. Проще говоря как решаются конфликты состояний игровых миров.
Итого: система не справилась и образовался хаос в мире, нельзя глядя на логи определить текущее актуальное состояние мира в данный момент времени (квант времени).

tac
> тут изменена последовательность. На самом деле: сервер получает информацию о всех этих изменениях (с периодичностью скажем 0.1 сек) и сразу асинхронно рассылает всем играющим клиентам, затем изменения поступают в лог.

Опять-таки нет. Сервер не может физически получить сразу сообщение: оно может прийти через 0.1 секунду, через 1 секунду, через 10 секунд, через 100 секунд, а может и вовсе не прийти. Клиенты не могут сразу получить текущее актуальное состояние мира от сервера, так как это самое состояние может прийти через 0.1 секунду, через 1 секунду, через 10 секунд, через 100 секунд, а может и вовсе не прийти. Опустим тот факт, что серверу необходимо еще выполнить дополнительную логику, несвязанную с логами, которая тоже занимает время (диспетчеризация потоков, склеивание и обработка сообщений клиентов например). А состояние игрового мира актуально только в том случае, когда логи уже попали в базу данных, потому что сервер отправляет состояние мира не из логов, а из базы данных, которое еще не успело обновиться. Допустим сервер не идет в базу данных, а сразу отправляет логи (не важно где и как он их хранит), но тогда будет конфликт версий игровых миров, потому что ряд событий может произойти и обработаться в абсолютно произвольное время, не говоря уже о возможных нескольких событий в один квант времени (будь он хоть 0.1 секунда, что физически невозможно). Этой ситуацией я хотел определить как система решает конфликт событий за любой неопределенный отрезок времени (неопределенное число квантов времени). Проще говоря как решаются конфликты состояний игровых миров.
Итого: система не справилась и образовался хаос в мире, нельзя глядя на логи определить текущее актуальное состояние мира в данный момент времени (квант времени).

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

Говоря вскользь о хаосе состояния игрового мира:
1. Как определить за какой период времени необходимо клиенту отправлять логи о текущем состоянии игрового мире? Ведь игрок мог не появляться в мире день, неделю, месяц, а может даже год.
2. Оптимизацию программного обеспечения можно себе очень грубо представить в виде каната. С одной стороны на себя канат тянет мистер Вычислить, с другой же - миссис Хранить. Мы уменьшили нагрузку на сервер, скинув все вычисления на клиентов, но очень сильно увеличили количество хранимой информации на сервере. Много информации на сервере = много передаваемых данных клиентам через сеть в момент их подключения к игровому миру. Как долго сервер вынужден хранить логи о текущем состоянии игрового мира? Ведь игра может продолжаться день, неделю, месяц, а может даже год с поправкой на неисчисляемое множество возможных событий за этот период времени. Что же получается? Новоподключенный клиент должен скачивать логи за всю историю жизни игрового мира?

Напоследок затронем масштабируемость системы. Бытует мнение, что программисты - люди очень ленивые, на то они и программисты, чтобы автоматизировать рутину. Живя в идеальном мире, однажды написанный код должен легко быть использованным вновь. Мы написали игру. Прошло время, она набрала популярность (по моей сугубо субъективной оценке - 10 игроков в лучшем случае, думаю сервер больше не выдержит). Мы же были хорошими программистами и написали хороший код, который написан максимально производительно? Будь я заказчиком такой игры, мои возможные варианты решения справиться с возросшей нагрузкой на сервер:
1. Купить более лучшее железо, а потом выяснить, что даже самые топовые модели не справляются с нагрузкой. В то время как какой-нибудь клон майнкрафта сделанный на коленке (да и сам майнкрафт не далеко он них ушел) справляется с похожей задачей на порядок лучше и выдерживает большее число пользователей на компьютерах школьников для учебы. А ведь топовое железо уже было куплено зазря.
2. Купить еще один-несколько серверов. Благо если хостить сервер на каком-нибудь облаке это делается парой щелчков мыши. И спустя пару минут времени выяснить, что логика игры никак не была рассчитана на несколько серверов. А ведь ноды для серверов уже были куплены, настроены и запущены зазря.
Я думаю мне нет нужды говорить о последствиях, которые из этого следуют со стороны заказчика.

tacПостоялецwww5 окт. 201623:13#86
i2um1
> Важно, данные не хранятся в оперативной памяти или где-либо еще, а напрямую
> достаются из базы данных и сразу отдаются клиенту.

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

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

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

Какое нарушение возникает? Никакого.

i2um1
> то каждый игрок будет видеть у себя на экране свое состояние мира

Замечательно. В чем проблема?

i2um1
> что не даст корректно восстановить актуальное состояние мира любому другому игроку

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

i2um1
> игрок А увидел смерть игрока Б, в то время как игрок Б благополучно смог спастись через телепорт.

И вот ваша ошибка. Он не сможет увидеть смерть игрока Б, пока она не произойдет на компьютере игрока Б, а как мы помним видит ВСЕГДА прошлое, т.е. он это увидит позже.

i2um1
> Сервер не контроллирует целостность данных, его поведение будет приблизительно такое

Сервер ничего не контролирует, контролируют клиенты, поэтому его поведения не будет вообще

ну и дальше ком недоразумений исходящий совсем не из тех посылов ... нет смысла рассматривать

i2um1
> Клиенты могут сами сразу писать состояние мира в общее хранилище, скажем, в облако.

долго спорили со мной о том что совсем не касается предложенного, чтобы прийти к тому с чего я начал ))

i2um1Постоялецwww5 окт. 201623:29#87
tac
> Вы что опять один из тех, кто поленился внимательно прочитать предлагаемое решение, и пишет со своей колокольни?
Это скорее следствие решения проблемы, а не требование. Проблема в пренебрежении значимости информации.

tac
> Клиент отправляет сообщение, сервер его пересылает (может вообще не хранить нигде), другие клиенты кто был в сети получают отправленное сообщение. В чем проблема? О какой целостности данных мы тут говорим?
Нет гарантий получения достоверной информации своевременно.

tac
> Какое нарушение возникает? Никакого.
Полученная информация неправильная и уже давно не актуальна.

tac
> Замечательно. В чем проблема?
Всегда негативно относился к телепортам игроков и предметов в играх, причем в зависимости от состояния сервера эти телепорты могут превратить игру в мучение. Попытки выполнить действие с n-ого разного это из этой оперы. Не говоря уже о неопределенности как клиент должен решать ситуацию одновременно живого и мертвого игрока.

tac
> И вот ваша ошибка. Он не сможет увидеть смерть игрока Б, пока она не произойдет на компьютере игрока Б, а как мы помним видит ВСЕГДА прошлое, т.е. он это увидит позже.
В таком случае возможны ситуации, когда игрок А должен ждать неопределенное количество времени, пока событие произойдет у игрока Б и ничего не делать, чтобы не создавать еще больше конфликтов событий. В то время как игрок Б спустя, например, минуту, занимаясь своими делами за три-девять земель от игрока А и вовсе позабыв о нем, как вдруг умирает. Негодование игрока будет обеспечено.

tacПостоялецwww5 окт. 201623:35#88
i2um1
> Полученная информация неправильная и уже давно не актуальна.

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

i2um1Постоялецwww5 окт. 201623:37#89
tac
> ну и дальше ком недоразумений исходящий совсем не из тех посылов ... нет смысла рассматривать
Хозяин - барин. В тех суждениях перечислен довольно большой пласт проблем реализации похожей логики в моих сингл- и мульти- плеерных играх и эмуляциях.

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

Страницы: 15 6 7 812 Следующая »

/ Форум / Программирование игр / Сеть

Тема в архиве.

2001—2018 © GameDev.ru — Разработка игр