Version: 2017.1
Guía Legacy de referencial del Network
Elementos de redes en Unity (Legacy)

Conceptos de Networking de Alto Nivel (Legacy -Depreciado)

(Para nuevos proyectos puedes usar el Nuevo Networking System introducido en 5.1. Esta información es para antiguos proyectos usando el sistema antiguo de networking.)

Esta sección cubre los conceptos generales de networking que se deben entender antes de desarrollar un juego con la arquitectura de networking de Unity.

Qué es Networking?

El Networking es la comunicación entre dos o más computadores. Una idea fundamental es la relación entre el client (el computador que está solicitando información) y el server (el computador que responde a las solicitudes de información(. El server puede ser una maquina anfitriona dedicada utilizada por todos los clientes, o simplemente una maquina de un jugador que está ejecutando el juego (client) pero también funciona como un server para otros jugadores. Una vez el servidor ha sido establecido y un cliente se ha conectado, los dos computadores pueden cambiar datos según lo exigido por el gameplay.

Crear un juego en red requiere de mucha atención a algunos detalles específicos. Incluso si las acciones en red son fáciles de diseñar y crear en Unity, el networking sigue siendo complejo. Una decisión de diseño importante en Unity es hacer del networking lo más robusto y flexible que se pueda. Esto significa que usted, como el creador del juego, es responsable por cosas que podrían ser manejadas de una manera automática pero menos robusta en otros motores. Las decisiones que usted tome, potencialmente puede que tengan un mayor efecto en el diseño de su juego, por lo que es mejor hacerlas en la etapa de diseño tan pronto como sea posible. Entender los conceptos de networking le ayudarán a planear su diseño del juego y evitar problemas durante la implementación.

Enfoques en Networking

Hay dos enfoques comunes y probados para estructurar un juego en red que se conocen como Authoritative Server y Non-Authoritative Server. Ambos enfoques dependen de un servidor que conecta los clientes y pasa información entre ellos. Ambos ofrecen privacidad para los usuarios finales ya que los clientes en realidad nunca se conectan directamente con el otro o tienen sus direcciones IP reveladas a otros clientes.

Authoritative Server

El enfoque de authoritative server requiere que el servidor realice todas las simulaciones del mundo, reglas de la aplicación del juego y procesar todo el input que vienen de los clientes jugador. Cada cliente envía su input (en la forma de pulsaciones al teclado o acciones solicitadas) al servidor y continuamente recibe el estado actual del juego del servidor. El cliente nunca hace cambios al estado del juego en sí. Más bien, le dice al servidor lo que quiere que haga, y el servidor luego maneja la solicitud y responde al cliente para explicar lo que sucedió como un resultado.

Fundamentalmente, hay una capa de separación entre lo que el jugador quiere hacer y lo que realmente sucede. Esto le permite al servidor escuchar a cada solicitud del cliente antes de decidir cómo actualizar el estado de juego.

Una ventaja de este enfoque es que se le hace más difícil al cliente hacer trampa.Por ejemplo, los clientes no tienen la posibilidad de hacer trampa al decirle al servidor (y por lo tanto a otros clientes) que un enemigo ha sido matado, ya que ellos no toman esa decisión por sí solos. Solamente le pueden decir al servidor que una arma ha sido disparada y de ahí, depende del servidor determinar si fue una muerte en efecto ocurrió.

Otro ejemplo de un authoritative server sería un juego multi-jugador que depende en física. Si cada cliente se le permite ejecutar su propia simulación de física, entonces unas pequeñas variaciones entre los clientes causaría que queden a la deriva de la sincronización entre ellos de manera gradual. No obstante, si la simulación de todos los objetos de física se manejan en un servidor central entonces el estado actualizado se envía de vuelta a los clientes, garantizando que todos son consistentes.

Una desventaja potencial con authoritative servers es el tiempo que toma los mensajes de viajar a través de la red. Si el jugador presiona un control para moverse hacia al frente y toma 1/10 de segundo para que la respuesta se devuelva del servidor, entonces el retraso sería perceptible por el jugador. Una solución a esto es lo que se llama client-side prediction. La esencia de esta técnica es que el cliente se le permite actualizar su versión local del estado del juego pero debe ser capaz de recibir correcciones de la versión authoritative del servidor dónde sea necesario. Típicamente, esto solamente se puede utilizar para acciones simples de juego y no en cambios lógicos del estado del juego. Por ejemplo, no sería una buena idea reportarle a un jugador que un enemigo fue matado solamente para que el servidor anule esta decisión.

Debido a que la predicción por el lado del cliente es un tema avanzado, no lo intentamos cubrir en esta guía pero hay recursos en linea como libros que están disponibles si quiere investigar más.

Un authoritative server tiene una sobre-cargar de procesamiento mayor que un non-authoritative. Cuando el servidor no se requiere que maneje todos los cambios del estado del juego, mucho de esta carga se puede distribuir entre los clientes.

Non-Authoritative Server

Un non-authoritative server que no controla el resultado de cada input del usuario. Los clientes en sí procesan el input de usuario y la lógica del juego localmente, luego envía el resultado de cualquier acción determinada al servidor. El servidor luego sincroniza todas las acciones con el estado del mundo. Esto es más fácil de implementar desde una perspectiva de diseño, ya que el servidor solamente envía mensajes entre los clientes no incurre en un procesamiento extra más allá de lo que los clientes hacen.

No hay necesidad de cualquier tipo de métodos de prediction (predicción) ya que el cliente maneja toda la física y los eventos por sí solo y envía lo que sucede al servidor. Ellos son los owners (dueños) de sus objetos y son los únicos agentes permitidos en enviar modificaciones locales de esos objetos sobre la red.

Métodos de Comunicación en Red

Ahora que hemos cubierto las arquitecturas básicas de los juegos en red, exploraremos los niveles más bajos de cómo los clientes y los servidores pueden hablar entre sí.

Hay dos métodos importantes: Remote Procedure Calls y State Synchronization. No es raro utilizar ambos métodos en diferentes puntos en un juego en particular.

Remote Procedure Calls (Llamadas a procedimientos remotos)

Los Remote Procedure Calls (RPCs) se utilizan para invocar funciones en otros computadores a través de la red, aunque el “network” también puede significar el canal de mensajes entre el cliente y el servidor cuando se están ejecutando en el mismo computador. Los clientes pueden enviar RPCs al servidor y el servidor puede enviar RPCs a uno o más clientes. Más común, son utilizados para acciones que no ocurren frecuentemente. Por ejemplo, si un cliente activa el interruptor para abrir una puerta, puede enviar un RPC al servidor diciéndole que la puerta se ha abierto. El servidor puede luego enviar otro RPC a todos los clientes, invocando sus funciones locales para abrir la misma puerta. Son utilizados para manejar y ejecutar eventos individuales.

Sincronización del Estado

La sincronización de estado se utiliza para compartir datos que constantemente cambian. El mejor ejemplo de esto sería la posición de un juego en un juego de acción. El jugador siempre se está moviendo, corriendo alrededor, saltando, etc. Todos los demás jugadores en la red, incluso aquellos que no están controlando este jugador localmente, necesitan saber dónde están y qué están haciendo. Al transmitir datos constantemente sobre la posición de este jugador, el juego puede de manera precisa representar la posición a otros jugadores.

Este tipo de datos se envía regularmente y frecuentemente a través de la red. Ya que estos datos son sensibles al tiempo, y se requiere tiempo para viajar a través de la red de una maquina a otra, es importante reducir la cantidad de datos que se envían tanto como sea posible. En términos más simples, la sincronización de estado por lo general requiere mucho bando de ancha, por lo que debería apuntar a utilizar tan poco bando de ancha como sea posible.

Conectando los servidores y los clientes juntos

Conectar a los servidores y clientes juntos puede ser un proceso complejo. Las maquinas pueden tener sus direcciones IP privadas o públicas y pueden que tengan firewalls locals o externos que bloqueen el acceso. El Unity Networking apunta a manejar tantas situaciones como sea posible pero no hay una solución universal.

Las direcciones privadas son direcciones IP que no se pueden acceder directamente del internet (también se llaman Network Address Translation o direcciones NAT por el método utilizado que las implementan). Una explicación simple, es que la dirección privada pasa a través de un enrutador local que traduce la dirección a una dirección pública. Al hacer esto, muchas maquinas con direcciones privadas pueden utilizar una sola dirección IP pública para comincarse con el internet. Esto está bien hasta que alguien en otra parte en internet quiere iniciar un contacto con una de las direcciones privadas. La comunicación deben suceder mediante la dirección pública del enrutador, que luego debe pasar el mensaje a la dirección privada. Una técnica llamada NAT punchthrough utiliza un servidor compartido conocido como facilitator para mediar la comunicación de tal manera que las direcciones privadas se puedan alcanzar desde una dirección pública. Esto funciona al hacer que la dirección privada primero contacte el facilitator, que “punches” (perfora) un hueco a través del enrutador local. El facilitator puede ahora ver la dirección pública y el puerto que la dirección privada está utilizando. Usando esta información, cualquier maquina en internet se puede conectar ahora directamente con la antes inalcanzable dirección privada. (Tenga en cuenta que los detalles de NAT punchthrough son algo complicados que esto en la práctica.)

Las direcciones públicas son más directas. Aquí, el problema principal es que la conectividad se puede bloquear por una firewall interna o externa (un firewall interna es una que corre localmente en el computador que está protegiendo). Para una firewall interna, al usuario se le puede preguntar que quite las restricciones de un puerto en particular para que el servidor del juego sea accesible. Un firewall externo, por el contrario, no está bajo el control de los usuarios. Unity puede intentar usar NAT punchthrough para obtener acceso a través de un firewall externo pero esta técnica no se garantiza que funcione. Nuestras pruebas sugieren que por lo general funciona en práctica pero no hay una investigación formal que confirme este hallazgo.

Los problemas de conectividad mencionados afectan a los servidores y los clientes de manera diferente. Las solicitudes de los clientes involucran solamente un tráfico de red saliente el cual es bastante directo. Si el cliente tiene una dirección pública esto por lo genera siempre funciona ya que el tráfico que sale típicamente se bloquea en reds corporativas que imponen restricciones severas de acceso. Si el cliente tiene una dirección privada, este puede conectarse a todos los servidores menos los servidores con direcciones privadas que no pueden hacer NAT punchthrough (se dirá más sobre esto después). El extremo del servidor es más complicado ya que el servidor necesita ser capaz de aceptar conexiones entrantes de fuentes desconocidas. Con una dirección pública, el servidor necesita tener un puerto del juego abierto al internet (ie, no bloqueado por una firewall). O de lo contrario no podrá aceptar conexiones de clientes y por lo tanto será inutilizable. Si el servidor tiene una dirección privada debe ser capaz de hacer NAT punchthrough para permitir conexiones y los clientes también deben permitir NAT punchthrough para que se pueda conectar.

Unity proporciona herramientas para probar todas estas situaciones de conectividad diferentes. Cuando se establece que se puede realizar una conexión, hay dos métodos que pueden ocurrir: conexiones directas (dónde un cliente necesita saber el nombre DNS o dirección IP del servidor) y unas conexiones vía el Master Server. El Master Server permite a los servidores anunciar su presencia a los clientes que no necesitan saber nada sobre servidores de juego en particular de antemano.

Minimizando el bando de ancha de la Red

Cuando se trabaje con la Sincronización de Estados a través de varios clientes, usted no necesariamente necesita sincronizar cada detalle para hacer que los objetos parezcan sincronizados. Por ejemplo, cuando sincronice un avatar de un personaje usted solo necesita enviar su posición y rotación entre los clientes. A pesar de que el personaje en sí es mucho más complejo y puede contener una jerarquía profunda del Transform, los datos sobre la jerarquía completa no se necesitan compartir.

Muchos de los datos de su juego efectivamente son estáticos, y los clientes no necesitan transferirlos inicialmente ni sincronizarlos. Utilizar llamadas RPC poco frecuentes o una sola vez debe ser suficiente para hacer que muchas de sus funcionalidades funcionen. Aproveche los datos que sabe que existirán en cada instalación de su juego y mantenga el cliente funcionando por si solo lo más que pueda. Por ejemplo, usted sabe que los assets como texturas y meshes existen en todas las instalaciones y por lo general no cambian, por lo que nunca deberán sincronizarse. Este es un ejemplo simple pero debería empezar hacerlo pensar sobre qué datos son absolutamente críticos en compartir de un cliente a otro. Estos son los únicos datos que debería compartir.

Puede ser difícil calcular exactamente qué necesita ser compartido y qué no, especialmente si nunca ha hecho un juego en red antes. Tenga en cuenta que usted puede utilizar una sola llamada RPC con un nombre del nivel para hacer que todos los clientes carguen completamente el nivel especificado y agreguen sus propios elementos en red automáticamente. La estructuración de su juego para hacer que cada cliente sea lo más autosuficiente posible resultará en un ancho de banda reducido.

Rendimiento de un juego Multi-jugador

La ubicación física y rendimiento del servidor en sí pueden afectar en gran medida la jugabilidad del juego ejecutando en él. Los clientes que están ubicados en un continente lejos del servidor pueden experimentar un gran lag. Esto se debe a una limitación física del internet y la única solución posible es organizar que el servidor esté lo más cerca posible a los clientes que lo usarán, o al menos en el mismo continente.

Recursos extra

Hemos coleccionado los siguientes enlaces para unos recursos adicionales sobre el networking :-

  • http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
  • http://developer.valvesoftware.com/wiki/Lag_Compensation
  • http://developer.valvesoftware.com/wiki/Working_With_Prediction
  • http://www.gamasutra.com/resource_guide/20020916/lambright_01.htm
Guía Legacy de referencial del Network
Elementos de redes en Unity (Legacy)