Ir a la lista de artículos
08/06/20

El estado del registro de impactos

Hola, soy Kevin Lee, ingeniero de software del equipo de sistemas de juego de VALORANT. Nuestro equipo es el responsable de desarrollar muchos de los sistemas principales que sustentan la experiencia de juego de VALORANT, como el movimiento, el combate y las entradas de comandos. En esta publicación hablaré sobre uno de los sistemas principales de la experiencia de juego con los FPS: el registro de impactos.

En un juego como VALORANT, es probable que el registro de impactos sea uno de los sistemas más importantes, ya que la diferencia entre ganar o perder puede deberse a un único disparo a la cabeza. Nuestro objetivo como desarrolladores es asegurarnos de que, cuando el jugador realiza un disparo, el resultado del disparo sea claro, que parezca correcto y, por encima de todo, que sea el correcto.

A veces vemos que los jugadores publican o nos envían mensajes con vídeos en los que el registro de impactos parece funcionar mal. Nos tomamos muy en serio estos informes y repasamos cada vídeo, fotograma a fotograma, para comprobar que el sistema funciona como es debido.

Dicho esto, creemos que el registro de impactos de VALORANT está ahora mismo en buen estado. Sí, puede haber todavía errores en casos excepcionales y siempre nos los tomaremos en serio. Siempre estamos intentando mejorar la calidad y la claridad de todos nuestros sistemas.

PRECISIÓN VS. CLARIDAD

Durante la versión beta 0.50, observamos un incremento en los informes acerca de problemas con el registro de impactos. Tras comprobar los informes de los jugadores, sus vídeos y realizar pruebas internas de forma exhaustiva, pudimos identificar unos cuantos errores que sucedían en casos excepcionales en el registro de impactos, pero ninguno de ellos era lo bastante grave como para explicar la cantidad de informes recibidos. Al realizar un repaso más de cerca, descubrimos que la mayoría de vídeos no tenían problemas de precisión, sino de claridad. Los disparos se procesaban de forma correcta, pero la representación visual del disparo resultaba ser engañosa para el jugador. Esto resalta la importante distinción entre precisión y claridad.

Aunque ambos elementos son importantes para garantizar las sensaciones de un disparo...

  • La precisión hace referencia a un resultado del disparo erróneo (por ejemplo, que las balas impacten en la cabeza pero se registren como impactos al cuerpo o que haya discrepancias entre la posición de los jugadores enemigos en el cliente y en el servidor).
  • La claridad hace referencia a la dificultad para interpretar la presentación de los disparos (por ejemplo, una bala que impacta en el hombro pero que visualmente se representa como si hubiera impactado en la cabeza).
  • Los errores de precisión son mucho peores que los de claridad.

Esperamos que este artículo arroje algo de luz sobre el sistema para que todo el mundo pueda considerar su experiencia de juego pasada y comprender qué sucede en la pantalla con respecto a sus disparos. Hablaré sobre cómo funciona el sistema en los niveles altos y explicaré qué sucede desde el momento en que se pulsa el botón de disparo hasta que se muestra el disparo a la cabeza.

Para ver un análisis técnico en detalle, echad un vistazo a este artículo sobre el código de red de VALORANT en el blog de tecnología de Riot.

También veremos algunos casos típicos de informes de errores del registro de impactos e intentaremos explicar qué sucede y qué vamos a hacer para mejorar la claridad en esas situaciones.

DESDE EL CLIC HASTA EL DISPARO A LA CABEZA

Antes de ver qué pasa cuando se realiza un disparo, es importante entender cómo el juego simula lo que está pasando. La experiencia de juego de VALORANT se simula dos veces: una en el servidor (la autoridad a la hora de resolver la simulación) y otra en vuestro cliente (que predice los resultados del servidor para que el juego dé sensación de responder bien).

La simulación del juego incluye todo lo que pasa en el mundo, como las posiciones de todos los jugadores, cualquier habilidad volando por el aire y el humo en el campo de batalla. A cada fotograma, el juego toma una imagen de la simulación y la usa para renderizar un fotograma en vuestra pantalla. Además, el servidor hace esto con cada uno de sus fotogramas (aunque saltándose el proceso de renderizado puesto que no hay nadie que lo vea).

