Hay una larga historia de cómo llegamos a esta convención común, con muchos desafíos fascinantes en el camino, así que intentaré motivarlo por etapas:
1. Problema: los dispositivos funcionan a diferentes velocidades
¿Alguna vez trataste de jugar un viejo juego de DOS en una PC moderna y se ejecuta de manera increíblemente rápida?
Muchos juegos antiguos tenían un ciclo de actualización muy ingenuo: recolectaban información, actualizaban el estado del juego y renderizaban lo más rápido que permitía el hardware, sin tener en cuenta cuánto tiempo había transcurrido. Lo que significa que tan pronto como cambia el hardware, cambia la jugabilidad.
En general, queremos que nuestros jugadores tengan una experiencia consistente y una sensación de juego en una variedad de dispositivos (siempre que cumplan con algunas especificaciones mínimas) ya sea que estén usando el teléfono del año pasado o el modelo más nuevo, una computadora de escritorio de juegos de alta gama o un Portátil de nivel medio.
En particular, para los juegos que son competitivos (ya sea multijugador o tablas de clasificación) no queremos que los jugadores que se ejecutan en un dispositivo en particular tengan una ventaja sobre otros porque pueden correr más rápido o tener más tiempo para reaccionar.
La solución segura aquí es bloquear la velocidad a la que hacemos actualizaciones de estado de juego. De esa manera podemos garantizar que los resultados siempre serán los mismos.
2. Entonces, ¿por qué no simplemente bloquear la velocidad de fotogramas (p. Ej., Usando VSync) y aún ejecutar las actualizaciones de estado del juego y la representación en bloque?
Esto puede funcionar, pero no siempre es agradable al público. Hubo mucho tiempo en que correr a 30 fps fue considerado el estándar de oro para los juegos. Ahora, los jugadores esperan habitualmente 60 fps como la barra mínima, especialmente en juegos de acción multijugador, y algunos títulos más antiguos ahora se ven notablemente entrecortados ya que nuestras expectativas han cambiado. También hay un grupo vocal de jugadores de PC en particular que se oponen a los bloqueos de velocidad de fotogramas. Pagaron mucho por su hardware de última generación y quieren poder usar ese músculo informático para obtener el renderizado más suave y de mayor fidelidad que sea capaz.
En realidad, en realidad, la velocidad de fotogramas es el rey, y el estándar sigue aumentando progresivamente. Al principio del reciente resurgimiento de la realidad virtual, los juegos a menudo corrían alrededor de 60 fps. Ahora 90 es más estándar, y el hardware como el PSVR está comenzando a admitir 120. Esto puede seguir aumentando aún. Entonces, si un juego de realidad virtual limita su velocidad de cuadros a lo que es factible y aceptado hoy, es probable que se quede atrás a medida que el hardware y las expectativas se desarrollen aún más.
(Como regla, tenga cuidado cuando le digan "los jugadores no pueden percibir nada más rápido que XXX", ya que generalmente se basa en un tipo particular de "percepción", como reconocer un cuadro en secuencia. La percepción de la continuidad del movimiento es generalmente mucho más sensible. )
El último problema aquí es que un juego que usa una velocidad de fotogramas bloqueada también debe ser conservador: si alguna vez encuentras un momento en el juego en el que estás actualizando y mostrando una cantidad inusualmente alta de objetos, no querrás perderte tu fotograma. fecha límite y causar un tartamudeo o enganche notable. Por lo tanto, debe establecer sus presupuestos de contenido lo suficientemente bajos como para dejar margen de maniobra, o invertir en funciones de ajuste de calidad dinámica más complicadas para evitar vincular toda la experiencia de juego al rendimiento en el peor de los casos en hardware de especificaciones mínimas.
Esto puede ser especialmente problemático si los problemas de rendimiento aparecen tarde en el desarrollo, cuando todos sus sistemas existentes se construyen y ajustan suponiendo una velocidad de fotogramas de representación que ahora no siempre se puede alcanzar. El desacoplamiento de las tasas de actualización y representación brinda más flexibilidad para lidiar con la variabilidad del rendimiento.
3. ¿La actualización en un intervalo de tiempo fijo no tiene los mismos problemas que (2)?
Creo que este es el meollo de la pregunta original: si desacoplamos nuestras actualizaciones y, a veces, procesamos dos cuadros sin actualizaciones de estado del juego en el medio, entonces no es lo mismo que la representación de bloqueo a una velocidad de cuadros más baja, ya que no hay un cambio visible en ¿la pantalla?
En realidad, hay varias maneras diferentes en las que los juegos usan el desacoplamiento de estas actualizaciones con buenos resultados:
a) La velocidad de actualización puede ser más rápida que la velocidad de fotogramas renderizada
Como señala tyjkenn en otra respuesta, la física en particular a menudo se escalona a una frecuencia más alta que la representación, lo que ayuda a minimizar los errores de integración y proporciona colisiones más precisas. Entonces, en lugar de tener 0 o 1 actualizaciones entre cuadros renderizados, puede tener 5 o 10 o 50.
Ahora, el reproductor que renderiza a 120 fps puede obtener 2 actualizaciones por cuadro, mientras que el jugador con un rendimiento de hardware de menor especificación a 30 fps obtiene 8 actualizaciones por cuadro, y ambos juegos se ejecutan a la misma velocidad de juego-ticks-por-tiempo real-segundo. El mejor hardware hace que parezca más fluido, pero no altera radicalmente el funcionamiento del juego.
Aquí existe el riesgo de que, si la velocidad de actualización no coincide con la velocidad de fotogramas, puede obtener una "frecuencia de latido" entre los dos . P.ej. En la mayoría de los cuadros tenemos tiempo suficiente para 4 actualizaciones de estado del juego y un poco de sobra, y de vez en cuando tenemos suficiente guardado para hacer 5 actualizaciones en un cuadro, haciendo un pequeño salto o tartamudeo en el movimiento. Esto puede ser abordado por ...
b) Interpolar (o extrapolar) el estado del juego entre actualizaciones
Aquí a menudo dejaremos que el estado del juego viva un paso de tiempo fijo en el futuro, y almacenaremos suficiente información de los 2 estados más recientes para que podamos representar un punto arbitrario entre ellos. Luego, cuando estamos listos para mostrar un nuevo cuadro en pantalla, nos mezclamos con el momento apropiado solo para mostrar (es decir, no modificamos el estado de juego subyacente aquí)
Cuando se hace bien, esto hace que el movimiento se sienta suave e incluso ayuda a enmascarar alguna fluctuación en la velocidad de fotogramas, siempre que no bajemos demasiado .
c) Agregar suavidad a los cambios de estado que no son del juego
Incluso sin interpolar el estado del juego, aún podemos obtener algunas victorias de suavidad.
Los cambios puramente visuales como la animación de personajes, los sistemas de partículas o VFX, y los elementos de la interfaz de usuario como HUD, a menudo se actualizan por separado del paso de tiempo fijo del estado de juego. Esto significa que si estamos marcando nuestro estado de juego varias veces por cuadro, no estamos pagando su costo con cada marca, solo en el pase de render final. En cambio, escalamos la velocidad de reproducción de estos efectos para que coincida con la longitud del cuadro, para que se reproduzcan tan suavemente como lo permita la velocidad de fotogramas de renderizado, sin afectar la velocidad del juego o la equidad como se discutió en (1).
El movimiento de la cámara también puede hacer esto, especialmente en VR, a veces mostraremos el mismo cuadro más de una vez, pero lo reproyectaremos para tener en cuenta el movimiento de la cabeza del jugador en el medio , para que podamos mejorar la latencia y la comodidad percibidas, incluso si podemos No renderizar todo de forma nativa tan rápido. Algunos sistemas de transmisión de juegos (donde el juego se ejecuta en un servidor y el jugador solo ejecuta un cliente ligero) también usan una versión de este.
4. ¿Por qué no usar ese estilo (c) para todo? Si funciona para la animación y la interfaz de usuario, ¿no podemos simplemente escalar nuestras actualizaciones de estado de juego para que coincidan con la velocidad de fotogramas actual?
Sí * esto es posible, pero no, no es simple.
Esta respuesta ya es un poco larga, así que no entraré en todos los detalles sangrientos, solo un resumen rápido:
Multiplicar por deltaTime
trabajos para ajustarse a actualizaciones de longitud variable para un cambio lineal (por ejemplo, movimiento con velocidad constante, cuenta regresiva de un temporizador o progreso a lo largo de una línea de tiempo de animación)
Desafortunadamente, muchos aspectos de los juegos no son lineales . Incluso algo tan simple como la gravedad exige técnicas de integración más sofisticadas o subpasos de mayor resolución para evitar resultados divergentes con velocidades de cuadro variables. La entrada y el control del jugador es en sí misma una gran fuente de no linealidad.
En particular, los resultados de la detección y resolución discretas de colisiones dependen de la velocidad de actualización, lo que lleva a errores de tunelado y fluctuación de fase si los cuadros se alargan demasiado. Por lo tanto, una velocidad de fotogramas variable nos obliga a usar métodos de detección de colisión continua más complejos / costosos en más de nuestro contenido, o tolerar la variabilidad en nuestra física. Incluso la detección de colisión continua se enfrenta a desafíos cuando los objetos se mueven en arcos, lo que requiere pasos de tiempo más cortos ...
Por lo tanto, en el caso general de un juego de complejidad media, mantener un comportamiento coherente y equitativo por completo a través de la deltaTime
escala es algo muy difícil y de mantenimiento intensivo a absoluto inviable.
La estandarización de una tasa de actualización nos permite garantizar un comportamiento más consistente en una variedad de condiciones , a menudo con un código más simple.
Mantener esa tasa de actualización desacoplada del renderizado nos da flexibilidad para controlar la suavidad y el rendimiento de la experiencia sin alterar la lógica del juego .
Incluso entonces , nunca obtenemos una independencia de framerate verdaderamente "perfecta", pero al igual que muchos enfoques en los juegos, nos da un método controlable para marcar "lo suficientemente bueno" para las necesidades de un juego determinado. Es por eso que comúnmente se enseña como un punto de partida útil.