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 ...
- 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.
- A también envía un mensaje al servidor diciendo: "Disparé a lo largo de este vector"
- 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.
- 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ó.
- 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
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.
fuente
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.
fuente
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?
fuente
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