Vale, entonces, pongamos que un enemigo se asoma por una esquina y, con un posicionamiento increíble de la mira, apuntáis a su cabeza, apretáis el botón izquierdo para disparar y... ¿Qué sucede?

hit_reg_flow.jpg

En el momento en que se pulsa una tecla, se envía esa información a nuestro sistema de entrada (sujeto a una pequeña cantidad de latencia del sistema operativo y el hardware). En cada fotograma del juego, el sistema de entrada procesará toda la información de entrada que ha recibido desde el fotograma anterior. Entonces, cuando se realiza un disparo, la información de ese "disparo" se envía al servidor junto con una marca de tiempo que señala en qué fotograma de la simulación tuvo lugar el disparo.

Es importante tener en cuenta que la marca de tiempo queda registrada según lo que se renderiza en vuestras pantallas en el momento en que VALORANT recibe esa información de entrada. Ahora tenemos que seguir el disparo en dos simulaciones diferentes: la del cliente y la del servidor.

Empecemos con el cliente, nuestra máquina local. Inmediatamente después de que el disparo sea enviado al servidor, el cliente empieza a trabajar en mostrar un destello y una estela para el disparo. Esto sucede un fotograma después de recibir vuestra información de entrada, puesto que el juego necesita renderizar un nuevo fotograma en vuestras pantallas. Es importante porque significa que el fotograma en el que se procesa un disparo no es el mismo fotograma en el que se muestra la estela: es al menos un fotograma anterior.

A veces esto puede derivar en un fallo de claridad del disparo. La forma habitual de solucionarlo es demorar el proyectil. Nosotros optamos por no hacerlo porque demorar el proyectil hace aumentar la latencia de entrada y queremos minimizarla en VALORANT. Con respecto a la confirmación del impacto, el cliente espera la respuesta del servidor sobre el resultado antes de mostrar la confirmación del impacto. A fin de garantizar la consistencia para todos los usuarios y prevenir que los tramposos pirateen el cliente para lograr resultados falsos, el servidor tiene total autoridad para determinar el resultado de los disparos.

Mientras tanto, el servidor recibe un mensaje del cliente que le comunica que se ha realizado un disparo. Debido a la latencia de internet, desde que se ha realizado dicho disparo ha pasado un tiempo. Para asegurar que el disparo se realiza en la misma simulación que se le mostró al jugador, el servidor rebobina la simulación a la marca de tiempo que facilitó el cliente antes de evaluar el registro de impacto. Ese proceso incluye rebobinar las posiciones de los jugadores y las poses de la animación. Acto seguido, envía el resultado del disparo de regreso al cliente. Para seguir con el mismo ejemplo, ¡pongamos que ha sido un disparo a la cabeza!

El cliente recibirá un mensaje del servidor con el resultado del disparo y reproducirá los efectos visuales y de sonido correspondientes. En este caso, reproducirá los efectos de un disparo a la cabeza. Puesto que el cliente tiene que esperar a que el servidor le indique la respuesta del disparo, se produce una demora entre la estela y el efecto de impacto que equivale a la ida y la vuelta de vuestra conexión (por ejemplo, 40 ms hasta el servidor = 80 ms de demora entre la estela y el efecto visual de impacto) más una pequeña cantidad que se debe al tiempo de procesamiento. Con una latencia más alta, esa demora puede llegar a notarse en tiempo real.

Esto es algo que estamos trabajando activamente para mejorarlo desde la perspectiva de la claridad.

CASO PRÁCTICO 1: Impactos contra objetivos en movimiento

Case_Study_1.gif

En muchos informes relativos al registro de impactos vemos que el objetivo del disparo está corriendo. Echemos un vistazo más de cerca a lo que sucede visualmente cuando un disparo impacta contra un objetivo a la carrera. Vemos que el jugador logra un disparo a la cabeza contra el jugador que corre. Para ilustrar de forma más sencilla el problema del ejemplo, pongamos que el cliente se está ejecutando a 60 FPS. Se puede ver como en el fotograma anterior a la estela, la mira se alinea con la cabeza del enemigo.

