El mayor portal de MU Online de Brasil — desde 2003
Tutorial Avanzado Servidor

Cómo configurar subservidores (channels) en MU Online

Aprende a dividir tu servidor de MU Online en múltiples channels (subservidores) que comparten la misma base de datos, distribuyendo la carga de jugadores entre instancias y sabiendo el momento justo de dividir.

GA Gabriel · Actualizado el 30 dic 2024 · ⏱ 17 min de lectura
Respuesta rápida

A medida que un servidor de MU Online crece, llega el momento en que un único GameServer ya no da abasto con el volumen de jugadores simultáneos: empiezan a aparecer lag en áreas llenas, retraso en eventos y picos de CPU que degradan la experiencia de todos al mismo tiempo. La respuesta clásica para

A medida que un servidor de MU Online crece, llega el momento en que un único GameServer ya no da abasto con el volumen de jugadores simultáneos: empiezan a aparecer lag en áreas llenas, retraso en eventos y picos de CPU que degradan la experiencia de todos al mismo tiempo. La respuesta clásica para esto es dividir el servidor en subservidores, también llamados channels — múltiples instancias de GameServer que comparten la misma base de datos y los mismos personajes, pero distribuyen a los jugadores en procesos separados. El jugador sigue siendo el mismo en cualquier channel; solo elige, en la pantalla de selección, a qué instancia quiere entrar. Este modelo aumenta la capacidad total, reduce la concentración en una única instancia y además permite un mantenimiento más granular. Este tutorial cubre la arquitectura multi-channel, la configuración de puertos, la ServerList del ConnectServer, estrategias de balanceo de jugadores y —lo más importante— el momento justo de dividir, para que no agregues complejidad antes de tiempo.

Qué son los channels (subservidores)

Un channel es una instancia de GameServer que forma parte del mismo servidor lógico. Todos los channels de un servidor:

  • Comparten la misma base de datos — cuentas, personajes, ítems, guild, ranking son únicos.
  • Aparecen en la misma pantalla de selección (Channel 1, Channel 2...), servidos por el mismo ConnectServer.
  • Tienen el mismo contenido — mapas, drops, rates suelen ser idénticos (aunque es posible diferenciar rates por channel, ese no es el uso más común).

La diferencia esencial respecto a correr dos servidores separados es la base de datos compartida. Con channels, el personaje "Guerrero01" existe una sola vez y puede entrar por cualquier channel. Esto es fundamental: los channels sirven para escalar capacidad, no para crear mundos diferentes.

Arquitectura multi-channel

El diseño típico con base única y varios GameServers:

                    BASE SQL (única)
                         │
              ┌──────────┼──────────┐
              │          │          │
         DataServer  DataServer  DataServer
              │          │          │
         JoinServer  JoinServer  JoinServer
              │          │          │
         GameServer  GameServer  GameServer
         Channel 1   Channel 2   Channel 3
        (porta 55901)(porta 55902)(porta 55903)
              │          │          │
              └──────────┼──────────┘
                         │
                   ConnectServer
                    (porta 44405)
                         │
                      JUGADOR
                (ve la lista de channels)

Cada channel es una pila completa (DataServer + JoinServer + GameServer) apuntando a la misma base. El ConnectServer centraliza las conexiones y muestra los channels disponibles.

Requisitos previos

  • Un servidor de MU Online ya funcional con un único channel estable. Si aún estás armando el servidor base, mira la guía de cómo crear un servidor de MU Online.
  • Máquina (VPS/dedicado) con holgura de recursos: cada channel adicional consume CPU y RAM.
  • SQL Server con la base única (estándar MuOnline) y DSN ODBC 32-bit configurada.
  • Acceso administrativo para abrir puertos en el firewall.
  • Editor de texto que preserve la codificación (Notepad++/VS Code), pues ServerList.txt y .ini son sensibles.
  • Entendimiento claro de que todos los channels usan la misma base: jamás apuntes un channel a otra base por error.
  • Backup completo antes de cualquier cambio.

> No confundas los channels con servidores independientes. Si apuntas cada channel a una base diferente, dejas de tener channels y pasas a tener dos servidores desconectados. La base compartida es lo que define el modelo.

Paso 1 — Estructura de carpetas por channel

Cada channel necesita su propia carpeta y sus propios archivos de configuración:

MuServer/
├── Channel1/
│   ├── DataServer/
│   ├── JoinServer/
│   └── GameServer/
├── Channel2/
│   ├── DataServer/
│   ├── JoinServer/
│   └── GameServer/
└── ConnectServer/
    ├── ConnectServer.exe
    └── ServerList.txt

El ConnectServer es único y sirve a todos los channels: no se duplica.

Paso 2 — Puertos por channel

Como todos los channels viven en la misma máquina, cada proceso de red necesita un puerto único. Solo la base es compartida. Un esquema de ejemplo (las claves y puertos varían según el emulador):

