Mejoras en el cálculo del ping

Aunque, antes de nada, me gustaría dejar aquí una pequeña introducción sobre algunos términos que utilizaré con frecuencia para aquellos menos familiarizados con ellos:
Cliente y servidor: cada consola, dispositivo móvil, PC o Mac es un cliente, y estos se conectan a un servidor dedicado que aloja el juego. El servidor mantiene el estado general del juego (la ubicación de los jugadores, el estado del círculo, qué cofres están activos y otras muchas cosas más). También es el responsable de actualizar los clientes cuando el estado del juego cambia.
Paquete: un paquete es un bloque de datos que se envía a través de la red del cliente al servidor, o viceversa. De esta forma, los clientes y el servidor se comunican entre ellos. En Fortnite, y en UE4, utilizamos estos paquetes en nuestro método para calcular el ping.
Fotograma: en el servidor, un fotograma indica con cuánta frecuencia realiza el servidor sus tareas, como buscar nuevos paquetes, actualizar el estado del juego y enviar actualizaciones a los clientes. Por su parte, en el cliente, un fotograma indica con cuánta frecuencia se actualiza la imagen en pantalla. La frecuencia de imágenes, también conocida como FPS o imágenes por segundo, indica cuántos fotogramas procesará el servidor o el cliente en un segundo. Así que, cuando decimos que el cliente funciona a 60 FPS, eso se traduce en que cada segundo contiene 60 fotogramas.
Con esto resuelto, ¡hablemos sobre el ping!
Nuestro método antiguo para calcular el paquete de ping
Cuando la mayoría piensa en el "ping", lo que le viene a la mente es la cantidad de tiempo que tarda un cliente en enviar un paquete al servidor y ese servidor en mandar una respuesta, o viceversa. A esto también se le denomina tiempo de ida y vuelta, o RTT. De esta forma, se consigue la información que interesa a la mayoría de jugadores: cuánto tiempo tardarán en recibir las actualizaciones del servidor y cuánto tardará este en recibir sus actualizaciones. Cuanto más alto sea el valor de ping de un jugador, más probabilidad hay de que vea errores en el juego, como a otros jugadores teletransportándose, siendo eliminados de forma repentina o incluso retrasos al interactuar con cofres u otros objetos.El valor de ping se muestra en milisegundos, y cuánto más bajo sea mejor. Si tenéis la suerte de vivir cerca de un centro de datos que aloje nuestros servidores, ¡es posible que vuestro ping solo sea de un dígito! Sin embargo, si jugáis en un servidor que se encuentre al otro lado del mundo, puede que vuestro ping alcance los 100 ms o más.
Aunque, todo sea dicho, existen más factores que influyen en la comunicación entre el cliente y el servidor aparte de cuánto tardan los paquetes en ir de un lado a otro. En Fortnite, solemos buscar nuevos paquetes una vez por fotograma cerca de su inicio, tanto en el servidor como en el cliente. Esto implica que existe un posible retraso de hasta un fotograma entre el momento en el que llega el paquete y cuando el cliente o el servidor lo busca, si este llega justo después de la comprobación de nuevos paquetes. Además, también lleva algo de tiempo leer el paquete y actualizar el estado del juego según los datos que contenga.
Aquí tenéis un diagrama que os ayudará a entenderlo:
Las flechas del cliente y del servidor representan el tiempo. En este ejemplo, ambos están completamente sincronizados y funcionan con la misma frecuencia de imágenes. Las líneas verticales negras representan el inicio de cada fotograma, los puntos azules indican cuándo comprueba el cliente o el servidor si hay algún paquete en proceso, y las líneas naranjas indican cuándo envían paquetes. Las líneas discontinuas moradas representan el viaje del paquete a través de internet.
Esta es la secuencia de eventos:
- El cliente envía un paquete al servidor.
- El servidor recibe el paquete que ha enviado el cliente.
- El servidor comprueba si hay algún paquete nuevo y es entonces cuando ve el que ha mandado el cliente. Se da cuenta de que este lleva esperando casi un fotograma entero porque llegó justo después de que comprobara si había paquetes nuevos.
- El servidor envía su respuesta al cliente confirmando que lo ha recibido.
- La respuesta del servidor llega al cliente.
- El cliente lee la respuesta del servidor.
En el valor que mostramos, promediamos este cálculo de los paquetes durante varios segundos para conseguir que el valor sea más coherente.
Sin embargo, en la práctica, no resulta tan preciso como nos gustaría. No tiene en cuenta el tiempo que transcurre cuando los paquetes llegan y esperan a ser procesados, por lo que con frecuencia el valor de ping que se muestra es demasiado alto. El reto se encuentra en que la mayoría de plataformas no permiten saber cuándo un paquete en concreto ha llegado, por lo que desconocemos cuánto tiempo tenemos que restar exactamente.
Nuestra forma de calcular el ping en la 7.30
Durante la 7.30 tuvimos una idea y quisimos poner a prueba algo nuevo: qué pasaría si solo utilizáramos los paquetes que tardan menos tiempo en viajar del cliente al servidor y recibir una respuesta. La teoría consistía en que los paquetes que tardaban menos tiempo serían los que se procesarían al momento, y eso nos permitiría ignorar los tiempos de espera ya que serían casi inexistentes. Terminamos utilizando el 25 % de nuestros paquetes más rápidos para calcular el valor de ping, porque parecía que elegir los paquetes más rápidos mientras contábamos con suficientes datos para obtener un valor realista nos proporcionaría un buen equilibrio.¿Qué salió mal?
Tras el lanzamiento de la 7.30, nos fijamos en muchísimos informes de jugadores que tenían un ping bajo de una sola cifra, o incluso 0, cuando tendría que haber sido mayor. Si esto fuera cierto, estaríamos enviando paquetes más rápido que la velocidad de la luz y, aunque UE4 es genial, ¡todavía no hemos llegado a ese nivel! Así que era evidente que algo no funcionaba.Parte de nuestro cálculo del ping era erróneo. Os dejo aquí la fórmula a modo de referencia:
El problema radicaba en restar el tiempo entre fotogramas del servidor. Al solo tener en cuenta los paquetes más rápidos, estamos restando una cantidad demasiado elevada: si el servidor se ocupa de un paquete en cuanto llega, es posible que solo tarde unos milisegundos en procesar el contenido y enviar una respuesta. ¡Pero el tiempo entre fotogramas del servidor puede llegar a ser 5 veces eso!
Aquí tenéis un diagrama que lo explica:
Este es un cliente que cuenta con una frecuencia de imágenes superior a la del servidor. Ya que solo tenemos en cuenta los paquetes verdes, estos llegan justo antes de que el servidor los busque. En este caso, el servidor va más rápido que su frecuencia de imágenes fija, así que entra en suspensión (no hace nada durante un rato) al inicio del fotograma antes de volver a buscar paquetes.
La línea roja indica lo que restamos como frecuencia de imágenes del servidor, pero lo que sería correcto lo indica la línea naranja. No hay duda de que es demasiado tiempo, por lo que muchos clientes empezaron a mostrar un ping de 0.
Aunque, en nuestro antiguo método, donde teníamos en cuenta una variedad más amplia de paquetes, esto sigue siendo un problema. Sin embargo, tenemos más probabilidades de considerar los paquetes que han esperado más tiempo a ser procesados, para que puedan contrarrestar a aquellos a los que les restamos demasiado tiempo.
Planes de futuro
Tenemos en mente una serie de mejoras que queremos implementar en futuros lanzamientos para conseguir que el valor de ping mostrado sea más preciso. Ya comenté esto antes:
"El reto se encuentra en que la mayoría de plataformas no permiten saber cuándo un paquete en concreto ha llegado, por lo que desconocemos cuánto tiempo tenemos que restar".
Pero, por suerte, ¡Linux sí lo permite! Como nuestros servidores funcionan exclusivamente en Linux, podemos cambiar el cálculo del ping de esta forma:
Ping = tiempo que tarda el paquete en viajar al servidor + tiempo que tarda el paquete en viajar al cliente – tiempo entre la llegada del paquete al servidor y respuesta – tiempo entre fotogramas del cliente hasta el momento.
De esta forma eliminamos las conjeturas que realizábamos al restar el tiempo entre fotogramas del servidor. Aunque creemos que de esta forma conseguiremos unos valores más precisos, todavía tenemos muchas pruebas por delante.
También estamos investigando la forma de que el cliente compruebe los paquetes con más frecuencia, lo que nos permitiría eliminar el elemento "tiempo entre fotogramas del cliente hasta el momento" de la ecuación.
Con suerte, estos dos cambios juntos nos permitirán mostrar un valor de ping más exacto.
Conclusión
Espero que este artículo os haya resultado útil para comprender cómo calculamos el ping y qué estamos haciendo para mejorar nuestro método. Cuando mostramos información de esta manera, resulta fundamental que esta sea precisa, ya que enseñar valores inexactos puede ser incluso peor que no mostrar nada. Es importante que los jugadores sepan si cuando fallan un disparo o el juego tiene lag se debe a un mal valor de ping, para que puedan corregirlo.
Estaré pendiente de los comentarios en caso de preguntas y las responderé encantado cuando pueda. ¡Gracias por la lectura!