La física no se sincroniza correctamente a través de la red cuando se usa Bullet

11

Estoy tratando de implementar un sistema físico de cliente / servidor usando Bullet, sin embargo, tengo problemas para sincronizar las cosas.

He implementado un estado de movimiento personalizado que lee y escribe la transformación de los objetos de mi juego y funciona localmente, pero he probado dos enfoques diferentes para juegos en red:

  1. Los objetos dinámicos en el cliente que también están en el servidor (p. Ej., Desechos no aleatorios y otras cosas sin importancia) se hacen cinemáticos. Esto funciona correctamente pero los objetos no se mueven muy suavemente
  2. Los objetos son dinámicos en ambos, pero después de cada mensaje del servidor de que el objeto se ha movido, configuro la velocidad lineal y angular a los valores del servidor y llamo a btRigidBody :: proceToTransform con la transformación en el servidor. También llamo btCollisionObject :: activar (verdadero); para forzar al objeto a actualizar.

Mi intención con el método 2 era básicamente hacer el método 1, pero secuestrar a Bullet para hacer la predicción de un hombre pobre en lugar de hacer la mía para suavizar el método 1, pero esto no parece funcionar (por razones que no son 100% claras para incluso cuando paso por Bullet) y los objetos a veces terminan en diferentes lugares.

¿Me dirijo en la dirección correcta? Bullet parece tener su propio código de interpolación incorporado. ¿Puede eso ayudarme a hacer que el método 1 funcione mejor? ¿O mi código del método 2 no funciona porque accidentalmente estoy pisoteando eso?

EDITAR: Otro problema con el método 1 que acabo de notar es que la respuesta de colisión estará lejos para colisiones contra objetos no sincronizados. Los cuerpos cinéticos disparan cosas hasta el infinito a veces, ya que no pueden ser rechazados.

Lucas
fuente
Algunas cosas que podrían ayudarlo a obtener una respuesta: ¿Qué idioma / motor está utilizando? ¿Qué tipo de conexión es? ¿Qué tan malo es el déficit de sincronización, en comparación con el ping al servidor?
Fibericon
2
La segunda opción no funciona porque solo establece las velocidades a los valores del servidor después de unos pocos cuadros, por lo que entre cada paquete hay unos pocos cuadros donde las cosas pueden derivar. Recomiendo leer todas las publicaciones de Gaffer sobre física del juego, probablemente deberías leer primero 'arregla tu paso de tiempo' pero aquí está el artículo final que habla sobre la física en red gafferongames.com/game-physics/networked-physics
Roy T.
Estoy usando un motor de desarrollo propio en C ++. Sin embargo, estoy bastante seguro de que el déficit de sincronización no es tan malo, probablemente 1 trama sobre ping si tuviera que adivinar, pero todavía estoy haciendo principalmente pruebas de LAN solamente. Revisaré esos artículos y sí, tienes razón en que las velocidades están apagadas. Sin embargo, las cosas están muy lejos, como si la caja estuviera al otro lado del mapa. ¿No debería establecer explícitamente la transformación hacer que la cosa generalmente se ajuste eventualmente? (incluso si aún no es bonito, se agita, etc.)
Lucas
Leí la publicación de Gaffer y fue informativa, pero parecía tratar principalmente con el movimiento de los jugadores, que es algo en lo que ya estoy trabajando. He estado leyendo y parece que mi código del método 2 es prácticamente idéntico al método utilizado en el motor Unreal . No proporcionan muchos detalles, pero me hace preguntarme si la idea es correcta, pero mi uso de Bullet es incorrecto.
Lucas
Una lectura interesante, que está relacionada en parte con su tema: gamasutra.com/view/feature/3094/… . Se trata de un rts y no se trata de física, pero llegan al punto, donde tienen que sincronizar una simulación en el servidor y los clientes. La forma en que lo hacen? Se ejecutan simulaciones independientes sobre el cliente y el servidor, pero el servidor envía envía paquetes que aseguran, que la simulación cliente no divergen y se corrige, si sucede ...
van tom verde

Respuestas:

4

Necesita una predicción adecuada del lado del cliente .

