Redes y movimiento en la UNIDAD de MMORPG


8

Estoy programando un servidor dedicado en C # usando BeamServer2 DLL's. Al principio quería ver a otros jugadores moverse en nuestro mapa Omuni ya hecho. Esto lo hice simplemente enviando su posición al servidor cada trama. Esto funcionó y pude jugar con algunos amigos, pero el movimiento no fue lento. Así que comencé a tratar de agregar suavizado de movimiento y también algo de seguridad para que no puedan enviar una posición falsa al servidor sin que el servidor impida que llegue a los otros clientes.

Lo que hice, hice un masterClient que tiene un control de movimiento en el RemotePlayer. Cuando un cliente quiere moverse, se mueve localmente y envía un mensaje al servidor con la dirección de moverse. El servidor que toma su velocidad y lo envía al masterClient. El MasterClient que mueve el RemotePlayer al igual que el RemotePlayer se mueve a sí mismo. Cuando deja de moverse, envía un mensaje con su posición. El cliente maestro que comprueba si la posición a la que ha llegado es tan cercana como la posición que tiene del cliente, si es realista de acuerdo con el ping del cliente, el servidor lo coloca en la posición del cliente.

Esto funciona, pero todavía tengo un problema de retraso y no estoy seguro de cómo solucionarlo. Debo hacer movimientos suaves en el cliente, pero descubrí que solo puedo saltar (x / 2, y / 2, z / 2) a la posición y colocarlo en la posición real el próximo cuadro, fallé en eso y yo Lo intentaremos nuevamente pronto. Incluso si se agrega eso, no estoy seguro de si el retraso está reparado.

¿Alguna otra técnica, sugerencia, pregunta, ...? Gracias Diede.

Respuestas:


8

Hay muchos problemas / tareas involucrados al programar juegos de red en tiempo real "sin retraso".

  • velocidad de hardware (se necesita potencia de CPU para el reproductor, tanto el cliente como el servidor)
  • distancia de red y equipo (conexión LAN o WAN?)
  • ancho de banda del servidor (cuántos jugadores)

En segundo lugar, tienes a los "chicos malos" que siempre intentan hacer trampa en los juegos. Si su juego se hace público, considere lo que sucedería si me sentara e inyectara paquetes de red "falsos". Considere si alguien publicó "posiciones inalcanzables" o "salud completa / munición".

Para empezar, mi sugerencia para su arquitectura sería algo como esto:

  • Servidor, controla todos los datos vitales, calcula y valida el movimiento.
  • Cliente, recibe datos sobre qué mostrar en la pantalla + algunos datos de "anticipación" sobre objetos en movimiento.

La mayoría de los FPS en tiempo real, como lo sé, hacen algún tipo de "sabemos que te estás moviendo en esta dirección a esta velocidad, así que simplemente simulamos eso hasta que obtengamos otros detalles del servidor"

Por lo tanto, su cliente debe publicar "lo que solicita" e incluso podría comenzar a moverse en esa dirección, pero el servidor podría "obligarlo a retroceder" si el servidor rechaza el movimiento. Aquí tienes que pensar, ¿qué pasa si el cliente publica "falsas coordenadas" fuera del mapa, o de repente "salta"? El servidor necesita rastrear si la nueva posición es posible desde su punto anterior O el servidor solo recibe el mensaje que dice: "CLIENT MOVE FORWARD 200" y luego el servidor procesa lo que hará de acuerdo con los datos del mapa y del juego.

Esto dará cierto retraso, pero nuevamente, si deja que el cliente reciba estos datos y hace algunos cálculos matemáticos, no necesita una actualización cada ms / fotograma, puede retrasarse un poco sin un retraso notable en la pantalla.

Quizás incluso pueda dividir el mapa en "mosaicos virtuales" (si es un juego de vectores) para tener una forma rápida de calcular dónde deberían estar los objetos a continuación.

World of Warcraft / Battlefield / Counterstrike

Creo que WOW también lo está haciendo de esta manera. Presiona una tecla, el servidor recibe su movimiento "deseo" y responde con "te estás moviendo ahora" y luego el cliente muestra esto + el servidor simula la nueva posición en el servidor en algún tipo de "sesión pr. Cliente". Esta es la "cantidad máxima de jugadores por juego" se está volviendo desagradable, porque su servidor tiene que hacer un seguimiento de todos y básicamente hacer esto como "basado en turnos", pero tan rápido que parece en tiempo real.

Entonces...

Foreach (Client in GameSessionList)
{
   ParseInput();
   ParseMovement(); // including collission test
   ResponseSend(); // new positions+movement data for client and objects/other players
}

3
Independientemente de los méritos de su respuesta, ¿hay alguna razón para ser grosero?
Konrad el

Tenía la impresión de que en la mayoría de los juegos de FPS, los clientes y el servidor colisionan de forma independiente, y el servidor corrige a los clientes si varían demasiado, en lugar de que los clientes simplemente simulen.
Magus

No sé cómo lo hace cada FPS. Pero sí, por ejemplo. la serie BF tiene algo que llaman Netcode, lo que significa que realizan los cálculos localmente y envían los resultados al servidor que luego verifica y distribuye los resultados (según lo que me han dicho). Esto podría tener que ver con la gran cantidad de "partículas" / detalles que deben transferirse de otra manera. Donde como WOW es un mundo más estático y no tienes colisión entre personajes (en modo normal), entonces está bien permitirte "deslizarte" a través de otra persona.
BerggreenDK

2

La parte desafiante en la compensación de retraso es que recibirá actualizaciones de clientes que están fuera de servicio. El comando de un cliente laggy enviado en el momento T puede muy bien llegar después de un comando del cliente no laggy enviado a T + 40ms. La aplicación de los comandos en el orden en que los obtienes dará lugar a todo tipo de maldad. Hacerlo correctamente, por otro lado, implica reducir el tiempo y volver a reproducir todos los comandos que se han emitido desde entonces.

No hay una manera fácil de evitar esto, pero hay varias soluciones válidas. Puede encontrar uno relativamente fácil descrito aquí .

Hay mucha investigación en este campo, ¡echa un vistazo!


1

Crearía el cliente como si fuera un juego sin red. Es decir, todo lo que hagas lo haces de forma inmediata en el cliente. Luego agregue, paralelo a eso, su código de red. Este código obtendrá los datos de movimiento. Simple como de coords, dirección y velocidad. Simplemente envía esto al servidor que valida. El servidor le envía un ok o una nueva posición.

Entonces, tiene todo su código de cliente ejecutándose como si estuviera solo en el mundo. Luego solo recibe nuevos datos de corrección del servidor o un ok. Si presiona hacia adelante y lo mantiene presionado durante diez segundos, el servidor solo recibirá esos datos. Puede pensar en enviar / recibir datos cada segundo a pesar de que solo está presionando el botón de avance, o si golpea un pico de retraso podría correr para siempre.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.