Создание реал-тайм сетевой игры
| |
Pesets | Дата: Понедельник, 16 Июля 2012, 11:57 | Сообщение # 1 |
постоянный участник
Сейчас нет на сайте
| Всем привет. Я тут недавно начал делать сетевую игру в духе данжн кравлера с немного упрощенным геймплеем. Это мой первый опыт писать реал-тайм сеть. Собственно, я впервые столкнулся с надобностью писать систему предсказаний. Сделал попытку написать систему сам, вышло не ахти. Можно было, конечно, взять и довести ее до ума своими силами, но я решил-таки пробежаться по интернетам, посмотреть, что народ советует. Годных статей толком не нашел. Все в основном советуют курить исходники готовых игр.
Так вот, может кто-нибудь знает какой-нибудь годный материал на тему системы предсказаний / устранения задержек при работе с сетью?Добавлено (16.07.2012, 11:57) --------------------------------------------- На самом деле очень печально, что на нубовопросы, где люди просят сравнить мягкое и теплое сразу налетает куча народу, пусть и троллей, а на вполне конкретный вопрос никто даже не попытался ответить. Привет товарищу GC-Vic, который дал мне предупреждение за мнение, что здесь нет профи. Профи, ау!
|
|
| |
MasTerilDar | Дата: Понедельник, 16 Июля 2012, 12:03 | Сообщение # 2 |
безталантливый ХУДОжник пиксель артист :3
Сейчас нет на сайте
| Pesets, ну профи тут может есть, но они либо заняты, либо им это неинтересно, либо профи не по теме
Alle von euch Nya!
|
|
| |
Apati | Дата: Понедельник, 16 Июля 2012, 12:22 | Сообщение # 3 |
заслуженный участник
Сейчас нет на сайте
| Тема весьма интересная, но литературы к сожалению мало. Вот статья интересная, но там только в общих чертах.
|
|
| |
Qvant | Дата: Понедельник, 16 Июля 2012, 12:29 | Сообщение # 4 |
почти ветеран
Сейчас нет на сайте
| Pesets есть в интернете статьи с интерполяцией и апроксимацией с примерами в реалтайме для игр... Если в двух словах: То нужен протокол UDP , клиент жёстко синхронизован с сервером (посылает данные часто с постоянным промежутком времени). Пакеты обрабатываются (пропущенные отчёты апроксимируются , те что пришли не в своём порядке надо переставить). Если пропущен один или два пакет , то данные ещё можно апроксимировать , если больше - тогда соедининие рвётся. Ну и методом интерполяции в клиенте вычисляется движение других игроков по этим же отчётам.
|
|
| |
Apati | Дата: Понедельник, 16 Июля 2012, 12:37 | Сообщение # 5 |
заслуженный участник
Сейчас нет на сайте
| Quote (Qvant) нужен протокол UDP Почему именно UDP?
|
|
| |
Qvant | Дата: Понедельник, 16 Июля 2012, 12:56 | Сообщение # 6 |
почти ветеран
Сейчас нет на сайте
| Quote (Apati) Почему именно UDP? При передачи небольшого пакета скорость будит до 3 раз быстрей , чем больше пакет тем будит меньше разница.
|
|
| |
stalker5889 | Дата: Понедельник, 16 Июля 2012, 13:08 | Сообщение # 7 |
Свободный игродел
Сейчас нет на сайте
| Quote (Qvant) При передачи небольшого пакета скорость будит до 3 раз быстрей , чем больше пакет тем будит меньше разница. Но нет никакой проверки на сохранность пакета. Быстнее, но ненадёжнее и небезопастно. К тому же пакеты легко перехватить. Если нужно гарантировать доставку и безопасность пакета то лучше TCP, если скорость то UDP. Ах, да это всё ИХМО.
|
|
| |
Qvant | Дата: Понедельник, 16 Июля 2012, 13:29 | Сообщение # 8 |
почти ветеран
Сейчас нет на сайте
| Quote Но нет никакой проверки на сохранность пакета. Быстнее, но ненадёжнее и небезопастно. К тому же пакеты легко перехватить. Если нужно гарантировать доставку и безопасность пакета то лучше TCP, если скорость то UDP. Ах, да это всё ИХМО. Конечно это справедливое высказывание , но немного поясню - в реал тайме важна скорость (UDP) Пропал один два пакета - фик с ним , движение интерполируется по соседним отчётам , важная информация при пропадания отчёта может быть послана снова - если есть обратная связь (какой пакет пропал) В каждом пакете высылается номер пакета - это итак понятно. В итоге всёравно имеем быстрей чем TCP.
Теперь о птичках - TCP как ни странно тоже не гарантирует передачу данных! Грубо говоря отличие в том что TCP идёт 2 подтверждение что слушатель готов принять пакет и что пакет дошёл . Хорошо для редких пакетов , и скорость до 3 раз ниже. А в реалтайме несколько пакетов в секунду отсылается и не прырывно - вичислить что пропало легко.
Перехватить одинаково легко и TCP и UDP - шифровать пакеты надо
|
|
| |
Pesets | Дата: Понедельник, 16 Июля 2012, 14:23 | Сообщение # 9 |
постоянный участник
Сейчас нет на сайте
| Однако. Стоило апнуть тему, сразу появились ответы! Ура!) Про TCP и UDP - ну, я пишу на TCP, хотя в принципе это не важно. По-хорошему, игра при пинге в ~500 должна быть еще играбельной.
Apati, эх, вот найти бы что-то подобное, но немного подробнее...
Уточняю вопрос. А точнее, отбрасываю то, в чем уже разобрался. Пусть у нас есть такая ситуация: -Клиент посылает команду (скажем, идет вперед) -Миллисекунд через 200 сервер эту команду получает. -Если сервер начинает двигать клиента как получил команду, то на клиенте будет лаг минимум в 200 мс -Если сервер начинает откатываться в прошлое, во-первых, неизвестно точно, на сколько откатываться, во-вторых, умный клиент может сделать fake delay при отправке и нагибать сервер как ему захочется.
Что делать серверу?
|
|
| |
Apati | Дата: Понедельник, 16 Июля 2012, 17:41 | Сообщение # 10 |
заслуженный участник
Сейчас нет на сайте
| В моем представлении диванного теоретика сетевой код выглядит так: Когда сервер отправляет сообщение клиенту, он запоминает время, когда он его отправил. Клиент имеет что-то вроде таймера, который сбрасывается на 0 каждый раз при получении сообщения с сервера. Когда в клиенте происходит событие (нажатие клавиши например), он отправляет сообщение серверу и в сообщении прилагает значение таймера (т.е. время, прошедшее с момента получения сообщения до срабатывания события). Сервер получает сообщение и прибавляет к запомненному ранее времени значение таймера полученное от клиента - таким образом сервер будет знать на сколько откатываться. Конечно сервер должен проверять корректность таймера (значение слишком большое например).
Например: отправка сообщения от сервера клиенту - время на сервере 300 клиент получает сообщение - время на сервере 320 спустя 5 миллисекунд после этого происходит событие на клиенте и он отправляет на сервер сообщение со значением 5 - время на сервере 325 сервер получает сообщение в 345, проверяет корректность данных(если, допустим полученное время с клиента >200, то оно приравнивается 200), высчитывает время происхождения события на клиенте - 300+5=305 - откатывается на 305
|
|
| |
AGENTX001 | Дата: Понедельник, 16 Июля 2012, 23:20 | Сообщение # 11 |
почётный гцупер
Сейчас нет на сайте
| Pesets, а зачем тебе столь точная синхронизация данных между клиентами? Для проверки стрельбы? Я "придумал" более изящный способ, который можно использовать например в топ-даун шутерах: Quote -Игрок А стреляет, при этом клиент рассчитывает в кого теоретически должен попасть выстрел (допустим это игрок Б). -Клиент А отсылает на сервер информацию о выстреле (в кого стреляем, в частности игрок Б). -Сервер проверяет возможность выстрела (у игрока А достаточно патронов, между А и Б нет стен и т. д.), а затем вычисляет попадёт ли А в Б и сколько нанесёт урона, на основании их статов, расстояния, брони на и немножечко рандома. -Сервер отсылает всем клиентам информацию о выстреле А. -Все кто получает информацию о выстреле "подстраивают" картинку под себя: разварачивают спрайт игрока А в сторону игрока Б, рисуют пулю, кровь и т. д. Я думаю метод имеет право на жизнь. Естественно картинка будет немного различать у игроков, но пикселей 20-30 ничего не решают.
|
|
| |
Qvant | Дата: Вторник, 17 Июля 2012, 00:07 | Сообщение # 12 |
почти ветеран
Сейчас нет на сайте
| Quote (Pesets) Пусть у нас есть такая ситуация: -Клиент посылает команду (скажем, идет вперед) бьём по рукам такому разработчику ММО игры Например у нас движение по прямой: игрок кликает мышкой куда ему идти на сервер отправляется начальное время , начальные и конечные координаты и сразу начинает движение не дожидаясь отклика от сервера
сервер вычисляет есть ли другие игроки рядом и если есть то им отсылается эти параметры начальное время , начальные и конечные координаты
другие клиенты начинают отрисовавать движения , но с немного большей скоростью вначале , чтоб на конечной точке совпало время прибытия самого игрока и у других клиентов. Получается что другой игрок как бы побежал...
Передвижние по алгоритму А* с обходом препятствий - путь вычисляется на первом клиенте и передаётся начальное время и массив координат точек пути Всё тоже самое но остальные клиенты проверяют путь первого игрока чтоб не было читов (сервер путь и колизии вообще не должен вычислять)
|
|
| |
Qvant | Дата: Вторник, 17 Июля 2012, 00:13 | Сообщение # 13 |
почти ветеран
Сейчас нет на сайте
| Quote (Qvant) Сервер проверяет возможность выстрела (у игрока А достаточно патронов, между А и Б нет стен и т. д.), а затем вычисляет попадёт ли А в Б и сколько нанесёт не желательно на сервере проверять коллизии ...
|
|
| |
AGENTX001 | Дата: Вторник, 17 Июля 2012, 00:32 | Сообщение # 14 |
почётный гцупер
Сейчас нет на сайте
| Qvant, ну я это и не собирался делать, просто так написал Пускай тогда другие клиенты проверяют, если есть неточности - отключаем с психопадным воем "пошол вон читер галимый")
|
|
| |
Pesets | Дата: Вторник, 17 Июля 2012, 01:29 | Сообщение # 15 |
постоянный участник
Сейчас нет на сайте
| Окай, окай. Все понял, значит берем однозначно вариант 2. Тогда встает вопрос - что делать с нагибаторами, которые при отправке пакетов могут выставить неверное время отправки команды?
|
|
| |
Vinchensoo | Дата: Вторник, 17 Июля 2012, 08:19 | Сообщение # 16 |
Злобный социопат с комплексом Бога
Сейчас нет на сайте
| Pesets, криптографить
|
|
| |
Qvant | Дата: Вторник, 17 Июля 2012, 08:55 | Сообщение # 17 |
почти ветеран
Сейчас нет на сайте
| Quote (Pesets) Тогда встает вопрос - что делать с нагибаторами, которые при отправке пакетов могут выставить неверное время отправки команды? Простенькая проверка на сервере сравниваем полученое время от клиента с временем на сервере. Если отправленое время будит опережать время на сервере , тогда переносим игрока в локацию "тюрьма" и там его пытаем Если время запаздывает больше положеного (например у нас стоит граница в несколько секунд , а пришла команда что игрок начал движение час назад) - выкидываем этого игока в меня с окошком "соединение разорвано".
|
|
| |
zodiak | Дата: Вторник, 17 Июля 2012, 10:16 | Сообщение # 18 |
постоянный участник
Сейчас нет на сайте
| Quote (Qvant) TCP как ни странно тоже не гарантирует передачу данных Не правда. Если не придираться к словам, то в TCP все, что было отправлено, будет получено. Именно для этого он и создавался. В случае неполучения пакета TCP отправляет его повторно. В UDP же этот механизм нужно делать самому. И для его реализации тоже будут затраты сетевого времени.
Точка зору окремо взятого індивіда завжди суб'єктивна!
Взломщик Battle City.Net
|
|
| |
Qvant | Дата: Вторник, 17 Июля 2012, 11:35 | Сообщение # 19 |
почти ветеран
Сейчас нет на сайте
| Quote (zodiak) Не правда. Если не придираться к словам, то в TCP все, что было отправлено, будет получено. Именно для этого он и создавался. В случае неполучения пакета TCP отправляет его повторно. Нет , повторный и последующие пакет тоже может не дойти по TCP если он не дошёл то вернётся ошибка , по UDP ошибка не вернётся.
Quote (zodiak) В UDP же этот механизм нужно делать самому. И для его реализации тоже будут затраты сетевого времени. так я написал если пакеты посылаются часто в равный промежуток времени тогда для UDP легко сделать проверку тех пакетов которые теряются и приходят вне очереди! шлём n пакет на сервер шлём n+1 пакет на сервер шлём n+2 пакет на сервер шлём n+3 пакет на сервер пришла команда от сервера что пропал пакет шлём n+2 пакет на сервер если там важная информация тогда шлём n+4 пакет + n+2 если важного ничего нет (например промежуточные координаты , которые сервер сам вычислил методом интерполяции по n+1 и n+3) тогда просто шлём n+4 пакет
В TCP при этом будут жестоки задержки - послали запрос на передачу пакета - ждём пришёл запрос , если сервер готов - посылаем пакет ждём ответ от сервер что пакет дошёл посылаем запрос на второй пакет...
если не дошёл тогда снова посылаем запрос Если так передавать движение то игрок помрёт от задержек!!!
Если у нас одиночное событие - например клиент посылает команду раз в несколько минут в произвольный промежуток времени то тут TCP выгодней.
|
|
| |
AGENTX001 | Дата: Вторник, 17 Июля 2012, 11:49 | Сообщение # 20 |
почётный гцупер
Сейчас нет на сайте
| Qvant, всё зависит от требуемых задач. УДП, тоже знаешь не идеален. Для "не очень" реалтаймовой игры - ТСП идеальный вариант.
|
|
| |
|