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

Cómo Configurar un Sistema de Premios y Tiempo Online en tu Servidor MU

Aprende a configurar un sistema automatizado de seguimiento de tiempo online y entrega de premios en tu servidor privado de MU Online.

EQ Equipo ViciadosMU · Actualizado el 4 jul 2026 · ⏱ 18 min de lectura

Descripcion General y Objetivos

Un sistema de premios vinculado al tiempo en linea es una de las herramientas mas eficaces que un administrador de servidor MU Online puede implementar para mejorar la retencion de jugadores y el compromiso diario. En lugar de depender exclusivamente de eventos o distribuciones manuales por parte del GM, un sistema automatizado registra cuanto tiempo permanece conectada cada cuenta y entrega premios incrementales — Zen, items o fichas personalizadas — al alcanzar hitos definidos.

Esta guia recorre la implementacion completa: diseno del esquema de base de datos, logica del procedimiento almacenado, programacion del trabajo de premios y conexion de la salida con la economia del juego. Todos los ejemplos usan Microsoft SQL Server, que es el backend estandar para el software de servidores MU Online de Season 6 y Season 9.

Nota: Esta guia asume que ya tienes un servidor MU Online en funcionamiento con acceso a la base de datos MuOnline mediante SQL Server Management Studio. Debes sentirte comodo escribiendo procedimientos almacenados basicos en T-SQL y programando trabajos del Agente SQL.

Esquema de Base de Datos para el Seguimiento de Tiempo

Antes de escribir cualquier logica, necesitas dos tablas de soporte. La primera registra los eventos de sesion en bruto; la segunda almacena los totales agregados que se usan en el calculo de premios.

-- Registro de eventos de sesion
-- → Captura las marcas de tiempo de inicio y cierre de sesion por cuenta
CREATE TABLE AccountTimeLog (
    LogID        INT IDENTITY(1,1) PRIMARY KEY,
    AccountID    VARCHAR(10)  NOT NULL,  -- → referencia a MEMB_INFO.memb___id
    CharName     VARCHAR(10)  NOT NULL,
    EventType    CHAR(1)      NOT NULL,  -- → 'L' = login, 'O' = logout
    EventTime    DATETIME     NOT NULL DEFAULT GETDATE(),
    ServerCode   TINYINT      NOT NULL DEFAULT 0
);

-- Tabla de acumulacion de premios
-- → Una fila por cuenta, actualizada por el trabajo programado
CREATE TABLE AccountRewards (
    AccountID       VARCHAR(10)  NOT NULL PRIMARY KEY,
    TotalMinutes    INT          NOT NULL DEFAULT 0,
    LastRewardTier  INT          NOT NULL DEFAULT 0,  -- → indice del ultimo hito reclamado
    PendingZen      BIGINT       NOT NULL DEFAULT 0,
    PendingTokens   INT          NOT NULL DEFAULT 0,
    LastUpdated     DATETIME     NOT NULL DEFAULT GETDATE()
);

La columna EventType usa codigos de un solo caracter para mantener el registro compacto. Los ganchos de inicio y cierre de sesion de tu servidor escriben en AccountTimeLog; el trabajo programado lee de ahi y actualiza AccountRewards.

> [!CONSEJO] > Agrega un indice en AccountTimeLog (AccountID, EventTime) de inmediato. Sin el, la consulta de agregacion realizara un escaneo completo de la tabla cada vez que se ejecute el trabajo, y el rendimiento se degradara rapidamente a medida que el registro crezca.


Calculo del Tiempo Online Acumulado

La logica de agregacion central empareja los eventos de inicio de sesion con el evento de cierre mas proximo posterior para la misma cuenta. Este enfoque es robusto ante caidas del servidor: si no existe un cierre de sesion, el calculo usa la marca de tiempo actual como fin de sesion.