Realmente deberías leer en detalle el enlace que Roy T. te proporcionó en su comentario . Describe qué hacer con la entrada del jugador y la física del personaje, pero el principio sigue siendo el mismo para la "física dirigida por el servidor".

Esto no es trivial de implementar, pero en pocas palabras, para los objetos del juego que necesitan estar sincronizados:

  • Ejecute la física tanto en el servidor como en el cliente;
  • El servidor envía actualizaciones regularmente;
  • El cliente reajusta continuamente y sin problemas su mundo físico a los valores del servidor.

Entonces, sí, se dirige en la dirección correcta con su método 2. Sin embargo, anular los valores no es suficiente, obtendrá saltos en el cliente, lo que debe hacer es interpolar sin problemas y continuamente los valores del servidor.

Para su error real, no estoy familiarizado con Bullet, pero probablemente le faltan algunos valores, por ejemplo, ha establecido las velocidades lineal y angular, pero ¿ha establecido las aceleraciones?

Laurent Couvidou
fuente
¡Gracias! Esto me hace sentir mejor que estoy en el camino correcto. Revisaré mi código con un peine de dientes finos ahora. Tal vez alguna notificación no se active o, como usted dice, me falta un valor ya que el método 2 debería funcionar (bruscamente).
Lucas
3

Lo que hago personalmente es quien aloja el juego crea el mundo de la física y sincroniza los objetos con los clientes. Incluso si es un esquema de red p2p, sigo basando el motor de física en uno de los clientes de los jugadores.

Otra física que uso que es puramente dulce ni siquiera necesita sincronizarse.

En un prototipo que hice hace un tiempo llamado "boilerzerker", ejecuté la física en el host y los efectos de partículas (también usando física) no se sincronizaron a través de una red, sino que eran independientes para cada cliente porque eran muy atractivos.

tsturzl
fuente
Gracias, sí, esa es una forma de hacerlo. Sin embargo, no da como resultado respuestas agradables de colisión en el cliente a las cosas que el cliente hace y tampoco las cosas interesantes no siempre interactúan correctamente, ya que no puede hacer retroceder las cosas del servidor (al menos dentro de ese paso de tiempo). Siento que esto debe ser posible ya que motores como Unreal y Source parecen hacerlo.
Lucas
eye candy no necesita sincronizarse, puede calcularse por cliente. la respuesta en el cliente se calcula en el servidor, las coordenadas para el cliente solo se calculan y se envían de vuelta, no se envía una devolución de llamada al cliente diciendo que colisionó, eso probablemente se vería horrible.
tsturzl
2

Es imposible implementar mundos de física síncrona de red. Pequeña diferencia en el paso N, por supuesto, una diferencia mucho más grande en el paso N + 1. No puede aplicar fuerzas o impulsos para mantener la sincronización y parecer realista.

Soluciones: -

  1. Puede considerar sincronizar solo unos pocos objetos, como personajes o autos de carreras, especialmente si son cinemáticos. Pero la mayor parte del mundo no estaría sincronizada para parecer realista.

  2. Puede tener mundos físicos en el servidor y transmitir posiciones y velocidades de objetos a los clientes.

Max
fuente
Puedes intentar jugar algún juego de red con física para ver que los mundos no están sincronizados. Por ejemplo, Need For Speed ​​World es gratuito y tiene múltiples jugadores y física básica. (cajas en el camino y objetos destructibles)
Max
No estoy seguro de seguirte exactamente. Estoy bastante seguro de que esto es posible ya que muchos juegos permiten a los jugadores tirar cajas (por ejemplo). Parece que su opción 2 es similar a mi opción 2, pero no puedo hacer que Bullet ajuste los objetos a sus posiciones de servidor. Tal vez ese es mi problema raíz?
Lucas
1
No. Por lo general, es una ilusión de sincronía. Si compara pantallas, verá que cuando rebota en cajas, las cajas vuelan en diferentes direcciones. o las cajas no son física en absoluto (solo animaciones ed). El número de cajas es diferente. Cuando digo animación quiero decir que no hay animación física detrás de los movimientos. No hacen varios trucos para que la imagen se vea un poco sincronizada, pero no se trata de mundos de física sincrónicos. Debes mirar y comparar cómo se mueven en diferentes juegos.
Max