Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Синзронизация на AS3 (http://www.flasher.ru/forum/showthread.php?t=214198)

Dezar 03.05.2017 19:22

Синзронизация на AS3
 
Всем привет.
есть задача, сделать приложение, где будут разные люди бить по разным объектам.
например есть 20 кружков на экране.и есть 2 игрока, которые с этими шарами взаимодействуют(толкают, двигают не важно). и эти шары между собой так же сталкиваются и отскакивают.
2человека с разных пк через интернет соединяются.

ВОПРОС.
как лучше сделать синхронизацию на as3 , чтобы у всех в итоге отображалось всё одинаково.

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

FlashRus 03.05.2017 19:27

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

Dezar 03.05.2017 19:32

а как сложную коллизию на серваке обработать?есть какие-то примеры?или что почитать?

Nooob 03.05.2017 21:22

Есть кучу способов, хороший доклад на тему https://www.youtube.com/watch?v=CHX3cRjIv3U
Если нужна абсолютно идентичная картина на обоих девайсах и не хочется нагружать сервер, то нужна детерминированная симуляция на каждом девайсе и пересылать друг другу действия юзера через сервер http://www.gamasutra.com/view/featur...8_network_.php

Dezar 03.05.2017 21:59

спасибо

undefined 04.05.2017 00:25

Цитата:

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

caseyryan 04.05.2017 08:16

Цитата:

Сообщение от Nooob (Сообщение 1200483)
Есть кучу способов, хороший доклад на тему https://www.youtube.com/watch?v=CHX3cRjIv3U
Если нужна абсолютно идентичная картина на обоих девайсах и не хочется нагружать сервер, то нужна детерминированная симуляция на каждом девайсе и пересылать друг другу действия юзера через сервер http://www.gamasutra.com/view/featur...8_network_.php

Думается мне, что для динамичной игры, где действия пользователя могут опережать пинг, никакая детерминированная симуляция в принципе невозможна.
Чем-то придется жертвовать в любом случае
1) Идентичная картина = серверный просчет, и задержки на обработку
2) Быстрая обработка на клиенте = рассинхронизации

Nooob 04.05.2017 09:42

Цитата:

Сообщение от undefined (Сообщение 1200487)
Вот только скорость пересылки данных, может отличаться на порядки у разных юзеров. Единсвенный худо-бедно надежный способ держать всех синхронизорованными - считать все на сервере.

скорость пересылки не влияет на синхронность симуляции

Добавлено через 30 минут
Цитата:

Сообщение от caseyryan (Сообщение 1200489)
Думается мне, что для динамичной игры, где действия пользователя могут опережать пинг, никакая детерминированная симуляция в принципе невозможна.
Чем-то придется жертвовать в любом случае
1) Идентичная картина = серверный просчет, и задержки на обработку
2) Быстрая обработка на клиенте = рассинхронизации

Все верно, есть три возможных требования:
1. динамика действий пользователя
2. количество изменяемых объектов
3. идентичность картинки
выберите любые два)

есть пять адекватных решения:
a. независимая симуляция ("телевизор" состояния с аппроксимацией объектов) подходит для шутеров, где малое количество объектов, идентичность картинки не важна, и динамика пересылки данных раз в 7-15 мс (Counter-Strike)
b. синхронная симуляция (детерминированная симуляция мира) подходит для стратегий, где большое количество объектов живущих своей жизнью, идентичная картинка, динамика пересылки данных раз в 250-500 мс (Age of Empires)
c. гибридная симуляция (детерминированная симуляция с аппроксимацией действий пользователя с оптимистичным выполнением и возможностью отката мира с пересимуляцией) подходит для кооперативных игр с большим количеством объектов живущих своей жизнью, большая динамика, немного другая картинка
d. авторитарный сервер подходит для игр с низкой динамикой и большим количеством объектов, например пошаговая игра
e. синхронная симуляция с масштабируемым tickrate, подходит для файтингов, где малое количество объектов с большой динамикой и важна полная синхронизация

Psycho Tiger 04.05.2017 10:23

Почему в шутерах не важна идентичность картинки?

Nooob 04.05.2017 10:49

Цитата:

Сообщение от Psycho Tiger (Сообщение 1200493)
Почему в шутерах не важна идентичность картинки?

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

undefined 04.05.2017 11:31

Цитата:

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

Nooob 04.05.2017 11:45

Цитата:

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

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

undefined 04.05.2017 11:50

