Paso de tiempo en el juego multijugador

8

Estoy tratando de entender el concepto de crear una experiencia multijugador servidor / cliente.

Mi problema está relacionado principalmente con el paso del tiempo. Considere el siguiente escenario:

Un cliente se conecta a un servidor. El cliente envía sus entradas al servidor para indicar que quiere moverse. El servidor simula la entrada y determina la posición de ese cliente en el mundo del juego.

Dado que el cliente y el servidor se ejecutan en diferentes pasos de tiempo, ¿cómo simula con precisión para que todos los clientes estén sincronizados con el servidor? Mi servidor está configurado actualmente a 30 ms de tiempo. Cuando proceso los movimientos de clientes, hay potencialmente cientos de solicitudes en espera de ser procesadas, pero no hay forma de indicar cuánto tiempo transcurrió entre cada una de las solicitudes.

Realmente no entiendo cómo simular correctamente en el servidor en función del tiempo, para que todo se sincronice.

jgallant
fuente

Respuestas:

3

En pocas palabras, debe enviar una marca de tiempo con cada instantánea del servidor y con cada entrada del cliente.

En ambos extremos, necesita un proceso para "completar" los marcos en los que no se reciben paquetes.

En mi juego (un juego de acción acelerado, el tuyo puede ser diferente), en el servidor, descarto cualquier entrada "anterior" (fuera de orden) y simplemente supongo que si no llegan nuevos paquetes de entrada, los mismos botones simplemente manténgalo presionado (hay un poco más de cosas para asegurarse de que se manejan las pulsaciones / liberaciones breves de los botones, pero esa es la premisa básica).

En el cliente mantengo un "búfer de retraso" (descrito en este artículo que Tetrad enlazó). Utilizo un promedio continuo de tiempos de llegada para asegurar que el búfer de retraso permanezca en la longitud correcta, haciendo que el juego del cliente funcione un poco más lento o más rápido para ponerse al día. Si las instantáneas no llegan a tiempo, entonces hago una extrapolación en el cliente. De lo contrario, interpolaré entre instantáneas en el búfer.

El cliente también es responsable de rastrear el tiempo de ida y vuelta para las entradas y usarlo para la predicción (el servidor envía la marca de tiempo de la entrada que utilizó al calcular un marco dado). Almacena las entradas durante ese período de tiempo, repitiéndolas para tomar la posición del jugador desde la posición "antigua" (en la instantánea del servidor) a la posición "presente" predicha.

Básicamente, el servidor sigue funcionando a una velocidad de cuadro fija. Depende de los clientes permanecer sincronizados con el servidor.

Por supuesto, esto es solo una descripción general de alto nivel. Hay muchos detalles esenciales que tienes que descubrir cuando lo implementas.

Andrew Russell
fuente
Si el servidor recibe 10 comandos de entrada de un cliente entre un paso de tiempo del servidor. El servidor ejecuta los 10 comandos de entrada. ¿Cómo sabemos cuánto tiempo simular cada comando de entrada? ¿Qué sucede si solo recibe un comando de entrada, simula el comando durante todo el intervalo de tiempo del paso de tiempo?
jgallant
1
@Jon La mayoría de los juegos de "acción" envían información como botón arriba / abajo en cada cuadro. Luego, el servidor solo usa el último estado recibido como el estado para esa marca de actualización. Los paquetes descartados, retrasados ​​y fuera de servicio se ignoran. (Al menos en el nivel básico, podría, por ejemplo, agregar información de secuencia adicional para que no se ignore un estado muy breve hacia arriba o hacia abajo, incluso si se cae). Esto es probablemente lo que debe hacer para todas las entradas que tienen temporización asociada . Las acciones basadas en comandos (por ejemplo, "muévete aquí" en un RTS) generalmente no tienen una duración asociada, por lo que simplemente las ejecutarías en orden.
Andrew Russell el