Como configurar o sistema de VIP e benefícios no MU Online
Monte um sistema de VIP completo no seu servidor de MU Online — tabela de controle, níveis, bônus de EXP e drop, benefícios exclusivos e integração com o site.
Um sistema de VIP bem feito é o pilar de sustentação da maioria dos servidores privados de MU Online. Ele recompensa os jogadores que apoiam o projeto com bônus recorrentes — mais experiência, mais drop, acessos exclusivos — e, ao mesmo tempo, dá previsibilidade para você custear VPS, proteção anti-
Um sistema de VIP bem feito é o pilar de sustentação da maioria dos servidores privados de MU Online. Ele recompensa os jogadores que apoiam o projeto com bônus recorrentes — mais experiência, mais drop, acessos exclusivos — e, ao mesmo tempo, dá previsibilidade para você custear VPS, proteção anti-DDoS e desenvolvimento. Mas VIP mal configurado tem dois efeitos colaterais graves: se os bônus forem exagerados, ele quebra o balanceamento e afasta quem não paga; se a expiração não funcionar, você entrega benefícios eternos por engano. Este guia mostra como montar o sistema do zero, cobrindo banco de dados, arquivo de configuração, tipos de benefício e a integração com o site.
Os exemplos usam o schema clássico do MuServer (SQL Server, banco MuOnline, tabela MEMB_INFO) e a seção [VIP] do arquivo de configuração do GameServer. Nomes de tabela, colunas e parâmetros variam por season/emulador — trate cada trecho como um exemplo a adaptar ao seu servidor.
Como o sistema de VIP funciona
O ciclo de vida de um VIP passa por quatro momentos:
1. Ativação (site, doação ou comando de GM)
│
2. Grava/atualiza a linha na tabela de VIP
com data de início e expiração
│
3. Ao logar, o GameServer lê o status VIP
e aplica os multiplicadores de EXP/Drop/Zen
│
4. Verificação periódica: se a data expirou,
o status volta a normal e os bônus somem
Repare que o servidor não "empurra" o VIP em tempo real: ele consulta a tabela ao logar e em um intervalo definido. Isso significa que quase toda a lógica vive em dois lugares — a tabela de controle e o arquivo de configuração — e é por aí que começamos.
Pré-requisitos
Antes de configurar, garanta que você tem:
- Servidor de MU funcional (GameServer, ConnectServer e banco no ar). Se ainda não chegou nesse ponto, siga primeiro o guia de como criar servidor de MU Online.
- Acesso ao SQL Server com permissão para criar tabelas e procedures no banco de jogo.
- Acesso aos arquivos de configuração do GameServer (geralmente em
GameServer/Data/ou similar). - Backup do banco antes de criar tabelas novas.
- Site do servidor (se for automatizar a venda/doação de VIP), com conexão PHP/PDO ao banco.
- Plano de níveis definido: quantos níveis, quais bônus e por quanto tempo.
Passo 1 — Criar a tabela de controle de VIP
Algumas distribuições já trazem essa tabela. Se a sua não tem, crie uma dedicada — é mais limpo do que espalhar colunas pela MEMB_INFO:
USE MuOnline;
GO
CREATE TABLE MEMB_VIP (
AccountID VARCHAR(10) NOT NULL, -- login (FK lógica para MEMB_INFO)
VipLevel TINYINT NOT NULL DEFAULT 1, -- 1=Bronze, 2=Prata, 3=Ouro
StartDate DATETIME NOT NULL DEFAULT GETDATE(),
ExpireDate DATETIME NOT NULL, -- data de expiração
Active TINYINT NOT NULL DEFAULT 1, -- 1=ativo, 0=expirado
CONSTRAINT PK_MEMB_VIP PRIMARY KEY (AccountID)
);
GO
-- Índice para o GameServer varrer expirações rapidamente
CREATE INDEX IX_VIP_Expire ON MEMB_VIP (ExpireDate, Active);
GO
Alternativa: colunas na MEMB_INFO
Distribuições que esperam o VIP embutido às vezes leem direto da conta:
ALTER TABLE MEMB_INFO ADD VipLevel TINYINT DEFAULT 0;
ALTER TABLE MEMB_INFO ADD VipExpire DATETIME NULL;
GO
Verifique qual modelo a sua distribuição usa antes de escolher — o GameServer só aplica o VIP se ler da estrutura que ele espera.
Passo 2 — Ativar VIP para uma conta
Para dar ou estender VIP, o padrão é: se já existe, estende a partir da maior data entre "agora" e a expiração atual (assim ninguém perde dias ao renovar); se não existe, cria.
-- Dar/estender VIP nível 1 por 30 dias para a conta 'jogador01'
IF EXISTS (SELECT 1 FROM MEMB_VIP WHERE AccountID = 'jogador01')
UPDATE MEMB_VIP
SET ExpireDate = DATEADD(DAY, 30,
CASE WHEN ExpireDate > GETDATE() THEN ExpireDate ELSE GETDATE() END),
VipLevel = 1,
Active = 1
WHERE AccountID = 'jogador01';
ELSE
INSERT INTO MEMB_VIP (AccountID, VipLevel, StartDate, ExpireDate)
VALUES ('jogador01', 1, GETDATE(), DATEADD(DAY, 30, GETDATE()));
GO
Empacotar isso numa procedure evita repetição e facilita a chamada pelo site:
CREATE PROCEDURE sp_AtivarVIP
@conta VARCHAR(10),
@nivel TINYINT = 1,
@dias INT = 30
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM MEMB_INFO WHERE memb___id = @conta)
BEGIN RAISERROR('Conta inexistente', 16, 1); RETURN; END;
IF EXISTS (SELECT 1 FROM MEMB_VIP WHERE AccountID = @conta)
UPDATE MEMB_VIP
SET ExpireDate = DATEADD(DAY, @dias,
CASE WHEN ExpireDate > GETDATE() THEN ExpireDate ELSE GETDATE() END),
VipLevel = @nivel, Active = 1
WHERE AccountID = @conta;
ELSE
INSERT INTO MEMB_VIP (AccountID, VipLevel, StartDate, ExpireDate)
VALUES (@conta, @nivel, GETDATE(), DATEADD(DAY, @dias, GETDATE()));
END;
GO
-- Uso:
EXEC sp_AtivarVIP 'jogador01', 2, 30; -- VIP Prata por 30 dias
Passo 3 — Configurar os bônus no arquivo do GameServer
Aqui é onde o VIP "ganha efeito". A seção exata varia por season/emulador, mas o formato costuma ser parecido com este:
; ===== SISTEMA VIP =====
[VIP]
Enable = 1 ; liga o sistema de VIP
; --- Nível 1 (Bronze) ---
VIP1_ExpRate = 150 ; +50% de EXP (150% do valor base) — formato varia
VIP1_DropRate = 130 ; +30% de drop
VIP1_ZenRate = 120 ; +20% de zen
; --- Nível 2 (Prata) ---
VIP2_ExpRate = 200 ; +100% de EXP
VIP2_DropRate = 150
VIP2_ZenRate = 140
; --- Nível 3 (Ouro) ---
VIP3_ExpRate = 300 ; +200% de EXP
VIP3_DropRate = 200
VIP3_ZenRate = 180
CheckInterval = 60 ; segundos entre verificações de expiração
ExpireNotify = 1 ; avisa o jogador quando o VIP expira
> Atenção ao formato do multiplicador: algumas distribuições usam porcentagem (150 = +50%), outras usam fator absoluto (2 = 2x), e outras somam ao rate base. Leia o arquivo da sua distribuição e teste com um personagem antes de anunciar os números aos jogadores.
Depois de editar, reinicie o GameServer para carregar a configuração.
Passo 4 — Escolher os benefícios de cada nível
Bônus de EXP e drop são o começo, não o fim. A tabela abaixo lista benefícios comuns e como cada um costuma ser implementado. Nem todos existem em toda season — confirme o suporte na sua distribuição.
| Benefício | Onde se configura | Observação |
|---|---|---|
| EXP aumentado | VIPx_ExpRate no config do GS | Bônus mais valorizado; não exagere |
| Drop aumentado | VIPx_DropRate no config do GS | Impacta a economia — ajuste com cuidado |
| Zen extra | VIPx_ZenRate no config do GS | Efeito inflacionário se muito alto |
| Acesso a mapa exclusivo | Checagem de VIP no mapa (config/GS) | Move de gate + spot melhor |
| Slots extras de personagem | Coluna de slots na MEMB_INFO | Depende da distribuição |
| Comando exclusivo (ex.: /offlevel) | Verificação de nível VIP no handler | Nem toda season tem |
| Baú/armazém expandido | Config do warehouse por VIP | Requer suporte da distribuição |
| Nome colorido/tag VIP | Prefixo no nome | Cosmético, alta percepção de valor |
Uma estrutura de níveis equilibrada, apenas como exemplo (os valores variam por season/emulador e pelo seu público):
| Nível | Duração | EXP | Drop | Extra |
|---|---|---|---|---|
| Bronze | 30 dias | +50% | +30% | Tag VIP |
| Prata | 30 dias | +100% | +50% | Tag + acesso a mapa VIP |
| Ouro | 30 dias | +200% | +100% | Tudo + slot extra + comando |
> Os preços e a decisão de monetizar são seus. Servidores privados de MU têm restrições de direitos autorais; mantenha o projeto como hobby sem fins lucrativos e trate valores apenas como referência de estruturação.
Passo 5 — Consultar e gerenciar VIPs
Ter comandos SQL de manutenção à mão evita dor de cabeça no dia a dia.
-- VIPs ativos e dias restantes
SELECT AccountID, VipLevel,
DATEDIFF(DAY, GETDATE(), ExpireDate) AS DiasRestantes
FROM MEMB_VIP
WHERE ExpireDate > GETDATE() AND Active = 1
ORDER BY ExpireDate ASC;
GO
-- Marcar expirados (rode como job agendado)
UPDATE MEMB_VIP
SET Active = 0
WHERE ExpireDate < GETDATE() AND Active = 1;
GO
-- Remover VIP de uma conta manualmente
UPDATE MEMB_VIP
SET Active = 0, ExpireDate = GETDATE()
WHERE AccountID = 'jogador01';
GO
Agende o UPDATE de expiração como um SQL Server Agent Job (a cada hora, por exemplo) para manter a tabela coerente mesmo que o GameServer não faça a limpeza.
Passo 6 — Integrar com o site
O objetivo final é dar VIP sem intervenção manual após uma doação confirmada. Do lado do site (PHP/PDO), a chamada é simples porque a lógica está na procedure:
<?php
// dar-vip.php — chamado após confirmar o pagamento
function ativarVip(PDO $db, string $conta, int $nivel, int $dias): bool {
$stmt = $db->prepare("EXEC sp_AtivarVIP :conta, :nivel, :dias");
$stmt->bindValue(':conta', $conta);
$stmt->bindValue(':nivel', $nivel, PDO::PARAM_INT);
$stmt->bindValue(':dias', $dias, PDO::PARAM_INT);
return $stmt->execute();
}
// Uso, após validar a confirmação de pagamento do provedor:
// ativarVip($db, $contaDoUsuario, 2, 30);
Boas práticas de integração:
- Valide a confirmação no servidor, nunca confie apenas no retorno do navegador do usuário.
- Registre um log de cada ativação (conta, nível, dias, data, referência do pagamento) para auditoria e suporte.
- Seja idempotente: se o mesmo pagamento for notificado duas vezes, não conceda o benefício em dobro (guarde o ID da transação já processada).
- Mostre no site os dias restantes de VIP do jogador, lendo a
MEMB_VIP— reduz tickets de suporte.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Bônus de VIP não aplicam | Seção do config errada ou Enable=0 | Confirme o nome exato da seção e reinicie o GS |
| VIP não expira nunca | Job de expiração ausente e GS não checa | Crie o job SQL de UPDATE Active=0 por hora |
| Jogador reclama que perdeu dias ao renovar | Renovação sobrescreveu a data em vez de estender | Use o CASE WHEN ExpireDate > GETDATE() para estender |
| VIP concedido em dobro | Webhook de pagamento processado duas vezes | Torne a ativação idempotente por ID de transação |
| EXP absurdamente alto | Formato do multiplicador mal interpretado | Teste com personagem; confirme se é % ou fator |
| Site diz "conta inexistente" | Diferença de maiúsculas/espaços no login | Normalize o login antes de chamar a procedure |
Checklist de lançamento
- Backup do banco feito antes de criar tabelas/procedures
- Tabela
MEMB_VIP(ou colunas equivalentes) criada e indexada - Procedure
sp_AtivarVIPcriada e testada com uma conta real - Seção
[VIP]do config preenchida e GameServer reiniciado - Multiplicadores testados com personagem (formato % vs fator confirmado)
- Níveis e benefícios documentados para a equipe e para os jogadores
- Job SQL de expiração agendado e validado
- Integração com o site testada com um pagamento de teste
- Ativação idempotente confirmada (notificação dupla não duplica VIP)
- Painel do jogador mostrando dias restantes de VIP
- Log de ativações funcionando para auditoria e suporte
Perguntas frequentes
Preciso modificar o executável do GameServer para ter VIP?
Na maioria das distribuições não. O suporte a VIP já vem embutido e é ativado pelo arquivo de configuração e por uma tabela no banco. Só distribuições muito antigas exigem edição de código para tratar níveis.
Quantos níveis de VIP devo criar?
Três costuma ser o equilíbrio ideal — algo como Bronze, Prata e Ouro. Menos que isso limita a progressão de valor; mais que isso confunde o jogador e dá trabalho de balancear os bônus de cada camada.
Como o servidor sabe quando o VIP expirou?
O GameServer verifica a data de expiração da tabela de VIP em um intervalo configurável e ao logar. Quando a data passa, o status é revertido e os bônus deixam de ser aplicados na sessão seguinte.
Posso dar VIP automaticamente após uma doação no site?
Sim. O fluxo padrão é: o site recebe a confirmação de pagamento, chama uma procedure ou faz um UPDATE na tabela de VIP com a nova data de expiração, e o GameServer aplica os bônus na próxima sessão do jogador.
VIP e Cash Shop são a mesma coisa?
Não. VIP concede bônus recorrentes por tempo (EXP, drop, acessos) enquanto a assinatura está ativa. O Cash Shop vende itens avulsos por moeda virtual. Muitos servidores usam os dois sistemas juntos.