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

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

Поделиться
Advanced: Тема повышенной сложности или важная.

Страницы: 1 2 3 4 ... 10 11 12 Следующая

tacПостоялецwww3 окт. 201620:50#0
Решил написать сетевое решение, достаточно универсальное. Рассмотрим только логику, без частностей реализации. Для простоты рассмотрим лишь синхронизацию простых объектов между клиентами и сервером. Ну например, камни в игре, которые любой из игроков может поднимать в инвентарь и выбрасывать назад в мир.

Есть как минимум два варианта:
1. Толстый сервер

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

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

2. Тонкий сервер

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

Второй вариант мне кажется лучше, но может я чего то не учитываю?

P.S. Решение планируется использовать для Конструктора выживания (Survival Сonstructor)

upd.
выше описана просто начальная идея, более подробное описание находится в документе: http://cyberrise.eu/Share/CyberKernel.pdf (раздел Сетевое решение)

Выдержка из документа, относящиеся к теме ... много букв

+ Показать

Правка: 4 окт. 2016 19:58

greencrazycatПостоялецwww3 окт. 201621:42#1
tac
> Но главное - это необходимость иметь на сервере базу данных, а соответственно
> нагрузка на сервер.
в чем нагрузка ?

- сервер знает состояние мира
- сервер записывает в БД изменения состояния мира (отправляет драйверам БД инфу о необходимости записи, какая тут нагрузка на сервер учитывая что БД может физически располагаться на другом сервере/кластере серверов?)
- сервер отсылает вновь подключившимся игрокам текущее состояние мира

Правка: 3 окт. 2016 21:43

tacПостоялецwww3 окт. 201621:46#2
greencrazycat
> - сервер записывает в БД изменения состояния мира (отправляет драйверам БД инфу
> о необходимости записи, какая тут нагрузка на сервер учитывая что БД может
> физически располагаться на другом сервере/кластере серверов?)

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

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


> да и при старте не нужно получать инфу с сервера, только, чтобы достроить текущие состояние

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

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

Правка: 3 окт. 2016 22:01

robotcityПостоялецwww3 окт. 201622:04#3
оба варианта плохи. Возьми за основу майнкрафт, он не передает логи изменений карты, он передает http://minecraft.gamepedia.com/Chunk.
То что ты хочешь реализовать старая и несбыточная мечта, единственное что можно здесь сделать это написать алгоритм предсказывающий что нужно передать, что игрок увидит следующим, тем самым как то минимизировать объемы которые будут передаваться.
greencrazycatПостоялецwww3 окт. 201622:10#4
tac
> Ну сравним - сколько сервер потянет игроков/комнат/миров ... и все чего то
> шубуршаться, каждый хочет, чтобы база данных пополнялась ...
да : 2 базы, одна для профилей игроков которые редко меняются и важна логика "хитрых" запросов к БД, вторая для мира на быструю запись (какой нить nosql)
tacПостоялецwww3 окт. 201622:15#5
robotcity
> он не передает логи изменений карты, он передает
> http://minecraft.gamepedia.com/Chunk.

ну, т.е. он передает полное состояние карты с определенным радиусом от игрока (скажем на область его видимости - 300 м.), а когда он двигается он судорожно обращается к серверу за информацией ...
Когда карта огромная больше 4000 м. тогда это имеет смысл. Хотя опять надо взвесить - что лучше получать ПОСТОЯННО локальное состояние карты или иметь знание о всей карте, и когда нет изменений - нет и нагрузки, и получая ПОСТОЯННО - она есть всегда.

robotcity
> написать алгоритм предсказывающий что нужно передать, что игрок увидит
> следующим, тем самым как то минимизировать объемы которые будут передаваться

ну это по сути тоже локальное состояние - он увидит то, в какую сторону двигается.

tacПостоялецwww3 окт. 201622:20#6
greencrazycat
> на быструю запись (какой нить nosql)

быстрая запись не равно nosql ;) Наоборот c nosql у нас проблемы с формирование состояния мира из сообщений если передаются изменения мира. Единственно, если как говорит robotcity - клиенты будут постоянно передавать свое локальное состояние в мире, тем самым просто обновлять области состояния мира целиком ...

Но так мне кажется они будут передавать много лишнего и постоянно. По сути будет дублироваться то, что надо передать ... если 3 игрока находятся рядом, они все три будут передавать плюс минус одно и то же.

Правка: 3 окт. 2016 22:21

tacПостоялецwww3 окт. 201622:22#7
robotcity
> То что ты хочешь реализовать старая и несбыточная мечта

почему? Что в описанном (тонком сервере) не реально или не сбыточного?

Правка: 3 окт. 2016 22:23