case-study-1_frame-1.jpgcase-study-1_frame-2.jpg

Sin embargo, en el fotograma en que aparece la estela, ese ya no es el caso.

case_study_1_part_2.gif

El segundo vídeo muestra el mismo escenario, pero el disparo no logra alcanzar al objetivo. Cuando se mira el vídeo fotograma a fotograma, se puede apreciar el caso contrario: la mira no se sitúa sobre la cabeza en el fotograma anterior a la estela, lo hace cuando aparece la estela. A primera vista, se podría señalar al fotograma de la estela y decir: "¿Lo ves? ¡era claramente un disparo a la cabeza!" Al visualizar vídeos o repeticiones, en realidad tenemos que mirar el fotograma anterior al de la estela para saber con precisión cuándo se realizó el disparo.

case-study-1_part2_frame-1.jpgcase-study-1_part2_frame-2.jpg
case-study-1_part2_no-hit-vfx.jpg

Volvamos al ejemplo en el que el disparo impacta y veamos el fotograma con el efecto visual de impacto renderizado. Hay una diferencia perceptible entre la ubicación actual del jugador y la ubicación del efecto visual de impacto. Esto se debe a la demora causada por la latencia de internet. Puede resultar confuso a la hora de entender qué sucede con un disparo, ya que lo más probable es que nos fijemos en la ubicación actual del enemigo, no en su ubicación en el momento del disparo. Además, puede resultar todavía más confuso en los casos en los que el jugador está agachado o desplazándose lateralmente (los cuales examinaremos en el caso práctico 2).

case-study-1_part2_frame-where-hit-vfx-rendered.jpg

Este caso muestra la falta de claridad del sistema actual de registros de impacto. Lo ideal sería no tener que entender toda esa información de fondo para comprender la situación con claridad. Como desarrolladores, somos conscientes de ello y estamos investigando formas de mejorar la claridad en estos casos.

CASO PRÁCTICO 2: Efecto visual de un disparo contra un jugador agachado

Os habéis metido en un tiroteo a largo alcance. Mantenéis pulsado el clic izquierdo y disparáis sin parar, algo de lo que luego os arrepentiréis. Al menos una de la balas dará en la cabeza, ¿no? Pero no; lográis 3 impactos al cuerpo con la Vandal, lo que inflige un total de 117 de daño, antes de recibir vosotros un disparo en la cabeza.

Muy enfadados, vais a ver la repetición después de la partida, convencidos de que algo falla en el registro de impactos. Veis como el jugador enemigo se agacha constantemente para intentar esquivar las balas. Para vuestra sorpresa, veis el efecto visual de un impacto en la parte alta de su cabeza mientras el jugador se agacha. ¡Pero el informe de combate solo mostraba impactos al cuerpo! ¿¿Qué pasa aquí??

Este es un enlace a una publicación real de reddit titulada
"Los disparos a la cabeza no se registran cuando un jugador se agacha (Headshots not registering when a player crouches)" sobre el caso hipotético.

Cuando nuestro equipo se pone a investigar informes sobre errores en el registro de impactos, situaciones como esta son los casos más frecuentes en los que parece que se registran impactos de forma incorrecta. En realidad, el registro de impactos funciona correctamente. Los disparos van hacia donde se apunta (haciendo caso omiso a errores de dispersión y de movimiento) cuando se pulsa el botón y ese disparo se registra de forma precisa en el servidor.

Sin embargo, unos cuantos factores provocan que este caso en concreto resulte engañoso visualmente:

  1. Los efectos visuales de impacto tienen una demora a causa de la latencia de internet.
  2. Los efectos visuales de impacto se muestran en la ubicación del impacto original del disparo.
  3. El jugador objetivo está en movimiento (casi siempre, agachándose).

Case_Study_2.gif

