Compensación de retraso con juegos 2D en red

31

Quiero hacer un juego en 2D que sea básicamente un juego de sandbox / actividad impulsado por la física. Sin embargo, hay algo que realmente no entiendo. Según la investigación, parece que las actualizaciones del servidor solo deberían ser aproximadamente cada 100 ms. Puedo ver cómo funciona esto para un jugador, ya que pueden simular simultáneamente la física y compensar el retraso a través de la interpolación.

Lo que no entiendo es cómo funciona esto para las actualizaciones de otros jugadores. Si los clientes solo reciben notificaciones de las posiciones de los jugadores cada 100 ms, no veo cómo funciona eso porque pueden pasar muchas cosas en 100 ms. El jugador podría haber cambiado de dirección dos veces más o menos en ese tiempo. Me preguntaba si alguien tendría alguna idea sobre este tema.

Básicamente, ¿cómo funciona esto para disparar y cosas así?

Gracias

jmasterx
fuente

Respuestas:

58

Resumen para aquellos que no les gustan las respuestas largas ...

Se puede hacer, pero es imposible hacer una física multijugador perfecta si hay alguna latencia. Se explica por qué la latencia afecta la física, y luego se ofrecen consejos para reducir el impacto de la latencia en su simulación física.


Crear un juego de física multijugador puede estar lleno de peligros. Es imposible crear una experiencia de física multijugador en línea "perfecta". Hay cosas que puede hacer para mejorarlo, pero no hay forma de hacer una física perfecta asumiendo una latencia.

El problema es que la física debe ser rápida y receptiva para ser realista, pero al mismo tiempo debe calcularse en función de las acciones combinadas de TODOS los factores, es decir, las acciones combinadas de todos los jugadores. Y si hay latencia, esto no se puede hacer en tiempo real.

Depende de usted como desarrollador decidir si puede mantener los diferentes factores bajo control y comprender que la experiencia del jugador se degradará si la latencia se vuelve demasiado alta. Si puedes vivir con eso (y tus jugadores pueden), entonces adelante. Vea al final de esta publicación algunas notas sobre cómo puede mantener las cosas funcionando sin problemas.

Un ejemplo para mostrar cómo las cosas pueden desordenarse

Imagine un juego donde dos jugadores (clientes) están conectados a un servidor. Se necesitan 100 milisegundos (1/10 de segundo) para que un mensaje pase a través de Internet desde el cliente al servidor. Cuando un jugador hace algo, se envía un mensaje al servidor que dice lo que hizo. El servidor luego transmite el mensaje a los otros jugadores para que todos sepan lo que hizo el jugador en funciones.

Ahora crea un escenario donde dos jugadores tienen una caja en el suelo que es un objeto de física. El jugador A lo golpea en un lado y lo mueve en alguna dirección. Sin embargo, al mismo tiempo, el jugador B lo golpea en otro lado, enviándole otra dirección.

Veamos diferentes formas de manejar esto y cuáles serían los resultados ...

¿Qué pasa si la física se calcula solo en el servidor?

Supongamos que tenemos la física calculada solo en el servidor. El jugador A envía el mensaje "Golpeé la caja de esta manera" al servidor, 1/10 segundos después el servidor recibe el mensaje. El jugador B envía su mensaje "I hit cajón de esta manera". El servidor calcula el cambio físico a partir de la combinación de las dos acciones y envía un mensaje a los dos jugadores diciendo: "OK, se mueve así". Se realiza una física perfecta, basada en las acciones de ambos jugadores combinados.

Pero el problema es que pasarán dos décimas de segundo antes de que cualquier jugador vea que la caja reacciona. Los mensajes de ambos jugadores tardan 1/10 de segundo en llegar al servidor, luego otra 1/10 de segundo para que se envíen los resultados de cálculo de los servidores a ambos jugadores.

En pocas palabras, juego lento.

¿Qué pasa si la física solo se calcula en el cliente?

Supongamos que tenemos física calculada solo para el cliente. Veámoslo desde el punto de vista del jugador A. El jugador A golpea la caja e inmediatamente comienza a ir en su dirección. También se envía un mensaje al servidor que dice lo que hizo el jugador A.

Sin embargo, al mismo tiempo, B hizo su golpe y vio que la caja iba en su dirección y envió un mensaje al servidor sobre lo que hicieron.

2/10 de segundo después, llega un mensaje del servidor a los clientes. A A se le dice lo que hizo B, y a B se le dice lo que A hizo. El problema es que ambos clientes dicen: "Bueno, el jugador X puede haber hecho ese golpe en este lugar, pero ya no hay una caja en ese lugar, por lo que su golpe no hizo nada".

