He leído Valve + Gafferon y cientos de páginas de Google, pero por alguna razón no puedo entender las predicciones de los clientes.
A mi entender, el problema básico es:
- El cliente A envía información a
T0
- El servidor recibe entrada en
T1
- Todos los clientes reciben el cambio en
T2
En T2
sin embargo, utilizando predicción cliente, el cliente A se encuentra ahora en una posición apropiada para T4
.
¿Cómo se asegura de que el Cliente A, al predecir que el servidor aceptará la solicitud de movimiento, no se adelantará al servidor? Obviamente todo el tiempo están adelante, esto resulta en regresar a donde el servidor los vio por última vez. Con todas las correcciones que he probado, esto todavía se nota cuando se detiene, porque el servidor se detiene detrás de usted
fuente
Realmente no he implementado esto (por lo que puede haber algunos problemas que no estoy viendo de inmediato), pero pensé que intentaría ayudar.
Esto es lo que dijiste que está sucediendo:
Probablemente sería útil pensar en términos de tiempo de servidor. Es (probablemente) muy similar a cómo funciona la interpolación .
Cada comando se envía con un tiempo de servidor. Este tiempo del servidor se calcula al comienzo de una coincidencia al consultar la marca del servidor, compensando el tiempo de ping. En el cliente, tiene su propio recuento de tics local, y cada comando que envía se convierte en ticks del servidor (es una operación de resta simple)
Además, el cliente siempre representa "en el pasado". Entonces, asume que el mundo que ve el cliente está, digamos, 100 ms atrás de lo que realmente es el tiempo del servidor.
Así que reformulemos su ejemplo con la hora del servidor (designada por S).
El cliente envía la entrada en T0 con el tiempo del servidor S0 (que supongo que es realmente "representación del cliente del tiempo del servidor menos el tiempo de interpolación"). El cliente no espera la respuesta del servidor y se mueve de inmediato.
El servidor recibe la entrada en T1. El servidor calcula la posición autorizada del cliente en el momento del servidor S0 proporcionado por el cliente. Envía eso al cliente.
El cliente recibe el puesto de autoridad en T2 (aún con la designación del tiempo del servidor S0). El cliente realiza un seguimiento de una cantidad de tiempo anterior de eventos anteriores (probablemente solo una cola de todas las predicciones no confirmadas).
Si la posición / velocidad predicha / lo que sea que el servidor envíe de vuelta en S0 es diferente de lo que el cliente ha almacenado en S0, el cliente maneja esto de alguna manera. Ya sea volviendo a colocar al jugador en su posición anterior o volviendo a simular la entrada anterior, o tal vez algo más en lo que no he pensado.
fuente
En realidad, hay una implementación de código abierto en github que muestra cómo se hace esto. Mira Lance.gg
repositorio de github: https://github.com/lance-gg/lance
El código de predicción del cliente se implementa en el módulo llamado
src/syncStrategies/ExtrapolateStrategy.js
Además de la extrapolación, hay dos conceptos que no vi mencionados anteriormente:
fuente
El cliente A siempre está por delante del servidor, pero no importa. Solo tiene que volver a ajustar el cliente si el servidor dice que hubo un problema con la posición informada, momento en el cual el cliente vuelve a ejecutar todos los cambios realizados desde el error con los valores corregidos, para llevarlo a un estado compatible con el servidor
Para hacer esto, el cliente necesita recordar algunas de sus actualizaciones pasadas y de estado. Esto puede ser solo unos pocos valores simples como posición, velocidad, orientación, ese tipo de cosas. El servidor enviará periódicamente un reconocimiento de que varias actualizaciones de clientes eran legítimas, lo que significa que ahora pueden olvidarse del cliente. Sin embargo, si el servidor informa que una actualización no es válida, el estado del cliente vuelve a ese punto y los cambios futuros se aplican a ese estado modificado.
Hay algunos enlaces adicionales en la parte inferior del artículo de Valve que vale la pena leer; este es uno de ellos: https://developer.valvesoftware.com/wiki/Prediction
fuente
t=4
) recibe informaciónt=2
, por lo que restablece el estado parat=2
luego volver a ejecutar las actualizaciones para llevar los objetost=2
at=4
?