Pongamos otro ejemplo con un jugador que tiene 50 de ping. El jugador realiza un disparo que impacta en el hombro del enemigo. Como tenemos que esperar a que el servidor confirme el disparo, el efecto visual comienza a reproducirse, 100 ms después, en la ubicación del disparo al cuerpo. Pero, durante esos 100 ms, el jugador enemigo ha comenzado a agacharse, poniendo la cabeza justo detrás del recién aparecido efecto visual. A largo alcance y durante el fragor de un tiroteo, el efecto visual de un impacto al cuerpo se puede confundir con un efecto visual de un impacto a la cabeza.

case-study-2_cursor-on-body.jpgcase-study-2_hit-VFX-on-body-correctly.jpgcase-study-2_player-crouches-into-vfx.jpg

Esto sucedía sobre todo en la versión beta 0.50, en la que se desactivó la sangre de forma no intencional para todo el mundo y el efecto visual de chispa tenía menos claridad visual a la hora de distinguir entre los efectos de un disparo a la cabeza y uno al cuerpo. Siempre ha habido efectos visuales distintos para diferenciar los disparos a la cabeza de los disparos al cuerpo, pero nos dimos cuenta de que no siempre se discernían claramente durante el combate.

Este es un fallo de claridad del registro de impactos que estamos intentando corregir activamente. Una de las cosas con las que estamos experimentando son los efectos visuales de impacto para cada parte del cuerpo del personaje en la que se realizó el impacto, para que así haya una relación clara, incluso con latencia alta.

Comparación del efecto visual de impacto a la cabeza sin sangre actual con el efecto visual de disparo al cuerpo:

headshot-VFX.jpgbody-shot-VFX.jpg

MEJORAS DE CLARIDAD PLANIFICADAS

Estos dos casos prácticos ponen de manifiesto áreas en las que los efectos visuales de confirmación de impacto actuales se quedan cortas. Uno de los cambios que estamos probando es que la sangre y los efectos de chispa aparezcan en la ubicación actual del personaje, de forma acorde con la parte del cuerpo que sufrió el impacto, y que lo sigan mientras se mueve. De ese modo, aumentaría mucho la claridad en situaciones como el número 2 en el que los enemigos se agachan, porque el efecto visual se desplazaría con los movimientos del cuerpo.

Un inconveniente que presenta ese método es que puede que el efecto visual de confirmación de impacto se desplace detrás de una cobertura junto al jugador al que va unido. Pensad en el caso de un jugador que tiene un ping de 100 ms y que dispara a otro jugador que asoma detrás de una esquina. Si logra un impacto contra el enemigo y este se pone a cubierto justo antes de que llegue la confirmación del impacto del servidor, puede que el atacante no llegue a ver la confirmación del impacto cuando aparezca.

Para mitigar este problema, hemos pensado añadir varias partículas: que algunas sigan al personaje y otras aparezcan inmediatamente en la ubicación del impacto, basada en la simulación del cliente. Sin embargo, esto podría ocasionar confusión si las simulaciones del cliente y del servidor no están de acuerdo en el resultado de un disparo: los efectos tienen que ser claros en lo que representan para que sea fácil entender el resultado de un disparo.

Seguimos insistiendo en esta y otras mejoras a la claridad y esperamos poder compartir pronto un conjunto de actualizaciones de claridad en una versión próxima.

SEGUID MANDANDO VÍDEOS

Con suerte, esta publicación os habrá servido para entender mejor cómo funciona el registro de impactos en VALORANT y entender mejor por qué los disparos se resuelven de la forma en que lo hacen. Seguid enviando vídeos cuando creáis que el registro de impactos no funciona como debe, nosotros nos esforzamos al máximo para verlos todos.

Incluso cuando no existe ningún problema, nos sirve para rastrear errores de precisión en el registro de impactos mucho más rápido cuando estos suceden (también se me acelera el pulso cada vez que veo las palabras "registro de impactos" en una publicación de reddit muy votada).

Este enlace muestra un ejemplo de un error de precisión en el registro de impactos publicado en reddit.