Эта страница ещё не переведена — показана английская версия.
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, пока не решено (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[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 подтвердил бы, что за стеной что-то есть. - Читать стоимость персональных пакетов можно только из
fnadm: из облачной функции или панели, но никогда с клиента.
Ограничения
Конкретные числа появятся в главе об ограничениях платформы, а что происходит при достижении каждого потолка, определено уже сейчас.
- Стоимость персонального пакета: когда бюджет исчерпан — объявленная деградация до общего пакета с уведомлением, но никогда не произвольная потеря получателей.
- Объектов на правило: ограничение с объявленным порядком и видимым флагом обрезки.
- Подписок на актора: новая подписка отклоняется, существующие продолжают работать.
- Размер дельты: дельта разбивается, а не обрезается, и разбиение видно.
- Частота отправки: это верхняя граница, а не гара нтия.