¿Con qué frecuencia para guardar el estado del jugador en juegos en línea persistentes?

9

En los juegos en línea, las personas prefieren iniciar y cerrar sesión cuando lo deseen. Por lo general, sus logros en el juego se guardan sin problemas en el servidor. Eso no es tan difícil de lograr, pero me pregunto cómo se puede hacer de una manera eficiente que tenga sentido y escalará.

¿Tiene sentido guardar las coordenadas y el estado del jugador cada vez que lo envían? Mi servidor node.js puede hacerlo fácilmente sin bloquear una respuesta, y quiero emplear una base de datos Mongo, pero ¿tal vez sea más apropiado hacerlo una vez por segundo y en un evento de todo el servidor, recolectando todo de una vez?

Lanbo
fuente
Guardo el estado del juego cada 10 segundos. Creo que es suficiente, pasa desapercibido (y estoy ejecutando mi servidor MMORPG en mi netbook que tiene 512Mb de RAM).
jcora

Respuestas:

10

Tengo en mente un MMORPG tradicional como World of Warcraft.

Guardar después de cada comando de cada jugador y cosa autónoma (por ejemplo, NPC)

  • Copia de seguridad constante. El servidor podría fallar en cualquier momento, y el estado del juego se guarda hasta ese momento (o lo más reciente posible, de todos modos).
  • Impacto en el rendimiento del servidor; incluso si no está bloqueando (es decir, en otro hilo), incluso si la base de datos está en otro servidor, está procesando lo que de otro modo no haría. Si no se bloquea como usted dice, entonces otro hilo tiene que manejarlo, y ese es un hilo que podría estar ocupado con otra cosa.
  • Aumento de E / S de disco, lo que aumenta el riesgo / tasa de falla. Esto es especialmente preocupante si está utilizando SSD para almacenamiento, dada su menor vida útil.
  • Si descarga la base de datos a otro servidor, aumentará el ancho de banda; Esto podría ser una preocupación si está pagando por el ancho de banda, y si no está en una tarjeta de red separada, entonces está consumiendo recursos que podrían utilizarse mejor para manejar el tráfico de jugadores.
  • ¿Qué sucede si el servidor se retrasa cada vez más al guardar el estado de estos comandos? Es decir, si entran más comandos de los que se pueden guardar, ¿entonces se apilan en una cola? ¿Esta cola se desborda y causa un error? ¿Detiene todo para que la cola pueda ponerse al día?
  • Me parece que este enfoque, aunque parezca simple, debería planificarse cuidadosamente. Por ejemplo, los comandos consecutivos que dependen unos de otros deberán guardarse juntos; de lo contrario, podría ocurrir una falla en el medio de los comandos, y solo se guardará uno pero no el otro. Considere si dos jugadores ejecutan un intercambio y dos comandos se guardan en el disco: "agregar 1 del artículo al destinatario" y "restar 1 del artículo del remitente". Si ocurre una falla después del primer comando pero antes de que se guarde el segundo comando, tiene una duplicación de elementos. (si el pedido se invierte, entonces tiene un artículo perdido)

Guarda todo periódicamente

  • En caso de falla, el servidor estará un poco desactualizado. Esperemos que use algo como un enfoque diario, por lo que la instantánea más reciente al menos será completa y consistente, y todos los jugadores activos se retrasan por la misma cantidad de tiempo.
  • Cualquier sistema de base de datos que use podría tener una optimización para la actualización por lotes, que es más eficiente (menos sobrecarga) que la actualización de uno en uno.
  • Si opta por un sistema de archivos binarios, este método es muy simple. Cree un nuevo archivo, descargue memoria en él, arroje un marcador al final que indique que la copia de seguridad se completó por completo. Una vez que se completa una copia de seguridad, elimine la copia de seguridad anterior (o no).
  • Es posible que el proceso de copia de seguridad también deba tener en cuenta las cosas mencionadas en el último punto de viñeta de la otra sección, como guardar en medio de comandos consecutivos que no se deben dividir. Puede optar por bloquear todo el conjunto de datos, volcarlo en el disco y desbloquearlo, pero dependiendo de cuánto tiempo tome, podría resultar en una pausa o desaceleración bastante fuerte en el juego.

Guarde un personaje al cerrar sesión (no guarde nada más)

  • Lo más importante para un jugador es su personaje, que incluye los elementos que tiene, las habilidades que ha ganado, su lista de amigos, etc. Si matan a un monstruo y el botín está en el suelo frente a ellos y luego el servidor falla, van a estar un poco desconsolados por no tener la oportunidad de recoger su botín, pero lo superarán. Así que solo guarde las cosas importantes y no se preocupe por las cosas pequeñas. No guarde las posiciones de los NPC, por ejemplo; si el servidor se cae, cuando vuelva a encenderse, aparecerán en el área general en la que deberían estar. La excepción, por supuesto, es para cualquier NPC "inteligente" que por alguna razón deba permanecer en el lugar en el que se encuentran. fueron cuando el servidor se cayó.
  • Además, un jugador no debe iniciar sesión durante demasiadas horas a la vez (tenga en cuenta que aquí estoy considerando "volver a un lobby" como cerrar sesión). Eventualmente necesitarán tomar un descanso en el baño o conseguir comida o ser interrumpidos por sus padres / amigos / lo que sea o dormir. Por lo tanto, en realidad no deberían iniciar sesión sin parar más de, digamos, 8 horas, incluso para el jugador más hardcore. Si un "jugador" está conectado durante un período de tiempo realmente largo, existe una buena posibilidad de que se trate de varias personas o de un bot, y ninguno es deseable o normal.
  • Además, su proceso de cierre de sesión ya debería estar buscando cosas como los comandos consecutivos mencionados anteriormente. Básicamente, ya debería estar empaquetando el personaje, por lo que obviamente es el mejor momento para volcarlo en el disco.