robotcityПостоялецwww3 окт. 201622:24#8
tac
прям тебя в крайности бросает, майнкрафт это пример полностью изменяемого мира, если у тебя мир имеет карту статичную и камни которые можно таскать, то статичную карту передавать не надо, а камни передавать чанками. Придумаешь что то новое обязательно напиши, а хранить логи на клиенте и синхронизовать это по сути P2P или bitcoin или что там еще придумали в этом плане, большая проблема с временем сихнронизации и огромная брешь в безопастности так как за достоверность данных уже отвечает клиент, а клиент это аморальная личность)
robotcityПостоялецwww3 окт. 201622:26#9
tac
> почему? Что в описанном (тонком сервере) не реально или не сбыточного?
потому что все ммо имеют статичный мир, не зря же, конечно реализовать можно, только сервер выдержит мало народу и конечно же можно будет создать скрипт который будет нагружать твой сервер, создать огромное количество записей в бд, перекладывая камень с места на место, да проблем там много, плохая затея.
mcivПостоялецwww3 окт. 201622:26#10
Если в мире мало камней, но при этом их постоянно швыряют игроки, то записей логов во 2-м варианте окажется больше, чем записей о координатах камней в 1-м.
Соответственно, разделение "толстый/тонкий" не совсем корректно.
Достаточно универсальное решение (если нужно именно универсальное) поэтому будет поддерживать и координаты, и логи.

Разделение "имеет/не имеет базу данных" - непонятно, т.к. логи можно хранить в СУБД, а координаты можно хранить в массиве в памяти. На этом уровне описания непонятно, и что имеется в виду под базой данных (СУБД, данные в памяти или произвольный набор файлов).
По-моему, достаточно универсальное решение должно поддерживать длинные игровые сессии, а значит, должно сохранять данные на сервере при перезагрузке сервера, т.е. обязательно нужна какая-либо база данных, поддерживающая долговременное хранение.

greencrazycatПостоялецwww3 окт. 201622:37#11
tac
> быстрая запись не равно nosql ;) Наоборот c nosql у нас проблемы с формирование
> состояния мира из сообщений если передаются изменения мира. Единственно, если
> как говорит robotcity - клиенты будут постоянно передавать свое локальное
> состояние в мире, тем самым просто обновлять области состояния мира целиком
> ...
>
> Но так мне кажется они будут передавать много лишнего и постоянно. По сути
> будет дублироваться то, что надо передать ... если 3 игрока находятся рядом,
> они все три будут передавать плюс минус одно и то же.
>
>
зачем всё в одну кучу намешал :)
есть игроки - есть их допустим перемещения и действия - это одна модель (модель игрока)
есть мир меняемый игроками (твой пример с камнем) - это другая модель (модель мира)

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

если нет необходимости делать реплей всегои вся - зачем пихать в БД действий игрока которые не влияют на вновь подключившихся игроков

пример:
игрок "Vasja" переметился из точки А в точку Б и поднял камень id122334

что нужно знать новому игроку "Petja" который подключился ?
1. где находиться сейчас игрок "Vasja" и что у него есть камень
2. модель мира во всеми камнями которые есть в мире

сервер даёт "Petja" инфу вообще не дергая БД - т.к. вся эта инфа у сервера есть

Правка: 3 окт. 2016 22:40

tacПостоялецwww3 окт. 201622:39#12
mciv
> что имеется в виду под базой данных (СУБД, данные в памяти или произвольный набор файлов)

В моем классическом понимании - база данных - это сугубо реляционная база данных, с СУБД если говорим о сервере, и без СУБД если говорим о клиенте (например, SQLite или старый .dbf). Все остальное не является базой данных, т.к. не хранится в 3-ей нормальной форме. Вот такой я мамонт )

mciv
> логи можно хранить в СУБД, а координаты можно хранить в массиве в памяти

Можно, но нет смысла для логов задействовать базу данных. Нужный отрезок логов проще найти от конца файла до нужного timestamp и отправить клиенту для разбора. А вот координаты повляются только после парсинга логов, и преступление их снова скидывать в неформатированный текст.

А в массиве памяти можно держать только во время сессии, что и сам написал

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

но не обязательно на сервере

Правка: 3 окт. 2016 22:48

robotcityПостоялецwww3 окт. 201622:41#13
tac
ты приписал мне чужой коммент, напомнил мне высказывания знаменитостей в социальных сетях) я такого не говорил)
tacПостоялецwww3 окт. 201622:44#14
greencrazycat
> зачем всё в одну кучу намешал :)

да не, видимо меня не поняли )

Все верно про модель мира и модель игрока. Я пока говорю ТОЛЬКО про модель мира. Просто для клиента модель мира можно обновлять не целиком, а локально вокруг игрока (это тот скажем так 3 подход, на который указали говоря о майнкрафте)

Страницы: 1 2 3 4 ... 10 11 12 Следующая

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

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