Todos los artículos

Crear un MMORPG con Unreal Engine 5.8 — Devlog n.º 1: el servidor autoritativo y la arquitectura del mundo

La arquitectura de Ancient Online: cliente en Unreal Engine 5.8, servidor autoritativo en C++, bucle de mundo a 25 Hz y mundo unificado editado en vivo.

Un puesto de trabajo con monitores y portátiles colocados uno junto a otro en un estudio con poca luz

Lo que distingue a un MMORPG de un juego para un solo jugador es el servidor que hay detrás de todo lo que ves. En esta primera parte del diario de desarrollo (devlog) de Ancient Online: Remastered, explicamos cómo estamos creando un MMORPG con Unreal Engine 5.8: cómo se reparte el trabajo entre el cliente y el servidor, cómo se simula el mundo y cómo conseguimos editar en vivo un mundo único y unificado.

Dos piezas: cliente y servidor

Ancient Online se compone de dos programas independientes:

  • El cliente está escrito en C++ sobre Unreal Engine 5.8. El renderizado, el audio, la interfaz y la entrada son cosa suya.
  • El servidor es independiente de Unreal: lo hemos escrito desde cero en C++23. Todas las reglas del juego se ejecutan aquí.

¿Por qué escribimos el servidor aparte en lugar de hacerlo dentro del motor? Porque lo que necesita un servidor de MMORPG es distinto de lo que necesita un motor de juego: no hay gráficos, pero sí miles de entidades, datos persistentes, largos periodos en funcionamiento y la necesidad de un rendimiento predecible. Un servidor aparte nos permite hacer solo el trabajo imprescindible y controlar cada byte.

El servidor autoritativo: no fiarse del cliente

Nuestra regla básica es esta: el cliente afirma, el servidor decide.

  • Movimiento: la entrada del jugador va al servidor, y el servidor calcula la posición. El cliente muestra la posición que le comunica el servidor mediante una interpolación suave. Así, un cliente que «se teletransporta» o atraviesa una pared no llega a ninguna parte en lo que al servidor respecta.
  • Combate: resultados como el daño, los impactos y los empujones se calculan en el servidor. Por ejemplo, el servidor decide si un golpe de combo derriba al rival y difunde el resultado a todo el mundo al mismo tiempo.
  • Economía: los objetos, la moneda y las transacciones de la tienda solo cambian en el servidor y en la base de datos.

El coste de este enfoque es tener que gestionar bien la latencia de red; la recompensa es un mundo en el que hacer trampas es mucho más difícil y en el que se aplican las mismas reglas a todos.

Un bucle de mundo a 25 Hz

El servidor actualiza el mundo 25 veces por segundo. En cada paso avanzan la IA de los monstruos, el movimiento, el combate, los efectos de las habilidades y el clima. Un paso fijo mantiene la simulación predecible y garantiza que la misma entrada produzca siempre el mismo resultado.

No todos los jugadores necesitan saberlo todo. El servidor divide el mundo en una cuadrícula y envía a cada jugador únicamente las actualizaciones de las entidades que están dentro de su área de interés (las cercanas). Así el tráfico de red se mantiene razonable incluso en una ciudad abarrotada.

Un protocolo binario ligero

Entre el cliente y el servidor no hay JSON ni REST; cada mensaje es un paquete binario con una estructura fija. Eso ahorra tanto ancho de banda como tiempo de CPU. Cuando añadimos un sistema nuevo (como el clima, el movimiento o el servicio de cuentas dentro del juego), escribimos para él un contrato de paquetes aparte y versionado, y usamos archivos de cabecera compartidos para garantizar que el cliente y el servidor trabajan con el mismo contrato.

Persistencia: guardar sin hacer esperar al juego

Los datos de los jugadores viven en una base de datos PostgreSQL. Pero no es aceptable que el bucle de mundo espere a la base de datos en cada paso. Por eso el guardado se hace en segundo plano, con persistencia diferida (write-behind): el servidor de mundo deja los cambios en una cola (Redis), y un proceso de escritura en segundo plano los confirma en la base de datos por lotes. El ritmo del juego no depende de la velocidad de la base de datos.

Los canales y el servidor de acceso

Los jugadores se conectan primero a un servidor de acceso, que se encarga de la verificación de la cuenta, la selección de personaje y la sesión. Después pasan a uno de los cuatro canales de juego (CH1–CH4). El estado en directo de los canales se muestra en la página de Estado del servidor del sitio del juego.

Un mundo unificado, editado en vivo

El mundo de Ancient Online está diseñado como un mundo único y unificado y no como mapas separados por pantallas de carga; está dividido en celdas y se carga mediante streaming.

El contenido del mundo (terreno, objetos, ubicación de los monstruos) no se guarda en el código, sino en la base de datos, versionado. Podemos editar este mundo con un editor de mundo dentro del juego: los cambios se hacen primero en un borrador, se revisan y después se publican. Cada publicación crea una nueva versión, y el cliente verifica que los datos del mundo que tiene coinciden con los del servidor comparando un resumen (digest). Si no coinciden, espera a que los datos se actualicen antes de continuar hacia el juego.

Misiones: Lua como lenguaje de scripts

Las misiones y los diálogos de los PNJ se escriben en Lua 5.4 en el servidor. Eso nos permite desarrollar y probar misiones sin recompilar el servidor.

Los mensajes de los jugadores nunca salen de nuestros servidores

No usamos ningún servicio de traducción externo para la traducción del chat del juego. Ejecutamos en nuestros propios servidores un modelo de traducción local que funciona solo con CPU; los mensajes de los jugadores no se envían a ninguna API externa. De ese modo, jugadores que hablan idiomas distintos pueden entenderse sin que sus mensajes salgan nunca del estudio.

Qué viene después

La segunda parte del diario de desarrollo repasa las decisiones que tomamos para que el mismo mundo se pueda jugar con ratón, con pantalla táctil y con mando. Para conocer el estudio, lee ¿Quién es Astronaut Entertainment?; para el juego en sí, consulta la página de Juegos.

Compartir:
También disponible en29