ну так и где же тут?
Цитата:

абсолютно идентичная картина на обоих девайсах
И кто говорит про стратегию?

Добавлено через 59 секунд
спор как раз о том,что абсолютно идентичная картина невозможна в принципе.

Nooob 04.05.2017 12:02

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

undefined 04.05.2017 12:31

т.е. отвал одного игрока стопорит всех остальных?Так себе решение.

Tails 04.05.2017 13:07

Чувак из видео советует написать свой float, для детерминированных расчётов. Жёсткий совет, ппц какой жёсткий :) Параллельно придётся переписать и всю физику и любую другую либу, использующую float и участвующую в симуляции, ещё и постоянно следить за этим.. Такая проблема различия обработки чисел с плавающей запятой касается только компилируемых языков (c++), или в интерпретируемых она тоже имеется? Вот, к примеру, флешовый Number, он на всех девайсах работает одинаково? Что-то я не нашёл упоминания об этом в хелпе.

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

caseyryan 04.05.2017 13:24

Цитата:

или в интерпретируемых она тоже имеется?
Тоже имеется. Основа то все равно та же. И тут дело не в языке, а в платформе.
Цитата:

Вот, к примеру, флешовый Number, он на всех девайсах работает одинаково?
Читал, что тоже не одинаково. Сам не проверял

Nooob 04.05.2017 13:33

Цитата:

Сообщение от undefined (Сообщение 1200503)
т.е. отвал одного игрока стопорит всех остальных?Так себе решение.

Нет, смотри у тебя есть два клиента, один сервер, общение по сокету, запускается игра, сервер начинает слать всем клиентам через каждые 200мс 4 байта - номер тика, когда пользователь совершает действие, он отправляет на сервер запрос я пнул шар по координатам x y, сервер получает действие и всем клиентам в следующей раздаче тиков отправляет 4 байта(текущий номер тика) + 12 байт (x, y, user). клиенты на указанном тике применяют действие (запускают физику и тд). итого получается так что если у игрока лаганула сеть то он будет ждать следующий тик, когда он придет он домотает моментально симуляцию до текущего известного тика и он никак не стопроит остальных. потому что за раздачу тиков отвечает сервер а не клиенты, клиенты лишь уведомляют сервер о том что хотят совершить такое-то действие, а когда оно совершится решает сервер

Добавлено через 12 минут
Цитата:

Вот, к примеру, флешовый Number, он на всех девайсах работает одинаково?
Number реализован по стандарту IEE754, внутри виртуальной машины работает в качестве double C++ c -fp-model precise (написана только кастомная флешовая сереализация/десереализация в string)
Статья на тему https://habrahabr.ru/post/112953/
я проверял на различных процессорах, x86, x86_64, armv7, arm64, intel, amd, ios, андроиды, на sqrt, sin, cos, на малых диапазонах если после каждой операции округлять до 4 знака после запятой то значения получаются одинаковые, но лучше по возможности использовать int, uint.
ну и упрощать всякие вычисления, к примеру при поиске ближайшего противника достаточно сравнивать вместо честной дистанции (sqrt(x*x + y*y)) использовать квадрат дистанции (x*x + y*y)

undefined 05.05.2017 09:32

Цитата:

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

caseyryan 05.05.2017 12:00

Цитата:

а если новый юзер приходит кто ему полный стейт скажет?Прокручивать весь геймплей с самого начала?Уж лучше чтоб бэкенд тоже считал мир,правда тогда возвращаемся к варианту когда всем заведует сервер.
А зачем ему полный геймплей? Я разруливал это просто передачей текущего стейта. Относительно текущего он и начинал считать все происходящее. По той же схеме, что и остальные. Всё работало. Не всегда есть возможность сделать, чтобы весь мир считал сервер

Nooob 05.05.2017 14:51

Цитата:

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

Домотать логику обычно не составляет проблем, к примеру тик симуляции считается в худшем случае 2 мс то симуляция 5 минутного геймплея будет не больше 18 сек, после пяти минут сервер спрашивает у всех клиентов состояние мира, если оно у всех одинаковое продолжает игру и сохраняет его для следующих новых игроков

undefined 05.05.2017 15:42

Nooob,объясни с чем может быть связано такое острое нежелание хранить полный стейт на сервере?Уж если клиент может считать симуляцию, то сервер сможет и подавно.
Ты описываешь какие-то дикие велосипеды с сомнительной надежностью(например что делать если выяснится таки что не все единогласно сходятся по поводу стейта игрового мира.Как решить кто прав?)

