Estoy haciendo un juego de estilo servidor MMO. Hasta ahora tengo el marco configurado para que el servidor y los clientes interactúen entre ellos para proporcionar actualizaciones de estado. El servidor mantiene el estado del juego y periódicamente calcula el siguiente estado y luego de vez en cuando (cada milisegundos) envía el nuevo estado a todos los clientes. Este nuevo estado puede ser visto y reaccionado en el lado del cliente por el usuario. Estas acciones luego se envían nuevamente al servidor para ser procesadas y enviadas para la próxima actualización.Sincronización del estado del juego Cliente-Servidor
El problema obvio es que lleva tiempo que estas actualizaciones viajen entre el servidor y los clientes. Si un cliente actúa para atacar a un enemigo, para cuando la actualización haya regresado al servidor, es muy posible que el servidor haya progresado el estado del juego lo suficiente como para que el enemigo ya no esté en el mismo lugar y fuera de alcance.
Para combatir este problema, he intentado encontrar una buena solución. He visto lo siguiente, y ha ayudado a algunos, pero no completamente: Mutli Player Game synchronization. Ya llegué a la conclusión de que, en lugar de simplemente transmitir el estado actual del juego, puedo transmitir otra información, como la dirección (o la posición del objetivo para el movimiento AI) y la velocidad. A partir de esto, tengo parte de lo que se necesita para 'adivinar', en el lado del cliente, cuál es el estado real (como lo ve el servidor) al avanzar el estado del juego n milisegundos hacia el futuro.
El problema es determinar la cantidad de tiempo para progresar en el estado, ya que dependerá del tiempo de demora entre el servidor y el cliente, que podría variar considerablemente. Además, si avanzo el estado del juego a lo que sería actualmente cuando el cliente lo visualiza (es decir, solo cuenta el tiempo que tardó la actualización en llegar al cliente) o debería progresar lo suficiente para que cuando se envíe su respuesta de vuelta al servidor, será el estado correcto para entonces (cuenta para ambos viajes).
¿Alguna sugerencia?
Reiterar:
1) ¿Cuál es la mejor manera de calcular la cantidad de tiempo entre la emisión y recepción?
2) ¿Debo avanzar el estado del lado del cliente lo suficiente como para contar para el viaje de ida y vuelta completo, o simplemente el tiempo que lleva obtener los datos del servidor al cliente?
EDIT: Lo que he encontrado hasta el momento
Puesto que ya tienen muchos paquetes que van y vienen entre los clientes y el servidor, no quiero añadir a ese tráfico si tengo que hacerlo. Actualmente, los clientes envían paquetes de actualización de estado (UDP) al servidor ~ 150 milisegundos (solo si algo ha cambiado), y luego estos son recibidos y procesados por el servidor. Actualmente, el servidor no envía ninguna respuesta a estos paquetes.
Para comenzar, haré que los clientes intenten estimar su tiempo de retraso. Lo predeterminaré a algo así como 50 a 100 milisegundos. Propongo que cada 2 segundos (por cliente) el servidor responda inmediatamente a uno de estos paquetes, devolviendo el índice del paquete en un paquete de actualización de tiempo especial. Si el cliente recibe el paquete de tiempo, usará el índice para calcular cuánto tiempo hace que se envió este paquete, y luego usar el tiempo entre paquetes como el nuevo tiempo de retraso.
Esto debería mantener a los clientes razonablemente actualizados en su retraso, sin exceso de tráfico de red.
¿Sonido aceptable, o hay una manera mejor? Esto todavía no responde a la pregunta dos.
"Pero este es un escenario bastante improbable, ¿no?" ¿Qué ocurre si un dispositivo está utilizando una conexión celular y el otro está utilizando wifi? Solo un pensamiento. De cualquier manera, usted está diciendo que le muestre al usuario el estado en el que estará el juego cuando llegue la respuesta al servidor, ¿correcto? –
* "conexión celular y wifi" *: normalmente, ambos intentarían usar la conexión más rápida. Podrían tratar de hacer trampa de esta manera, pero me parece un poco complicado. Sería una especie de trampa, pero en MMO hay formas mucho más fáciles de hacer trampa. – maaartinus
Y sí, estaba diciendo esto. Ahora estoy agregando, que podría reducir la diferencia de tiempo en una pequeña constante para todos los jugadores. Menos extrapolación podría significar menos problemas; solo una idea. – maaartinus