Сеть и репликация
Сетевая модель Unreal Engine — репликация свойств и Actor'ов, RPC, серверный авторитет, релевантность, дормантность и Replication Graph.
21 вопросов
JuniorТеорияОчень частоЧто такое реплицируемое свойство в Unreal и как оно держит состояние в синхроне?
Что такое реплицируемое свойство в Unreal и как оно держит состояние в синхроне?
Реплицируемое свойство — это переменная со спецификатором Replicated, чтобы сервер рассылал её значение клиентам. Сервер владеет значением; при изменении движок автоматически синхронизирует его с релевантными клиентами.
Типичные ошибки
- ✗Пытаться изменить реплицируемое свойство на клиенте и ждать, что оно сохранится
- ✗Забывать добавить свойство в
GetLifetimeReplicatedProps - ✗Путать реплицируемое свойство с
MulticastRPC
Уточняющие вопросы
- →Что позволяет делать функция
RepNotify(ReplicatedUsing)? - →Почему реплицируемое свойство нужно регистрировать в
GetLifetimeReplicatedProps?
JuniorТеорияОчень частоЧто такое RPC (Remote Procedure Call) в сетевой модели Unreal?
Что такое RPC (Remote Procedure Call) в сетевой модели Unreal?
RPC — это функция с сетевым спецификатором, которая выполняется на другой машине, а не на вызвавшей. Server RPC идут Client→Server, Client RPC — Server→владеющий Client, а Multicast RPC — на сервере и всех клиентах.
Типичные ошибки
- ✗Путать RPC (события/вызовы) с реплицируемыми свойствами (синхронизация состояния)
- ✗Забывать, что
ServerRPC должен вызываться с владеющего клиента actor - ✗Ожидать, что
MulticastRPC дойдёт до ещё не подключённых клиентов
Уточняющие вопросы
- →В чём разница между reliable и unreliable RPC?
- →Почему
ServerRPC требует ownership, чтобы реально выполниться?
JuniorТеорияОчень частоЧто такое репликация в Unreal Engine и какую задачу она решает?
Что такое репликация в Unreal Engine и какую задачу она решает?
Репликация — это сетевой механизм Unreal, который синхронизирует состояние Actor'ов с авторитетного сервера на подключённых клиентов. Он зеркалит помеченные свойства и направляет RPC, удерживая мир каждого клиента согласованным с сервером.
Типичные ошибки
- ✗Думать, что репликация работает P2P, а не от авторитетного сервера
- ✗Считать, что каждое свойство реплицируется автоматически без разметки
- ✗Путать репликацию с локальной сериализацией сохранений
Уточняющие вопросы
- →В чём разница между репликацией свойства и отправкой RPC?
- →Почему у Actor'а должен быть включён
bReplicates, чтобы участвовать в репликации?
JuniorТеорияЧастоЧто делает флаг bReplicates и зачем он нужен Actor'у в сетевой игре?
Что делает флаг bReplicates и зачем он нужен Actor'у в сетевой игре?
bReplicates включает Actor'а в сеть. Когда он true, сервер создаёт и отслеживает Actor'а на релевантных клиентах и обрабатывает его реплицируемые свойства. Когда false, Actor существует только локально и никогда не синхронизируется.
Типичные ошибки
- ✗Ждать синхронизации реплицируемых свойств при
bReplicatesравномfalse - ✗Думать, что
bReplicates— лишь редакторская метка без эффекта в рантайме - ✗Забывать, что реплицируемый Actor должен быть создан на сервере
Уточняющие вопросы
- →Что происходит с RPC, вызванными на Actor'е с
bReplicatesравнымfalse? - →Как
bReplicatesвзаимодействует с релевантностью и частотой сетевых обновлений Actor'а?
MiddleТеорияЧастоЧто такое владение Actor'ом и почему оно важно для RPC?
Что такое владение Actor'ом и почему оно важно для RPC?
Владение связывает Actor'а с Connection, прослеживаясь через цепочку Owner до PlayerController. Server RPC срабатывает, только если вызывающий клиент владеет Actor'ом; Client RPC достигает лишь клиента-владельца. Без владения такие RPC молча отбрасываются.
Типичные ошибки
- ✗Вызывать
ServerRPC с Actor'а, которым клиент не владеет - ✗Думать, что владение — лишь C++-указатель создателя без сетевой роли
- ✗Забывать, что владение определяется через цепочку
OwnerдоPlayerController
Уточняющие вопросы
- →Как задать владение Actor'ом, чтобы конкретный клиент мог вызывать его
ServerRPC? - →Почему
Pawnможет вызыватьServerRPC, а размещённый в мире объект обычно нет?
MiddleТеорияЧастоКакие распространённые ошибки репликации встречаются в проектах Unreal Engine?
Какие распространённые ошибки репликации встречаются в проектах Unreal Engine?
Частые ошибки: изменение реплицируемого состояния на клиенте вместо сервера, забытая регистрация DOREPLIFETIME, вызов RPC с Actor'а-не-владельца, использование RPC там, где поздним участникам нужно свойство, и предположение, что OnRep срабатывает на сервере.
Типичные ошибки
- ✗Менять реплицируемое состояние на клиенте и ждать, что оно сохранится
- ✗Забыть
DOREPLIFETIME, из-за чегоReplicated-свойство не синхронизируется - ✗Ждать, что колбэк
OnRepавтоматически выполнится на сервере
Уточняющие вопросы
- →Как заставить логику инициализации выполниться и на сервере, и на клиентах?
- →Почему реплицируемое свойство иногда приходит раньше
BeginPlayсвоего Actor'а?
MiddleТеорияЧастоДля чего нужна функция GetLifetimeReplicatedProps()?
Для чего нужна функция GetLifetimeReplicatedProps()?
GetLifetimeReplicatedProps() — это место, где регистрируются реплицируемые свойства класса, обычно через макрос DOREPLIFETIME. Движок вызывает её, чтобы узнать, какие свойства отслеживать, и она позволяет задать условия репликации для каждого свойства.
Типичные ошибки
- ✗Думать, что функция выполняется каждый тик, а не один раз при регистрации
- ✗Забывать вызвать
Super::GetLifetimeReplicatedProps()внутри переопределения - ✗Пометить
UPROPERTYкакReplicated, но не добавитьDOREPLIFETIME
Уточняющие вопросы
- →Чем
DOREPLIFETIME_CONDITIONотличается от обычногоDOREPLIFETIME? - →Что произойдёт, если забыть вызвать
Super-версию функции?
MiddleДебаггингЧастоПочему функция работает в PIE в одиночке, но ломается в мультиплеере?
Почему функция работает в PIE в одиночке, но ломается в мультиплеере?
В одиночке одна машина — и сервер, и клиент, поэтому нереплицируемое состояние и клиентские изменения просто работают. В мультиплеере сервер и клиенты разделены, что вскрывает отсутствие репликации, запись не с тем авторитетом и невыверенные вызовы RPC. Здесь в OnPickup нет проверки авторитета, поэтому клиент уничтожает предмет лишь локально, а Count не зарегистрирован для репликации, поэтому удалённые клиенты не видят его изменения.
Типичные ошибки
- ✗Считать, что работающий в одиночном PIE код уже сетево-корректен
- ✗Писать геймплейное состояние на клиенте, раз локально это сработало
- ✗Тестировать только с одним игроком вместо режима нескольких клиентов в PIE
Уточняющие вопросы
- →Как режим нескольких клиентов в PIE помогает рано ловить эти ошибки?
- →Почему
HasAuthority()— ключевая проверка при переносе одиночной логики?
MiddleТеорияЧастоКак реплицировать значение здоровья по сети в Unreal?
Как реплицировать значение здоровья по сети в Unreal?
Пометьте Health как UPROPERTY(ReplicatedUsing=OnRep_Health), зарегистрируйте его в GetLifetimeReplicatedProps через DOREPLIFETIME и изменяйте только на сервере. Колбэк OnRep_Health обновляет HUD на клиентах, когда значение приходит.
Типичные ошибки
- ✗Изменять
Healthна клиенте — сервер просто перезапишет его - ✗Забыть регистрацию
DOREPLIFETIME, из-за чего свойство не реплицируется - ✗Слать RPC каждый кадр вместо того, чтобы репликация свойства сама сравнивала значение
Уточняющие вопросы
- →Как ещё проигрывать эффект урона ровно в момент падения здоровья?
- →Почему логика нанесения урона должна жить на сервере, а не на клиенте?
MiddleТеорияЧастоКогда использовать реплицируемое свойство, а когда RPC?
Когда использовать реплицируемое свойство, а когда RPC?
Реплицируемое свойство — для постоянного состояния, которое должен видеть любой подключающийся клиент: здоровье, счёт. RPC — для разовых событий, которым не нужно сохраняться: звук попадания, вспышка выстрела. Свойства синхронизируют состояние, RPC доставляют действия.
Типичные ошибки
- ✗Использовать RPC для постоянного состояния, которое пропустят поздно подключившиеся клиенты
- ✗Использовать реплицируемое свойство для разового эффекта, что ведёт к пропущенным или устаревшим срабатываниям
- ✗Думать, что RPC переотправляются клиентам, подключившимся после вызова
Уточняющие вопросы
- →Как построить надёжное разовое событие через реплицируемое свойство и колбэк
OnRep? - →Почему
NetMulticastRPC — плохой выбор для состояния, которое должен увидеть поздний участник?
MiddleТеорияЧастоЧто такое Server, Client и NetMulticast RPC в Unreal Engine?
Что такое Server, Client и NetMulticast RPC в Unreal Engine?
Server RPC выполняется на сервере, вызывается клиентом-владельцем. Client RPC выполняется на клиенте-владельце, вызывается сервером. NetMulticast RPC, вызванный на сервере, выполняется на сервере и всех релевантных клиентах.
Типичные ошибки
- ✗Вызывать
ServerRPC с клиента-не-владельца и ждать срабатывания - ✗Думать, что
NetMulticastRPC достигнет клиентов, если вызван на клиенте - ✗Путать, какая машина вызывает, а какая исполняет RPC
Уточняющие вопросы
- →Почему
NetMulticastRPC нужно вызывать на сервере, чтобы он достиг всех клиентов? - →Что определяет, достигнет ли
ClientRPC конкретного игрока?
MiddleТеорияИногдаЧто означает Reliable для RPC, и должны ли все RPC быть Reliable?
Что означает Reliable для RPC, и должны ли все RPC быть Reliable?
Reliable RPC гарантированно доставляется и выполняется, переотправляясь до подтверждения. Не все RPC должны быть надёжными — буфер надёжных вызовов ограничен, и его переполнение частыми вызовами может отключить клиента. Для частых косметических событий — Unreliable.
Типичные ошибки
- ✗Помечать частые косметические RPC как
Reliableи переполнять буфер - ✗Думать, что
Reliableгарантирует доставку в тот же кадр или по порядку со свойствами - ✗Считать, что надёжность не имеет затрат по производительности или трафику
Уточняющие вопросы
- →Что происходит при переполнении буфера надёжных RPC?
- →Почему
ReliableRPC не может гарантировать порядок относительно реплицируемых свойств?
MiddleТеорияИногдаКак реплицировать снаряды вроде пуль или ракет в Unreal?
Как реплицировать снаряды вроде пуль или ракет в Unreal?
Создавайте снаряд на сервере как реплицируемого Actor'а; движок создаст его на релевантных клиентах. Пусть ProjectileMovementComponent симулирует движение локально на каждой стороне, а попадания и урон разрешаются авторитетно на сервере.
Типичные ошибки
- ✗Создавать снаряд на клиенте, из-за чего сервер его не отслеживает
- ✗Разрешать попадания и урон на клиенте вместо сервера
- ✗Реплицировать трансформ каждый тик вместо локальной симуляции движения
Уточняющие вопросы
- →Как фиктивный косметический спавн снаряда на клиенте улучшает ощущаемую задержку?
- →Почему серверное разрешение попаданий важно против читерства?
MiddleТеорияИногдаЧто делает спецификатор ReplicatedUsing у UPROPERTY?
Что делает спецификатор ReplicatedUsing у UPROPERTY?
ReplicatedUsing=OnRep_Func помечает свойство как реплицируемое и задаёт колбэк. Когда значение меняется на клиенте, движок вызывает указанную функцию OnRep, позволяя отреагировать — обновить UI, проиграть эффекты — а не просто молча сохранить новое значение.
Типичные ошибки
- ✗Думать, что колбэк
OnRepпо умолчанию срабатывает и на сервере - ✗Считать, что
ReplicatedUsingзаставляет свойство реплицироваться каждый кадр - ✗Забывать, что свойство всё равно нужно регистрировать в
GetLifetimeReplicatedProps
Уточняющие вопросы
- →Выполняется ли функция
OnRepна сервере, и как запустить эту логику там? - →Почему колбэк
OnRepможет не сработать, хотя значение изменилось?
SeniorДебаггингИногдаКак отлаживать проблемы репликации в проекте Unreal Engine?
Как отлаживать проблемы репликации в проекте Unreal Engine?
В чистой локальной сессии PIE нет ни задержки, ни потерь, поэтому баг в ней не виден. Воспроизведите в PIE с несколькими клиентами, затем используйте Net PktLag/PktLoss для симуляции плохой сети, оверлей showdebug net, Net.DumpRelevantActors и логирование авторитета, чтобы понять, какая машина пишет состояние и зарегистрировано ли свойство.
Типичные ошибки
- ✗Тестировать только на идеальной локальной сети без задержки и потерь
- ✗Отлаживать на одной машине и считать, что серверная сторона ведёт себя так же
- ✗Никогда не проверять, зарегистрировано ли свойство для репликации
Уточняющие вопросы
- →Что
Net PktLagпоказывает такого, чего не даёт чистый локальный тест? - →Как подтвердить регистрацию свойства, не читая исходный код?
SeniorТеорияИногдаЧто такое сетевая релевантность в Unreal Engine и как она экономит трафик?
Что такое сетевая релевантность в Unreal Engine и как она экономит трафик?
Релевантность — это решение для каждого соединения о том, реплицируется ли Actor конкретному клиенту. Сервер пропускает нерелевантных Actor'ов — далёких, невидимых — экономя трафик. Этим управляют IsNetRelevantFor и настройки вроде NetCullDistanceSquared.
Типичные ошибки
- ✗Думать, что релевантность глобальна, а не оценивается для каждого соединения
- ✗Считать, что релевантность фиксируется при спавне и не переоценивается
- ✗Путать сетевую релевантность с клиентским отсечением при отрисовке
Уточняющие вопросы
- →Как
bAlwaysRelevantменяет поведение репликации Actor'а? - →Как релевантность взаимодействует с дормантностью для снижения нагрузки на сервер?
SeniorТеорияРедкоЧто такое сетевая дормантность в Unreal Engine и что именно она экономит?
Что такое сетевая дормантность в Unreal Engine и что именно она экономит?
Дормантность позволяет реплицируемому Actor'у перестать обрабатываться для репликации, пока его состояние неизменно, экономя CPU сервера. Дормантный Actor пропускается каждый тик, пока вы не вызовете FlushNetDormancy или не разбудите его, чтобы протолкнуть изменение.
Типичные ошибки
- ✗Думать, что дормантность уничтожает Actor'а, а не приостанавливает его репликацию
- ✗Менять свойство дормантного Actor'а, не вызвав
FlushNetDormancy - ✗Считать, что дормантность ускоряет репликацию, а не пропускает её
Уточняющие вопросы
- →Что пойдёт не так, если изменить состояние дормантного Actor'а, но забыть сбросить дормантность?
- →Когда
DORM_Initial— подходящая настройка дормантности?
SeniorДизайнРедкоВ многопользовательском уровне 100+ реплицируемых актёров — игроки, снаряды, подбираемые предметы и статичные декорации — и десятки подключённых игроков. Выделенный сервер упирается в CPU на сетевом цикле: каждый тик он пересчитывает релевантность по соединениям и сравнивает реплицируемые свойства каждого актёра, а трафик к каждому клиенту насыщен. Большинство актёров меняются редко, и многие далеки от любого конкретного игрока. Опишите, как вы снизите стоимость сетевого цикла за тик. Требования: далёкие и нерелевантные актёры перестают тратить работу отправки для данного клиента; редко меняющиеся актёры не рассматриваются каждый тик; клиенту шлются только нужные ему свойства; а подход продолжает масштабироваться с ростом числа актёров и игроков.
В многопользовательском уровне 100+ реплицируемых актёров — игроки, снаряды, подбираемые предметы и статичные декорации — и десятки подключённых игроков. Выделенный сервер упирается в CPU на сетевом цикле: каждый тик он пересчитывает релевантность по соединениям и сравнивает реплицируемые свойства каждого актёра, а трафик к каждому клиенту насыщен. Большинство актёров меняются редко, и многие далеки от любого конкретного игрока. Опишите, как вы снизите стоимость сетевого цикла за тик. Требования: далёкие и нерелевантные актёры перестают тратить работу отправки для данного клиента; редко меняющиеся актёры не рассматриваются каждый тик; клиенту шлются только нужные ему свойства; а подход продолжает масштабироваться с ростом числа актёров и игроков.
Снижайте работу за тик: настройте NetUpdateFrequency и NetCullDistanceSquared, применяйте дормантность для статичных актёров, ограничивайте свойства через DOREPLIFETIME_CONDITION и внедрите Replication Graph для пространственного отсечения при масштабе.
Типичные ошибки
- ✗Помечать всё
bAlwaysRelevant, что сводит на нет отсечение по релевантности - ✗Оставлять высокий
NetUpdateFrequencyу редко меняющихся актёров - ✗Никогда не применять дормантность для статичных или простаивающих актёров, из-за чего сервер обрабатывает их каждый тик
Уточняющие вопросы
- →Как профилировать, чтобы подтвердить, что узкое место именно репликация?
- →Какой компромисс вносит снижение
NetUpdateFrequencyдля быстро движущихся актёров?
SeniorТеорияРедкоЧто такое Replication Graph в Unreal Engine и зачем он нужен?
Что такое Replication Graph в Unreal Engine и зачем он нужен?
Replication Graph — масштабируемая система репликации, которая раскладывает Actor'ов по пространственным узлам и собирает из них списки для каждого соединения. Он нужен потому, что стандартный поактёрный цикл релевантности слишком дорог по CPU при множестве актёров и игроков.
Типичные ошибки
- ✗Думать, что Replication Graph — это редакторский инструмент диаграмм
- ✗Считать, что он заменяет транспортный протокол, а не цикл релевантности
- ✗Полагать, что он экономит в основном трафик, а не CPU сервера
Уточняющие вопросы
- →Что такое узел сеточной пространственной разбивки и как он масштабируется с числом игроков?
- →Когда стоит переводить проект на Replication Graph?