Intenta mantener esto lo más simple posible e interfaces bien definidas y documentadas. Mantener y depurar un sistema complejo en producción se convierte fácilmente en un infierno. Entonces, si hay un enfoque simple y complejo, piénselo dos veces antes de optar por el complejo.
Definiendo servicios
Creo que el primer paso es identificar los servicios y sus dependencias : Contenido estático, Autenticación, Chat local, Canales de chat globales, Canales de chat regionales, Lista de amigos, Gremios, Bolsa / Inventario, Casa de subastas, Mapa global, Mundo, ...
A continuación, para cada uno de estos servicios decidido si el cliente puede hablar con ellos directamente. Por ejemplo, es bastante fácil dejar que el cliente hable directamente con los servidores responsables de los canales de chat global. Los servidores mundiales no tienen que estar involucrados en los mensajes de chat. El chat regional se puede implementar de la misma manera, pero los servidores del mundo tienen que avisar a los servidores de chat cuando los jugadores cambian de región. Una vez más, no tienen que preocuparse por los mensajes.
El tercer paso es pensar en el equilibrio de carga dentro de un servicio . Por ejemplo, los canales de chat globales y regionales se pueden dividir en varios servidores según su nombre. Probablemente sea una buena idea no codificar esta división en el cliente, sino proporcionar un servicio de búsqueda.
Servidores mundiales
La parte más difícil suele ser los servidores del mundo , por lo que estoy comenzando con un enfoque simple. Probablemente sea una buena idea dejar que el cliente hable directamente con el servidor responsable de la región en la que se encuentra. Por lo tanto, al iniciar sesión o cruzar la región, el cliente debe saber a qué servidor conectarse.
El enfoque simple es dividir el mundo en regiones independientes . Con regiones independientes quiero decir que un jugador no puede mirar de una parte a otra y los monstruos no pueden cruzar partes. Esas regiones son diferentes de las regiones que el jugador ve en función del paisaje y la historia del mundo exterior. Por lo general, la mayoría de los monstruos están en mazmorras y los jugadores tienden a aceptar que tienen que atravesar una puerta de entrada para ingresar a una mazmorra. Especialmente si esas mazmorras se instancian por grupo de jugadores. Otros ejemplos en el mundo exterior son diferentes continentes y valles encerrados por altas montañas.
Un enfoque mundial continuo se vuelve complejo realmente rápido, por lo que tiene sentido planificarlo bien: ¿qué información necesita el cliente? ¿Qué información tienen que compartir los servidores? El jugador interactuará principalmente solo con los objetos (incluidos monstruos y NPC) en la misma región. Puede hacer trampa colocando objetos fuera del rango de clic desde el borde de la zona. Esto significa que el cliente está principalmente interesado en la información de solo lectura para las zonas vecinas. Para estos casos, los servidores de zona no tienen que coordinar nada excepto la verificación de permiso de que el jugador está lo suficientemente cerca como para conectarse a una zona vecina.
Esto deja solo un número muy pequeño de casos difíciles en los que los objetos o acciones tienen que cruzar un borde del servidor. Lo cual es bueno porque esos casos como flechas y hechizos son críticos para el rendimiento. Puede ser una buena idea dividir el combate en atacar y defender. Entonces el servidor de un lanzador de hechizos definirá los parámetros de ataque, incluida la posición del lanzador. El servidor del defensor recibirá el mensaje sobre el ataque y calculará el impacto. El servidor del atacante no necesita saber sobre el impacto; el cliente lo aprenderá usando su conexión de solo lectura.
Dependiendo de cuán complejo sea su modelo de reproductor, puede tomar un par de segundos transferirlo a otro servidor (Second Life tiene un gran problema con esto). El problema se puede mitigar preparando la transferencia por adelantado cuando el jugador se acerca a un borde virtual. De modo que la mayoría de los datos del reproductor ya están almacenados en caché en el servidor de destino cuando ocurre la transferencia real.
Resumen
Divida el problema definiendo diferentes servicios que se pueden dividir en servidores con pocas dependencias. Como siguiente paso, mire cómo hacer el equilibrio de carga dentro de los servicios críticos. Delegue el trabajo de equilibrio al cliente indicándole que se conecte directamente a los servidores relevantes (obviamente, los servidores deben verificar los permisos). Manténgalo lo más simple posible, documente bien las responsabilidades de los diversos servicios y servidores, brinde la opción de habilitar la salida de depuración.
PD: algunas de estas técnicas se pueden utilizar para mejorar la fiabilidad. Y debe tener eso en cuenta porque usar muchos servidores implica un riesgo mucho mayor de que las cosas se rompan; no solo en el software sino también a nivel de hardware.