ProcesoChannel 1Channel 2Channel 3¿Expuesto?
GameServer559015590255903
DataServer555575556755577No
JoinServer555555556555575No
ServerCode012
ConnectServer44405 (compartido)

El ServerCode (también llamado código de servidor) debe ser único por channel y coincidir con lo que esté en la ServerList.

Paso 3 — Configurar los GameServers

Cada channel recibe un GameServer.ini con su ServerCode y sus puertos, pero con la misma DSN:

; Channel1/GameServer/GameServer.ini
[General]
ServerCode=0
ServerName=Channel 1
[Network]
GameServerPort=55901
[JoinServer]
JoinServerIP=127.0.0.1
JoinServerPort=55555
[Database]
DSN=MuOnline        ; misma base en TODOS los channels
; Channel2/GameServer/GameServer.ini
[General]
ServerCode=1
ServerName=Channel 2
[Network]
GameServerPort=55902      ; puerto diferente
[JoinServer]
JoinServerIP=127.0.0.1
JoinServerPort=55565      ; puerto diferente
[Database]
DSN=MuOnline              ; MISMA base

Haz lo mismo para los DataServer.ini y JoinServer.ini de cada channel, siempre con puertos distintos y la misma DSN.

Paso 4 — Configurar la ServerList del ConnectServer

El ConnectServer lee la lista de channels y la presenta al cliente. El formato clásico del ServerList.txt (varía según el emulador; algunas distros usan Setting.xml):

; ServerList.txt
; Formato: Index  IP  Port  Nombre  MaxUsers  Fill
; Fill = indicador visual de ocupación (0=vacío ... 30=lleno)

0  TU_IP  55901  "Channel 1"  1000  0
1  TU_IP  55902  "Channel 2"  1000  0
2  TU_IP  55903  "Channel 3"  1000  0

Versión en XML, común en distribuciones más recientes:

<?xml version="1.0" encoding="utf-8"?>
<ServerList>
    <Server>
        <ServerCode>0</ServerCode>
        <ServerName>Channel 1</ServerName>
        <IP>TU_IP</IP>
        <Port>55901</Port>
        <MaxUsers>1000</MaxUsers>
        <Visible>1</Visible>
    </Server>
    <Server>
        <ServerCode>1</ServerCode>
        <ServerName>Channel 2</ServerName>
        <IP>TU_IP</IP>
        <Port>55902</Port>
        <MaxUsers>1000</MaxUsers>
        <Visible>1</Visible>
    </Server>
</ServerList>

El ServerCode de cada entrada debe coincidir con el ServerCode del GameServer.ini correspondiente, o el jugador es enviado al channel equivocado.

Paso 5 — Firewall

Abre solo el ConnectServer y los GameServers; mantén DataServer y JoinServer internos:

netsh advfirewall firewall add rule name="MU Connect" dir=in action=allow protocol=TCP localport=44405
netsh advfirewall firewall add rule name="MU Ch1" dir=in action=allow protocol=TCP localport=55901
netsh advfirewall firewall add rule name="MU Ch2" dir=in action=allow protocol=TCP localport=55902
# DataServer/JoinServer (55557,55555,55567,55565): NO exponer a internet

Paso 6 — Orden de inicio

Levanta los procesos de cada channel en el orden canónico y deja el ConnectServer para el final:

@echo off
start "" "MuServer\Channel1\DataServer\DataServer.exe"
timeout /t 3
start "" "MuServer\Channel1\JoinServer\JoinServer.exe"
timeout /t 3
start "" "MuServer\Channel1\GameServer\GameServer.exe"
timeout /t 5
start "" "MuServer\Channel2\DataServer\DataServer.exe"
timeout /t 3
start "" "MuServer\Channel2\JoinServer\JoinServer.exe"
timeout /t 3
start "" "MuServer\Channel2\GameServer\GameServer.exe"
timeout /t 5
start "" "MuServer\ConnectServer\ConnectServer.exe"
echo Todos los channels en linea.

Balanceo de jugadores

Distribuir a los jugadores de forma equilibrada entre los channels es lo que garantiza el beneficio de rendimiento. Estrategias comunes:

  • Indicador de ocupación (Fill/CurrentUsers): haz que el ConnectServer refleje la ocupación real. Así los propios jugadores tienden a elegir el channel menos lleno.
  • Ordenar la lista por el menos ocupado: algunas distros permiten que el channel con menos gente aparezca primero.
  • MaxUsers por channel: define un tope por channel para que, al llenarse, deje de aceptar conexiones y empuje a los nuevos jugadores a otro.
  • Monitoreo activo: sigue la distribución por la base de datos.
-- Online por channel (si el GameServer registra la sesión con ServerCode)
SELECT ServerCode, COUNT(*) AS Online
FROM GameServerSessions   -- el nombre de la tabla varía por distribución
WHERE IsOnline = 1
GROUP BY ServerCode
ORDER BY Online DESC;