-- Procedimiento almacenado: calcular y acreditar minutos online
-- → Ejecutar en un horario (se recomienda cada 10 minutos)
CREATE PROCEDURE sp_UpdateOnlineTime
AS
BEGIN
    SET NOCOUNT ON;

    -- Paso 1 → Calcular duraciones de sesion desde el registro
    ;WITH SessionPairs AS (
        SELECT
            l.AccountID,
            l.EventTime AS LoginTime,
            ISNULL(
                (SELECT MIN(o.EventTime)
                 FROM AccountTimeLog o
                 WHERE o.AccountID  = l.AccountID
                   AND o.EventType  = 'O'
                   AND o.EventTime  > l.EventTime),
                GETDATE()           -- → tratar sesion activa como en progreso
            ) AS LogoutTime
        FROM AccountTimeLog l
        WHERE l.EventType = 'L'
    ),
    SessionMinutes AS (
        SELECT
            AccountID,
            SUM(DATEDIFF(MINUTE, LoginTime, LogoutTime)) AS EarnedMinutes
        FROM SessionPairs
        GROUP BY AccountID
    )

    -- Paso 2 → Insertar o actualizar en AccountRewards
    MERGE AccountRewards AS destino
    USING SessionMinutes  AS origen ON destino.AccountID = origen.AccountID
    WHEN MATCHED THEN
        UPDATE SET
            TotalMinutes = origen.EarnedMinutes,
            LastUpdated  = GETDATE()
    WHEN NOT MATCHED THEN
        INSERT (AccountID, TotalMinutes, LastUpdated)
        VALUES (origen.AccountID, origen.EarnedMinutes, GETDATE());
END;

Este procedimiento recalcula el total de por vida desde el registro en cada ejecucion. Para servidores con muchos jugadores, puede preferirse un enfoque incremental: registrar el ultimo LogID procesado y agregar solo las filas nuevas desde la ejecucion anterior.


Definicion de Niveles de Premios y Entrega de Recompensas

Con los minutos acumulados almacenados en AccountRewards, un segundo procedimiento almacenado compara el total de cada cuenta con una tabla de niveles y entrega premios por los umbrales recien superados.

-- Referencia de niveles de premios (ajusta los valores segun la economia de tu servidor)
-- → TierID | MinutosRequeridos | PremioZen | PremioFichas | Descripcion
-- →      1 |               60 |    500000 |            1 | 1 Hora Online
-- →      2 |              300 |   2000000 |            5 | 5 Horas Online
-- →      3 |              720 |   5000000 |           12 | 12 Horas Online
-- →      4 |             1440 |  10000000 |           25 | 24 Horas Online

CREATE TABLE RewardTiers (
    TierID          INT    PRIMARY KEY,
    MinutesRequired INT    NOT NULL,
    ZenReward       BIGINT NOT NULL DEFAULT 0,
    TokenReward     INT    NOT NULL DEFAULT 0,
    Description     VARCHAR(50)
);

-- Procedimiento almacenado: otorgar premios por nuevos niveles alcanzados
CREATE PROCEDURE sp_GrantOnlineRewards
AS
BEGIN
    SET NOCOUNT ON;

    -- Encontrar cuentas que han superado nuevos umbrales de nivel
    UPDATE ar
    SET
        PendingZen    = ar.PendingZen    + rt.ZenReward,
        PendingTokens = ar.PendingTokens + rt.TokenReward,
        LastRewardTier = rt.TierID
    FROM AccountRewards ar
    INNER JOIN RewardTiers rt
        ON rt.TierID = ar.LastRewardTier + 1   -- → proximo nivel no reclamado
       AND ar.TotalMinutes >= rt.MinutesRequired;
END;

Las columnas de pendientes funcionan como una cola. Tu servidor de juego lee PendingZen y PendingTokens al iniciar sesion o mediante un ciclo de sondeo, acredita al personaje y luego restablece esas columnas a cero. Esto desacopla el trabajo de base de datos del proceso del juego en vivo y previene la doble entrega.

> [!ATENCION] > Nunca escribas Zen o items directamente en las columnas del personaje desde un trabajo externo mientras el servidor de juego esta en funcionamiento. El motor del juego mantiene estado en memoria para los personajes conectados y sobreescribira tus cambios en el proximo ciclo de guardado. Usa siempre un patron de cola de pendientes y deja que el proceso del juego consuma los premios de forma segura.


Programacion del Trabajo con el Agente de SQL Server

Abre SQL Server Management Studio, expande el nodo del Agente SQL Server y crea un nuevo trabajo con dos pasos:

  • Paso 1 — Ejecutar sp_UpdateOnlineTime
  • Paso 2 — Ejecutar sp_GrantOnlineRewards

Configura el horario para que se repita cada 10 minutos, comenzando en el horario de inicio del servidor. Ponle un nombre descriptivo al trabajo, como MU_OnlineRewardJob, para identificarlo facilmente en la lista de trabajos.

Si prefieres un enfoque basado en scripts para reproducibilidad:

-- Programar el trabajo mediante T-SQL
EXEC msdb.dbo.sp_add_job
    @job_name = N'MU_OnlineRewardJob';

