Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Многопользовательская игра реального времени - нужен совет (http://www.flasher.ru/forum/showthread.php?t=127976)

iflamberg 27.07.2009 17:24

О какой потере данных вообще речь? У нас tcp/ip соединение, никаких потерь, только следующий пакет не передается пока не пришло подтверждение о доставке предыдущего, что приводит к лагам в 100мс.

2BloodHound. Именно так и делают. Иначе на экране будут подвисшие изображение по 300мс.
См., например, http://www.kongregate.com/games/DJSt...isputed-galaxy - достаточно частые случаи, когда стреляешь ты стреляешь, а потом дерг - противник совсем в другом углу.

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

Gaen 27.07.2009 17:44

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

BlooDHounD 27.07.2009 18:38

iflamberg, подвисшие на 300 мс o_0? ну тут скорее дело в кривизне сервера, чем в недостатке предсказаний.

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

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

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

принцип простой на самом деле:
1. синхронизируется время с точностью до 100 миллисекунд между сервером и клиентом
2. всё действия, которые должны выполнять игроки, сервер посылает вместе со временем, в которое они должны эти действия закончить.
3. все расчёты на клиенте проводятся относительно серверного времени
4. получаем систему, которая показывает в реальном времени, что сейчас происходит на сервере, с точностью до 100 миллисекунд.
5. чтобы добиться плавности и сгладить задержки сети, мы самостоятельно рассчитываем скорость исходя из текущих и конечных данных. будут получаться не большие ускорения/замедления незаметные игроку. что бы сгладить ответ сервера, мы можете, например, начать поворачивать Ваш кораблик, или сделать анимационную фиговинку под курсором, что бы отвлечь пользователя на 200 миллисекунд, пока сервер будет отвечать :)

таким образом при СИЛЬНОМ лаге, у Вас все кораблики очень быстро прилетят к своим точкам, а не телепортнуться, и пользователь будет видеть, что произошло, а не пытаться врубиться, откуда это всё взялось. не будет писать багрепорты, что он стрелял в кораблик и не попадал, а его застрелил кто-то невидимый в спины.

Gaen 27.07.2009 20:05

BlooDHounD, как бы вам объяснить, чтобы вы меня наконец поняли.

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

Вы описываете систему, в которой всё синхронно с точностью до 100 миллисекунд. Пока закроем глаза на то, что это это значит 10 раз в секунду принимать данные от каждого клиента, пересчитывать поле и рассылать всем клиентам новые данные.

Цитата:

Всё действия, которые должны выполнять игроки, сервер посылает вместе со временем, в которое они должны эти действия закончить.
Цитата:

чтобы добиться плавности и сгладить задержки сети, мы самостоятельно рассчитываем скорость исходя из текущих и конечных данных
Нет никаких конечных данных! Если вы под конечными данными подразумеваете те, которые только что пришли с сервера, то они уже устарели ровно на то время, которое добирались от сервера до клиента. Они будут актуальными только в том случае, если пинг до клиента меньше игрового тика, а это далеко не всегда верно.

Если я вас правильно понял, то вы предлагаете такую систему:
1. Игрок А начинает движение и извещает об этом сервер
[проходит время]
2. Сервер получает сообщение, ждет конца таймаута и пересчитывает поле
3. Сервер рассылает клиентам обновленные данные
[проходит время]
4. Игрок Б получает сообщение
5. Клиент игрока Б начинает двигать корабль А. Хотя реально к этому моменту корабль А уже двигался в течение какого-то времени, и находится не там, где его видит игрок Б. Более того, игрок Б получает оповещение о собственном движении тоже с задержкой, и видит себя не в том месте, где он сейчас реально находится.

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

Цель всего этого - построить систему, которая сможет оставаться синхронной на больших пингах.

BlooDHounD 27.07.2009 20:19

это Вы меня не поняли.

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

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

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

я предлагаю такую схему:
1. игрок А хочет начать движение и извещает об этом сервер
2. сервер ждет конца таймаута и пересчитывает поле ( вот тут как бы дело ваше. я бы сразу считал, тогда нагрузка на сервер была бы распределена по мере поступления данных, а не пиково в моменты тиков )
3. сервер рассылает клиентам обновленные данные
[проходит время] ( с нормальным нетом ~20-50 миллисекунд )
4. игрок Б получает сообщение ( как и игрок А, практически в одно и тоже время )
5. клиент игрока Б начинает двигать корабль А, ровно в тот момент, в который это начинает и делать и игрок А.
6. корабль игрока А начинает двигаться на обоих машинах практически одновременно, и двигается он синхронно.

кстати у нас в дестени время синхронизируется обычно с точностью до 10-20 мс. в локальной сети до 2-4 мс.

Gaen 27.07.2009 22:22

Цитата:

1. игрок А хочет начать движение и извещает об этом сервер
2. сервер ждет конца таймаута и пересчитывает поле ( вот тут как бы дело ваше. я бы сразу считал, тогда нагрузка на сервер была бы распределена по мере поступления данных, а не пиково в моменты тиков )
3. сервер рассылает клиентам обновленные данные
[проходит время] ( с нормальным нетом ~20-50 миллисекунд )
4. игрок Б получает сообщение ( как и игрок А, практически в одно и тоже время )
5. клиент игрока Б начинает двигать корабль А, ровно в тот момент, в который это начинает и делать и игрок А.
6. корабль игрока А начинает двигаться на обоих машинах практически одновременно, и двигается он синхронно.
Предельно ясно, нет вопросов.
В этом подходе меня смущало то, что все-таки существует постоянная задержка, хоть и незначительная. Но главное, я наконец полностью осмыслил, что же пытался сказать :) Метод позволит большую часть времени держать синхронизацию теоретически идеальную, она будет немного нарушаться только при изменении вектора скорости. Вместо незначительной задержки мы получим незначительные корректировки координат, скорости и ускорения.
Насчет того, когда пересчитывать - зависит от. Если висит скажем 5 клиентов, то выгоднее пересчитывать сразу при получении данных. Если их сотня, то лучше собрать команды, которые они наприсылали, и обсчитать всё пачкой.

Цитата:

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

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

Что вы имеете в виду под действием?

BlooDHounD 27.07.2009 22:53

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

Gaen 27.07.2009 22:56

например?

BlooDHounD 27.07.2009 23:06

идти, туда, и быть там во столько-то

Gaen 27.07.2009 23:29

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

Я хочу сделать именно живое управление кораблем. Играли может в такую старую игрушку Roketz?


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

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