Tails 05.05.2017 16:52

Цитата:

Как решить кто прав?)
Рассинхронизация = конец игры для всех. Делать какие-то защитные механизмы или способы восстановления бессмысленно потому, почему и бессмысленно делать защиту от обращения к несуществующему индексу массива, например. Это есть баг и такого просто не должно быть изначально.

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

Я знаю, что такой метод используется в стратегиях реального времени. Представь себе карту, на которой 1к юнитов и 12 игроков. Каждый игровой шаг (~10 раз в секунду) тебе надо будет отослать 12 игрокам положение, направление, скорость движения (состояние) всех 10к юнитов. Какое количество трафика это будет? Вместо этого, ты можешь отослать этим 12 игрокам "приказ движения" 10к юнитам в указанную точку. А дальше они сами посчитают, где и как будет находиться каждый конкретный юнит.

undefined 05.05.2017 17:19

Цитата:

Я знаю, что такой метод используется в стратегиях реального времени. Представь себе карту, на которой 1к юнитов и 12 игроков. Каждый игровой шаг (~10 раз в секунду) тебе надо будет отослать 12 игрокам положение, направление, скорость движения (состояние) всех 10к юнитов. Какое количество трафика это будет? Вместо этого, ты можешь отослать этим 12 игрокам "приказ движения" 10к юнитам в указанную точку. А дальше они сами посчитают, где и как будет находиться каждый конкретный юнит.
Пример с потолка.А что мешает серверу отслать тоже самое(приказ движение)?Никто в здравом уме не будет на каждый чих посылать полный стейт.
Цитата:

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

Tails 05.05.2017 17:33

Цитата:

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

Цитата:

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

undefined 05.05.2017 17:45

Цитата:

Суть в том, что если о способе изменения знает только сервер, то тебе по любому придётся слать состояние, события и прочее всем игрокам. А событии в реал тайм игре будет очень много, помимо перемещения.
Сервер шлет только дифы к стейту(игрок 1 выделил группу из 1к юнитов и направил их в x,y).Это не так много данных.Огромный плюс при этом что сервер сам знает точно где и кто находится, так что даже если у кого-то случится рассинхрон, он может просто скачать полный стейт с сервера и продолжить игру.
Цитата:

Почему?
Представь что играют 5 юзеров из России и 5 из США.Вдруг метеорит раскалывает планету пополам.Обе группы быстро назначают нового сервера и играют независимо.Дальше выясняется что существует обходной канал через спутник и сеть восстанавливается.В результате имеем две группы юзеров с сильно разными стейтами синхронизировать которых невозможно.

Tails 05.05.2017 17:55

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

undefined 05.05.2017 18:02

предложи свой вариант,гарантирующий 100% синхронизацию без сервера.

Добавлено через 3 минуты
и не забываем что группа юзеров вполне может на время перестроения сети отвалиться и потом назад приконнектиться.

Tails 05.05.2017 18:20

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

Обычно используются все 3 варианта. Сперва игра ставится на паузу, затем, если связь не восстановлена, следует пункт 1 или 2, в зависимости от каких-то обстоятельств. Можно дать игроку выбрать.

undefined 05.05.2017 18:25

возаращаясь к первоначальному посылу, какие это дает преимущества по сравнению с сервером?

Nooob 05.05.2017 19:06

Цитата:

Nooob, объясни с чем может быть связано такое острое нежелание хранить полный стейт на сервере?
Это не нежелание, я говорю о том что есть другие наиболее интересные и удобные альтернативы многопользовательского взаимодействия, а то всех кого не спросишь про это всегда отвечают авторитарный сервер.
Цитата:

Сообщение от undefined (Сообщение 1200521)
Сервер шлет только дифы к стейту(игрок 1 выделил группу из 1к юнитов и направил их в x,y).Это не так много данных.

Давай посчитаем, худший случай 1к юнитов которые куда-то бегут и по пути атакуют по пути врагов, сталкиваются друг с другом, с объектами, отрабатывают поиск пути и перемещаются по всем канонам steering behaviors
4 байта id юнита
4 байта x позиция
4 байта y позиция
4 байта здоровье
4 байта стейт
4 байта x вектора скорости
4 байта y вектора скорости