La conclusión es que dos juegos no están sincronizados y los jugadores no tienen una experiencia compartida. ¿Qué sentido tiene el modo multijugador si ambos ven cosas diferentes?

¿Qué pasa si la física se calcula tanto en el cliente como en el servidor?

En este caso, la física se calcula en el cliente para que los jugadores vean una reacción inmediata sin retraso, pero también se calcula en el servidor, por lo que es "correcta" para todos los jugadores.

Ambos jugadores golpean la caja en sus respectivas direcciones y cada uno ve el movimiento de la caja basándose solo en su golpe. Pero luego, dos décimas de segundo después, el servidor regresa y dice: "Bueno, en realidad, ambos están equivocados. La caja fue de esta manera". De repente, ambos jugadores ven que la caja cambia drásticamente las direcciones y falla a una nueva ubicación.

En pocas palabras, es un juego glitchy.

Conclusión

Básicamente no hay forma de hacer un juego de física perfecto con múltiples jugadores cuando existe algún tipo de latencia. Puedes hacer un juego bastante bueno, pero siempre tendrás el riesgo de una latencia excesiva creando una mala experiencia para algunos jugadores. Sin embargo, hay cosas que puedes hacer para que tu experiencia de juego sea buena.

Cosas que puedes hacer para que un juego multijugador funcione bien

Use volúmenes de colisión simples. No se moleste en modelar cada detalle de una forma con la física cuando una simple forma de cubo servirá. Una pelota puntiaguda no tiene que ser modelada como una pelota puntiaguda para la física. En cambio, simplemente modelarlo como una esfera.

Haga pequeños objetos intrascendentes artículos solo para clientes. Un ejemplo podría ser trozos de vidrio roto de una ventana rota. Puede dejar que cada cliente lo simule por sí mismo, y realmente no importará si son diferentes.

Solo haga objetos de objetos físicos si necesitan ser objetos físicos para mantener bajo el número de objetos físicos activos.

Ejecuta tu juego en cámara lenta al hacer física multijugador. Piensa en "tiempo de bala" tal vez. Los juegos de cámara lenta compensan la latencia y permiten que varios jugadores interactúen juntos con la física.

Permita a los jugadores configurar una situación de algún tipo juntos, y luego, en algún momento, la física se simula para ambos jugadores y ambos observan el resultado de sus acciones combinadas. Los jugadores no pueden interferir con la secuencia hasta que se complete.

Separe la física de los jugadores para que no puedan interferir entre sí. Esto sería genial para un juego como bolos o billar, donde solo un jugador a la vez tiene el control, o cada jugador tiene su propia "caja de arena" (como una pista de bolos).

Si no puedes vencerlos, únete a ellos y haz que el retraso físico sea parte de tu juego. Imagina una historia sobre estar en un universo glitchy con leyes físicas rotas o algo :)

Apéndice: cómo lidian los juegos de disparos

Los juegos de disparos se ocupan de ello al no hacer física demasiado compleja. Utilizan los efectos secundarios del cliente para que los jugadores vean las cosas rápidamente, pero luego el servidor hace la última llamada sobre lo que sucedió.

Imagine un escenario en el que el jugador A dispara al jugador B. Su típico juego de disparos hará algo como esto ...

  1. A calculará localmente si golpean a B, y si parece que hay un golpe, juega un efecto de "golpe" como una nube de sangre. Esto se hace del lado del cliente para que el jugador vea inmediatamente una reacción a su acción. Si no haces esto, el juego se siente lento.
  2. A también envía un mensaje al servidor diciendo: "Disparé a lo largo de este vector"
  3. Cuando el servidor recibe el mensaje, observa dónde cree que están los jugadores y decide si el vector de disparo de A golpea a B.
  4. Si el servidor decide que A golpeó a B, decide que B es golpeado y envía un mensaje a AMBOS clientes diciendo lo que sucedió.
  5. Si el servidor decide que A NO golpeó a B, B está bien y A "falla". Puede parecerle a A como si golpearan ("¡Vi la bocanada de sangre!") Pero es la llamada de los servidores lo que perdieron.

Entonces, ¿cómo podría A fallar B cuando parecía que los golpearon? Debido a que B puede haberse movido, pero A aún no lo ha visto porque el servidor aún no ha enviado el mensaje "B se mudó aquí" al cliente.

Valve tiene una buena crítica en su sitio sobre esto. Ver http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

