Перейти к основному содержимому
Живая игра

Эта страница ещё не переведена — показана английская версия.

Visibility

На 40 игроков снапшот всей комнаты годится. На 200 — уже нет. Кто что получает, решает зона видимости — объявленный предикат, а не переключатель, который вы щёлкаете для каждого объекта. Общая рассылка и персональные пакеты — два объявленных режима доставки одной модели, поэтому перейти с одного на другой можно настройкой, без переписывания кода. Это оптимизация канала, а не разрешение: о разрешениях — на странице Access & Roles.

Одну объявленную модель — предикат, слои, уровни детализации — можно прочитать двумя способами:

Общая рассылкаПерсональные пакеты
Что отправляетвсю комнату, всемкаждому игроку (player) — только ту часть, которую выбирают его правила
Для чего подходитдля небольшой комнаты; это режим по умолчаниюдля толпы, где размер пакета должен оставаться предсказуемым
Как читает объявлениеодин раз на комнатудля каждого актора отдельно

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

Когда это нужно

  • Комнаты (room) переросли рассылку всей комнаты: 200 игрокам нужен у каждого клиента свой поток данных об окрестностях, а не каждая дельта.
  • Состояние не должно утечь: туман войны и поля (field), доступные только владельцу, вообще не должны отправляться, а не скрываться на клиенте.
  • Несколько сессий делят одну карту (map) и не должны видеть друг друга: слой — это ещё один предикат.
  • Размер пакета в толпе должен быть предсказуемым: ограничьте число объектов и объявите порядок отбора, чтобы «ближайшие N» были обещанием, а не случайностью плотности.
  • Игрок у границы должен видеть, что за ней: объявите, какие соседние области видны, потому что по умолчанию виден только его собственный участок.
  • Не нужно, если комната небольшая. С этим справится режим доставки общим пакетом.

Кто что делает

АкторЧто делает на этой странице
schema-authorобъявляет предикат видимости (visibility), лимит объектов и порядок отбора, какие соседние области видны, и режим доставки
anyподписывается и получает то, что пропускает зона; может сам себе снизить лимит объектов в объявленных пределах

Коротко

Правила радиуса и слоя, объявленные на Tank; Ammo видно только владельцу — это указано рядом с полем
[Entity("tank")]
[Visible(Radius = 60)]                           // spatial
[Visible(Rule.SameLayer)]                        // layers of one map
public class Tank
{
    [Sync] public Vector3 Position;
    [Sync(To = Scope.Owner)] public int Ammo;    // per-field scope
}
@Entity('tank')
@Visible({ radius: 60 })                       // spatial
@Visible(Rule.SameLayer)                       // layers of one map
export class Tank {
  @Sync() position!: Vector3;
  @Sync({ to: Scope.Owner }) ammo = 0;         // per-field scope
}
@entity("tank")
@visible(radius=60)                              # spatial
@visible(Rule.SAME_LAYER)                        # layers of one map
class Tank:
    position: Vector3 = sync()
    ammo: int = sync(to=Scope.OWNER)             # per-field scope
Скоро — Go

Как объявлять через атрибуты в Go, пока не решено (O-1). Примеры появятся, когда выберут способ записи.

// multi-entry values are one quoted list (a specifier value is a single token)
UCLASS(PSEntity = "tank",
       PSVisible = "radius:60, rule:SameMapInstance")   // spatial + instances of one map
class UTank : public UObject
{
    GENERATED_BODY()

    UPROPERTY(PSSync)                  FVector3f Position;
    UPROPERTY(PSSync = (To = "Owner")) int32     Ammo;   // per-field scope
};
// declarations compile into the same pushed model — playserv push from the UE project or CI
Unity C# is the same C# API here — те же атрибуты компилируются в Unity на базовой версии 2021.3 — синтаксис C# 12 здесь не используется
[Entity("tank")]
[Visible(Radius = 60)]                           // spatial
[Visible(Rule.SameLayer)]                        // layers of one map
public class Tank
{
    [Sync] public Vector3 Position;
    [Sync(To = Scope.Owner)] public int Ammo;    // per-field scope
}

Модель

Что объявляет правило видимости.

Что объявляетсяЧто это
предикатсамо правило, записанное на том же языке предикатов, что и предикаты доступа и условия переходов. Радиус, экземпляр карты, команда и владение — частные случаи предиката, а не отдельные механизмы: такой язык в контракте ровно один
лимит объектов и порядок отбораправило может ограничить число объектов, и тогда порядок отбора объявляется, а не угадывается. «Ближайшие N» — это предикат плюс сортировка по расстоянию плюс лимит. Одним предикатом это не выразить: предикат отвечает на вопрос «подходит ли эта строка», а не «какая из подходящих ближе»
соседние областивидны ли объекты из соседней комнаты или соседнего экземпляра карты и какие именно. Никогда не подразумевается: без объявления область — та, в которой находится получатель
режим доставкиобщий пакет: всем одно и то же, дёшево для CPU. персональный пакет: каждый получатель получает свой, по своей зоне; дорого для CPU, но необходимо при большом числе игроков

Что верно для любой зоны.

ВсегдаЧто это
видимость— не разрешение (permission): то, что скрывает зона, может быть доступно по разрешению, и наоборот (см. ниже)
получательможет снизить лимит — в пределах объявленного максимума и не ниже объявленного минимума. Предикат одинаков для всех, чей контекст ему подошёл, а размер пакета — забота получателя
обрезкавидна: получатель узнаёт, что пакет обрезан и по какому порядку. Молча обрезать запрещено — такую обрезку не отличить от того, что объектов больше нет
деградацияобъявляется: когда бюджет на сборку персональных пакетов заканчивается, платформа переходит на общий пакет так, как объявлено, а не начинает произвольно терять получателей
форма пакета— слабое обещание: желательно, чтобы размер и состав пакета не выдавали существование скрытых объектов

Видимость — это не разрешение

Зона — оптимизация канала, а не управление доступом. Не смешивайте их: иначе настройка тумана войны незаметно расширит права, или права начнут зависеть от расстояния. По размеру пакета можно догадаться, что скрытые объекты существуют, поэтому там, где их существование не должно утечь, используйте разрешения из Access & Roles, а не зону.

На вопросы «кто это видит?» и «что именно они видят?» можно получить ответ запросом. Стоимость персональных пакетов — полноценная метрика, её можно прочитать и в коде, и в панели.

Ошибки

  • Необъявленная цель подписки — отказ при валидации.
  • Нет разрешения на подписку — ответ forbidden или not found, в зависимости от того, секретно ли само существование цели: отказ не должен выдавать то, в чём отказывает.
  • Позиция возобновления, которую не удалось разобрать, — это некорректный запрос, а не молчаливый перезапуск с текущего момента.
  • Подписка, закрытая платформой, и исчерпанный лимит подписок (subscription) — оба случая считаются конфликтом.
  • Расширить обзор можно только из fn. Выдача расширенного обзора и настройка уровней детализации (detail tier) для сессии игрока отклоняются с forbidden, и её обзор не меняется. Клиент зрителя не может расширить собственные выданные права (grant).
  • Экземпляр, который исключён из обзора вызывающего, отвечает not found — так же, как несуществующий. Ответ forbidden подтвердил бы, что за стеной что-то есть.
  • Читать стоимость персональных пакетов можно только из fn adm : из облачной функции или панели, но никогда с клиента.

Ограничения

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

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