Como configurar sub-servidores (channels) no MU Online
Aprenda a dividir seu servidor de MU Online em múltiplos channels (sub-servidores) que compartilham o mesmo banco, distribuindo a carga de jogadores entre instâncias e sabendo o momento certo de dividir.
À medida que um servidor de MU Online cresce, chega o momento em que um único GameServer não dá mais conta do volume de jogadores simultâneos: começam a aparecer lag em áreas lotadas, atraso em eventos e picos de CPU que degradam a experiência de todos ao mesmo tempo. A resposta clássica para isso é
À medida que um servidor de MU Online cresce, chega o momento em que um único GameServer não dá mais conta do volume de jogadores simultâneos: começam a aparecer lag em áreas lotadas, atraso em eventos e picos de CPU que degradam a experiência de todos ao mesmo tempo. A resposta clássica para isso é dividir o servidor em sub-servidores, também chamados de channels — múltiplas instâncias de GameServer que compartilham o mesmo banco de dados e os mesmos personagens, mas distribuem os jogadores em processos separados. O jogador continua sendo o mesmo em qualquer channel; ele só escolhe, na tela de seleção, para qual instância quer entrar. Esse modelo aumenta a capacidade total, reduz a concentração em uma única instância e ainda permite manutenção mais granular. Este tutorial cobre a arquitetura multi-channel, a configuração de portas, a ServerList do ConnectServer, estratégias de balanceamento de jogadores e — o mais importante — o momento certo de dividir, para você não adicionar complexidade antes da hora.
O que são channels (sub-servidores)
Channel é uma instância de GameServer que faz parte do mesmo servidor lógico. Todos os channels de um servidor:
- Compartilham o mesmo banco de dados — contas, personagens, itens, guild, ranking são únicos.
- Aparecem na mesma tela de seleção (Channel 1, Channel 2...), servidos pelo mesmo ConnectServer.
- Têm o mesmo conteúdo — mapas, drops, rates costumam ser idênticos (embora seja possível diferenciar rates por channel, isso não é o uso mais comum).
A diferença essencial em relação a rodar dois servidores separados é o banco compartilhado. Com channels, o personagem "Guerreiro01" existe uma vez só e pode entrar por qualquer channel. Isso é fundamental: channels servem para escalar capacidade, não para criar mundos diferentes.
Arquitetura multi-channel
O desenho típico com banco único e vários GameServers:
BANCO SQL (único)
│
┌──────────┼──────────┐
│ │ │
DataServer DataServer DataServer
│ │ │
JoinServer JoinServer JoinServer
│ │ │
GameServer GameServer GameServer
Channel 1 Channel 2 Channel 3
(porta 55901)(porta 55902)(porta 55903)
│ │ │
└──────────┼──────────┘
│
ConnectServer
(porta 44405)
│
JOGADOR
(vê a lista de channels)
Cada channel é uma pilha completa (DataServer + JoinServer + GameServer) apontando para o mesmo banco. O ConnectServer centraliza as conexões e mostra os channels disponíveis.
Pré-requisitos
- Um servidor de MU Online já funcional com um único channel estável. Se ainda está montando o servidor base, veja o guia de como criar servidor de MU Online.
- Máquina (VPS/dedicado) com folga de recursos — cada channel adicional consome CPU e RAM.
- SQL Server com o banco único (padrão MuOnline) e DSN ODBC 32-bit configurada.
- Acesso administrativo para abrir portas no firewall.
- Editor de texto que preserve encoding (Notepad++/VS Code), pois
ServerList.txte.inisão sensíveis. - Entendimento claro de que todos os channels usam o mesmo banco — jamais aponte um channel para outro banco por engano.
- Backup completo antes de qualquer alteração.
> Não confunda channels com servidores independentes. Se você apontar cada channel para um banco diferente, deixa de ter channels e passa a ter dois servidores desconectados. O banco compartilhado é o que define o modelo.
Passo 1 — Estrutura de pastas por channel
Cada channel precisa da própria pasta e dos próprios arquivos de configuração:
MuServer/
├── Channel1/
│ ├── DataServer/
│ ├── JoinServer/
│ └── GameServer/
├── Channel2/
│ ├── DataServer/
│ ├── JoinServer/
│ └── GameServer/
└── ConnectServer/
├── ConnectServer.exe
└── ServerList.txt
O ConnectServer é único e serve todos os channels — ele não é duplicado.
Passo 2 — Portas por channel
Como todos os channels vivem na mesma máquina, cada processo de rede precisa de porta única. Só o banco é compartilhado. Um esquema de exemplo (as chaves e portas variam por emulador):
| Processo | Channel 1 | Channel 2 | Channel 3 | Exposto? |
|---|---|---|---|---|
| GameServer | 55901 | 55902 | 55903 | Sim |
| DataServer | 55557 | 55567 | 55577 | Não |
| JoinServer | 55555 | 55565 | 55575 | Não |
| ServerCode | 0 | 1 | 2 | — |
| ConnectServer | 44405 (compartilhado) | Sim |
O ServerCode (também chamado de código de servidor) precisa ser único por channel e bater com o que estiver na ServerList.
Passo 3 — Configurar os GameServers
Cada channel recebe um GameServer.ini com seu ServerCode e suas portas, mas com a mesma 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 ; mesmo banco em TODOS os channels
; Channel2/GameServer/GameServer.ini
[General]
ServerCode=1
ServerName=Channel 2
[Network]
GameServerPort=55902 ; porta diferente
[JoinServer]
JoinServerIP=127.0.0.1
JoinServerPort=55565 ; porta diferente
[Database]
DSN=MuOnline ; MESMO banco
Faça o mesmo para os DataServer.ini e JoinServer.ini de cada channel, sempre com portas distintas e a mesma DSN.
Passo 4 — Configurar a ServerList do ConnectServer
O ConnectServer lê a lista de channels e a apresenta ao cliente. O formato clássico do ServerList.txt (varia por emulador; algumas distros usam Setting.xml):
; ServerList.txt
; Formato: Index IP Port Nome MaxUsers Fill
; Fill = indicador visual de lotação (0=vazio ... 30=lotado)
0 SEU_IP 55901 "Channel 1" 1000 0
1 SEU_IP 55902 "Channel 2" 1000 0
2 SEU_IP 55903 "Channel 3" 1000 0
Versão em XML, comum em distribuições mais recentes:
<?xml version="1.0" encoding="utf-8"?>
<ServerList>
<Server>
<ServerCode>0</ServerCode>
<ServerName>Channel 1</ServerName>
<IP>SEU_IP</IP>
<Port>55901</Port>
<MaxUsers>1000</MaxUsers>
<Visible>1</Visible>
</Server>
<Server>
<ServerCode>1</ServerCode>
<ServerName>Channel 2</ServerName>
<IP>SEU_IP</IP>
<Port>55902</Port>
<MaxUsers>1000</MaxUsers>
<Visible>1</Visible>
</Server>
</ServerList>
O ServerCode de cada entrada precisa bater com o ServerCode do GameServer.ini correspondente, ou o jogador é enviado para o channel errado.
Passo 5 — Firewall
Abra apenas o ConnectServer e os GameServers; mantenha DataServer e 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): NAO expor à internet
Passo 6 — Ordem de inicialização
Suba os processos de cada channel na ordem canônica e deixe o ConnectServer por último:
@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 os channels no ar.
Balanceamento de jogadores
Distribuir os jogadores de forma equilibrada entre os channels é o que garante o benefício de desempenho. Estratégias comuns:
- Indicador de lotação (Fill/CurrentUsers): faça o ConnectServer refletir a ocupação real. Assim os próprios jogadores tendem a escolher o channel menos cheio.
- Ordenar a lista pelo menos lotado: algumas distros permitem que o channel com menos gente apareça primeiro.
- MaxUsers por channel: defina um teto por channel para que, ao lotar, ele deixe de aceitar conexões e empurre novos jogadores para outro.
- Monitoramento ativo: acompanhe a distribuição pelo banco.
-- Online por channel (se o GameServer registra sessão com ServerCode)
SELECT ServerCode, COUNT(*) AS Online
FROM GameServerSessions -- nome da tabela varia por distribuição
WHERE IsOnline = 1
GROUP BY ServerCode
ORDER BY Online DESC;
-- Total geral online
SELECT COUNT(*) AS TotalOnline
FROM Character
WHERE ConnectStat = 1;
Lembre que, por compartilharem o banco, itens em NPCs pessoais, guild, ranking e comércio ficam consistentes entre os channels — o jogador troca de channel sem perder nada.
Quando dividir em channels (e quando não)
Divida quando: seu único channel se aproxima do limite prático de jogadores simultâneos do emulador; você observa lag e CPU alta concentrados em horários de pico; ou áreas específicas (cidades, spots de eventos) ficam intransitáveis de tão cheias. Não divida cedo demais: um servidor recém-lançado, com poucas dezenas de online, só ganha complexidade de manutenção sem benefício real com múltiplos channels. Como regra prática, mantenha um único channel enquanto ele estiver confortável e adicione o segundo quando a ocupação de pico passar de forma consistente de cerca de 70% da capacidade estável do primeiro.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Jogador entra no channel errado | ServerCode da ServerList não bate com o do GameServer | Alinhe os ServerCodes entre ServerList e cada GameServer.ini |
| Channel não aparece na seleção | Entrada ausente ou Visible=0 na ServerList | Adicione/ative a entrada e reinicie o ConnectServer |
| Personagem "some" ao trocar de channel | Channels apontando para bancos diferentes | Aponte todos para a MESMA DSN/banco |
| Segundo GameServer não sobe | Porta duplicada com o primeiro channel | Ajuste as portas do Channel 2 (Game/Data/Join) |
| Um channel sempre lotado, outro vazio | Sem indicador de lotação/ordenação | Ative Fill/CurrentUsers e ordene pelo menos cheio |
| Lag continua após dividir | Gargalo no banco, não no GameServer | Otimize índices/consultas; verifique disco (SSD) |
Checklist de lançamento
- Backup completo do servidor e do banco realizado
- Necessidade de channels confirmada por dados de ocupação/CPU
- Pasta separada para cada channel
- Portas únicas por processo em cada channel (Game/Data/Join)
- ServerCode único por channel
- Todos os channels apontando para a MESMA DSN/banco
- ServerList (ou Setting.xml) com uma entrada por channel e ServerCodes batendo
- Firewall abrindo só ConnectServer e GameServers
- DataServer/JoinServer fechados para a internet
- Indicador de lotação/MaxUsers configurado para balanceamento
.batde inicialização na ordem correta- Teste: cliente vê todos os channels na seleção
- Teste: entrar em cada channel e confirmar o mesmo personagem
- Teste: trocar de channel sem perder itens/guild/ranking
- Monitoramento de online por channel funcionando
Com channels bem configurados — portas únicas, ServerCodes alinhados e banco único compartilhado — seu servidor de MU Online escala para muito mais jogadores simultâneos sem sacrificar a estabilidade. Adote a divisão guiado por dados de ocupação, valide a troca de channel com testes reais de personagem, e mantenha o balanceamento sempre de olho para que a capacidade extra se traduza em jogabilidade fluida para todos.
Perguntas frequentes
Qual a diferença entre channels e servidores independentes?
Channels (sub-servidores) compartilham o MESMO banco de dados e os MESMOS personagens — o jogador é o mesmo em qualquer channel, apenas distribuído em instâncias diferentes para aliviar a carga. Servidores independentes têm bancos, contas e personagens separados. Channel é sobre capacidade; servidor separado é sobre projetos distintos.
Quantos channels devo criar?
Comece com o mínimo necessário. Um único GameServer costuma aguentar de algumas centenas a mais de mil jogadores dependendo do emulador e do hardware. Só adicione um segundo channel quando o primeiro se aproximar do limite prático de players simultâneos ou de CPU.
Os channels precisam de portas diferentes?
Sim. Cada GameServer/channel na mesma máquina precisa de uma porta única (ex.: 55901, 55902, 55903). O DataServer e o JoinServer de cada channel também precisam de portas próprias. Só o banco é compartilhado.
Como o jogador escolhe o channel?
Pelo ConnectServer. Ele lê a ServerList e apresenta ao cliente a lista de channels disponíveis (Channel 1, Channel 2...), muitas vezes com um indicador de lotação. O jogador escolhe e é redirecionado para o GameServer daquele channel.
Posso ter channels em máquinas diferentes?
Sim. Em servidores grandes, cada channel pode rodar em uma VPS distinta, todos apontando para o mesmo banco central. A ServerList do ConnectServer usa os IPs reais de cada máquina. Isso exige baixa latência entre os servidores e o banco.