Saltar al contenido principal
El juego en vivo

Esta página aún no está traducida: se muestra la versión en inglés.

Visibility

Con 40 jugadores, un snapshot de toda la sala funciona. Con 200, no. Una zona de visibilidad decide quién recibe qué, como un predicado declarado y no como un interruptor que activas objeto por objeto. La difusión y los paquetes por actor son dos modos de entrega declarados de un mismo modelo, así que pasar de uno a otro es cuestión de configuración, no de reescribir código. Es una optimización del canal y no un permiso; para eso, consulta Access & Roles.

Un mismo modelo declarado (el predicado, las capas, los niveles de detalle) se lee de dos maneras:

DifusiónPaquetes por actor
Envíatoda la sala (room), a todosa cada jugador (player), solo la parte que eligen sus reglas
Conviene parauna sala pequeña; es el modo predeterminadouna multitud, donde el tamaño del paquete tiene que seguir siendo predecible
Lee la declaraciónuna vez, para la salapor cada actor

Lo que no debe filtrarse no está en el paquete, en lugar de estar oculto en el cliente: nunca se envía, y por eso es una propiedad de seguridad y no de ancho de banda.

Cuándo usarlo

  • Tus salas ya no caben en una difusión de toda la sala: 200 jugadores necesitan flujos de su entorno cercano por cliente, no cada delta.
  • El estado no debe filtrarse: la niebla de guerra y los campos (field) que solo ve el dueño nunca deben enviarse, en vez de ocultarse en el cliente.
  • Varias sesiones comparten un mapa y no deben verse entre sí: una capa es un predicado más.
  • El tamaño del paquete tiene que ser predecible en una multitud: limita los objetos y declara el orden, para que “los N más cercanos” sea una promesa y no un accidente de la densidad.
  • Un jugador en un límite tiene que ver del otro lado: declara qué áreas vecinas son visibles, porque de forma predeterminada solo lo es la suya.
  • No lo necesitas si la sala es pequeña. El modo de entrega con paquete compartido ya lo resuelve.

Quién hace qué

ActorQué hace en esta página
schema-authordeclara el predicado de visibilidad, el límite de objetos y su orden, qué áreas vecinas son visibles y el modo de entrega
anyse suscribe y recibe lo que la zona admite; puede bajar el límite de objetos para sí mismo dentro de los márgenes declarados

En resumen

Reglas de radio y de capa declaradas en Tank; Ammo, limitado a su dueño junto al campo
[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
Próximamente — Go

Todavía no está decidido cómo declarar con atributos en Go (O-1). Los ejemplos llegarán cuando se elija la forma de escribirlo.

// 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 — los mismos atributos compilan en Unity, sobre la base 2021.3; aquí no hay sintaxis de 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
}

El modelo

Qué declara una regla de visibilidad.

DeclaraQué es
predicadola regla en sí, escrita en el mismo lenguaje de predicados que los predicados de acceso y las condiciones de transición. Un radio, una instancia de mapa, un equipo y la propiedad de un objeto son casos particulares de un predicado, no mecanismos aparte: en el contrato hay exactamente un lenguaje así
límite de objetos y su ordenuna regla puede limitar la cantidad de objetos, y entonces el orden de selección se declara, no se deduce: “los N más cercanos” es un predicado más un ordenamiento por distancia más un límite. Un predicado solo no puede expresarlo, porque responde “¿esta fila califica?”, no “¿cuál de las que califican está más cerca?”
áreas vecinassi los objetos de una sala o instancia de mapa vecina son visibles, y cuáles exactamente. Nunca es implícito: sin declaración, el área es aquella donde está el destinatario
modo de entregapaquete compartido: lo mismo para todos, barato en CPU. paquete por actor: cada receptor recibe el suyo, según su zona; caro en CPU e imprescindible con poblaciones grandes

Qué se cumple en toda zona.

SiempreQué es
visibilidadno es un permiso: lo que la zona oculta puede estar disponible por permiso, y al revés (ver abajo)
el destinatariopuede bajar el límite: dentro del máximo declarado y nunca por debajo del mínimo declarado, porque un predicado es el mismo para todos aquellos cuyo contexto coincidió, mientras que el tamaño del paquete es problema del destinatario
truncamientoes observable: el destinatario se entera de que el paquete se cortó y con qué orden. El truncamiento silencioso está prohibido, porque no se distingue de que ya no haya más objetos
degradaciónse declara: cuando se agota el presupuesto para armar paquetes por actor, la plataforma vuelve al paquete compartido tal como está declarado, en lugar de empezar a perder destinatarios al azar
forma del paquetees una promesa débil: el tamaño y la composición de un paquete no deberían permitir deducir que existen objetos ocultos

La visibilidad no es un permiso

La zona es una optimización del canal, no un control de acceso. No los mezcles: una configuración de niebla de guerra ampliaría los derechos sin avisar, o los derechos empezarían a depender de la distancia. El tamaño del paquete puede insinuar que existen objetos ocultos, así que, donde su existencia no deba filtrarse, usa los permisos de Access & Roles, no la zona.

“¿Quién ve esto?” y “¿qué ve?” se pueden consultar. El costo de los paquetes por actor es una lectura de primera clase, en el código y en el panel.

Errores

  • Un destino de suscripción no declarado es un rechazo de validación.
  • La falta de permiso para suscribirse responde forbidden o not found según si la existencia del destino es secreta: el propio rechazo no debe revelar lo que rechaza.
  • Una posición de reanudación que no se puede interpretar es una solicitud incorrecta, no un reinicio silencioso desde el momento actual.
  • Una suscripción que cerró la plataforma y una cantidad de suscripciones agotada son, ambas, conflictos.
  • Ampliar una vista es fn. Otorgar una vista ampliada y fijar niveles de detalle se rechazan con forbidden para una sesión de jugador, y su vista no cambia: un cliente espectador no puede ampliar sus propios permisos otorgados (grant).
  • Una instancia que la vista del llamador excluye responde not found, la misma respuesta que una que no existe: un forbidden confirmaría que hay algo detrás del muro.
  • Leer el costo de los paquetes por actor es fn adm : una función en la nube o el panel, nunca un cliente.

Límites

Las cifras llegarán con el capítulo de límites de la plataforma; lo que pasa en cada tope ya está definido.

  • El costo de un paquete por actor: al agotarse, degradación declarada al paquete compartido con un aviso, nunca una pérdida arbitraria de destinatarios.
  • Objetos por regla: limitados, con un orden declarado y un indicador de truncamiento observable.
  • Suscripciones por actor: una nueva se rechaza y las existentes siguen.
  • Tamaño de la delta: la delta se divide, no se trunca, y la división es observable.
  • La tasa de envío: un límite superior, no una garantía.