28 байт на юнита. 28 000 байт на один тик, для приемлемой игры нужно отправлять состояние/дифы каждые 33 мс, если у нас игра работает под 30 fps так как юниты всегда что то делают и не стоят на месте то отправляется вся инфа. за одну секунду должно отправиться 840000 байт. игроков 6 каждому нужно отправлять это состояние, стало быть сервер должен отдавать данные через канал 38,45 Мбит/сек и это лишь одна игровая сессия. 820 Кбайт данных каждую секунду клиент должен обработать своевременно, и это в противовес 16 байтам в секунду. И сервер должен в реальном времени все это проигрывать, если 1 тик считается 2 мс, то на один сервер можно повесить лишь 500 игровых сессий.

undefined 05.05.2017 19:18

блин вы меня не слушаете.Не надо передавать координаты каждого юнита.Вы че никто так не делает.Передаются действия игроков(юзер 1 ткнул мышью в x,y и выделил группу юнитов и послал в w,z).Просто реально проще и надежнее чтоб был авторитетный центр,который знает правду-матку.

Добавлено через 35 секунд
Цитата:

я говорю о том что есть другие наиболее интересные и удобные альтернативы
а в чем удобство то?

FlashRus 05.05.2017 19:31

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

Nooob 05.05.2017 19:36

Цитата:

Сообщение от undefined (Сообщение 1200529)
блин вы меня не слушаете.Не надо передавать координаты каждого юнита.Вы че никто так не делает.Просто реально проще и надежнее чтоб был авторитетный центр,который знает правду-матку.

Юниты перемещаются не линейно сталкиваясь с друг другом и с объектами, с поиском пути и stearing behavior, у них есть машина состояний атака/ходьба.

Если ты передаешь от сервера только действия пользователя, то тем самым ту приходишь к варианту что на каждом клиенте есть синхронная симуляция мира и это уже не схема авторитарный сервер, это схема синхронной симуляции, где сервер лишь играет роль наблюдателя (такой же как клиент).
минус сервера наблюдателя в том что:
1. он нагружается наблюдением, если клиентов много и каждого своя аппаратная мощность, то сервер стало быть будет играть во много игр одновременно
2. логика симуляции в таком случае должна быть написана на двух языках (клиент на AS3, сервер на C++/Java/C#/Python) и быть абсолютно идентичной, что сделать сложнее. писать сервер на AS3/Haxe через чур глупо) и на больших объемах все загнется
при этом это сервер решает лишь задачу выдачи актуального состояния для нового игрока, если это скажем игра типа Clash Royale, где нельзя по геймплею войти по середине боя, то смысла реализации такого сервера нету

undefined 05.05.2017 19:39

Noob по сути и предлагает классическую схему
Цитата:

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

Добавлено через 8 минут
Цитата:

Если ты передаешь от сервера только действия пользователя, то тем самым ту приходишь к варианту что на каждом клиенте есть синхронная симуляция мира и это уже не схема авторитарный сервер, это схема синхронной симуляции, где сервер лишь играет роль наблюдателя (такой же как клиент).
Да,он отслеживает стейт как и клиент, но его версия является приоритетной, что избавляет от механизма синхронизации.Который, кстати, совсем не факт что сможет так быстро смотать симуляцию вперед во времени.
Цитата:

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

Nooob 05.05.2017 19:50

Цитата:

Сообщение от FlashRus (Сообщение 1200531)
Noob, клиент не должен отправлять новое состояние системы, а как сказал undefined - должен отправлять своё воздействие на неё.

Я не говорил про то что отправляет клиент, я говорил о том что отправляет сервер

undefined 05.05.2017 19:52

Цитата:

логика симуляции в таком случае должна быть написана на двух языках (клиент на AS3, сервер на C++/Java/C#/Python) и быть абсолютно идентичной,
переложить логику с as3 на java- считай синтаксис поменять.Все равно сервер хочешь не хочешь нужен.А если там они округлять будут по-разному или еще какая мелочь - не страшно.

Добавлено через 1 минуту
Цитата:

Я не говорил про то что отправляет клиент, я говорил о том что отправляет сервер
так и я не говорил :)

Nooob 05.05.2017 19:58

Цитата:

Сообщение от undefined (Сообщение 1200536)
А если там они округлять будут по-разному или еще какая мелочь - не страшно.

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

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

undefined 05.05.2017 20:00

по мере надобности.

Nooob 05.05.2017 20:02

Цитата:

Сообщение от undefined (Сообщение 1200539)
по мере надобности.

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


Часовой пояс GMT +4, время: 13:01.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.