Juego de lógica en el servidor! ¿Bueno o malo?

25

Actualmente estoy planeando un simple juego multijugador en línea. Y aquí está la pregunta. ¿Tiene sentido hacer toda la lógica del juego en el servidor y simplemente enviar la entrada del cliente al servidor? ¿Cuáles son los pros y los contras o hay alguna razón por la que no debería hacer eso?

Dominic Bartl
fuente

Respuestas:

37

No desea enviar la entrada del jugador al servidor. Lo que probablemente quiera hacer es enviar una representación abstracta de lo que el jugador quiere hacer al servidor, y luego ejecutar la lógica allí.

Del mismo modo, no necesariamente desea devolver todo lo que el cliente debe hacer. Por ejemplo, puede enviar algún tipo de mensaje diciendo "NPC X murió", y el cliente determina qué animación / sonidos reproducir. Cosas como esas.

El truco consiste en encontrar la línea donde el ancho de banda y la potencia de procesamiento (en el servidor) se superan al evitar que las personas hagan trampa. Por lo general, toma cualquier tipo de decisión autoritaria que cambie el juego solo en el servidor y deja todas las cosas visuales auxiliares al cliente.

Hay muchas preguntas más específicas sobre este tema en todo el sitio. Por ejemplo:

¿La detección de colisión se debe realizar en el lado del servidor o de forma cooperativa entre el cliente / servidor?

¿Quién hace los cálculos de IA en un MMO?

¿Debería el anfitrión del juego ser la autoridad u otro cliente tonto?

Tétrada
fuente
44
+1 Golpéame en eso. Además, dependiendo del estilo del juego, es posible que desee / necesite hacer alguna predicción del lado del cliente.
John McDonald
14

Bueno, tienes respuestas, pero tu verdadera respuesta es "pruébate a ti mismo". Las cosas difieren de un juego a otro.

Hice un par de juegos multijugador para un curso de diseño de juegos en red distribuido. El más desafiante fue hacer un juego de acción en tiempo real en el que participaban muchos jugadores y enviaba entradas como el infierno. Cuando se trata de ese punto, todo se convierte en un problema. Como ve el primer enlace que envió Tetrat, incluso determinar una colusión se convierte en un problema. Y leerá o escuchará términos como retraso, interpolación, extrapolación, predicción ... Pero si nunca intentó codificar desde cero, simplemente aceptará estas palabras y no sabrá lo que realmente significan.

Mi recomendación es:

Paso 1
Simplemente comience con un diseño basado en servidor totalmente autorizado por ahora. Como dijiste, solo envía las entradas del usuario al servidor y deja que el servidor haga todo y los clientes obtengan los resultados. Tu juego funcionará completamente consistente. Pero cuando mira a sus clientes, notará algunos retrasos, algunos problemas de teletransportación, no un movimiento suave ... ect.

Paso 2
Comience a solucionar los problemas en el lado del cliente. Los problemas de teletransportación, por ejemplo. Tu personaje estaba en (0,0) y el servidor dijo que ahora estás en (100,100). Tu personaje solo se teletransportará a (100,100), lo que no es bueno. Llega la interpolación. Debería tener un código en el lado del cliente que deslizará el carácter de (0,0) a (100, 100) de manera uniforme. Sí, moverás a tu personaje de (0,0) a (100,100) pero ¿qué tan rápido? Por ahora solo puede usar la diferencia horaria entre cada actualización del servidor. Si su servidor envía 10 paquetes en un segundo, lo que significa un retraso de 100 ms entre cada paquete.

Paso 3
Ahora su juego ya es bueno para redes rápidas donde hay un retraso de (1-50) ms. Pero se condena si hay una pérdida de paquetes, una alta latencia o un cálculo tarda mucho en el servidor ... ect. En esas situaciones, notará que al presionar la flecha izquierda, verá que su personaje se mueve hacia la izquierda con un retraso de 200 ms. El retraso entre su paquete va al servidor, el tiempo de cálculo y vuelve a usted con su última posición. Esto es malo, la peor desventaja del diseño autorizado del servidor. El jugador quiere que su personaje se mueva hacia la izquierda tan pronto como presiona hacia la izquierda, no puede hacerlo esperar. Afortunadamente, el cliente también tiene el mismo código que el servidor, entonces, ¿por qué no ejecutarlo en el cliente de inmediato y corregir el resultado final con la respuesta del servidor? Eso es básicamente la predicción de entrada. El cliente presiona a la izquierda, el código en su lado lo moverá a la izquierda, Después de un tiempo, digamos 200 ms, la posición real proviene del servidor y el cliente corrige su posición con él. Si todo salió bien, el cliente no notará nada, el "paso 2" también nos ayudará con esto.

Bueno, net tiene muchos tutoriales y cosas sobre este tema. Pero hay 2 que realmente me gustan:

Muy bueno, cubre los puntos oscuros: Valve-Source Engine Networking multijugador
Tipo de historia, divertido de leer y valioso: 1500 Archers en 28.8 ,

tesla
fuente
3

Pros:

  • este enfoque es más (la mayoría) a prueba de piratería
  • puedes aplicar actualizaciones más fácilmente
  • comunidad centralizada

Contras:

  • enormes requisitos de ancho de banda
  • algunos usuarios pueden odiar ese enfoque (privacidad y demás)
  • problemas con el juego local (fiestas LAN), un jugador
neciu
fuente
Los problemas con el juego de LAN pueden evitarse proporcionando un servidor binario dedicado o permitiendo que uno de los clientes actúe como servidor. Una solución que soluciona los problemas de un solo jugador y LAN sería alojar de forma transparente un servidor en la computadora del cliente (si es solo un juego de un solo jugador, no debería haber ninguna diferencia significativa en la potencia informática entre este enfoque y un binario tradicional). Esto puede no funcionar para todos los tipos de juegos
3Doubloons
2

La lógica del lado del servidor también crea problemas de escalabilidad: debe hacer todo el trabajo para todos los clientes en su servidor, versículos que permiten que cada cliente haga su propia parte del trabajo total.

ddyer
fuente
Es divertido cuando hice preguntas similares aquí en 2016, todos me dijeron "nunca confíes en el cliente".
Newguy
Depende del juego, pero los clientes que se engañan a sí mismos no son una preocupación seria, y los clientes que engañan a otros clientes honestos; Lo que sea que haya hecho el servidor para no confiar en el cliente, los clientes honestos pueden hacerlo.
ddyer
2

Depende de qué juego quieras crear y qué parte del juego. Si desarrolla un RTS (o cualquier juego con un modelo bloqueado), entonces definitivamente solo debe enviar la entrada y en qué paso de simulación se recibió la entrada.

Si desea hacer un tirador, puede usar tanto las funciones de entrada como las abstractas. Si tomas el Unreal Tournament 3 como el caso, crearon el modo multijugador principalmente a través de llamadas de función replicadas.
Para el movimiento, toman la entrada del jugador (comprimida en un solo bit para cada acción) rotación delta, aceleración y marca de tiempo y la envían al servidor.
Para otros fines, como el arma, se sincronizan cuando disparas (AFAIK, todavía no he examinado esta parte en profundidad).
Para valores más estáticos / menos modificados, como el estado, envían la variable al cliente o al servidor, según lo que especifique el programador.

Y para juegos que no sean RTS, recuerde la predicción del cliente.

Peter Ølsted
fuente