-- Total general online
SELECT COUNT(*) AS TotalOnline
FROM Character
WHERE ConnectStat = 1;

Recuerda que, al compartir la base, los ítems en NPCs personales, guild, ranking y comercio quedan consistentes entre los channels: el jugador cambia de channel sin perder nada.

Cuándo dividir en channels (y cuándo no)

Divide cuando: tu único channel se acerca al límite práctico de jugadores simultáneos del emulador; observas lag y CPU alta concentrados en horarios pico; o áreas específicas (ciudades, spots de eventos) quedan intransitables de tan llenas. No dividas demasiado pronto: un servidor recién lanzado, con pocas decenas de online, solo gana complejidad de mantenimiento sin beneficio real con múltiples channels. Como regla práctica, mantén un único channel mientras esté cómodo y agrega el segundo cuando la ocupación pico supere de forma consistente cerca del 70% de la capacidad estable del primero.

Errores comunes y soluciones

SíntomaCausa probableSolución
El jugador entra al channel equivocadoEl ServerCode de la ServerList no coincide con el del GameServerAlinea los ServerCodes entre la ServerList y cada GameServer.ini
El channel no aparece en la selecciónEntrada ausente o Visible=0 en la ServerListAgrega/activa la entrada y reinicia el ConnectServer
El personaje "desaparece" al cambiar de channelChannels apuntando a bases diferentesApunta todos a la MISMA DSN/base
El segundo GameServer no levantaPuerto duplicado con el primer channelAjusta los puertos del Channel 2 (Game/Data/Join)
Un channel siempre lleno, otro vacíoSin indicador de ocupación/ordenaciónActiva Fill/CurrentUsers y ordena por el menos lleno
El lag continúa tras dividirCuello de botella en la base, no en el GameServerOptimiza índices/consultas; verifica el disco (SSD)

Lista de verificación de lanzamiento

  • Backup completo del servidor y de la base realizado
  • Necesidad de channels confirmada por datos de ocupación/CPU
  • Carpeta separada para cada channel
  • Puertos únicos por proceso en cada channel (Game/Data/Join)
  • ServerCode único por channel
  • Todos los channels apuntando a la MISMA DSN/base
  • ServerList (o Setting.xml) con una entrada por channel y ServerCodes coincidiendo
  • Firewall abriendo solo ConnectServer y GameServers
  • DataServer/JoinServer cerrados a internet
  • Indicador de ocupación/MaxUsers configurado para el balanceo
  • .bat de inicio en el orden correcto
  • Prueba: el cliente ve todos los channels en la selección
  • Prueba: entrar en cada channel y confirmar el mismo personaje
  • Prueba: cambiar de channel sin perder ítems/guild/ranking
  • Monitoreo de online por channel funcionando

Con los channels bien configurados —puertos únicos, ServerCodes alineados y base única compartida— tu servidor de MU Online escala para muchos más jugadores simultáneos sin sacrificar la estabilidad. Adopta la división guiado por datos de ocupación, valida el cambio de channel con pruebas reales de personaje, y mantén el balanceo siempre bajo control para que la capacidad extra se traduzca en una jugabilidad fluida para todos.

Preguntas frecuentes

¿Cuál es la diferencia entre channels y servidores independientes?

Los channels (subservidores) comparten la MISMA base de datos y los MISMOS personajes: el jugador es el mismo en cualquier channel, solo distribuido en instancias diferentes para aliviar la carga. Los servidores independientes tienen bases, cuentas y personajes separados. El channel es sobre capacidad; el servidor separado es sobre proyectos distintos.

¿Cuántos channels debo crear?

Empieza con el mínimo necesario. Un único GameServer suele aguantar de algunos cientos a más de mil jugadores según el emulador y el hardware. Solo agrega un segundo channel cuando el primero se acerque al límite práctico de players simultáneos o de CPU.

¿Los channels necesitan puertos diferentes?

Sí. Cada GameServer/channel en la misma máquina necesita un puerto único (ej.: 55901, 55902, 55903). El DataServer y el JoinServer de cada channel también necesitan puertos propios. Solo la base de datos es compartida.

¿Cómo elige el jugador el channel?

Por el ConnectServer. Lee la ServerList y presenta al cliente la lista de channels disponibles (Channel 1, Channel 2...), muchas veces con un indicador de ocupación. El jugador elige y es redirigido al GameServer de ese channel.

¿Puedo tener channels en máquinas diferentes?

Sí. En servidores grandes, cada channel puede correr en una VPS distinta, todos apuntando a la misma base central. La ServerList del ConnectServer usa las IPs reales de cada máquina. Esto exige baja latencia entre los servidores y la base.

GA
Editor de guías y builds

Gabriel cubre gameplay, builds de clases, PvP y progresión. Prueba cada estrategia en un servidor antes de publicar.

Sigue leyendo

Artículos relacionados