EXEC msdb.dbo.sp_add_jobstep
    @job_name   = N'MU_OnlineRewardJob',
    @step_name  = N'UpdateOnlineTime',
    @command    = N'EXEC MuOnline.dbo.sp_UpdateOnlineTime';

EXEC msdb.dbo.sp_add_jobstep
    @job_name   = N'MU_OnlineRewardJob',
    @step_name  = N'GrantRewards',
    @command    = N'EXEC MuOnline.dbo.sp_GrantOnlineRewards';

EXEC msdb.dbo.sp_add_schedule
    @schedule_name        = N'Cada10Minutos',
    @freq_type            = 4,   -- → diario
    @freq_interval        = 1,
    @freq_subday_type     = 4,   -- → minutos
    @freq_subday_interval = 10;

EXEC msdb.dbo.sp_attach_schedule
    @job_name      = N'MU_OnlineRewardJob',
    @schedule_name = N'Cada10Minutos';

EXEC msdb.dbo.sp_add_jobserver
    @job_name = N'MU_OnlineRewardJob';

Mantenimiento y Monitoreo

Una vez que el sistema esta en produccion, el mantenimiento de rutina garantiza precision y buen rendimiento.

Archivado del registro. La tabla AccountTimeLog crecera de forma continua. Agrega un trabajo mensual de limpieza que mueva las filas de mas de 90 dias a una tabla de archivo o las elimine si no se requieren reportes historicos.

Ajuste de niveles. Los niveles de premios viven en RewardTiers, por lo que puedes ajustar los valores de Zen y fichas, o agregar nuevos hitos, sin modificar los procedimientos almacenados. Los cambios entran en vigor en la siguiente ejecucion del trabajo.

Visualizacion para el jugador. Considera exponer los minutos acumulados y el proximo umbral de premio a traves del sitio web del servidor o de un NPC en el juego, usando una consulta de solo lectura contra AccountRewards. La transparencia aumenta la motivacion y reduce los tickets de soporte que preguntan cuando llega el premio.

> [!CONSEJO] > Registra cada entrega de premio en una tabla de auditoria separada con una marca de tiempo y el nivel otorgado. Esto te da un historial claro para resolver disputas de jugadores y te ayuda a identificar si los umbrales de nivel estan correctamente calibrados para la duracion media de sesion en tu servidor.

Con estos componentes en su lugar — esquema, procedimiento de calculo, procedimiento de entrega de premios y un trabajo programado — tu servidor cuenta con un sistema de premios por tiempo online completamente automatizado, respaldado por base de datos, que funciona sin intervencion manual y escala limpiamente a medida que crece tu base de jugadores.

Perguntas frequentes

¿Qué tablas de base de datos son necesarias para el sistema de tiempo online?

Necesitas al menos dos tablas: una para registrar los eventos de sesión (inicio y cierre) por cuenta, por ejemplo AccountTimeLog, y otra para almacenar los minutos acumulados y los umbrales de premios, por ejemplo AccountRewards. Ambas deben referenciar el AccountID como clave foránea hacia la tabla MEMB_INFO.

¿Con qué frecuencia debe ejecutarse el trabajo de verificación de premios?

Un trabajo del Agente SQL o un procedimiento almacenado programado que se ejecute cada 5 a 15 minutos es la configuración ideal. Ejecutarlo con demasiada frecuencia desperdicia recursos de la base de datos; ejecutarlo con poca frecuencia hace que la entrega de premios se perciba con retraso. La mayoría de los administradores usan un intervalo de 10 minutos como valor equilibrado.

¿Pueden entregarse premios en Zen, en ítems o en ambos?

Sí. El procedimiento almacenado puede escribirse para insertar filas en la tabla de inventario del personaje para premios en ítems, añadir Zen directamente a la columna Money del personaje, o actualizar una tabla de premios pendientes que el manejador de eventos del servidor de juego lee y procesa durante el próximo inicio de sesión o cambio de zona.

¿Cómo evito que los jugadores exploten el tiempo AFK para acumular minutos online?

Agrega una verificación de actividad a la lógica de seguimiento de sesión. Consulta la posición del personaje y la marca de tiempo de la última acción en la base de datos del juego en cada intervalo. Si la posición no ha cambiado y no se ha registrado ninguna acción de habilidad o chat en los últimos N minutos, marca la sesión como inactiva y pausa el contador de tiempo acumulado para esa cuenta.

EQ

Equipo ViciadosMU

Equipe editorial do ViciadosMU — portal de MU Online no ar desde 2003.

Sigue leyendo

Artículos relacionados