Pensamientos finales

  • Claramente estoy a favor del último enfoque, pero traté de ser imparcial sobre los tres.
  • Es difícil decir cuál de los dos primeros métodos es más derrochador. Con el primer método, si el personaje envía varios comandos de movimiento, cada uno se guardará en el disco y se sobrescribirá, cuando claramente podrían agruparse en uno. Pero con el segundo método, si tiene la mitad de su población de pie, sus posiciones se guardan en el disco, incluso si son exactamente las mismas desde la última operación de copia de seguridad. En el tercer caso, es muy posible que alguien pueda iniciar sesión e inmediatamente cerrar sesión, pero la mayoría de las veces, muchas cosas sobre el jugador habrán cambiado, por lo que el derroche parece ser mínimo.
  • Tenga en cuenta que esto es completamente para respaldo en caso de falla, y una falla debe minimizarse absolutamente. Es bueno manejar este caso de excepción, pero al final, si el servidor falla, se perderán algunos datos y algunos jugadores se molestarán. Así que simplemente implemente cualquier método que pueda, lo que considere más simple o mejor, y continúe.
  • No confíe en esto como el guardado predeterminado; coloque un buen botón de apagado en la aplicación del servidor, que cierra con gracia las conexiones y escribe todo en la base de datos. Úselo sobre una base normal.

Por último, no tome este consejo como la verdad absoluta. No he escrito un sistema de copia de seguridad multijugador. Yo estoy trabajando en un "juego" en línea, por lo que he pensado en esto y escribió un vistazo a mis pensamientos más arriba, pero no he llegado a la etapa de implementación de esto todavía. Así que esto está escrito sin experiencia real, pero después de mucha lectura y recopilación de conocimientos sobre el tema.

Ricket
fuente
44
Por lo que he observado personalmente, los MMO comerciales usan una combinación de los tres. Las salvaciones ocurren después de eventos y acciones importantes, como asesinatos de jefes / saqueos / intercambios, periódicamente para evitar que se pierdan acciones no críticas (y no castigar a los que están conectados durante largos períodos de tiempo), y siempre al cerrar sesión. Un solo método generalmente no es suficiente. Casi todos estos métodos se basan en una base de datos de estilo SQL subyacente que se respalda y restaura de forma transparente si hay un mal funcionamiento del hardware.
NtscCobalt
@NtscCobalt - Estuve contigo hasta la "base de datos de estilo SQL". ¿Es SQL realmente un requisito? ¿Qué hay de NoSQL?
beatgammit
@tjameson Bueno, mi comentario fue escrito antes de tocar NoSQL. Solo estaba tratando de decir que no debería rodar su propio formato, pero de todos modos aún recomendaría SQL, ya que debe conocer el esquema de antemano (o ser perezoso y usar Entity-Key-Value) y la consistencia es más importante que el capacidad de particionar esos datos. Consulte stackoverflow.com/questions/7339374/… para obtener más información.
NtscCobalt
1

Supongo que depende del tipo de juego y la cantidad de tráfico entre los jugadores y el servidor.

En un MMORPG, no tendría sentido guardar la posición de los jugadores cada vez que envían la información al servidor. Tendría más sentido actualizar cuando los datos actuales del jugador estén "obsoletos", por así decirlo. También podría ser beneficioso salvar el estado del jugador en eventos importantes como cruzar a un nuevo territorio, derrotar a un jefe o salir de una tienda.

En un juego por turnos, definitivamente tendría sentido salvar el estado del jugador cada vez que termine su turno, así como después del turno de un jugador contrario (guardar pérdida de salud, efectos de hechizo, etc.).

Nuevamente, la respuesta depende completamente de la escala y las capacidades de su servidor. Se trata de encontrar el mejor equilibrio y optimizar tanto como sea posible sin sacrificar la calidad.

JMellow
fuente
1

Si su única preocupación es cuando cierran la sesión, entonces una respuesta simple es guardar su posición cuando se produzcan las condiciones para ellos que ya no existan en el mundo del juego (debido a cerrar sesión o desconectarse).

En una nota al margen, sin embargo, desconfiaría un poco del cliente que informa al servidor su posición, o al menos sin alguna forma de verificación de la cordura del lado del servidor. Sin embargo, si ya tiene esto en su lugar, es probable que pueda guardar esa posición al cerrar sesión o desconectarse, ya que no tiene que preocuparse por obtener datos directamente del cliente.

Lunin
fuente
Sí, de ahí la necesidad de enviar actualizaciones periódicas al servidor en valores como posición y XP. Cuanto más tiempo lo dejes, más discutible será si el jugador realmente acumuló los deltas informados o no. Si restringe esos períodos de "check-in", es mucho más fácil de monitorear / controlar.
Ingeniero
El problema de saber cuándo exactamente un jugador cerró la sesión en un juego de navegador de larga duración no es realmente trivial.
Lanbo
Estoy de acuerdo en que no es trivial, pero de todos modos es un problema que debes abordar de una forma u otra en la mayoría de los juegos, incluso solo para decidir cuándo su avatar ya no aparece. Una vez hecho esto, debería ser un asunto relativamente simple engancharse a ese escenario y guardar su última posición válida.
Lunin