Перейти к содержимому
CRUSHFORMV1.1.0
ПОЛУЧИТЬ НА FAB

МУЛЬТИПЛЕЕРРЕПЛИКАЦИЯ И ПРЕДСКАЗАНИЕ

Репликация и предсказание

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

Авария на одном клиенте сразу вминает кузов на этом клиенте. Затем сервер подтверждает вмятину, и её видит каждый другой игрок на своём экране.

Два окна Play In Editor рядом. Слева, NetMode Client 1: седан едет на оранжевую стену со скоростью 99 км/ч. Справа, NetMode Server 0: второй седан вдали стоит передним бампером на дороге рядом, а собственный седан сервера ждёт на переднем плане при 0 км/ч.
Управляющий клиент (слева) и сервер (справа) в двух окнах Play In Editor.
Авария в обоих окнах: бампер отрывается в окне клиента и в окне сервера.

Authority в адаптере автомобиля выбирает инстанс, который симулирует машину и засчитывает её удары. Две модели и допуск на таран описаны в Основных понятиях; правила, которые сервер применяет к каждому отчёту, — ниже.

С моделью Owning Client управляющий клиент применяет каждый удар к своей решётке сразу. Он применяет отчёт, который отправит, декодированный так же, как его декодирует сервер, поэтому обе стороны получают одинаковые числа. Удар сверх бюджета отчётов клиента (Max Reports Per Second) не рисуется совсем, а не рисуется и потом отменяется.

Клиент отправляет свои отчёты на сервер пачками, в каждой не больше Max Reports Per Batch отчётов. Сервер проверяет каждый отчёт, прежде чем его применить. Поколение ремонта должно совпадать. Точка должна лежать внутри решётки. Скорость и скольжение должны оставаться в пределах Max Plausible Delta V и ограничений на потёртости. Host-объект тоже может отклонить отчёт. Отклонённый отчёт возвращается клиенту как отказ, и клиент убирает свою вмятину. Предсказание, которое сервер не подтвердил и не отклонил за Pending Report Timeout, сбрасывается.

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

Сервер хранит истинную решётку и отправляет её чанками, как описано в Основных понятиях. Также реплицируются:

  • Поколение: число ремонтов. Чанки и отчёты другого поколения игнорируются.
  • Счётчик мойки: мойка заставляет каждый инстанс очистить грязь. Сама грязь по сети не передаётся.
  • Отделённые и качающиеся детали: какие навесные детали оторваны и какие отпустил качаться инстанс, который симулирует машину. Каждый инстанс отпускает деталь, когда приходит это решение, поэтому все игроки видят, как одна и та же деталь отходит в один и тот же момент. Само качание — собственная физика каждого инстанса.
  • Трещины стёкол, уровни разрушаемых элементов и недавние события разрушения, а также состояние поваленных деревьев. Что получает инстанс, который подключается позже, описано в Подключившихся позже игроках.
  • Звуки ударов: источник удара проигрывает удар и передаёт его дальше. Каждый другой инстанс проигрывает переданную копию.

Шины, звук качения и эффекты качения, а также звук двигателя не реплицируются. Каждый инстанс запускает свои.

  1. В Content Browser откройте Settings и отметьте Plugin Content. Откройте Plugins › Crushform Content › Blueprints › Sedan, продублируйте BP_VehicleAdvSedan в свой проект и откройте копию. На этой странице в качестве примера используется седан, но шаги подходят для любой машины с адаптером.

  2. В панели Components выберите CF_Adapter — адаптер Chaos для машины (UCFChaosVehicleAdapterComponent). Он наследует Authority от базового класса адаптера.

  3. В панели Details задайте Authority — Owning Client.

  4. Оставьте Ram Allowance Mps по умолчанию, 15, или повысьте его, если сильные тараны отклоняются. Это запас по скорости, который сервер допускает сверх недавнего пика.

    Crushform
    AuthorityOwning Client
    Ram Allowance Mps15.0 m/s
    Категория Crushform у адаптера Chaos, Authority установлен в Owning Client.
  5. Проверьте, что Deform Profile задан. Пустое значение берёт профиль проекта по умолчанию.

  6. Откройте Project Settings › Plugins › Crushform › Network. Значения по умолчанию подходят для первого теста. В таблице ниже описано, что делает каждое из них.

  7. В режиме игры, в котором вы играете, укажите в Default Pawn Class вашу копию. BP_VehicleAdvGameMode плагина создаёт собственный седан плагина как пешку, поэтому копия, которая не указана как Default Pawn Class, в игре никогда не едет, и её настройка Owning Client там ничего не делает.

  8. Сохраните Blueprint. В настройках Play задайте Number of Players равным 2 и Net Mode — Play As Listen Server, затем нажмите Play. Редактор откроет окно сервера (NetMode: Server 0) и окно клиента (NetMode: Client 1). Врежьте машину в стену в окне клиента и смотрите в окне сервера.

