Como integrar sua guilda de MU Online com Discord e bots
Monte um Discord de guilda para MU Online com bot próprio: sincronização de membros e cargos, alertas de eventos e boss, ranking de reset e notificação de ataque de castle siege em tempo real.
O Discord se tornou o centro de comunicação de praticamente toda guilda de MU Online ativa, mas a maioria trata ele como um chat genérico, desconectado do que realmente acontece dentro do jogo. Um Discord bem integrado sabe quem está na guilda em tempo real, avisa sobre boss e eventos automaticament
O Discord se tornou o centro de comunicação de praticamente toda guilda de MU Online ativa, mas a maioria trata ele como um chat genérico, desconectado do que realmente acontece dentro do jogo. Um Discord bem integrado sabe quem está na guilda em tempo real, avisa sobre boss e eventos automaticamente, mostra ranking de reset dos membros e notifica ataques de Castle Siege sem que ninguém precise digitar nada manualmente. Este tutorial mostra como estruturar esse Discord, escolher entre bots prontos e bot próprio, sincronizar membros e cargos com o banco do MuServer, e configurar os alertas mais valiosos para uma guilda competitiva.
Por que integrar (e não só usar um Discord genérico)
Um servidor Discord sem integração depende de alguém lembrar de avisar sobre o boss, atualizar manualmente quem entrou ou saiu da guilda, e checar o ranking no site à parte. Isso funciona em guildas pequenas, mas não escala. Uma integração básica com o banco do jogo resolve os três maiores atritos: presença desatualizada, falta de alerta automático e ranking manual.
Estrutura recomendada de canais
| Canal | Propósito | Automatizável? |
|---|---|---|
| #anuncios | Comunicados oficiais da guilda/servidor | Parcial (webhook de eventos do servidor) |
| #boss-alertas | Aviso automático de spawn de boss | Sim |
| #castle-siege | Notificação de ataque e status da guerra | Sim |
| #ranking | Ranking de reset/level atualizado periodicamente | Sim |
| #recrutamento | Aplicações de novos membros | Manual, com formulário |
| #geral | Conversa livre | Não aplicável |
Passo 1 — Escolher entre bot pronto e bot próprio
Bots genéricos (MEE6, Carl-bot, Dyno) cobrem bem moderação, cargos por reação e boas-vindas, mas não têm acesso aos dados do seu MuServer. Para presença de guilda, ranking e alertas de boss, você precisa de um bot próprio (discord.js ou discord.py) conectado a uma API que consulta o banco do jogo com permissão de leitura.
Passo 2 — Criar a aplicação do bot no Discord
- Acesse o Portal de Desenvolvedores do Discord e crie uma nova aplicação.
- Na aba Bot, gere o token e guarde-o como variável de ambiente, nunca no código.
- Convide o bot ao servidor com as permissões mínimas necessárias: gerenciar cargos, enviar mensagens, ler histórico.
# .env do bot
DISCORD_TOKEN=seu-token-aqui
API_MU_BASE_URL=https://seuservidor.com/api
Passo 3 — Expor uma API própria sobre o banco do MuServer
Nunca conecte o bot diretamente ao banco de produção do jogo. Crie endpoints dedicados, somente leitura:
<?php
// api/guild_membros.php
header('Content-Type: application/json');
$guildName = $_GET['guild'] ?? '';
$membros = consultarMembrosGuild($guildName); // SELECT Name, cLevel, Resets FROM Character WHERE G_Name = ?
echo json_encode($membros);
Passo 4 — Sincronizar membros e cargos automaticamente
Rode uma rotina periódica no bot que compara a lista de membros da guild no jogo com quem tem o cargo correspondente no Discord, aplicando e removendo cargos conforme necessário:
async function sincronizarCargosGuild() {
const membrosJogo = await fetch(`${API_BASE}/guild_membros.php?guild=Legends`).then(r => r.json());
const guild = client.guilds.cache.get(GUILD_DISCORD_ID);
const cargoGuild = guild.roles.cache.find(r => r.name === 'Legends');
for (const membro of guild.members.cache.values()) {
const estaNaGuildJogo = membrosJogo.some(m => m.discordId === membro.id);
if (estaNaGuildJogo && !membro.roles.cache.has(cargoGuild.id)) {
await membro.roles.add(cargoGuild);
} else if (!estaNaGuildJogo && membro.roles.cache.has(cargoGuild.id)) {
await membro.roles.remove(cargoGuild);
}
}
}
setInterval(sincronizarCargosGuild, 10 * 60 * 1000); // a cada 10 minutos
A vinculação entre conta Discord e personagem in-game precisa existir previamente — normalmente via um comando de vínculo (/vincular <nomedopersonagem>) que grava a relação em uma tabela própria.
Passo 5 — Alertas automáticos de boss
Para bosses com horário fixo, um agendamento simples resolve:
const bossSchedule = [
{ nome: 'Kundun', horario: '20:00' },
{ nome: 'Selupan', horario: '21:30' },
];
cron.schedule('*/1 * * * *', () => {
const agora = formatarHoraAtual();
const bossAgora = bossSchedule.find(b => proximoDe(b.horario, agora, 5)); // 5 min antes
if (bossAgora) {
canalBossAlertas.send(`⚔️ **${bossAgora.nome}** nasce em 5 minutos! Preparem-se.`);
}
});
Para bosses com spawn dentro de uma janela aleatória, consulte a tabela de monstros ativos do GameServer (se seu emulador expõe essa informação) ou trate como aviso de janela ("Kundun pode nascer entre 20h e 20h30").
Passo 6 — Notificação de Castle Siege
Castle Siege é o evento mais competitivo do jogo, e vale um canal dedicado com notificações de início de inscrição, início da guerra e resultado final:
async function notificarCastleSiege(status) {
const embed = new EmbedBuilder()
.setTitle('🏰 Castle Siege')
.setDescription(status.mensagem)
.addFields({ name: 'Guild atual dona do castelo', value: status.guildDona })
.setColor(status.emGuerra ? 0xff0000 : 0x00ff00);
canalCastleSiege.send({ embeds: [embed] });
}
Acione essa função a partir de um script que monitora o status do Castle Siege no banco do jogo ou via webhook disparado pelo próprio GameServer, se o emulador suportar.
Passo 7 — Ranking de reset atualizado no Discord
Publique um ranking automático dos membros da guilda, atualizado periodicamente, em vez de depender do site:
async function publicarRanking() {
const membros = await fetch(`${API_BASE}/guild_membros.php?guild=Legends`).then(r => r.json());
const ordenado = membros.sort((a, b) => b.resets - a.resets).slice(0, 10);
const texto = ordenado.map((m, i) => `${i + 1}. **${m.nome}** — Reset ${m.resets}, Lv ${m.nivel}`).join('\n');
canalRanking.send(`📊 **Ranking da Guild — atualizado agora**\n${texto}`);
}
Passo 8 — Comandos úteis para os membros
Ofereça comandos de barra (slash commands) para autoatendimento, reduzindo perguntas repetidas no chat:
| Comando | Função |
|---|---|
/personagem <nome> | Mostra nível, reset, classe do personagem |
/vincular <nome> | Vincula a conta Discord ao personagem in-game |
/proximoboss | Mostra o próximo boss agendado |
/eventohoje | Lista os eventos programados do dia |
/status | Mostra se o servidor está online e jogadores conectados |
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Cargos não sincronizam | Vínculo Discord-personagem ausente ou API fora do ar | Verificar tabela de vínculo e disponibilidade da API |
| Bot expulsa cargo de membro que ainda está na guild | Nome da guild com diferença de maiúsculas/case sensitivity na query | Normalizar comparação de nomes (case-insensitive) |
| Alerta de boss chega atrasado ou não chega | Cron do bot não está rodando ou processo caiu | Adicionar monitoramento/restart automático do processo do bot |
| Ranking desatualizado | Intervalo de atualização configurado longo demais | Reduzir intervalo ou disparar atualização por evento |
| Bot com acesso de escrita ao banco por engano | Configuração de usuário do banco sem restrição de permissão | Criar usuário de banco somente leitura dedicado ao bot |
| Token do bot vazado/comprometido | Token commitado no repositório ou compartilhado | Revogar e gerar novo token, mover para variável de ambiente |
Checklist de integração da guilda com Discord
- Estrutura de canais definida (anúncios, boss, castle siege, ranking, recrutamento).
- Bot próprio criado com permissões mínimas necessárias no servidor.
- API somente leitura exposta sobre o banco do MuServer para o bot consumir.
- Comando de vínculo entre conta Discord e personagem implementado.
- Sincronização automática de cargos rodando periodicamente.
- Alertas de boss e Castle Siege configurados e testados.
- Ranking automático publicado em canal dedicado.
- Comandos de autoatendimento (slash commands) disponíveis para os membros.
Com a guilda operando de forma automatizada no Discord, vale revisar também a integração do servidor como um todo com a comunidade — do fórum à página pública de status. Veja o guia de criação de servidor de MU Online para revisar a base completa do projeto.
Perguntas frequentes
Preciso saber programar para ter um bot de guilda no Discord?
Não obrigatoriamente. Existem bots genéricos configuráveis (MEE6, Carl-bot) que cobrem cargos e moderação básica. Mas para sincronizar dados reais do jogo (nível, reset, presença em boss) você vai precisar de um bot próprio ou de uma integração customizada, ainda que simples.
É seguro dar ao bot acesso ao banco de dados do servidor?
Só com acesso de leitura e por uma conexão restrita (idealmente uma API própria, não conexão direta ao banco de produção). Nunca dê ao bot credenciais de escrita no banco do jogo — ele deve consultar dados, não alterá-los.
Como o bot sabe quando um boss vai nascer?
Consultando a tabela de spawn de monstros do MuServer ou os logs do GameServer, ou de forma mais simples, com um calendário de horários fixos configurado manualmente se os spawns forem previsíveis. Bosses com spawn aleatório dentro de uma janela exigem monitoramento mais próximo do banco/log.
Vale a pena ter um bot separado para cada guilda ou um bot único do servidor?
Depende do tamanho da comunidade. Um bot único do servidor, com comandos filtrados por guild do jogador, atende bem a maioria dos casos e é mais fácil de manter. Bots por guilda fazem sentido em comunidades muito grandes com guildas que querem autonomia total de configuração.
O bot pode expulsar automaticamente quem sai da guilda no jogo?
Sim, se o bot consulta periodicamente a tabela de membros da guild no banco do MuServer e compara com os membros do servidor Discord, removendo o cargo (ou o acesso) de quem não está mais na guild in-game.