Estoy implementando un servidor de juegos que admite el combate cuerpo a cuerpo similar a Star Control . Entonces tienes barcos volando y disparando, con física súper simple de velocidad / aceleración / amortiguación para impulsar el movimiento.
Leí Valve, Gafferon y Gambetta e implementé el algoritmo de Gambetta para la predicción del cliente:
La predicción del cliente funciona en el barco del jugador actualizando su posición desde el servidor tal como viene y luego volviendo a aplicar la entrada aún no procesada por el servidor al barco del jugador.
Desafortunadamente, no funciona bien para mi juego. Creo que tiene que ver con el hecho de que el ejemplo de Gambetta no tiene en cuenta los objetos que ya se están moviendo o los comandos que se actualizan paso a paso. (por "paso" quiero decir marco). Entonces, en mi juego, el jugador presiona hacia arriba para acelerar la nave (ya en movimiento), que continúa moviéndose en el cliente, envía el comando al servidor y generalmente recibe la instantánea mundial del servidor en el siguiente paso. Tengo algo más como:
El comando del reproductor se ejecuta en el paso 3 del cliente , pero en el servidor solo se ejecuta en el paso 5 del servidor . Para cuando el cliente recibe la instantánea mundial en el paso 6 del cliente , la predicción está muy lejos, especialmente en velocidades más rápidas.
El quid del problema es que el cliente ejecuta el comando en el paso 5 , pero el servidor lo ejecuta en el paso 6 . Pensé en enviar el paso del cliente con el comando y hacer que el servidor retroceda y vuelva a ejecutar el comando con el paso de tiempo del cliente. Sin embargo, eso podría conducir a una serie de otros problemas, como lo que sucede con los comandos recibidos desde la reversión, o cómo los clientes engañadores pueden explotar cambiando el paso enviado.
Leer y mirar videos como este de Google menciona un enfoque diferente, donde cambia gradualmente la posición del jugador para que coincida con la de la instantánea en unos pocos pasos.
Mis preguntas:
¿Puedes hacer que el algoritmo de Gambetta funcione con movimientos constantes? ¿O es conceptualmente incompatible con mi juego?
¿Es la interpolación gradual sobre los pasos el camino correcto a seguir entonces? Si es así, ¿cómo interpola un objeto ya en movimiento desde la posición del cliente para que coincida con el que acaba de recibir del servidor?
¿Pueden estos métodos, la interpolación gradual y el algoritmo de Gambetta funcionar en conjunto, o son mutuamente excluyentes?
Respuestas:
Durante los 6 meses transcurridos desde que hice esta pregunta, terminé desarrollando un servidor de juegos de código abierto completo para tratar este problema exacto (¡y muchos otros!): Http://lance.gg
La I + D involucrada ahora me permite responder mis propias preguntas:
¿Puedes hacer que el algoritmo de Gambetta funcione con movimientos constantes? ¿O es conceptualmente incompatible con mi juego?
El algoritmo de Gambetta no funcionará cuando el movimiento de la entidad no sea determinista (desde el punto de vista del cliente). Si una entidad puede verse afectada sin aportes de la física u otros jugadores, por ejemplo, se debe adoptar un enfoque más similar.
¿Es la interpolación gradual sobre los pasos el camino correcto a seguir entonces? Si es así, ¿cómo interpola un objeto ya en movimiento desde la posición del cliente para que coincida con el que acaba de recibir del servidor?
Esto toca un tema diferente, que es la conciliación del cliente de las actualizaciones del servidor. La interpolación gradual funciona, pero para juegos de ritmo muy rápido como el de la pregunta, es mejor implementar la extrapolación
¿Pueden estos métodos, la interpolación gradual y el algoritmo de Gambetta funcionar en conjunto, o son mutuamente excluyentes?
Pueden trabajar juntos, pero solo si el movimiento de la entidad es determinista desde el punto de vista del cliente. Por lo tanto, no funcionará si la entidad se ve afectada por la física o la psuedo-física, como la inserción, el arrastre, etc.
fuente
Su juego parece ser demasiado "en tiempo real" para pensar en términos de pasos de tiempo. Solo pensaría en términos de "turnos" si el juego puede considerarse "basado en turnos". De lo contrario, simplemente abandone la idea de giros o pasos. Todo se vuelve más fácil entonces :)
Tenga en cuenta que predice localmente para su jugador e interpola solo para otras entidades (como se explica en el tercer artículo de la serie). La forma de lidiar con las actualizaciones del servidor para los objetos que ya se estaban moviendo es la reconciliación del lado del servidor, explicada en la mitad inferior del segundo artículo (al que se vinculó).
Espero que esto ayude :)
fuente