Частая задача Blueprint — починить машину на сервере. Repair и Wash выполняются только на инстансе-авторити, а то, что они очищают, реплицируется на каждый инстанс. График вызывает Repair из пользовательского события, которое вы вызываете с сервера, например из собственного серверного RPC.

График вызывает Repair из пользовательского события, которое вы вызываете с сервера.

Те же вызовы в C++:

// The vehicle actor that owns the adapter.
AActor* Vehicle = GetOwner();
if (UCFDeformComponent* Deform = Vehicle->FindComponentByClass<UCFDeformComponent>())
{
if (Vehicle->HasAuthority())
{
// Clears every dent and scratch, on every machine.
Deform->Repair();
}
// Hits this client sent that the server has not yet confirmed or refused.
const int32 Waiting = Deform->GetNumPendingReports();
// How many repairs the body has had.
const uint8 Generation = Deform->GetGeneration();
}
СвойствоЧто делаетПо умолчанию
UCFVehicleAdapterComponent::AuthorityКакой инстанс симулирует машину и засчитывает её удары: Server или Owning Client.Server
UCFVehicleAdapterComponent::RamAllowanceMpsПри Owning Client: насколько быстрее недавнего пика скорости, в м/с, может быть сообщённый удар.15
UCFProfile::MaxPlausibleDeltaVСамый сильный удар, в м/с, который может нести отчёт. Скольжение ограничено тем же пределом.40
UCFSettings::MaxReportsPerBatchОтчётов, которые управляющий клиент отправляет в одной пачке за кадр. Сервер отклоняет остаток более крупной пачки.8
UCFSettings::MaxReportsPerSecondОтчётов в секунду, которые принимает один компонент. Всплеск клиента такой же; корзина сервера в 1,5 раза глубже.60
UCFSettings::PendingReportTimeoutСекунд, в течение которых клиент хранит предсказанный удар, который сервер не подтвердил и не отклонил.10
UCFSettings::ScrapeReportIntervalСекунд между двумя отчётами о потёртостях одного компонента.0,1
UCFSettings::MaxScrapeDtСамое длинное скольжение, в секундах, которое может представлять один отчёт о потёртости.0,25

Запустите тест с двумя игроками из раздела «Настройка». В консоли редактора введите Crushform.Stats один раз. Команда выводит по строке на каждую деформируемую машину в каждом запущенном мире. Строка копии сервера говорит server lattice, а строка копии клиента — client view. Каждая строка выглядит так:

<vehicle>: <server lattice or client view>, generation <n>, <n> pending, <n> chunks | hits <n>, sent <n>, accepted <n>, rejected <n>, published <n>, received <n>, bad <n>, expired <n>, parts off sent <n>, accepted <n>, rejected <n>, collision builds <n>, longest <ms> ms, collision waits <n>, parts held <n>, part hulls <n>, longest <ms> ms, most points <n>

После аварии на клиенте его счётчик pending растёт и возвращается к 0, когда сервер подтверждает вмятину, а счётчик accepted на сервере растёт. Отклонённый удар виден как счётчик rejected на клиенте.

Причина. Сервер отклонил отчёт, и клиент убрал вмятину. Сервер отклоняет отчёт, когда его скорость или скольжение выше Max Plausible Delta V, когда его точка лежит вне решётки или когда его поколение ремонта устарело. При Owning Client также отклоняется удар сильнее недавнего пика скорости плюс Ram Allowance Mps.

Решение. Прочитайте счётчик rejected в Crushform.Stats. Задайте Authority — Owning Client, если клиенты должны засчитывать свои удары. Если реальные удары сильнее Max Plausible Delta V, повысьте его в профиле.

Причина. Authority машины стоит на Server. Клиент тогда не источник удара, поэтому он ничего не предсказывает и ждёт чанков сервера.

Решение. Задайте Authority — Owning Client, как в разделе «Настройка».

Вмятина откатывается через несколько секунд

Заголовок раздела «Вмятина откатывается через несколько секунд»

Причина. Сервер не подтвердил отчёт клиента за Pending Report Timeout (по умолчанию 10 секунд), и клиент сбросил предсказание.

Решение. Ищите rejected и expired в Crushform.Stats. Если тайм-аут слишком короткий для вашей сети, увеличьте Pending Report Timeout в разделе Network.