Tim Holt
fuente
2
Eso es cierto en un servidor con una buena conexión. Hay muchos casos en los que la física en los juegos multijugador falla y estoy seguro de que hay muchas malas experiencias físicas en los juegos Mod de Garry. Sin embargo, si hay latencia, los problemas que describí existirán. No se puede evitar el hecho de que la física debe calcularse muy rápidamente para que sea fluida. Y si tiene latencia, habrá un retraso. Demora significa retraso.
Tim Holt
1
Es posible que desee volver y releer mi publicación. Menos mi opinión al principio de mi parte, estoy describiendo exactamente lo que sucede en una simulación de física con varios jugadores, incluidas las sesiones de juego de Garry's Mod. No puedes evitar los hechos.
Tim Holt
2
Ok, cambié mi voto a favor. Pero dibujas una imagen realmente negativa para los juegos multijugador con física, cuando realmente se ha hecho antes y está relativamente libre de fallas.
AttackingHobo
77
@AttackingHobo: "Glitch free" es relativo. Después de haber trabajado en un juego con una buena predicción de red, ahora veo problemas técnicos que no había visto antes. Raramente afectan la mecánica de manera significativa, pero están presentes. Todo el punto de predicción es que una pequeña imprecisión en tiempo real es mejor que la precisión retrasada; eso no cambia el hecho de que siempre eres inexacto.
1
+1 para "Imagina una historia sobre estar en un universo con fallas en leyes de física o algo así".
Patryk Czachurski
13

He escrito una serie de artículos sobre el tema aquí: http://www.gabrielgambetta.com/fpm1.html

Los primeros tres artículos tratan de una introducción al tema, la predicción del lado del cliente, la reconciliación del servidor y la interpolación de entidades (esta es la parte que responde a su pregunta específica). El cuarto artículo (próximamente) tratará sobre "disparar cosas" :)

La respuesta de Tim Holt es más o menos eso. Mis artículos tienen un par de diagramas que pueden ayudarlo a comprender lo que está sucediendo, pero Tim y yo básicamente estamos diciendo lo mismo.

ggambett
fuente
Buenas cosas ggambett!
Tim Holt
2
Muchos jugadores no entienden cómo funcionan estas cosas, pero es muy importante para comprender lo eterno, "¿POR QUÉ FALTÉ?" pregunta.
Tim Holt
O "¿por qué mi personaje está atado a esa columna con una banda de goma gigante?" en una conexión caída :)
ggambett
El Wiki de Valve tiene una reseña que también aborda estos temas. La página está en developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
Tim Holt el
1
Me encanta la demostración en vivo. Qué gran manera de visualizar lo que está sucediendo.
Richard Marskell - Drackir
2

No es irrazonable hacer una predicción completa de su propio personaje para la capacidad de respuesta y hacer que otros personajes se retrasen 100ms para mantener la coherencia. Si esto se ve mal, entonces considera tener tu propio personaje un poco más lento para mantenerlos sincronizados. De cualquier manera, aún necesitará mecanismos de corrección para suavizar las predicciones incorrectas en caso de picos de retraso, y ese sistema se ocupará de situaciones como la que usted describe. No importa si la latencia es de 100 ms o de 1 ms: su cliente siempre llega "tarde" en algún sentido y, por lo tanto, siempre tiene que actuar como si estuviera tratando con datos antiguos y aplicar efectos cosméticos como la interpolación para que parezca razonable.

Kylotan
fuente
0

Al final, todo se trata de conformarse con los recursos de red disponibles. Idealmente, viviríamos en un mundo con latencia cero y todo se puede sincronizar perfectamente. Siendo realistas, actualiza los clientes cada 100, 200, 300 ms y en el cliente debe existir una lógica para que todo lo que sucedió parezca fluido. La "suavidad" es muy importante, al final el juego solo necesita sentirse suave incluso si en el back-end hay una sincronización caótica entre el cliente y el servidor.

Se puede encontrar una buena publicación y una mejor respuesta:

¿Cómo escribir un juego en red?

DeusAduro
fuente
0

El problema no es realmente la latencia. Se puede compensar y predecir bastante bien para ocultar cualquier problema que haya causado. La pérdida de paquetes tampoco es un problema: el sistema de red debe escribirse para que sea robusto y tolerable para la pérdida de paquetes. Sin embargo, el problema son los picos de retraso y la latencia impredecible. Paquetes que no están sincronizados, algunos de los cuales se descartaron solo debido a cambios de latencia, incapacidad para predecir e interpolar debido a cambios de latencia, etc.


fuente